Tested first run

This commit is contained in:
Mike Phares 2022-08-29 19:30:36 -07:00
parent 659e0e39bf
commit 753eeaba2a
26 changed files with 711 additions and 458 deletions

View File

@ -54,8 +54,8 @@ public class Compare
bool reverse = false; bool reverse = false;
string outputExtension = ".jpg"; string outputExtension = ".jpg";
PredictorModel? predictorModel = null; PredictorModel? predictorModel = null;
Dictionary<string, Shared.Models.Person> personKeyValuePairs = new(); Shared.Models.Person[] people = Array.Empty<Shared.Models.Person>();
Map.Models.MapLogic mapLogic = new(_AppSettings.MaxDegreeOfParallelism, propertyConfiguration, outputExtension, personKeyValuePairs); Map.Models.MapLogic mapLogic = new(_AppSettings.MaxDegreeOfParallelism, propertyConfiguration, outputExtension, people);
A_Property propertyLogic = GetPropertyLogic(reverse, model, outputExtension, predictorModel, mapLogic); A_Property propertyLogic = GetPropertyLogic(reverse, model, outputExtension, predictorModel, mapLogic);
foreach (string spelling in configuration.Spelling) foreach (string spelling in configuration.Spelling)
{ {

View File

@ -5,6 +5,7 @@ using System.Drawing.Imaging;
using System.Text.Json; using System.Text.Json;
using View_by_Distance.FaceRecognitionDotNet; using View_by_Distance.FaceRecognitionDotNet;
using View_by_Distance.Instance.Models; using View_by_Distance.Instance.Models;
using View_by_Distance.Map.Models;
using View_by_Distance.Metadata.Models; using View_by_Distance.Metadata.Models;
using View_by_Distance.Property.Models; using View_by_Distance.Property.Models;
using View_by_Distance.Resize.Models; using View_by_Distance.Resize.Models;
@ -74,7 +75,8 @@ public class DlibDotNet
else else
{ {
_FirstRun = true; _FirstRun = true;
_ = Directory.CreateDirectory(propertyRoot); string peopleDateGroupDirectory = Property.Models.Stateless.IResult.GetResultsDateGroupDirectory(propertyConfiguration, nameof(A2_People), "()");
File.WriteAllText(Path.Combine(peopleDateGroupDirectory, "KnownPeople.txt"), string.Empty);
} }
if (_FirstRun || !_ArgZeroIsConfigurationRootDirectory) if (_FirstRun || !_ArgZeroIsConfigurationRootDirectory)
people = Array.Empty<Person>(); people = Array.Empty<Person>();
@ -92,14 +94,15 @@ public class DlibDotNet
} }
{ {
(ImageCodecInfo imageCodecInfo, EncoderParameters encoderParameters, string filenameExtension) = C_Resize.GetPngLowQuality(); (ImageCodecInfo imageCodecInfo, EncoderParameters encoderParameters, string filenameExtension) = C_Resize.GetPngLowQuality();
_Faces = new D_Face(configuration, argZero, model, modelParameter, predictorModel, imageCodecInfo, encoderParameters, filenameExtension); (ImageCodecInfo hiddenImageCodecInfo, EncoderParameters hiddenEncoderParameters, string hiddenFilenameExtension) = C_Resize.GetGifLowQuality();
_Faces = new D_Face(configuration, argZero, model, modelParameter, predictorModel, imageCodecInfo, encoderParameters, filenameExtension, hiddenImageCodecInfo, hiddenEncoderParameters, hiddenFilenameExtension);
} }
{ {
(ImageCodecInfo imageCodecInfo, EncoderParameters encoderParameters, string filenameExtension) = C_Resize.GetTuple(configuration.OutputExtension, configuration.OutputQuality); (ImageCodecInfo imageCodecInfo, EncoderParameters encoderParameters, string filenameExtension) = C_Resize.GetTuple(configuration.OutputExtension, configuration.OutputQuality);
_Resize = new C_Resize(configuration.ForceResizeLastWriteTimeToCreationTime, configuration.OverrideForResizeImages, configuration.PropertiesChangedForResize, configuration.ValidResolutions, imageCodecInfo, encoderParameters, filenameExtension); _Resize = new C_Resize(configuration.ForceResizeLastWriteTimeToCreationTime, configuration.OverrideForResizeImages, configuration.PropertiesChangedForResize, configuration.ValidResolutions, imageCodecInfo, encoderParameters, filenameExtension);
} }
if (!configuration.SkipSearch) if (!configuration.SkipSearch)
Search(propertyConfiguration, model, predictorModel, argZero, propertyRoot, people, isSilent); Search(propertyConfiguration, model, predictorModel, argZero, propertyRoot, people);
if (!_FirstRun && _Exceptions.Count == 0 && _ArgZeroIsConfigurationRootDirectory) if (!_FirstRun && _Exceptions.Count == 0 && _ArgZeroIsConfigurationRootDirectory)
{ {
long ticks = DateTime.Now.Ticks; long ticks = DateTime.Now.Ticks;
@ -273,6 +276,7 @@ public class DlibDotNet
Shared.Models.Property property; Shared.Models.Property property;
List<Face> faceCollection; List<Face> faceCollection;
string original = "Original"; string original = "Original";
FileHolder? resizedFileHolder;
long ticks = DateTime.Now.Ticks; long ticks = DateTime.Now.Ticks;
DateTime dateTime = DateTime.Now; DateTime dateTime = DateTime.Now;
List<string> parseExceptions = new(); List<string> parseExceptions = new();
@ -298,8 +302,6 @@ public class DlibDotNet
(int metadataGroups, metadataCollection) = _Metadata.GetMetadataCollection(bResultsFullGroupDirectory, subFileTuples, parseExceptions, item); (int metadataGroups, metadataCollection) = _Metadata.GetMetadataCollection(bResultsFullGroupDirectory, subFileTuples, parseExceptions, item);
if (_AppSettings.MaxDegreeOfParallelism < 2) if (_AppSettings.MaxDegreeOfParallelism < 2)
ticks = LogDelta(ticks, nameof(B_Metadata.GetMetadataCollection)); ticks = LogDelta(ticks, nameof(B_Metadata.GetMetadataCollection));
FileHolder resizedFileHolder = new(Path.Combine(_Resize.AngleBracketCollection[0].Replace("<>", "()"), Path.GetFileName(item.ImageFileHolder.FullName)));
item.SetResizedFileHolder(_Resize.FilenameExtension, resizedFileHolder);
imageResizeKeyValuePairs = _Resize.GetResizeKeyValuePairs(cResultsFullGroupDirectory, subFileTuples, parseExceptions, original, metadataCollection, item); imageResizeKeyValuePairs = _Resize.GetResizeKeyValuePairs(cResultsFullGroupDirectory, subFileTuples, parseExceptions, original, metadataCollection, item);
if (_AppSettings.MaxDegreeOfParallelism < 2) if (_AppSettings.MaxDegreeOfParallelism < 2)
ticks = LogDelta(ticks, nameof(C_Resize.GetResizeKeyValuePairs)); ticks = LogDelta(ticks, nameof(C_Resize.GetResizeKeyValuePairs));
@ -308,11 +310,10 @@ public class DlibDotNet
_Resize.SaveResizedSubfile(outputResolution, cResultsFullGroupDirectory, subFileTuples, item, original, imageResizeKeyValuePairs); _Resize.SaveResizedSubfile(outputResolution, cResultsFullGroupDirectory, subFileTuples, item, original, imageResizeKeyValuePairs);
if (_AppSettings.MaxDegreeOfParallelism < 2) if (_AppSettings.MaxDegreeOfParallelism < 2)
ticks = LogDelta(ticks, nameof(C_Resize.SaveResizedSubfile)); ticks = LogDelta(ticks, nameof(C_Resize.SaveResizedSubfile));
item.SetResizedFileHolder(_Resize.FilenameExtension, Shared.Models.Stateless.Methods.IFileHolder.Refresh(resizedFileHolder));
} }
else if (outputResolution == _Configuration.OutputResolutions[0] && false) else if (outputResolution == _Configuration.OutputResolutions[0] && false)
{ {
byte[] bytes = _Resize.GetResizedBytes(outputResolution, cResultsFullGroupDirectory, subFileTuples, item, property, imageResizeKeyValuePairs); byte[] bytes = _Resize.GetResizedBytes(outputResolution, cResultsFullGroupDirectory, subFileTuples, item, imageResizeKeyValuePairs);
if (_AppSettings.MaxDegreeOfParallelism < 2) if (_AppSettings.MaxDegreeOfParallelism < 2)
ticks = LogDelta(ticks, nameof(C_Resize.GetResizedBytes)); ticks = LogDelta(ticks, nameof(C_Resize.GetResizedBytes));
string path = Path.Combine(resizedFileHolder.DirectoryName, resizedFileHolder.NameWithoutExtension); string path = Path.Combine(resizedFileHolder.DirectoryName, resizedFileHolder.NameWithoutExtension);
@ -326,7 +327,7 @@ public class DlibDotNet
int outputResolutionWidth = outputResolutionCollection[0]; int outputResolutionWidth = outputResolutionCollection[0];
int outputResolutionHeight = outputResolutionCollection[1]; int outputResolutionHeight = outputResolutionCollection[1];
int outputResolutionOrientation = outputResolutionCollection[2]; int outputResolutionOrientation = outputResolutionCollection[2];
faceCollection = _Faces.GetFaces(dResultsFullGroupDirectory, subFileTuples, parseExceptions, item, property, resizedFileHolder, outputResolutionWidth, outputResolutionHeight, outputResolutionOrientation); faceCollection = _Faces.GetFaces(dResultsFullGroupDirectory, subFileTuples, parseExceptions, item, property, outputResolutionWidth, outputResolutionHeight, outputResolutionOrientation);
if (_AppSettings.MaxDegreeOfParallelism < 2) if (_AppSettings.MaxDegreeOfParallelism < 2)
ticks = LogDelta(ticks, nameof(D_Face.GetFaces)); ticks = LogDelta(ticks, nameof(D_Face.GetFaces));
_Faces.SaveFaces(dResultsFullGroupDirectory, subFileTuples, parseExceptions, item, faceCollection); _Faces.SaveFaces(dResultsFullGroupDirectory, subFileTuples, parseExceptions, item, faceCollection);
@ -566,7 +567,7 @@ public class DlibDotNet
converted: true)); converted: true));
} }
private void FullDoWork(string argZero, Property.Models.Configuration configuration, Model? model, PredictorModel? predictorModel, string propertyRoot, long ticks, Map.Models.MapLogic mapLogic, A_Property propertyLogic, Container[] containers) private void FullDoWork(string argZero, Property.Models.Configuration configuration, Model? model, PredictorModel? predictorModel, string propertyRoot, long ticks, MapLogic mapLogic, A_Property propertyLogic, Container[] containers)
{ {
if (_Log is null) if (_Log is null)
throw new NullReferenceException(nameof(_Log)); throw new NullReferenceException(nameof(_Log));
@ -686,33 +687,7 @@ public class DlibDotNet
return results; return results;
} }
private void Search(Property.Models.Configuration configuration, Model? model, PredictorModel? predictorModel, string argZero, string propertyRoot, Person[] people, bool isSilent) private void MapLogic(string argZero, Container[] containers, long ticks, string dResultsFullGroupDirectory, string zResultsFullGroupDirectory, string d2ResultsFullGroupDirectory, MapLogic mapLogic, string outputResolution)
{
if (_Log is null)
throw new NullReferenceException(nameof(_Log));
Container[] containers;
long ticks = DateTime.Now.Ticks;
string aResultsFullGroupDirectory;
string bResultsFullGroupDirectory;
string cResultsFullGroupDirectory;
string dResultsFullGroupDirectory;
string eResultsFullGroupDirectory;
string zResultsFullGroupDirectory;
string d2ResultsFullGroupDirectory;
Dictionary<string, Person> personKeyValuePairs = A2_People.Convert(people);
Map.Models.MapLogic mapLogic = new(_AppSettings.MaxDegreeOfParallelism, _Configuration.PropertyConfiguration, _Resize.FilenameExtension, personKeyValuePairs);
A_Property propertyLogic = new(_AppSettings.MaxDegreeOfParallelism, _Configuration.PropertyConfiguration, _Resize.FilenameExtension, _Configuration.Reverse, model, predictorModel, mapLogic.IndicesFromNew, mapLogic.KeyValuePairs);
if (string.IsNullOrEmpty(configuration.RootDirectory))
containers = A_Property.Get(configuration, propertyLogic);
else
containers = Property.Models.Stateless.Container.GetContainers(configuration, _FirstRun, propertyLogic);
FullDoWork(argZero, configuration, model, predictorModel, propertyRoot, ticks, mapLogic, propertyLogic, containers);
foreach (string outputResolution in _Configuration.OutputResolutions)
{
if (_FirstRun)
break;
(aResultsFullGroupDirectory, bResultsFullGroupDirectory, cResultsFullGroupDirectory, dResultsFullGroupDirectory, d2ResultsFullGroupDirectory, eResultsFullGroupDirectory, zResultsFullGroupDirectory) = GetResultsFullGroupDirectories(configuration, model, predictorModel, outputResolution);
if (_ArgZeroIsConfigurationRootDirectory && _Exceptions.Count == 0 && outputResolution == _Configuration.OutputResolutions[0])
{ {
mapLogic.UseKeyValuePairsSaveFaceEncoding(containers); mapLogic.UseKeyValuePairsSaveFaceEncoding(containers);
foreach (Container container in containers) foreach (Container container in containers)
@ -732,6 +707,8 @@ public class DlibDotNet
zPropertyHolderSingletonDirectory = Path.Combine(zResultsFullGroupDirectory, "{}"); zPropertyHolderSingletonDirectory = Path.Combine(zResultsFullGroupDirectory, "{}");
zPropertyHolderContentDirectory = Path.Combine(zResultsFullGroupDirectory, $"({ticks})"); zPropertyHolderContentDirectory = Path.Combine(zResultsFullGroupDirectory, $"({ticks})");
zPropertyHolderCollectionDirectory = Path.Combine(zResultsFullGroupDirectory, $"[{ticks}]"); zPropertyHolderCollectionDirectory = Path.Combine(zResultsFullGroupDirectory, $"[{ticks}]");
mapLogic.SaveNotMappedPersonKeys(zPropertyHolderContentDirectory);
_ = LogDeltaInMinutes(ticks, nameof(mapLogic.SaveNotMappedPersonKeys));
Dictionary<string, List<(FaceRecognitionDotNet.FaceEncoding, MappingContainer)>> keyValuePairs = _Distance.ParallelWork(_AppSettings.MaxDegreeOfParallelism, _Configuration.IgnoreRelativePaths, argZero, ticks, containers); Dictionary<string, List<(FaceRecognitionDotNet.FaceEncoding, MappingContainer)>> keyValuePairs = _Distance.ParallelWork(_AppSettings.MaxDegreeOfParallelism, _Configuration.IgnoreRelativePaths, argZero, ticks, containers);
_ = LogDeltaInSeconds(ticks, nameof(E_Distance.ParallelWork)); _ = LogDeltaInSeconds(ticks, nameof(E_Distance.ParallelWork));
Dictionary<int, List<MappingContainer>> strippedKeyValuePairs = Strip(keyValuePairs); Dictionary<int, List<MappingContainer>> strippedKeyValuePairs = Strip(keyValuePairs);
@ -747,6 +724,37 @@ public class DlibDotNet
E_Distance.SavePropertyHolders(argZero, containers, zPropertyHolderSingletonDirectory); E_Distance.SavePropertyHolders(argZero, containers, zPropertyHolderSingletonDirectory);
_ = LogDeltaInSeconds(ticks, nameof(E_Distance.SavePropertyHolders)); _ = LogDeltaInSeconds(ticks, nameof(E_Distance.SavePropertyHolders));
} }
_ = LogDeltaInSeconds(ticks, nameof(MapLogic));
}
private void Search(Property.Models.Configuration configuration, Model? model, PredictorModel? predictorModel, string argZero, string propertyRoot, Person[] people)
{
if (_Log is null)
throw new NullReferenceException(nameof(_Log));
Container[] containers;
long ticks = DateTime.Now.Ticks;
string aResultsFullGroupDirectory;
string bResultsFullGroupDirectory;
string cResultsFullGroupDirectory;
string dResultsFullGroupDirectory;
string eResultsFullGroupDirectory;
string zResultsFullGroupDirectory;
string d2ResultsFullGroupDirectory;
MapLogic mapLogic = new(_AppSettings.MaxDegreeOfParallelism, _Configuration.PropertyConfiguration, _Resize.FilenameExtension, _Faces.FilenameExtension, _Faces.HiddenFilenameExtension, _FaceParts.FilenameExtension, people);
A_Property propertyLogic = new(_AppSettings.MaxDegreeOfParallelism, _Configuration.PropertyConfiguration, _Resize.FilenameExtension, _Configuration.Reverse, model, predictorModel, mapLogic.IndicesFromNew, mapLogic.KeyValuePairs);
if (string.IsNullOrEmpty(configuration.RootDirectory))
containers = A_Property.Get(configuration, propertyLogic);
else
containers = Property.Models.Stateless.Container.GetContainers(configuration, _FirstRun, propertyLogic);
FullDoWork(argZero, configuration, model, predictorModel, propertyRoot, ticks, mapLogic, propertyLogic, containers);
foreach (string outputResolution in _Configuration.OutputResolutions)
{
if (_FirstRun)
break;
(aResultsFullGroupDirectory, bResultsFullGroupDirectory, cResultsFullGroupDirectory, dResultsFullGroupDirectory, d2ResultsFullGroupDirectory, eResultsFullGroupDirectory, zResultsFullGroupDirectory) = GetResultsFullGroupDirectories(configuration, model, predictorModel, outputResolution);
if (_ArgZeroIsConfigurationRootDirectory && _Exceptions.Count == 0 && outputResolution == _Configuration.OutputResolutions[0])
{
MapLogic(argZero, containers, ticks, dResultsFullGroupDirectory, zResultsFullGroupDirectory, d2ResultsFullGroupDirectory, mapLogic, outputResolution);
if (!_Configuration.LoadOrCreateThenSaveImageFacesResultsForOutputResolutions.Any()) if (!_Configuration.LoadOrCreateThenSaveImageFacesResultsForOutputResolutions.Any())
break; break;
if (_FileKeyValuePairs.Any()) if (_FileKeyValuePairs.Any())

View File

@ -73,18 +73,4 @@ internal class A2_People
return results.ToArray(); return results.ToArray();
} }
internal static Dictionary<string, Person> Convert(Person[] people)
{
Dictionary<string, Person> results = new();
string personKey;
foreach (Person person in people)
{
personKey = Shared.Models.Stateless.Methods.IPersonBirthday.GetFormatted(person.Birthday);
if (results.ContainsKey(personKey))
break;
results.Add(personKey, person);
}
return results;
}
} }

View File

@ -15,8 +15,10 @@ namespace View_by_Distance.Instance.Models;
internal class D2_FaceParts internal class D2_FaceParts
{ {
protected readonly string _FilenameExtension;
public string FilenameExtension => _FilenameExtension;
private readonly Serilog.ILogger? _Log; private readonly Serilog.ILogger? _Log;
private readonly string _FilenameExtension;
private readonly Configuration _Configuration; private readonly Configuration _Configuration;
private readonly ImageCodecInfo _ImageCodecInfo; private readonly ImageCodecInfo _ImageCodecInfo;
private readonly EncoderParameters _EncoderParameters; private readonly EncoderParameters _EncoderParameters;

View File

@ -19,29 +19,39 @@ public class D_Face
internal List<string> AngleBracketCollection { get; } internal List<string> AngleBracketCollection { get; }
protected readonly string _FilenameExtension;
public string FilenameExtension => _FilenameExtension;
protected readonly string _HiddenFilenameExtension;
public string HiddenFilenameExtension => _HiddenFilenameExtension;
private readonly Model _Model; private readonly Model _Model;
private readonly string _ArgZero; private readonly string _ArgZero;
private readonly Serilog.ILogger? _Log; private readonly Serilog.ILogger? _Log;
private readonly string _FilenameExtension;
private readonly Configuration _Configuration; private readonly Configuration _Configuration;
private readonly ImageCodecInfo _ImageCodecInfo;
private readonly ModelParameter _ModelParameter; private readonly ModelParameter _ModelParameter;
private readonly PredictorModel _PredictorModel; private readonly PredictorModel _PredictorModel;
private readonly ImageCodecInfo _ImageCodecInfo;
private readonly EncoderParameters _EncoderParameters; private readonly EncoderParameters _EncoderParameters;
private readonly ImageCodecInfo _HiddenImageCodecInfo;
private readonly EncoderParameters _HiddenEncoderParameters;
private readonly JsonSerializerOptions _WriteIndentedJsonSerializerOptions; private readonly JsonSerializerOptions _WriteIndentedJsonSerializerOptions;
internal D_Face(Configuration configuration, string argZero, Model model, ModelParameter modelParameter, PredictorModel predictorModel, ImageCodecInfo imageCodecInfo, EncoderParameters encoderParameters, string filenameExtension) internal D_Face(Configuration configuration, string argZero, Model model, ModelParameter modelParameter, PredictorModel predictorModel, ImageCodecInfo imageCodecInfo, EncoderParameters encoderParameters, string filenameExtension, ImageCodecInfo hiddenImageCodecInfo, EncoderParameters hiddenEncoderParameters, string hiddenFilenameExtension)
{ {
_Model = model; _Model = model;
_ArgZero = argZero; _ArgZero = argZero;
_Configuration = configuration; _Configuration = configuration;
_ImageCodecInfo = imageCodecInfo;
_ModelParameter = modelParameter; _ModelParameter = modelParameter;
_PredictorModel = predictorModel; _PredictorModel = predictorModel;
_ImageCodecInfo = imageCodecInfo;
_EncoderParameters = encoderParameters; _EncoderParameters = encoderParameters;
_FilenameExtension = filenameExtension; _FilenameExtension = filenameExtension;
AngleBracketCollection = new List<string>();
_Log = Serilog.Log.ForContext<D_Face>(); _Log = Serilog.Log.ForContext<D_Face>();
AngleBracketCollection = new List<string>();
_HiddenImageCodecInfo = hiddenImageCodecInfo;
_HiddenEncoderParameters = hiddenEncoderParameters;
_HiddenFilenameExtension = hiddenFilenameExtension;
_WriteIndentedJsonSerializerOptions = new JsonSerializerOptions { WriteIndented = true }; _WriteIndentedJsonSerializerOptions = new JsonSerializerOptions { WriteIndented = true };
} }
@ -133,7 +143,7 @@ public class D_Face
return result; return result;
} }
private void SaveFaces(FileHolder resizedFileHolder, List<(Face, string)> collection) private void SaveFaces(FileHolder resizedFileHolder, List<(Face, FileInfo?, string)> collection)
{ {
int width; int width;
int height; int height;
@ -142,8 +152,10 @@ public class D_Face
Bitmap preRotated; Bitmap preRotated;
Rectangle rectangle; Rectangle rectangle;
using Bitmap source = new(resizedFileHolder.FullName); using Bitmap source = new(resizedFileHolder.FullName);
foreach ((Face face, string fileName) in collection) foreach ((Face face, FileInfo? fileInfo, string fileName) in collection)
{ {
if (fileInfo is null)
continue;
if (face.FaceEncoding is null || face?.Location is null) if (face.FaceEncoding is null || face?.Location is null)
continue; continue;
location = Shared.Models.Stateless.Methods.ILocation.GetLocation(face.Location, source.Height, source.Width, collection.Count); location = Shared.Models.Stateless.Methods.ILocation.GetLocation(face.Location, source.Height, source.Width, collection.Count);
@ -156,23 +168,40 @@ public class D_Face
{ {
using (graphics = Graphics.FromImage(preRotated)) using (graphics = Graphics.FromImage(preRotated))
graphics.DrawImage(source, new Rectangle(0, 0, width, height), rectangle, GraphicsUnit.Pixel); graphics.DrawImage(source, new Rectangle(0, 0, width, height), rectangle, GraphicsUnit.Pixel);
preRotated.Save(fileName, _ImageCodecInfo, _EncoderParameters); preRotated.Save(fileInfo.FullName, _ImageCodecInfo, _EncoderParameters);
} }
if (File.Exists(fileName))
File.Delete(fileName);
location = Shared.Models.Stateless.Methods.ILocation.GetLocation(IFaceDistance.HiddenImageFactor, face.Location, source.Height, source.Width, collection.Count);
if (location is null)
continue;
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(fileName, _HiddenImageCodecInfo, _HiddenEncoderParameters);
}
File.SetAttributes(fileName, FileAttributes.Hidden);
} }
} }
private List<Face> GetFaces(FileHolder resizedFileHolder, Item item, Shared.Models.Property property, int outputResolutionWidth, int outputResolutionHeight, int outputResolutionOrientation) private List<Face> GetFaces(Item item, Shared.Models.Property property, int outputResolutionWidth, int outputResolutionHeight, int outputResolutionOrientation)
{ {
List<Face> results = new(); List<Face> results = new();
if (item.ImageFileHolder is null) if (item.ImageFileHolder is null)
throw new NullReferenceException(nameof(item.ImageFileHolder)); throw new NullReferenceException(nameof(item.ImageFileHolder));
if (item.ResizedFileHolder is null)
throw new NullReferenceException(nameof(item.ResizedFileHolder));
FaceRecognitionDotNet.Image? unknownImage; FaceRecognitionDotNet.Image? unknownImage;
if (!resizedFileHolder.Exists) if (!item.ResizedFileHolder.Exists)
unknownImage = null; unknownImage = null;
else else
{ {
try try
{ unknownImage = FaceRecognition.LoadImageFile(resizedFileHolder.FullName); } { unknownImage = FaceRecognition.LoadImageFile(item.ResizedFileHolder.FullName); }
catch (Exception) catch (Exception)
{ unknownImage = null; } { unknownImage = null; }
} }
@ -214,7 +243,7 @@ public class D_Face
#pragma warning restore CA1416 #pragma warning restore CA1416
internal List<Face> GetFaces(string dResultsFullGroupDirectory, List<Tuple<string, DateTime>> subFileTuples, List<string> parseExceptions, Item item, Shared.Models.Property property, FileHolder resizedFileHolder, int outputResolutionWidth, int outputResolutionHeight, int outputResolutionOrientation) internal List<Face> GetFaces(string dResultsFullGroupDirectory, List<Tuple<string, DateTime>> subFileTuples, List<string> parseExceptions, Item item, Shared.Models.Property property, int outputResolutionWidth, int outputResolutionHeight, int outputResolutionOrientation)
{ {
List<Face>? results; List<Face>? results;
if (item.Property?.Id is null) if (item.Property?.Id is null)
@ -277,8 +306,6 @@ public class D_Face
if (!_Configuration.ForceFaceLastWriteTimeToCreationTime) if (!_Configuration.ForceFaceLastWriteTimeToCreationTime)
{ {
normalizedPixelPercentageCollection = Shared.Models.Stateless.Methods.IFace.GetInts(results); normalizedPixelPercentageCollection = Shared.Models.Stateless.Methods.IFace.GetInts(results);
if (normalizedPixelPercentageCollection.Contains(3))
throw new Exception($"Not allowed! <{fileInfo.FullName}>");
normalizedPixelPercentageDistinctCount = normalizedPixelPercentageCollection.Distinct().Count(); normalizedPixelPercentageDistinctCount = normalizedPixelPercentageCollection.Distinct().Count();
if (normalizedPixelPercentageDistinctCount != normalizedPixelPercentageCollection.Length) if (normalizedPixelPercentageDistinctCount != normalizedPixelPercentageCollection.Length)
throw new Exception($"Not distinct! <{fileInfo.FullName}>"); throw new Exception($"Not distinct! <{fileInfo.FullName}>");
@ -293,7 +320,7 @@ public class D_Face
} }
if (results is null) if (results is null)
{ {
results = GetFaces(resizedFileHolder, item, property, outputResolutionWidth, outputResolutionHeight, outputResolutionOrientation); results = GetFaces(item, property, outputResolutionWidth, outputResolutionHeight, outputResolutionOrientation);
json = JsonSerializer.Serialize(results, _WriteIndentedJsonSerializerOptions); json = JsonSerializer.Serialize(results, _WriteIndentedJsonSerializerOptions);
bool updateDateWhenMatches = dateTimes.Any() && fileInfo.Exists && dateTimes.Max() > fileInfo.LastWriteTime; bool updateDateWhenMatches = dateTimes.Any() && fileInfo.Exists && dateTimes.Max() > fileInfo.LastWriteTime;
DateTime? dateTime = !updateDateWhenMatches ? null : dateTimes.Max(); DateTime? dateTime = !updateDateWhenMatches ? null : dateTimes.Max();
@ -330,7 +357,7 @@ public class D_Face
bool check = false; bool check = false;
string parentCheck; string parentCheck;
double deterministicHashCodeKey; double deterministicHashCodeKey;
List<(Face, string)> collection = new(); List<(Face, FileInfo?, string)> collection = new();
string[] changesFrom = new string[] { nameof(A_Property), nameof(B_Metadata), nameof(C_Resize) }; string[] changesFrom = new string[] { nameof(A_Property), nameof(B_Metadata), nameof(C_Resize) };
string facesDirectory = Path.Combine(AngleBracketCollection[0].Replace("<>", "()"), item.ImageFileHolder.NameWithoutExtension); string facesDirectory = Path.Combine(AngleBracketCollection[0].Replace("<>", "()"), item.ImageFileHolder.NameWithoutExtension);
List<DateTime> dateTimes = (from l in subFileTuples where changesFrom.Contains(l.Item1) select l.Item2).ToList(); List<DateTime> dateTimes = (from l in subFileTuples where changesFrom.Contains(l.Item1) select l.Item2).ToList();
@ -341,7 +368,7 @@ public class D_Face
{ {
if (face.FaceEncoding is null || face.Location?.NormalizedPixelPercentage is null) if (face.FaceEncoding is null || face.Location?.NormalizedPixelPercentage is null)
{ {
collection.Add(new(face, string.Empty)); collection.Add(new(face, null, string.Empty));
continue; continue;
} }
deterministicHashCodeKey = Shared.Models.Stateless.Methods.IMapping.GetDeterministicHashCodeKey(item, face); deterministicHashCodeKey = Shared.Models.Stateless.Methods.IMapping.GetDeterministicHashCodeKey(item, face);
@ -354,7 +381,7 @@ public class D_Face
if (File.Exists(parentCheck)) if (File.Exists(parentCheck))
File.Delete(parentCheck); File.Delete(parentCheck);
} }
collection.Add(new(face, fileInfo.FullName)); collection.Add(new(face, fileInfo, Path.Combine(facesDirectory, $"{deterministicHashCodeKey}{item.ImageFileHolder.ExtensionLowered}{_HiddenFilenameExtension}")));
if (_Configuration.OverrideForFaceImages) if (_Configuration.OverrideForFaceImages)
check = true; check = true;
else if (!fileInfo.Exists) else if (!fileInfo.Exists)

View File

@ -612,6 +612,15 @@ internal class E_Distance
return results; return results;
} }
private static void SetNonFiltered(List<(FaceRecognitionDotNet.FaceEncoding, MappingContainer)> collection)
{
foreach ((FaceRecognitionDotNet.FaceEncoding _, MappingContainer mappingContainer) in collection)
{
if (mappingContainer.Mapping.Filtered is null)
mappingContainer.Mapping.SetFiltered(value: false);
}
}
private Dictionary<string, List<(FaceRecognitionDotNet.FaceEncoding, MappingContainer)>> GetThreeSigmaFaceEncodings(int maxDegreeOfParallelism, long ticks, Dictionary<string, List<MappingContainer>> keyValuePairs) private Dictionary<string, List<(FaceRecognitionDotNet.FaceEncoding, MappingContainer)>> GetThreeSigmaFaceEncodings(int maxDegreeOfParallelism, long ticks, Dictionary<string, List<MappingContainer>> keyValuePairs)
{ {
if (_Log is null) if (_Log is null)
@ -644,8 +653,9 @@ internal class E_Distance
faceDistances = FaceRecognition.FaceDistances(faceEncodings, faceEncodings[selectedIndex]); faceDistances = FaceRecognition.FaceDistances(faceEncodings, faceEncodings[selectedIndex]);
for (int i = 0; i < faceEncodings.Count; i++) for (int i = 0; i < faceEncodings.Count; i++)
collection[i].MappingContainer.SetDistance(faceDistances[i]); collection[i].MappingContainer.SetDistance(faceDistances[i]);
if (collection.Count > 1) if (collection.Count > 3)
SetFiltered(collection); SetFiltered(collection);
SetNonFiltered(collection);
totalSeconds = (int)Math.Floor(new TimeSpan(DateTime.Now.Ticks - ticks).TotalSeconds); totalSeconds = (int)Math.Floor(new TimeSpan(DateTime.Now.Ticks - ticks).TotalSeconds);
_Log.Information($"{keyValuePairsCount:0000}) {totalSeconds} total second(s) - {keyValuePair.Key} - {collection[selectedIndex].MappingContainer.Mapping.DisplayDirectoryName}"); _Log.Information($"{keyValuePairsCount:0000}) {totalSeconds} total second(s) - {keyValuePair.Key} - {collection[selectedIndex].MappingContainer.Mapping.DisplayDirectoryName}");
} }
@ -656,6 +666,11 @@ internal class E_Distance
{ {
Dictionary<string, List<(FaceRecognitionDotNet.FaceEncoding, MappingContainer)>> results; Dictionary<string, List<(FaceRecognitionDotNet.FaceEncoding, MappingContainer)>> results;
Dictionary<string, List<MappingContainer>> keyValuePairs = Map.Models.Stateless.IMapLogic.GetKeyValuePairs(ignoreRelativePaths, argZero, containers); Dictionary<string, List<MappingContainer>> keyValuePairs = Map.Models.Stateless.IMapLogic.GetKeyValuePairs(ignoreRelativePaths, argZero, containers);
if (!keyValuePairs.Any())
{
Map.Models.Stateless.IMapLogic.SetSingleImage(ignoreRelativePaths, argZero, containers);
keyValuePairs = Map.Models.Stateless.IMapLogic.GetKeyValuePairs(ignoreRelativePaths, argZero, containers);
}
results = GetThreeSigmaFaceEncodings(maxDegreeOfParallelism, ticks, keyValuePairs); results = GetThreeSigmaFaceEncodings(maxDegreeOfParallelism, ticks, keyValuePairs);
return results; return results;
} }
@ -719,11 +734,11 @@ internal class E_Distance
if (item.ImageFileHolder is null || item.Property is null || !item.Faces.Any() || !item.Closest.Any()) if (item.ImageFileHolder is null || item.Property is null || !item.Faces.Any() || !item.Closest.Any())
continue; continue;
json = JsonSerializer.Serialize(item, jsonSerializerOptions); json = JsonSerializer.Serialize(item, jsonSerializerOptions);
fileInfo = new(string.Concat(zPropertyHolderSingletonDirectory, item.RelativePath, ".json")); fileInfo = new(Path.GetFullPath(string.Concat(zPropertyHolderSingletonDirectory, item.RelativePath, ".json")));
if (fileInfo.Directory is null) if (fileInfo.Directory is null)
continue; continue;
if (!fileInfo.Directory.Exists) if (!fileInfo.Directory.Exists)
fileInfo.Directory.Create(); continue;
_ = Shared.Models.Stateless.Methods.IPath.WriteAllText(fileInfo.FullName, json, updateDateWhenMatches, compareBeforeWrite: true); _ = Shared.Models.Stateless.Methods.IPath.WriteAllText(fileInfo.FullName, json, updateDateWhenMatches, compareBeforeWrite: true);
} }
} }

View File

@ -2,7 +2,6 @@ using System.Diagnostics;
using System.Text.Json; using System.Text.Json;
using View_by_Distance.Property.Models; using View_by_Distance.Property.Models;
using View_by_Distance.Shared.Models; using View_by_Distance.Shared.Models;
using View_by_Distance.Shared.Models.Properties;
using WindowsShortcutFactory; using WindowsShortcutFactory;
namespace View_by_Distance.Map.Models; namespace View_by_Distance.Map.Models;
@ -11,6 +10,7 @@ public class MapLogic
{ {
protected readonly List<double> _SkipCollection; protected readonly List<double> _SkipCollection;
protected readonly List<string> _NotMappedPersonKeys;
protected readonly List<(int, string[])> _AllCollection; protected readonly List<(int, string[])> _AllCollection;
protected readonly Dictionary<int, int[]> _KeyValuePairs; protected readonly Dictionary<int, int[]> _KeyValuePairs;
protected readonly Dictionary<int, int[]> _IndicesFromNew; protected readonly Dictionary<int, int[]> _IndicesFromNew;
@ -25,23 +25,30 @@ public class MapLogic
public Dictionary<int, int[]> IndicesFromNew => _IndicesFromNew; public Dictionary<int, int[]> IndicesFromNew => _IndicesFromNew;
private readonly Serilog.ILogger? _Log; private readonly Serilog.ILogger? _Log;
private readonly string _OutputExtension;
private readonly Configuration _Configuration; private readonly Configuration _Configuration;
private readonly string _FacesFilenameExtension;
private readonly string _ResizeFilenameExtension;
private readonly string _FacePartsFilenameExtension;
private readonly string _FacesHiddenFilenameExtension;
public MapLogic(int maxDegreeOfParallelism, Configuration configuration, string outputExtension, Dictionary<string, Person> personKeyValuePairs) public MapLogic(int maxDegreeOfParallelism, Configuration configuration, string resizeFilenameExtension, string facesFilenameExtension, string facesHiddenFilenameExtension, string facePartsFilenameExtension, Person[] people)
{ {
_AllCollection = new(); _AllCollection = new();
_Configuration = configuration; _Configuration = configuration;
_Log = Serilog.Log.ForContext<MapLogic>(); _Log = Serilog.Log.ForContext<MapLogic>();
_FacesFilenameExtension = facesFilenameExtension;
_ResizeFilenameExtension = resizeFilenameExtension;
_FacePartsFilenameExtension = facePartsFilenameExtension;
_FacesHiddenFilenameExtension = facesHiddenFilenameExtension;
Dictionary<int, string[]>? deterministicHashCodeUnknownFaceKeyValuePairs; Dictionary<int, string[]>? deterministicHashCodeUnknownFaceKeyValuePairs;
if (configuration.VerifyToSeason is null || !configuration.VerifyToSeason.Any()) if (configuration.VerifyToSeason is null || !configuration.VerifyToSeason.Any())
throw new Exception(); throw new Exception();
string json; string json;
string[] files; string[] files;
string fullPath; string fullPath;
_OutputExtension = outputExtension;
List<double> skipCollection = new(); List<double> skipCollection = new();
Dictionary<int, int[]>? keyValuePairs; Dictionary<int, int[]>? keyValuePairs;
List<string> notMappedPersonKeys = new();
List<KeyValuePair<int, int[]>>? collection; List<KeyValuePair<int, int[]>>? collection;
string deterministicHashCodeContentDirectory; string deterministicHashCodeContentDirectory;
Dictionary<int, int[]> indicesFromNew = new(); Dictionary<int, int[]> indicesFromNew = new();
@ -52,6 +59,7 @@ public class MapLogic
Dictionary<string, (string, int?, string, PersonBirthday[])> peopleKeyValuePairs = new(); Dictionary<string, (string, int?, string, PersonBirthday[])> peopleKeyValuePairs = new();
if (string.IsNullOrEmpty(rootDirectoryParent)) if (string.IsNullOrEmpty(rootDirectoryParent))
throw new NullReferenceException(nameof(rootDirectoryParent)); throw new NullReferenceException(nameof(rootDirectoryParent));
string deterministicHashCodeRootDirectory = Path.Combine(rootDirectoryParent, "DeterministicHashCode");
files = Directory.GetFiles(rootDirectoryParent, "DeterministicHashCode*.json", SearchOption.TopDirectoryOnly); files = Directory.GetFiles(rootDirectoryParent, "DeterministicHashCode*.json", SearchOption.TopDirectoryOnly);
if (files.Length != 1) if (files.Length != 1)
deterministicHashCodeUnknownFaceKeyValuePairs = new(); deterministicHashCodeUnknownFaceKeyValuePairs = new();
@ -62,11 +70,9 @@ public class MapLogic
if (deterministicHashCodeUnknownFaceKeyValuePairs is null) if (deterministicHashCodeUnknownFaceKeyValuePairs is null)
throw new NullReferenceException(nameof(deterministicHashCodeUnknownFaceKeyValuePairs)); throw new NullReferenceException(nameof(deterministicHashCodeUnknownFaceKeyValuePairs));
} }
string[] directories = Directory.GetDirectories(rootDirectoryParent, "DeterministicHashCode", SearchOption.TopDirectoryOnly); if (!Directory.Exists(deterministicHashCodeRootDirectory))
if (!directories.Any()) _ = Directory.CreateDirectory(deterministicHashCodeRootDirectory);
deterministicHashCodeContentDirectory = string.Empty; deterministicHashCodeContentDirectory = Stateless.ByDeterministicHashCode.SetByRef(_ResizeFilenameExtension, people, skipCollection, peopleKeyValuePairs, notMappedPersonKeys, deterministicHashCodeUnknownFaceKeyValuePairs, deterministicHashCodeKeyValuePairs, incorrectDeterministicHashCodeKeyValuePairs, deterministicHashCodeRootDirectory);
else
deterministicHashCodeContentDirectory = Stateless.ByDeterministicHashCode.SetByRef(_OutputExtension, personKeyValuePairs, skipCollection, peopleKeyValuePairs, deterministicHashCodeUnknownFaceKeyValuePairs, deterministicHashCodeKeyValuePairs, incorrectDeterministicHashCodeKeyValuePairs, directories[0]);
if (!deterministicHashCodeUnknownFaceKeyValuePairs.Any()) if (!deterministicHashCodeUnknownFaceKeyValuePairs.Any())
sixCharacterNamedFaceInfo = new(); sixCharacterNamedFaceInfo = new();
else else
@ -113,6 +119,7 @@ public class MapLogic
_KeyValuePairs = keyValuePairs; _KeyValuePairs = keyValuePairs;
_IndicesFromNew = indicesFromNew; _IndicesFromNew = indicesFromNew;
_SkipCollection = skipCollection; _SkipCollection = skipCollection;
_NotMappedPersonKeys = notMappedPersonKeys;
_PeopleKeyValuePairs = peopleKeyValuePairs; _PeopleKeyValuePairs = peopleKeyValuePairs;
_SixCharacterNamedFaceInfo = sixCharacterNamedFaceInfo; _SixCharacterNamedFaceInfo = sixCharacterNamedFaceInfo;
_DeterministicHashCodeKeyValuePairs = deterministicHashCodeKeyValuePairs; _DeterministicHashCodeKeyValuePairs = deterministicHashCodeKeyValuePairs;
@ -121,6 +128,10 @@ public class MapLogic
_DeterministicHashCodeUnknownFaceKeyValuePairs = deterministicHashCodeUnknownFaceKeyValuePairs; _DeterministicHashCodeUnknownFaceKeyValuePairs = deterministicHashCodeUnknownFaceKeyValuePairs;
} }
public MapLogic(int maxDegreeOfParallelism, Configuration configuration, string outputExtension, Person[] people) :
this(maxDegreeOfParallelism, configuration, outputExtension, outputExtension, outputExtension, outputExtension, people)
{ }
public bool Skip(double deterministicHashCodeKey) => _SkipCollection.Contains(deterministicHashCodeKey); public bool Skip(double deterministicHashCodeKey) => _SkipCollection.Contains(deterministicHashCodeKey);
public void SaveShortcuts(string[] juliePhares, string dResultsFullGroupDirectory, long ticks, List<Item> items) public void SaveShortcuts(string[] juliePhares, string dResultsFullGroupDirectory, long ticks, List<Item> items)
@ -297,21 +308,13 @@ public class MapLogic
personKeys.AddRange(_DeterministicHashCodeKeyValuePairs[deterministicHashCodeKey]); personKeys.AddRange(_DeterministicHashCodeKeyValuePairs[deterministicHashCodeKey]);
for (int i = 0; i < personKeys.Count; i++) for (int i = 0; i < personKeys.Count; i++)
{ {
if (_PeopleKeyValuePairs.ContainsKey(personKeys[i])) if (!_PeopleKeyValuePairs.ContainsKey(personKeys[i]))
{ continue;
person = _PeopleKeyValuePairs[personKeys[i]]; person = _PeopleKeyValuePairs[personKeys[i]];
personBirthday = person.PersonBirthdays[0]; personBirthday = person.PersonBirthdays[0];
approximateYears = person.ApproximateYears; approximateYears = person.ApproximateYears;
displayDirectoryName = person.DisplayDirectoryName; displayDirectoryName = person.DisplayDirectoryName;
personKey = Shared.Models.Stateless.Methods.IPersonBirthday.GetFormatted(personBirthday); personKey = Shared.Models.Stateless.Methods.IPersonBirthday.GetFormatted(personBirthday);
}
else
{
approximateYears = null;
personKey = personKeys[i];
displayDirectoryName = "_ _ _";
personBirthday = Shared.Models.Stateless.Methods.IPersonBirthday.GetPersonBirthday(personKey);
}
if (personBirthday is null) if (personBirthday is null)
continue; continue;
mapping = new(approximateYears, displayDirectoryName, face.Location.NormalizedPixelPercentage, personBirthday, personKey); mapping = new(approximateYears, displayDirectoryName, face.Location.NormalizedPixelPercentage, personBirthday, personKey);
@ -325,21 +328,13 @@ public class MapLogic
personKeys.AddRange(_DeterministicHashCodeUnknownFaceKeyValuePairs[item.Property.Id.Value]); personKeys.AddRange(_DeterministicHashCodeUnknownFaceKeyValuePairs[item.Property.Id.Value]);
for (int i = 0; i < personKeys.Count; i++) for (int i = 0; i < personKeys.Count; i++)
{ {
if (_PeopleKeyValuePairs.ContainsKey(personKeys[i])) if (!_PeopleKeyValuePairs.ContainsKey(personKeys[i]))
{ continue;
person = _PeopleKeyValuePairs[personKeys[i]]; person = _PeopleKeyValuePairs[personKeys[i]];
personBirthday = person.PersonBirthdays[0]; personBirthday = person.PersonBirthdays[0];
approximateYears = person.ApproximateYears; approximateYears = person.ApproximateYears;
displayDirectoryName = person.DisplayDirectoryName; displayDirectoryName = person.DisplayDirectoryName;
personKey = Shared.Models.Stateless.Methods.IPersonBirthday.GetFormatted(personBirthday); personKey = Shared.Models.Stateless.Methods.IPersonBirthday.GetFormatted(personBirthday);
}
else
{
approximateYears = null;
personKey = personKeys[i];
displayDirectoryName = "_ _ _";
personBirthday = Shared.Models.Stateless.Methods.IPersonBirthday.GetPersonBirthday(personKey);
}
if (personBirthday is null) if (personBirthday is null)
continue; continue;
mapping = new(approximateYears, displayDirectoryName, personBirthday, personKey); mapping = new(approximateYears, displayDirectoryName, personBirthday, personKey);
@ -349,6 +344,72 @@ public class MapLogic
} }
} }
private void SaveContainers(List<SaveContainer> saveContainers)
{
WindowsShortcut windowsShortcut;
string[] directories = (from l in saveContainers select l.Directory).Distinct().ToArray();
foreach (string directory in directories)
{
if (string.IsNullOrEmpty(directory))
continue;
if (!Directory.Exists(directory))
_ = Directory.CreateDirectory(directory);
}
foreach (SaveContainer saveContainer in saveContainers)
{
if (string.IsNullOrEmpty(saveContainer.Directory) || string.IsNullOrEmpty(saveContainer.CheckFile) || saveContainer.ResizedFileHolder is null || saveContainer.FaceFileHolder is null || !string.IsNullOrEmpty(saveContainer.Json))
continue;
if (File.Exists(saveContainer.CheckFile))
continue;
if (saveContainer.FaceFileHolder.Exists)
File.Copy(saveContainer.FaceFileHolder.FullName, saveContainer.CheckFile);
else
File.Copy(saveContainer.ResizedFileHolder.FullName, saveContainer.CheckFile);
if (saveContainer.HiddenFaceFileHolder is not null && saveContainer.HiddenFaceFileHolder.Exists)
File.Copy(saveContainer.HiddenFaceFileHolder.FullName, Path.ChangeExtension(saveContainer.CheckFile, _FacesHiddenFilenameExtension));
else if (saveContainer.FacePartsFileHolder is not null && saveContainer.FacePartsFileHolder.Exists)
File.Copy(saveContainer.FacePartsFileHolder.FullName, Path.ChangeExtension(saveContainer.CheckFile, _FacePartsFilenameExtension));
}
foreach (SaveContainer saveContainer in saveContainers)
{
if (string.IsNullOrEmpty(saveContainer.Directory) || string.IsNullOrEmpty(saveContainer.CheckFile) || saveContainer.ResizedFileHolder is not null || saveContainer.FaceFileHolder is not null || string.IsNullOrEmpty(saveContainer.Json))
continue;
if (File.Exists(saveContainer.CheckFile))
continue;
_ = Shared.Models.Stateless.Methods.IPath.WriteAllText(saveContainer.CheckFile, saveContainer.Json, updateDateWhenMatches: false, compareBeforeWrite: true, updateToWhenMatches: null);
}
foreach (SaveContainer saveContainer in saveContainers)
{
if (string.IsNullOrEmpty(saveContainer.Directory) || string.IsNullOrEmpty(saveContainer.CheckFile) || saveContainer.ResizedFileHolder is null)
continue;
if (string.IsNullOrEmpty(saveContainer.ShortcutFile) || !saveContainer.ResizedFileHolder.Exists)
continue;
try
{
windowsShortcut = new() { Path = saveContainer.ResizedFileHolder.FullName };
windowsShortcut.Save(saveContainer.ShortcutFile);
windowsShortcut.Dispose();
}
catch (Exception)
{ }
}
}
public void SaveNotMappedPersonKeys(string zPropertyHolderContentDirectory)
{
string directory;
SaveContainer saveContainer;
List<SaveContainer> saveContainers = new();
const string facePopulatedKey = nameof(Closest);
foreach (string personKey in _NotMappedPersonKeys)
{
directory = Path.Combine(zPropertyHolderContentDirectory, $"{facePopulatedKey}NotMapped", personKey, Property.Models.Stateless.IResult.AllInOne);
saveContainer = new(directory);
saveContainers.Add(saveContainer);
}
SaveContainers(saveContainers);
}
public List<(Item, (string, Face?, (string, string, string, string))[])> GetCollection(List<Item> items, string dFacesContentDirectory) public List<(Item, (string, Face?, (string, string, string, string))[])> GetCollection(List<Item> items, string dFacesContentDirectory)
{ {
List<(Item, (string, Face?, (string, string, string, string))[])> results = new(); List<(Item, (string, Face?, (string, string, string, string))[])> results = new();
@ -508,110 +569,9 @@ public class MapLogic
} }
} }
private List<(IFileHolder? resizedFileHolder, string directory, FileInfo? faceFileInfo, string checkFile, string shortcutFile, string json)> GetClosest(string argZero, Container[] containers, string dFacesContentDirectory, string d2ResultsFullGroupDirectory, string zPropertyHolderContentDirectory) private List<SaveContainer> GetMappingSaveContainers(string argZero, Container[] containers, string dFacesContentDirectory, string d2ResultsFullGroupDirectory, string zPropertyHolderContentDirectory)
{ {
List<(IFileHolder?, string, FileInfo?, string, string, string)> results = new(); List<SaveContainer> results = new();
Closest? match;
string dateKey;
string checkFile;
string directory;
string shortcutFile;
FileInfo faceFileInfo;
string? directoryName;
string facesDirectory;
string personDirectory;
List<int> used = new();
FileInfo landmarkFileInfo;
string landmarksDirectory;
double deterministicHashCodeKey;
DateTime dateTime = DateTime.Now;
const string facePopulatedKey = nameof(Closest);
foreach (Container container in containers)
{
if (!container.Items.Any())
continue;
if (!container.SourceDirectory.StartsWith(argZero))
continue;
foreach (Item item in container.Items)
{
used.Clear();
if (item.ImageFileHolder is null || item.Property?.Id is null || item.ResizedFileHolder is null)
continue;
if (!item.Closest.Any())
continue;
directoryName = Path.GetDirectoryName(item.RelativePath);
if (directoryName is null)
throw new Exception();
foreach (Face face in item.Faces)
{
match = null;
if (face.FaceEncoding is null || face.Location?.NormalizedPixelPercentage is null)
continue;
foreach (Closest closest in item.Closest)
{
if (closest.NormalizedPixelPercentage != face.Location.NormalizedPixelPercentage.Value)
continue;
match = closest;
break;
}
if (match is null)
continue;
foreach (Mapping mapping in item.Mapping)
{
if (mapping.NormalizedPixelPercentage is null || mapping.NormalizedPixelPercentage.Value != face.Location.NormalizedPixelPercentage.Value)
continue;
throw new Exception();
}
dateKey = Stateless.MapLogic.GetDateKey(dateTime, match.Mapping, match.MinimumDateTime, match.IsWrongYear);
directory = Path.Combine(zPropertyHolderContentDirectory, facePopulatedKey, match.Mapping.PersonKey, dateKey);
personDirectory = Path.Combine(directory, match.Mapping.DisplayDirectoryName[..1], "lnk");
results.Add(new(null, personDirectory, null, string.Empty, string.Empty, string.Empty));
facesDirectory = string.Concat(dFacesContentDirectory, Path.Combine(directoryName, item.ImageFileHolder.NameWithoutExtension));
landmarksDirectory = string.Concat(d2ResultsFullGroupDirectory, Path.Combine(directoryName, item.ImageFileHolder.NameWithoutExtension));
deterministicHashCodeKey = Shared.Models.Stateless.Methods.IMapping.GetDeterministicHashCodeKey(item, face);
checkFile = Path.Combine(directory, $"{deterministicHashCodeKey}{item.ImageFileHolder.ExtensionLowered}");
faceFileInfo = new(Path.Combine(facesDirectory, $"{deterministicHashCodeKey}{item.ImageFileHolder.ExtensionLowered}.png"));
landmarkFileInfo = new(Path.Combine(landmarksDirectory, $"{deterministicHashCodeKey}{item.ImageFileHolder.ExtensionLowered}.gif"));
if (string.IsNullOrEmpty(personDirectory))
shortcutFile = string.Empty;
else
shortcutFile = Path.Combine(personDirectory, $"{deterministicHashCodeKey}{item.ImageFileHolder.ExtensionLowered}.lnk");
results.Add(new(item.ResizedFileHolder, directory, faceFileInfo, checkFile, shortcutFile, string.Empty));
personDirectory = Path.Combine(directory, match.Mapping.DisplayDirectoryName[..1], "lnk", match.Mapping.DisplayDirectoryName);
results.Add(new(null, personDirectory, null, string.Empty, string.Empty, string.Empty));
used.Add(face.Location.NormalizedPixelPercentage.Value);
}
foreach (Closest closest in item.Closest)
{
if (used.Contains(closest.NormalizedPixelPercentage))
continue;
dateKey = Stateless.MapLogic.GetDateKey(dateTime, closest.Mapping, closest.MinimumDateTime, closest.IsWrongYear);
directory = Path.Combine(zPropertyHolderContentDirectory, facePopulatedKey, closest.Mapping.PersonKey, dateKey);
personDirectory = Path.Combine(directory, closest.Mapping.DisplayDirectoryName, "lnk");
results.Add(new(null, personDirectory, null, string.Empty, string.Empty, string.Empty));
facesDirectory = string.Concat(dFacesContentDirectory, Path.Combine(directoryName, item.ImageFileHolder.NameWithoutExtension));
landmarksDirectory = string.Concat(d2ResultsFullGroupDirectory, Path.Combine(directoryName, item.ImageFileHolder.NameWithoutExtension));
deterministicHashCodeKey = Shared.Models.Stateless.Methods.IMapping.GetDeterministicHashCodeKey(item, closest);
checkFile = Path.Combine(directory, $"{deterministicHashCodeKey}{item.ImageFileHolder.ExtensionLowered}");
faceFileInfo = new(Path.Combine(facesDirectory, $"{deterministicHashCodeKey}{item.ImageFileHolder.ExtensionLowered}.png"));
landmarkFileInfo = new(Path.Combine(landmarksDirectory, $"{deterministicHashCodeKey}{item.ImageFileHolder.ExtensionLowered}.gif"));
if (string.IsNullOrEmpty(personDirectory))
shortcutFile = string.Empty;
else
shortcutFile = Path.Combine(personDirectory, $"{deterministicHashCodeKey}{item.ImageFileHolder.ExtensionLowered}.lnk");
results.Add(new(item.ResizedFileHolder, directory, faceFileInfo, checkFile, shortcutFile, string.Empty));
personDirectory = Path.Combine(directory, closest.Mapping.DisplayDirectoryName[..1], "lnk", closest.Mapping.DisplayDirectoryName);
results.Add(new(null, personDirectory, null, string.Empty, string.Empty, string.Empty));
used.Add(closest.NormalizedPixelPercentage);
}
}
}
return results;
}
private List<(IFileHolder? resizedFileHolder, string directory, FileInfo? faceFileInfo, string checkFile, string shortcutFile, string json)> GetMapping(string argZero, Container[] containers, string dFacesContentDirectory, string d2ResultsFullGroupDirectory, string zPropertyHolderContentDirectory)
{
List<(IFileHolder?, string, FileInfo?, string, string, string)> results = new();
string key; string key;
string json; string json;
string dateKey; string dateKey;
@ -620,14 +580,16 @@ public class MapLogic
string directory; string directory;
bool? isWrongYear; bool? isWrongYear;
string shortcutFile; string shortcutFile;
FileInfo faceFileInfo;
string? directoryName; string? directoryName;
string facesDirectory; string facesDirectory;
string personDirectory; string personDirectory;
List<int> used = new(); List<int> used = new();
DateTime minimumDateTime; DateTime minimumDateTime;
FileInfo landmarkFileInfo; FileHolder faceFileHolder;
string landmarksDirectory; string facePartsDirectory;
SaveContainer saveContainer;
FileHolder facePartsFileHolder;
FileHolder hiddenFaceFileHolder;
double deterministicHashCodeKey; double deterministicHashCodeKey;
DateTime dateTime = DateTime.Now; DateTime dateTime = DateTime.Now;
const string facePopulatedKey = nameof(Mapping); const string facePopulatedKey = nameof(Mapping);
@ -677,26 +639,31 @@ public class MapLogic
else else
directory = Path.Combine(zPropertyHolderContentDirectory, $"{facePopulatedKey}OutOfControl", match.PersonKey, dateKey); directory = Path.Combine(zPropertyHolderContentDirectory, $"{facePopulatedKey}OutOfControl", match.PersonKey, dateKey);
personDirectory = Path.Combine(directory, match.DisplayDirectoryName[..1], "lnk"); personDirectory = Path.Combine(directory, match.DisplayDirectoryName[..1], "lnk");
results.Add(new(null, personDirectory, null, string.Empty, string.Empty, string.Empty)); saveContainer = new(personDirectory);
results.Add(saveContainer);
facesDirectory = string.Concat(dFacesContentDirectory, Path.Combine(directoryName, item.ImageFileHolder.NameWithoutExtension)); facesDirectory = string.Concat(dFacesContentDirectory, Path.Combine(directoryName, item.ImageFileHolder.NameWithoutExtension));
landmarksDirectory = string.Concat(d2ResultsFullGroupDirectory, Path.Combine(directoryName, item.ImageFileHolder.NameWithoutExtension)); facePartsDirectory = string.Concat(d2ResultsFullGroupDirectory, Path.Combine(directoryName, item.ImageFileHolder.NameWithoutExtension));
deterministicHashCodeKey = Shared.Models.Stateless.Methods.IMapping.GetDeterministicHashCodeKey(item, face); deterministicHashCodeKey = Shared.Models.Stateless.Methods.IMapping.GetDeterministicHashCodeKey(item, face);
checkFile = Path.Combine(directory, $"{deterministicHashCodeKey}{item.ImageFileHolder.ExtensionLowered}"); checkFile = Path.Combine(directory, $"{deterministicHashCodeKey}{item.ImageFileHolder.ExtensionLowered}");
faceFileInfo = new(Path.Combine(facesDirectory, $"{deterministicHashCodeKey}{item.ImageFileHolder.ExtensionLowered}.png")); faceFileHolder = new(Path.Combine(facesDirectory, $"{deterministicHashCodeKey}{item.ImageFileHolder.ExtensionLowered}{_FacesFilenameExtension}"));
landmarkFileInfo = new(Path.Combine(landmarksDirectory, $"{deterministicHashCodeKey}{item.ImageFileHolder.ExtensionLowered}.gif")); hiddenFaceFileHolder = new(Path.Combine(facesDirectory, $"{deterministicHashCodeKey}{item.ImageFileHolder.ExtensionLowered}{_FacesHiddenFilenameExtension}"));
facePartsFileHolder = new(Path.Combine(facePartsDirectory, $"{deterministicHashCodeKey}{item.ImageFileHolder.ExtensionLowered}{_FacePartsFilenameExtension}"));
if (string.IsNullOrEmpty(personDirectory)) if (string.IsNullOrEmpty(personDirectory))
shortcutFile = string.Empty; shortcutFile = string.Empty;
else else
shortcutFile = Path.Combine(personDirectory, $"{deterministicHashCodeKey}{item.ImageFileHolder.ExtensionLowered}.lnk"); shortcutFile = Path.Combine(personDirectory, $"{deterministicHashCodeKey}{item.ImageFileHolder.ExtensionLowered}.lnk");
results.Add(new(item.ResizedFileHolder, directory, faceFileInfo, checkFile, shortcutFile, string.Empty)); saveContainer = new(checkFile, directory, faceFileHolder, hiddenFaceFileHolder, string.Empty, facePartsFileHolder, item.ResizedFileHolder, shortcutFile);
results.Add(saveContainer);
if (!string.IsNullOrEmpty(checkFile) && Shared.Models.Stateless.IMapping.SaveFaceEncoding) if (!string.IsNullOrEmpty(checkFile) && Shared.Models.Stateless.IMapping.SaveFaceEncoding)
{ {
checkFile = Path.Combine(directory, $"{deterministicHashCodeKey}{item.ImageFileHolder.ExtensionLowered}.json"); checkFile = Path.Combine(directory, $"{deterministicHashCodeKey}{item.ImageFileHolder.ExtensionLowered}.json");
json = JsonSerializer.Serialize(face.FaceEncoding); json = JsonSerializer.Serialize(face.FaceEncoding);
results.Add(new(null, directory, null, checkFile, string.Empty, json)); saveContainer = new(checkFile, directory, json);
results.Add(saveContainer);
} }
personDirectory = Path.Combine(directory, match.DisplayDirectoryName[..1], "lnk", match.DisplayDirectoryName); personDirectory = Path.Combine(directory, match.DisplayDirectoryName[..1], "lnk", match.DisplayDirectoryName);
results.Add(new(null, personDirectory, null, string.Empty, string.Empty, string.Empty)); saveContainer = new(personDirectory);
results.Add(saveContainer);
used.Add(face.Location.NormalizedPixelPercentage.Value); used.Add(face.Location.NormalizedPixelPercentage.Value);
} }
if (deterministicHashCodeKeyValuePairsAny && Shared.Models.Stateless.IMapping.UseDeterministicHashCodeUnknownFaceKeyValuePairsForSaveMapping) if (deterministicHashCodeKeyValuePairsAny && Shared.Models.Stateless.IMapping.UseDeterministicHashCodeUnknownFaceKeyValuePairsForSaveMapping)
@ -735,26 +702,31 @@ public class MapLogic
else else
directory = Path.Combine(zPropertyHolderContentDirectory, $"{facePopulatedKey}WithButOutOfControl", match.PersonKey, dateKey); directory = Path.Combine(zPropertyHolderContentDirectory, $"{facePopulatedKey}WithButOutOfControl", match.PersonKey, dateKey);
personDirectory = Path.Combine(directory, match.DisplayDirectoryName[..1], "lnk"); personDirectory = Path.Combine(directory, match.DisplayDirectoryName[..1], "lnk");
results.Add(new(null, personDirectory, null, string.Empty, string.Empty, string.Empty)); saveContainer = new(personDirectory);
results.Add(saveContainer);
facesDirectory = string.Concat(dFacesContentDirectory, Path.Combine(directoryName, item.ImageFileHolder.NameWithoutExtension)); facesDirectory = string.Concat(dFacesContentDirectory, Path.Combine(directoryName, item.ImageFileHolder.NameWithoutExtension));
landmarksDirectory = string.Concat(d2ResultsFullGroupDirectory, Path.Combine(directoryName, item.ImageFileHolder.NameWithoutExtension)); facePartsDirectory = string.Concat(d2ResultsFullGroupDirectory, Path.Combine(directoryName, item.ImageFileHolder.NameWithoutExtension));
deterministicHashCodeKey = Shared.Models.Stateless.Methods.IMapping.GetDeterministicHashCodeKey(item, face); deterministicHashCodeKey = Shared.Models.Stateless.Methods.IMapping.GetDeterministicHashCodeKey(item, face);
checkFile = Path.Combine(directory, $"{deterministicHashCodeKey}{item.ImageFileHolder.ExtensionLowered}"); checkFile = Path.Combine(directory, $"{deterministicHashCodeKey}{item.ImageFileHolder.ExtensionLowered}");
faceFileInfo = new(Path.Combine(facesDirectory, $"{deterministicHashCodeKey}{item.ImageFileHolder.ExtensionLowered}.png")); faceFileHolder = new(Path.Combine(facesDirectory, $"{deterministicHashCodeKey}{item.ImageFileHolder.ExtensionLowered}{_FacesFilenameExtension}"));
landmarkFileInfo = new(Path.Combine(landmarksDirectory, $"{deterministicHashCodeKey}{item.ImageFileHolder.ExtensionLowered}.gif")); facePartsFileHolder = new(Path.Combine(facesDirectory, $"{deterministicHashCodeKey}{item.ImageFileHolder.ExtensionLowered}{_FacesHiddenFilenameExtension}"));
facePartsFileHolder = new(Path.Combine(facePartsDirectory, $"{deterministicHashCodeKey}{item.ImageFileHolder.ExtensionLowered}{_FacePartsFilenameExtension}"));
if (string.IsNullOrEmpty(personDirectory)) if (string.IsNullOrEmpty(personDirectory))
shortcutFile = string.Empty; shortcutFile = string.Empty;
else else
shortcutFile = Path.Combine(personDirectory, $"{deterministicHashCodeKey}{item.ImageFileHolder.ExtensionLowered}.lnk"); shortcutFile = Path.Combine(personDirectory, $"{deterministicHashCodeKey}{item.ImageFileHolder.ExtensionLowered}.lnk");
results.Add(new(item.ResizedFileHolder, directory, faceFileInfo, checkFile, shortcutFile, string.Empty)); saveContainer = new(checkFile, directory, faceFileHolder, hiddenFaceFileHolder, string.Empty, facePartsFileHolder, item.ResizedFileHolder, shortcutFile);
results.Add(saveContainer);
if (!string.IsNullOrEmpty(checkFile) && Shared.Models.Stateless.IMapping.SaveFaceEncoding) if (!string.IsNullOrEmpty(checkFile) && Shared.Models.Stateless.IMapping.SaveFaceEncoding)
{ {
checkFile = Path.Combine(directory, $"{deterministicHashCodeKey}{item.ImageFileHolder.ExtensionLowered}.json"); checkFile = Path.Combine(directory, $"{deterministicHashCodeKey}{item.ImageFileHolder.ExtensionLowered}.json");
json = JsonSerializer.Serialize(face.FaceEncoding); json = JsonSerializer.Serialize(face.FaceEncoding);
results.Add(new(null, directory, null, checkFile, string.Empty, json)); saveContainer = new(checkFile, directory, json);
results.Add(saveContainer);
} }
personDirectory = Path.Combine(directory, match.DisplayDirectoryName[..1], "lnk", match.DisplayDirectoryName); personDirectory = Path.Combine(directory, match.DisplayDirectoryName[..1], "lnk", match.DisplayDirectoryName);
results.Add(new(null, personDirectory, null, string.Empty, string.Empty, string.Empty)); saveContainer = new(personDirectory);
results.Add(saveContainer);
used.Add(face.Location.NormalizedPixelPercentage.Value); used.Add(face.Location.NormalizedPixelPercentage.Value);
} }
} }
@ -763,63 +735,127 @@ public class MapLogic
return results; return results;
} }
private static void Save(List<(IFileHolder? resizedFileHolder, string directory, FileInfo? faceFileInfo, string checkFile, string shortcutFile, string json)> collection) private List<SaveContainer> GetClosestSaveContainers(string argZero, Container[] containers, string dFacesContentDirectory, string d2ResultsFullGroupDirectory, string zPropertyHolderContentDirectory)
{ {
WindowsShortcut windowsShortcut; List<SaveContainer> results = new();
string[] directories = (from l in collection select l.directory).Distinct().ToArray(); Closest? match;
foreach (string directory in directories) string dateKey;
string checkFile;
string directory;
string shortcutFile;
string? directoryName;
string facesDirectory;
string personDirectory;
List<int> used = new();
FileHolder faceFileHolder;
string facePartsDirectory;
SaveContainer saveContainer;
FileHolder facePartsFileHolder;
FileHolder hiddenFaceFileHolder;
double deterministicHashCodeKey;
DateTime dateTime = DateTime.Now;
const string facePopulatedKey = nameof(Closest);
foreach (Container container in containers)
{ {
if (string.IsNullOrEmpty(directory)) if (!container.Items.Any())
continue; continue;
if (!Directory.Exists(directory)) if (!container.SourceDirectory.StartsWith(argZero))
_ = Directory.CreateDirectory(directory); continue;
foreach (Item item in container.Items)
{
used.Clear();
if (item.ImageFileHolder is null || item.Property?.Id is null || item.ResizedFileHolder is null)
continue;
if (!item.Closest.Any())
continue;
directoryName = Path.GetDirectoryName(item.RelativePath);
if (directoryName is null)
throw new Exception();
foreach (Face face in item.Faces)
{
match = null;
if (face.FaceEncoding is null || face.Location?.NormalizedPixelPercentage is null)
continue;
foreach (Closest closest in item.Closest)
{
if (closest.NormalizedPixelPercentage != face.Location.NormalizedPixelPercentage.Value)
continue;
match = closest;
break;
} }
foreach ((IFileHolder? resizedFileHolder, string directory, FileInfo? faceFileInfo, string checkFile, string shortcutFile, string json) in collection) if (match is null)
continue;
foreach (Mapping mapping in item.Mapping)
{ {
if (string.IsNullOrEmpty(directory) || string.IsNullOrEmpty(checkFile) || resizedFileHolder is null || faceFileInfo is null || !string.IsNullOrEmpty(json)) if (mapping.NormalizedPixelPercentage is null || mapping.NormalizedPixelPercentage.Value != face.Location.NormalizedPixelPercentage.Value)
continue; continue;
if (File.Exists(checkFile)) throw new Exception();
continue; }
if (faceFileInfo.Directory is not null && faceFileInfo.Directory.Exists && faceFileInfo.Exists) dateKey = Stateless.MapLogic.GetDateKey(dateTime, match.Mapping, match.MinimumDateTime, match.IsWrongYear);
File.Copy(faceFileInfo.FullName, checkFile); directory = Path.Combine(zPropertyHolderContentDirectory, facePopulatedKey, match.Mapping.PersonKey, dateKey);
personDirectory = Path.Combine(directory, match.Mapping.DisplayDirectoryName[..1], "lnk");
saveContainer = new(personDirectory);
results.Add(saveContainer);
facesDirectory = string.Concat(dFacesContentDirectory, Path.Combine(directoryName, item.ImageFileHolder.NameWithoutExtension));
facePartsDirectory = string.Concat(d2ResultsFullGroupDirectory, Path.Combine(directoryName, item.ImageFileHolder.NameWithoutExtension));
deterministicHashCodeKey = Shared.Models.Stateless.Methods.IMapping.GetDeterministicHashCodeKey(item, face);
checkFile = Path.Combine(directory, $"{deterministicHashCodeKey}{item.ImageFileHolder.ExtensionLowered}");
faceFileHolder = new(Path.Combine(facesDirectory, $"{deterministicHashCodeKey}{item.ImageFileHolder.ExtensionLowered}{_FacesFilenameExtension}"));
hiddenFaceFileHolder = new(Path.Combine(facesDirectory, $"{deterministicHashCodeKey}{item.ImageFileHolder.ExtensionLowered}{_FacesHiddenFilenameExtension}"));
facePartsFileHolder = new(Path.Combine(facePartsDirectory, $"{deterministicHashCodeKey}{item.ImageFileHolder.ExtensionLowered}{_FacePartsFilenameExtension}"));
if (string.IsNullOrEmpty(personDirectory))
shortcutFile = string.Empty;
else else
File.Copy(resizedFileHolder.FullName, checkFile); shortcutFile = Path.Combine(personDirectory, $"{deterministicHashCodeKey}{item.ImageFileHolder.ExtensionLowered}.lnk");
saveContainer = new(checkFile, directory, faceFileHolder, hiddenFaceFileHolder, string.Empty, facePartsFileHolder, item.ResizedFileHolder, shortcutFile);
results.Add(saveContainer);
personDirectory = Path.Combine(directory, match.Mapping.DisplayDirectoryName[..1], "lnk", match.Mapping.DisplayDirectoryName);
saveContainer = new(personDirectory);
results.Add(saveContainer);
used.Add(face.Location.NormalizedPixelPercentage.Value);
} }
foreach ((IFileHolder? resizedFileHolder, string directory, FileInfo? faceFileInfo, string checkFile, string shortcutFile, string json) in collection) foreach (Closest closest in item.Closest)
{ {
if (string.IsNullOrEmpty(directory) || string.IsNullOrEmpty(checkFile) || resizedFileHolder is not null || faceFileInfo is not null || string.IsNullOrEmpty(json)) if (used.Contains(closest.NormalizedPixelPercentage))
continue; continue;
if (File.Exists(checkFile)) dateKey = Stateless.MapLogic.GetDateKey(dateTime, closest.Mapping, closest.MinimumDateTime, closest.IsWrongYear);
continue; directory = Path.Combine(zPropertyHolderContentDirectory, facePopulatedKey, closest.Mapping.PersonKey, dateKey);
_ = Shared.Models.Stateless.Methods.IPath.WriteAllText(checkFile, json, updateDateWhenMatches: false, compareBeforeWrite: true, updateToWhenMatches: null); personDirectory = Path.Combine(directory, closest.Mapping.DisplayDirectoryName, "lnk");
} saveContainer = new(personDirectory);
foreach ((IFileHolder? resizedFileHolder, string directory, FileInfo? _, string checkFile, string shortcutFile, string json) in collection) results.Add(saveContainer);
{ facesDirectory = string.Concat(dFacesContentDirectory, Path.Combine(directoryName, item.ImageFileHolder.NameWithoutExtension));
if (string.IsNullOrEmpty(directory) || string.IsNullOrEmpty(checkFile) || resizedFileHolder is null) facePartsDirectory = string.Concat(d2ResultsFullGroupDirectory, Path.Combine(directoryName, item.ImageFileHolder.NameWithoutExtension));
continue; deterministicHashCodeKey = Shared.Models.Stateless.Methods.IMapping.GetDeterministicHashCodeKey(item, closest);
if (string.IsNullOrEmpty(shortcutFile) || !resizedFileHolder.Exists) checkFile = Path.Combine(directory, $"{deterministicHashCodeKey}{item.ImageFileHolder.ExtensionLowered}");
continue; faceFileHolder = new(Path.Combine(facesDirectory, $"{deterministicHashCodeKey}{item.ImageFileHolder.ExtensionLowered}{_FacesFilenameExtension}"));
try hiddenFaceFileHolder = new(Path.Combine(facesDirectory, $"{deterministicHashCodeKey}{item.ImageFileHolder.ExtensionLowered}{_FacesHiddenFilenameExtension}"));
{ facePartsFileHolder = new(Path.Combine(facePartsDirectory, $"{deterministicHashCodeKey}{item.ImageFileHolder.ExtensionLowered}{_FacePartsFilenameExtension}"));
windowsShortcut = new() { Path = resizedFileHolder.FullName }; if (string.IsNullOrEmpty(personDirectory))
windowsShortcut.Save(shortcutFile); shortcutFile = string.Empty;
windowsShortcut.Dispose(); else
} shortcutFile = Path.Combine(personDirectory, $"{deterministicHashCodeKey}{item.ImageFileHolder.ExtensionLowered}.lnk");
catch (Exception) saveContainer = new(checkFile, directory, faceFileHolder, hiddenFaceFileHolder, string.Empty, facePartsFileHolder, item.ResizedFileHolder, shortcutFile);
{ } results.Add(saveContainer);
personDirectory = Path.Combine(directory, closest.Mapping.DisplayDirectoryName[..1], "lnk", closest.Mapping.DisplayDirectoryName);
saveContainer = new(personDirectory);
results.Add(saveContainer);
used.Add(closest.NormalizedPixelPercentage);
} }
} }
}
public void SaveClosest(string argZero, Container[] containers, string dFacesContentDirectory, string d2ResultsFullGroupDirectory, string zPropertyHolderContentDirectory) return results;
{
List<(IFileHolder? resizedFileHolder, string directory, FileInfo? faceFileInfo, string checkFile, string shortcutFile, string json)> collection = GetClosest(argZero, containers, dFacesContentDirectory, d2ResultsFullGroupDirectory, zPropertyHolderContentDirectory);
Save(collection);
} }
public void SaveMapping(string argZero, Container[] containers, string dFacesContentDirectory, string d2ResultsFullGroupDirectory, string zPropertyHolderContentDirectory) public void SaveMapping(string argZero, Container[] containers, string dFacesContentDirectory, string d2ResultsFullGroupDirectory, string zPropertyHolderContentDirectory)
{ {
List<(IFileHolder? resizedFileHolder, string directory, FileInfo? faceFileInfo, string checkFile, string shortcutFile, string json)> collection = GetMapping(argZero, containers, dFacesContentDirectory, d2ResultsFullGroupDirectory, zPropertyHolderContentDirectory); List<SaveContainer> saveContainers = GetMappingSaveContainers(argZero, containers, dFacesContentDirectory, d2ResultsFullGroupDirectory, zPropertyHolderContentDirectory);
Save(collection); SaveContainers(saveContainers);
}
public void SaveClosest(string argZero, Container[] containers, string dFacesContentDirectory, string d2ResultsFullGroupDirectory, string zPropertyHolderContentDirectory)
{
List<SaveContainer> saveContainers = GetClosestSaveContainers(argZero, containers, dFacesContentDirectory, d2ResultsFullGroupDirectory, zPropertyHolderContentDirectory);
SaveContainers(saveContainers);
} }
} }

View File

@ -7,6 +7,10 @@ public interface IMapLogic
static (bool?, string[]) IsWrongYear(Shared.Models.Item item) => static (bool?, string[]) IsWrongYear(Shared.Models.Item item) =>
MapLogic.IsWrongYear(item); MapLogic.IsWrongYear(item);
void TestStatic_SetSingleImage(string[] ignoreRelativePaths, string argZero, Shared.Models.Container[] containers);
static void SetSingleImage(string[] ignoreRelativePaths, string argZero, Shared.Models.Container[] containers) =>
MapLogic.SetSingleImage(ignoreRelativePaths, argZero, containers);
string TestStatic_GetDateKey(DateTime dateTime, Shared.Models.Mapping mapping, DateTime minimumDateTime, bool? isWrongYear); string TestStatic_GetDateKey(DateTime dateTime, Shared.Models.Mapping mapping, DateTime minimumDateTime, bool? isWrongYear);
static string GetDateKey(DateTime dateTime, Shared.Models.Mapping mapping, DateTime minimumDateTime, bool? isWrongYear) => static string GetDateKey(DateTime dateTime, Shared.Models.Mapping mapping, DateTime minimumDateTime, bool? isWrongYear) =>
MapLogic.GetDateKey(dateTime, mapping, minimumDateTime, isWrongYear); MapLogic.GetDateKey(dateTime, mapping, minimumDateTime, isWrongYear);

View File

@ -1,4 +1,5 @@
using View_by_Distance.Shared.Models; using View_by_Distance.Shared.Models;
using View_by_Distance.Shared.Models.Stateless;
namespace View_by_Distance.Map.Models.Stateless; namespace View_by_Distance.Map.Models.Stateless;
@ -90,4 +91,44 @@ internal abstract class MapLogic
return result; return result;
} }
internal static void SetSingleImage(string[] ignoreRelativePaths, string argZero, Container[] containers)
{
Mapping mapping;
string personKey;
int? approximateYears = null;
PersonBirthday? personBirthday = null;
const string displayDirectoryName = Property.Models.Stateless.IResult.AllInOne;
foreach (Container container in containers)
{
if (!container.Items.Any())
continue;
if (!container.SourceDirectory.StartsWith(argZero))
continue;
if (ignoreRelativePaths.Contains(Path.GetFileName(container.SourceDirectory)))
continue;
foreach (Item item in container.Items)
{
if (item.ImageFileHolder is null || item.Property?.Id is null)
continue;
foreach (Face face in item.Faces)
{
if (face.FaceEncoding is null || face.Location?.NormalizedPixelPercentage is null)
continue;
personKey = DateTime.MinValue.AddYears(IPersonBirthday.FirstYear).ToString(IPersonBirthday.Format);
personBirthday = Shared.Models.Stateless.Methods.IPersonBirthday.GetPersonBirthday(personKey);
if (personBirthday is null)
continue;
mapping = new(approximateYears, displayDirectoryName, face.Location.NormalizedPixelPercentage, personBirthday, personKey);
item.Mapping.Add(mapping);
if (personBirthday is not null)
break;
}
if (personBirthday is not null)
break;
}
if (personBirthday is not null)
break;
}
}
} }

View File

@ -7,7 +7,7 @@ namespace View_by_Distance.Map.Models.Stateless;
public class ByDeterministicHashCode public class ByDeterministicHashCode
{ {
private static void SetOther(string outputExtension, Dictionary<string, Person> personKeyValuePairs, string deterministicHashCodePeopleDirectory, List<double> skipCollection, List<(string, int?, string, PersonBirthday[])> peopleCollection) private static void SetOther(string resizeFilenameExtension, Person[] people, string deterministicHashCodePeopleDirectory, List<double> skipCollection, List<(string, int?, string, PersonBirthday[])> peopleCollection)
{ {
string json; string json;
string personKey; string personKey;
@ -18,22 +18,31 @@ public class ByDeterministicHashCode
string[] personKeyDirectories; string[] personKeyDirectories;
string personKeyJsonDirectory; string personKeyJsonDirectory;
PersonBirthday? personBirthday; PersonBirthday? personBirthday;
List<string> personKeys = new();
string[] personDisplayDirectories; string[] personDisplayDirectories;
string convertedPersonKeyDirectory; string convertedPersonKeyDirectory;
string? personDisplayDirectoryName; string? personDisplayDirectoryName;
List<PersonBirthday> personBirthdays; List<PersonBirthday> personBirthdays;
Dictionary<string, Person> personKeyValuePairs = new();
foreach (Person person in people)
{
personKey = Shared.Models.Stateless.Methods.IPersonBirthday.GetFormatted(person.Birthday);
if (personKeyValuePairs.ContainsKey(personKey))
break;
personKeyValuePairs.Add(personKey, person);
}
string[] groupDirectories = Directory.GetDirectories(deterministicHashCodePeopleDirectory, "*", SearchOption.TopDirectoryOnly); string[] groupDirectories = Directory.GetDirectories(deterministicHashCodePeopleDirectory, "*", SearchOption.TopDirectoryOnly);
foreach (string groupDirectory in groupDirectories) foreach (string groupDirectory in groupDirectories)
{ {
groupDirectoryName = Path.GetFileName(groupDirectory); groupDirectoryName = Path.GetFileName(groupDirectory);
if (groupDirectoryName[0] == '!') if (groupDirectoryName[0] == '!')
{ {
skipCollection.AddRange(from l in Directory.GetFiles(groupDirectory, $"*{outputExtension}", SearchOption.AllDirectories) select double.Parse(Path.GetFileNameWithoutExtension(l))); skipCollection.AddRange(from l in Directory.GetFiles(groupDirectory, $"*{resizeFilenameExtension}", SearchOption.AllDirectories) select double.Parse(Path.GetFileNameWithoutExtension(l)));
continue; continue;
} }
else if (groupDirectoryName[0] is not '_' and not '~' and not '^') else if (groupDirectoryName[0] is not '_' and not '~' and not '^')
continue; continue;
skipCollection.AddRange(from l in Directory.GetFiles(groupDirectory, $"*{outputExtension}", SearchOption.AllDirectories) select double.Parse(Path.GetFileNameWithoutExtension(l))); skipCollection.AddRange(from l in Directory.GetFiles(groupDirectory, $"*{resizeFilenameExtension}", SearchOption.AllDirectories) select double.Parse(Path.GetFileNameWithoutExtension(l)));
personDisplayDirectories = Directory.GetDirectories(groupDirectory, "*", SearchOption.TopDirectoryOnly); personDisplayDirectories = Directory.GetDirectories(groupDirectory, "*", SearchOption.TopDirectoryOnly);
foreach (string personDisplayDirectory in personDisplayDirectories) foreach (string personDisplayDirectory in personDisplayDirectories)
{ {
@ -84,10 +93,24 @@ public class ByDeterministicHashCode
json = JsonSerializer.Serialize(personKeyValuePairs[personKey], new JsonSerializerOptions() { WriteIndented = true }); json = JsonSerializer.Serialize(personKeyValuePairs[personKey], new JsonSerializerOptions() { WriteIndented = true });
_ = Shared.Models.Stateless.Methods.IPath.WriteAllText(personKeyJsonFileName, json, updateDateWhenMatches: false, compareBeforeWrite: true, updateToWhenMatches: null); _ = Shared.Models.Stateless.Methods.IPath.WriteAllText(personKeyJsonFileName, json, updateDateWhenMatches: false, compareBeforeWrite: true, updateToWhenMatches: null);
} }
personKeys.Add(personKey);
peopleCollection.Add(new(personDisplayDirectoryName, approximateYears, personKey, personBirthdays.OrderByDescending(l => l.Value).ToArray())); peopleCollection.Add(new(personDisplayDirectoryName, approximateYears, personKey, personBirthdays.OrderByDescending(l => l.Value).ToArray()));
} }
} }
} }
approximateYears = null;
const string displayDirectoryName = Property.Models.Stateless.IResult.AllInOne;
DateTime incrementDate = new(Shared.Models.Stateless.IPersonBirthday.FirstYear, 1, 1);
for (int i = 0; i < 500; i++)
{
incrementDate = incrementDate.AddDays(1);
personBirthday = new(incrementDate);
personKey = Shared.Models.Stateless.Methods.IPersonBirthday.GetFormatted(personBirthday);
if (personKeys.Contains(personKey))
continue;
personKeys.Add(personKey);
peopleCollection.Add(new(displayDirectoryName, approximateYears, personKey, new PersonBirthday[] { personBirthday }));
}
} }
internal static void SetKeyValuePairs(string deterministicHashCodeContentDirectory, List<(string, double)> deterministicHashCodeCollection, List<(string, double)> incorrectDeterministicHashCodeCollection, Dictionary<int, List<Face>> keyValuePairs) internal static void SetKeyValuePairs(string deterministicHashCodeContentDirectory, List<(string, double)> deterministicHashCodeCollection, List<(string, double)> incorrectDeterministicHashCodeCollection, Dictionary<int, List<Face>> keyValuePairs)
@ -138,8 +161,6 @@ public class ByDeterministicHashCode
continue; continue;
deterministicHashCodeCollection.Add(new(personKey, reversedDeterministicHashCodeKey.Value)); deterministicHashCodeCollection.Add(new(personKey, reversedDeterministicHashCodeKey.Value));
} }
if (personNameDirectory == personFirstInitialDirectory)
continue;
personNameLinkDirectories = Directory.GetDirectories(personNameDirectory, "*", SearchOption.TopDirectoryOnly); personNameLinkDirectories = Directory.GetDirectories(personNameDirectory, "*", SearchOption.TopDirectoryOnly);
foreach (string personNameLinkDirectory in personNameLinkDirectories) foreach (string personNameLinkDirectory in personNameLinkDirectories)
{ {
@ -152,6 +173,8 @@ public class ByDeterministicHashCode
} }
_ = Shared.Models.Stateless.Methods.IPath.DeleteEmptyDirectories(personNameLinkDirectory); _ = Shared.Models.Stateless.Methods.IPath.DeleteEmptyDirectories(personNameLinkDirectory);
} }
if (personNameDirectory == personFirstInitialDirectory)
continue;
Directory.Move(personNameDirectory, personFirstInitialDirectory); Directory.Move(personNameDirectory, personFirstInitialDirectory);
_ = Shared.Models.Stateless.Methods.IPath.DeleteEmptyDirectories(personNameDirectory); _ = Shared.Models.Stateless.Methods.IPath.DeleteEmptyDirectories(personNameDirectory);
} }
@ -163,28 +186,29 @@ public class ByDeterministicHashCode
} }
} }
internal static string SetByRef(string outputExtension, Dictionary<string, Person> personKeyValuePairs, List<double> skipCollection, Dictionary<string, (string, int?, string, PersonBirthday[])> peopleKeyValuePairs, Dictionary<int, string[]> deterministicHashCodeUnknownFaceKeyValuePairs, Dictionary<double, string[]> deterministicHashCodeKeyValuePairs, Dictionary<double, string[]> incorrectDeterministicHashCodeKeyValuePairs, string deterministicHashCodeRootDirectory) internal static string SetByRef(string resizeFilenameExtension, Person[] people, List<double> skipCollection, Dictionary<string, (string, int?, string, PersonBirthday[])> peopleKeyValuePairs, List<string> notMappedPersonKeys, Dictionary<int, string[]> deterministicHashCodeUnknownFaceKeyValuePairs, Dictionary<double, string[]> deterministicHashCodeKeyValuePairs, Dictionary<double, string[]> incorrectDeterministicHashCodeKeyValuePairs, string deterministicHashCodeRootDirectory)
{ {
string result; string result;
string[] distinctPersonKeys;
Dictionary<int, List<Face>> keyValuePairs = new();
List<string> deterministicHashCodePersonKeys = new(); List<string> deterministicHashCodePersonKeys = new();
List<string> deterministicHashCodeUnknownFacePersonKeys = new(); List<string> deterministicHashCodeUnknownFacePersonKeys = new();
Dictionary<double, List<string>> deterministicHashCodeScope = new();
Dictionary<double, List<string>> incorrectDeterministicHashCodeScope = new();
List<(string PersonKey, double IdAndNormalizedPixelPercentage)> deterministicHashCodeCollection = new();
string deterministicHashCodePeopleDirectory = Path.Combine(deterministicHashCodeRootDirectory, "People");
List<(string PersonKey, double IdAndNormalizedPixelPercentage)> incorrectDeterministicHashCodeCollection = new();
foreach (KeyValuePair<int, string[]> keyValuePair in deterministicHashCodeUnknownFaceKeyValuePairs) foreach (KeyValuePair<int, string[]> keyValuePair in deterministicHashCodeUnknownFaceKeyValuePairs)
deterministicHashCodeUnknownFacePersonKeys.AddRange(keyValuePair.Value); deterministicHashCodeUnknownFacePersonKeys.AddRange(keyValuePair.Value);
deterministicHashCodeUnknownFacePersonKeys = deterministicHashCodeUnknownFacePersonKeys.Distinct().ToList(); deterministicHashCodeUnknownFacePersonKeys = deterministicHashCodeUnknownFacePersonKeys.Distinct().ToList();
List<(string, int?, string, PersonBirthday[])> peopleCollection = new(); List<(string, int?, string, PersonBirthday[])> peopleCollection = new();
string deterministicHashCodePeopleDirectory = Path.Combine(deterministicHashCodeRootDirectory, "People"); if (!Directory.Exists(deterministicHashCodePeopleDirectory))
if (Directory.Exists(deterministicHashCodePeopleDirectory)) _ = Directory.CreateDirectory(deterministicHashCodePeopleDirectory);
SetOther(outputExtension, personKeyValuePairs, deterministicHashCodePeopleDirectory, skipCollection, peopleCollection); else
SetOther(resizeFilenameExtension, people, deterministicHashCodePeopleDirectory, skipCollection, peopleCollection);
result = Path.Combine(deterministicHashCodeRootDirectory, "()"); result = Path.Combine(deterministicHashCodeRootDirectory, "()");
if (!Directory.Exists(result)) if (!Directory.Exists(result))
result = string.Empty; _ = Directory.CreateDirectory(result);
else
{
Dictionary<int, List<Face>> keyValuePairs = new();
Dictionary<double, List<string>> deterministicHashCodeScope = new();
Dictionary<double, List<string>> incorrectDeterministicHashCodeScope = new();
List<(string PersonKey, double IdAndNormalizedPixelPercentage)> deterministicHashCodeCollection = new();
List<(string PersonKey, double IdAndNormalizedPixelPercentage)> incorrectDeterministicHashCodeCollection = new();
SetKeyValuePairs(result, deterministicHashCodeCollection, incorrectDeterministicHashCodeCollection, keyValuePairs); SetKeyValuePairs(result, deterministicHashCodeCollection, incorrectDeterministicHashCodeCollection, keyValuePairs);
deterministicHashCodeCollection = (from l in deterministicHashCodeCollection orderby l.IdAndNormalizedPixelPercentage select l).ToList(); deterministicHashCodeCollection = (from l in deterministicHashCodeCollection orderby l.IdAndNormalizedPixelPercentage select l).ToList();
incorrectDeterministicHashCodeCollection = (from l in incorrectDeterministicHashCodeCollection orderby l.IdAndNormalizedPixelPercentage select l).ToList(); incorrectDeterministicHashCodeCollection = (from l in incorrectDeterministicHashCodeCollection orderby l.IdAndNormalizedPixelPercentage select l).ToList();
@ -203,16 +227,49 @@ public class ByDeterministicHashCode
incorrectDeterministicHashCodeScope[idAndNormalizedPixelPercentage].Add(personKey); incorrectDeterministicHashCodeScope[idAndNormalizedPixelPercentage].Add(personKey);
} }
foreach (KeyValuePair<double, List<string>> keyValuePair in deterministicHashCodeScope) foreach (KeyValuePair<double, List<string>> keyValuePair in deterministicHashCodeScope)
deterministicHashCodeKeyValuePairs.Add(keyValuePair.Key, keyValuePair.Value.Distinct().ToArray()); {
distinctPersonKeys = keyValuePair.Value.Distinct().ToArray();
deterministicHashCodeKeyValuePairs.Add(keyValuePair.Key, distinctPersonKeys);
}
foreach (KeyValuePair<double, List<string>> keyValuePair in incorrectDeterministicHashCodeScope) foreach (KeyValuePair<double, List<string>> keyValuePair in incorrectDeterministicHashCodeScope)
incorrectDeterministicHashCodeKeyValuePairs.Add(keyValuePair.Key, keyValuePair.Value.Distinct().ToArray()); incorrectDeterministicHashCodeKeyValuePairs.Add(keyValuePair.Key, keyValuePair.Value.Distinct().ToArray());
} if (peopleCollection.Any())
foreach ((string personDisplayDirectoryName, int? approximateYears, string personKey, PersonBirthday[] personBirthdays) in peopleCollection)
{ {
if (peopleKeyValuePairs.ContainsKey(personKey) && peopleKeyValuePairs[personKey].Item1 != personDisplayDirectoryName) foreach ((string displayDirectoryName, int? approximateYears, string personKey, PersonBirthday[] personBirthdays) in peopleCollection)
{
if (peopleKeyValuePairs.ContainsKey(personKey) && peopleKeyValuePairs[personKey].Item1 != displayDirectoryName)
throw new NotImplementedException(); throw new NotImplementedException();
if (deterministicHashCodeUnknownFacePersonKeys.Contains(personKey) || deterministicHashCodePersonKeys.Contains(personKey)) if (deterministicHashCodeUnknownFacePersonKeys.Contains(personKey) || deterministicHashCodePersonKeys.Contains(personKey))
peopleKeyValuePairs.Add(personKey, new(personDisplayDirectoryName, approximateYears, personKey, personBirthdays)); peopleKeyValuePairs.Add(personKey, new(displayDirectoryName, approximateYears, personKey, personBirthdays));
else
notMappedPersonKeys.Add(personKey);
}
}
if (deterministicHashCodeUnknownFacePersonKeys.Any() || deterministicHashCodePersonKeys.Any())
{
int? approximateYears = null;
PersonBirthday? personBirthday;
const string displayDirectoryName = Property.Models.Stateless.IResult.AllInOne;
foreach (string personKey in deterministicHashCodeUnknownFacePersonKeys)
{
if (!peopleKeyValuePairs.ContainsKey(personKey))
{
personBirthday = Shared.Models.Stateless.Methods.IPersonBirthday.GetPersonBirthday(personKey);
if (personBirthday is null)
continue;
peopleKeyValuePairs.Add(personKey, new(displayDirectoryName, approximateYears, personKey, new PersonBirthday[] { personBirthday }));
}
}
foreach (string personKey in deterministicHashCodePersonKeys)
{
if (!peopleKeyValuePairs.ContainsKey(personKey))
{
personBirthday = Shared.Models.Stateless.Methods.IPersonBirthday.GetPersonBirthday(personKey);
if (personBirthday is null)
continue;
peopleKeyValuePairs.Add(personKey, new(displayDirectoryName, approximateYears, personKey, new PersonBirthday[] { personBirthday }));
}
}
} }
return result; return result;
} }

View File

@ -114,6 +114,10 @@ public class A_Property
Shared.Models.Property result; Shared.Models.Property result;
if (_Log is null) if (_Log is null)
throw new NullReferenceException(nameof(_Log)); throw new NullReferenceException(nameof(_Log));
if (filteredSourceDirectoryFileHolder.CreationTime is null)
throw new NullReferenceException(nameof(filteredSourceDirectoryFileHolder.CreationTime));
if (filteredSourceDirectoryFileHolder.LastWriteTime is null)
throw new NullReferenceException(nameof(filteredSourceDirectoryFileHolder.LastWriteTime));
long ticks; long ticks;
byte[] bytes; byte[] bytes;
string value; string value;
@ -275,7 +279,7 @@ public class A_Property
fileLength = 0; fileLength = 0;
else else
fileLength = filteredSourceDirectoryFileHolder.Length.Value; fileLength = filteredSourceDirectoryFileHolder.Length.Value;
result = new(filteredSourceDirectoryFileHolder.CreationTime, dateTime, dateTimeDigitized, dateTimeOriginal, fileLength, gpsDateStamp, height, id, indices.ToArray(), filteredSourceDirectoryFileHolder.LastWriteTime, make, model, orientation, width); result = new(filteredSourceDirectoryFileHolder.CreationTime.Value, dateTime, dateTimeDigitized, dateTimeOriginal, fileLength, gpsDateStamp, height, id, indices.ToArray(), filteredSourceDirectoryFileHolder.LastWriteTime.Value, make, model, orientation, width);
return result; return result;
} }

View File

@ -147,19 +147,15 @@ public class Container
private static Shared.Models.Container[] GetContainers(Configuration configuration, bool firstRun, string aPropertySingletonDirectory, List<(int, string, FileHolder[], int)> fileHolderGroupCollection, List<(int, string, List<(string, Shared.Models.Property?)>, int)> collectionFromJson) private static Shared.Models.Container[] GetContainers(Configuration configuration, bool firstRun, string aPropertySingletonDirectory, List<(int, string, FileHolder[], int)> fileHolderGroupCollection, List<(int, string, List<(string, Shared.Models.Property?)>, int)> collectionFromJson)
{ {
Shared.Models.Container[] results; Shared.Models.Container[] results;
Item item;
int length; int length;
int additional; int additional;
string inferred; string inferred;
string fileName;
string extension;
List<Item> items; List<Item> items;
string[] existing; string[] existing;
string keyWithJson; string keyWithJson;
string relativePath; string relativePath;
string? directoryName;
string extensionLowered;
FileHolder keyFileHolder; FileHolder keyFileHolder;
string? fileNameWithoutExtension;
bool isValidImageFormatExtension; bool isValidImageFormatExtension;
Shared.Models.Container container; Shared.Models.Container container;
List<string> keySourceDirectories; List<string> keySourceDirectories;
@ -170,22 +166,8 @@ public class Container
{ {
foreach (FileHolder sourceDirectoryFileHolder in sourceDirectoryFileHolderCollection) foreach (FileHolder sourceDirectoryFileHolder in sourceDirectoryFileHolderCollection)
{ {
relativePath = Shared.Models.Stateless.Methods.IPath.GetRelativePath(sourceDirectoryFileHolder.FullName, length); relativePath = Shared.Models.Stateless.Methods.IPath.GetRelativePath(sourceDirectoryFileHolder.FullName, length, forceExtensionToLower: true);
fileHolderKeyValuePairs.Add(relativePath, new(sourceDirectory, sourceDirectoryFileHolder)); fileHolderKeyValuePairs.Add(relativePath, new(sourceDirectory, sourceDirectoryFileHolder));
extension = Path.GetExtension(sourceDirectoryFileHolder.FullName);
extensionLowered = Path.GetExtension(sourceDirectoryFileHolder.FullName).ToLower();
if (extension != extensionLowered)
{
directoryName = Path.GetDirectoryName(sourceDirectoryFileHolder.FullName);
if (string.IsNullOrEmpty(directoryName))
continue;
fileNameWithoutExtension = Path.GetFileNameWithoutExtension(sourceDirectoryFileHolder.FullName);
if (string.IsNullOrEmpty(fileNameWithoutExtension))
continue;
fileName = Path.Combine(directoryName, $"{fileNameWithoutExtension}{extensionLowered}");
relativePath = Shared.Models.Stateless.Methods.IPath.GetRelativePath(fileName, length);
fileHolderKeyValuePairs.Add(relativePath, new(sourceDirectory, sourceDirectoryFileHolder));
}
} }
} }
length = aPropertySingletonDirectory.Length; length = aPropertySingletonDirectory.Length;
@ -197,7 +179,7 @@ public class Container
keySourceDirectories = new(); keySourceDirectories = new();
foreach ((string sourceDirectoryFile, Shared.Models.Property? property) in collection) foreach ((string sourceDirectoryFile, Shared.Models.Property? property) in collection)
{ {
keyWithJson = Shared.Models.Stateless.Methods.IPath.GetRelativePath(sourceDirectoryFile, length); keyWithJson = Shared.Models.Stateless.Methods.IPath.GetRelativePath(sourceDirectoryFile, length, forceExtensionToLower: false);
relativePath = keyWithJson[..^5]; relativePath = keyWithJson[..^5];
if (!fileHolderKeyValuePairs.ContainsKey(relativePath)) if (!fileHolderKeyValuePairs.ContainsKey(relativePath))
{ {
@ -207,7 +189,8 @@ public class Container
continue; continue;
keySourceDirectories.Add(string.Concat(keyFileHolder.DirectoryName)); keySourceDirectories.Add(string.Concat(keyFileHolder.DirectoryName));
isValidImageFormatExtension = configuration.ValidImageFormatExtensions.Contains(keyFileHolder.ExtensionLowered); isValidImageFormatExtension = configuration.ValidImageFormatExtensions.Contains(keyFileHolder.ExtensionLowered);
items.Add(new(sourceDirectoryFile, relativePath, keyFileHolder, isValidImageFormatExtension, property, true, null)); item = new(sourceDirectoryFile, relativePath, keyFileHolder, isValidImageFormatExtension, property, true, null);
items.Add(item);
} }
else else
{ {
@ -219,11 +202,12 @@ public class Container
continue; continue;
isValidImageFormatExtension = configuration.ValidImageFormatExtensions.Contains(keyFileHolder.ExtensionLowered); isValidImageFormatExtension = configuration.ValidImageFormatExtensions.Contains(keyFileHolder.ExtensionLowered);
if (property?.Id is null || property?.Width is null || property?.Height is null) if (property?.Id is null || property?.Width is null || property?.Height is null)
items.Add(new(sourceDirectoryFile, relativePath, keyFileHolder, isValidImageFormatExtension, property, false, null)); item = new(sourceDirectoryFile, relativePath, keyFileHolder, isValidImageFormatExtension, property, false, null);
else if (configuration.PropertiesChangedForProperty || property.LastWriteTime != keyFileHolder.LastWriteTime || property.FileSize != keyFileHolder.Length) else if (configuration.PropertiesChangedForProperty || property.LastWriteTime != keyFileHolder.LastWriteTime || property.FileSize != keyFileHolder.Length)
items.Add(new(sourceDirectoryFile, relativePath, keyFileHolder, isValidImageFormatExtension, property, false, true)); item = new(sourceDirectoryFile, relativePath, keyFileHolder, isValidImageFormatExtension, property, false, true);
else else
items.Add(new(sourceDirectoryFile, relativePath, keyFileHolder, isValidImageFormatExtension, property, false, false)); item = new(sourceDirectoryFile, relativePath, keyFileHolder, isValidImageFormatExtension, property, false, false);
items.Add(item);
} }
} }
if (items.Any()) if (items.Any())
@ -240,7 +224,7 @@ public class Container
items = new(); items = new();
foreach (FileHolder sourceDirectoryFileHolder in sourceDirectoryFileHolderCollection) foreach (FileHolder sourceDirectoryFileHolder in sourceDirectoryFileHolderCollection)
{ {
relativePath = Shared.Models.Stateless.Methods.IPath.GetRelativePath(sourceDirectoryFileHolder.FullName, length); relativePath = Shared.Models.Stateless.Methods.IPath.GetRelativePath(sourceDirectoryFileHolder.FullName, length, forceExtensionToLower: true);
if (!fileHolderKeyValuePairs.ContainsKey(relativePath)) if (!fileHolderKeyValuePairs.ContainsKey(relativePath))
continue; continue;
if (!fileHolderKeyValuePairs.Remove(relativePath)) if (!fileHolderKeyValuePairs.Remove(relativePath))
@ -248,7 +232,13 @@ public class Container
if (sourceDirectoryFileHolder.ExtensionLowered is ".json") if (sourceDirectoryFileHolder.ExtensionLowered is ".json")
continue; continue;
isValidImageFormatExtension = configuration.ValidImageFormatExtensions.Contains(sourceDirectoryFileHolder.ExtensionLowered); isValidImageFormatExtension = configuration.ValidImageFormatExtensions.Contains(sourceDirectoryFileHolder.ExtensionLowered);
items.Add(new(relativePath, sourceDirectoryFileHolder.FullName, sourceDirectoryFileHolder, isValidImageFormatExtension, null, null, null)); if (firstRun)
item = new(sourceDirectoryFileHolder.FullName, relativePath, sourceDirectoryFileHolder, isValidImageFormatExtension, null, null, null);
else if (!isValidImageFormatExtension)
item = new(sourceDirectoryFileHolder.FullName, relativePath, sourceDirectoryFileHolder, isValidImageFormatExtension, null, null, null);
else
item = new(sourceDirectoryFileHolder.FullName, relativePath, sourceDirectoryFileHolder, isValidImageFormatExtension, null, null, null);
items.Add(item);
} }
if (items.Any()) if (items.Any())
{ {
@ -261,9 +251,11 @@ public class Container
{ {
additional = 0; additional = 0;
container = keyValuePairs[sourceDirectory]; container = keyValuePairs[sourceDirectory];
length = items.Count;
existing = (from l in container.Items select l.ImageFileHolder?.FullName).ToArray(); existing = (from l in container.Items select l.ImageFileHolder?.FullName).ToArray();
foreach (Item item in items) for (int i = 0; i < length; i++)
{ {
item = items[i];
if (item.ImageFileHolder is null || existing.Contains(item.ImageFileHolder.FullName)) if (item.ImageFileHolder is null || existing.Contains(item.ImageFileHolder.FullName))
continue; continue;
additional += 1; additional += 1;

View File

@ -1,6 +1,5 @@
using System.Drawing; using System.Drawing;
using System.Drawing.Imaging; using System.Drawing.Imaging;
using System.Globalization;
using System.Reflection; using System.Reflection;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using System.Text; using System.Text;
@ -164,12 +163,16 @@ public class C_Resize
} }
} }
private byte[] SaveResizedSubfile3(string subFile, int[] resize, byte[] bytes, Shared.Models.FileHolder? fileHolder) private byte[] SaveResizedSubfile3(Shared.Models.Item item, int[] resize, bool returnAndDoNotWrite, byte[] bytes)
{ {
if (item.ImageFileHolder is null)
throw new NullReferenceException(nameof(item.ImageFileHolder));
if (item.ResizedFileHolder is null)
throw new NullReferenceException(nameof(item.ResizedFileHolder));
byte[] results; byte[] results;
Bitmap bitmap; Bitmap bitmap;
int outputResolutionWidth = resize[_OutputResolutionWidthIndex]; int outputResolutionWidth = resize[_OutputResolutionWidthIndex];
using Bitmap temp = new(subFile, useIcm: false); using Bitmap temp = new(item.ImageFileHolder.FullName, useIcm: false);
int outputResolutionHeight = resize[_OutputResolutionHeightIndex]; int outputResolutionHeight = resize[_OutputResolutionHeightIndex];
PropertyItem[] propertyItems = temp.PropertyItems; PropertyItem[] propertyItems = temp.PropertyItems;
int outputResolutionOrientation = resize[_OutputResolutionOrientationIndex]; int outputResolutionOrientation = resize[_OutputResolutionOrientationIndex];
@ -204,23 +207,27 @@ public class C_Resize
default: default:
break; break;
} }
if (fileHolder is null) if (returnAndDoNotWrite)
results = GetBitmapData(bitmap); results = GetBitmapData(bitmap);
else else
{ {
results = Array.Empty<byte>(); results = Array.Empty<byte>();
CopyPropertyItems(bytes, propertyItems, bitmap); CopyPropertyItems(bytes, propertyItems, bitmap);
bitmap.Save(fileHolder.FullName, _ImageCodecInfo, _EncoderParameters); bitmap.Save(item.ResizedFileHolder.FullName, _ImageCodecInfo, _EncoderParameters);
} }
bitmap.Dispose(); bitmap.Dispose();
return results; return results;
} }
private byte[] SaveResizedSubfile5(string subFile, int[] resize, byte[] bytes, Shared.Models.FileHolder? fileHolder) private byte[] SaveResizedSubfile5(Shared.Models.Item item, int[] resize, bool returnAndDoNotWrite, byte[] bytes)
{ {
if (item.ImageFileHolder is null)
throw new NullReferenceException(nameof(item.ImageFileHolder));
if (item.ResizedFileHolder is null)
throw new NullReferenceException(nameof(item.ResizedFileHolder));
byte[] results; byte[] results;
Bitmap bitmap; Bitmap bitmap;
using Bitmap temp = new(subFile, useIcm: false); using Bitmap temp = new(item.ImageFileHolder.FullName, useIcm: false);
PropertyItem[] propertyItems = temp.PropertyItems; PropertyItem[] propertyItems = temp.PropertyItems;
int tempResolutionWidth = resize[_TempResolutionWidth]; int tempResolutionWidth = resize[_TempResolutionWidth];
int tempResolutionHeight = resize[_TempResolutionHeight]; int tempResolutionHeight = resize[_TempResolutionHeight];
@ -268,13 +275,13 @@ public class C_Resize
{ {
using (Graphics graphics = Graphics.FromImage(preRotated)) using (Graphics graphics = Graphics.FromImage(preRotated))
graphics.DrawImage(bitmap, new Rectangle(0, 0, outputResolutionWidth, outputResolutionHeight), rectangle, GraphicsUnit.Pixel); graphics.DrawImage(bitmap, new Rectangle(0, 0, outputResolutionWidth, outputResolutionHeight), rectangle, GraphicsUnit.Pixel);
if (fileHolder is null) if (returnAndDoNotWrite)
results = GetBitmapData(bitmap); results = GetBitmapData(bitmap);
else else
{ {
results = Array.Empty<byte>(); results = Array.Empty<byte>();
CopyPropertyItems(bytes, propertyItems, bitmap); CopyPropertyItems(bytes, propertyItems, bitmap);
bitmap.Save(fileHolder.FullName, _ImageCodecInfo, _EncoderParameters); bitmap.Save(item.ResizedFileHolder.FullName, _ImageCodecInfo, _EncoderParameters);
} }
} }
bitmap.Dispose(); bitmap.Dispose();
@ -283,54 +290,37 @@ public class C_Resize
#pragma warning restore CA1416 #pragma warning restore CA1416
private byte[] SaveResizedSubfile(string subFile, Shared.Models.Property property, int[] resize, Shared.Models.FileHolder? fileHolder) private byte[] SaveResizedSubfile(Shared.Models.Item item, int[] resize, bool returnAndDoNotWrite)
{ {
if (item.Property is null)
throw new NullReferenceException(nameof(item.Property));
byte[] results; byte[] results;
// string subFile, Shared.Models.Property property, Shared.Models.FileHolder? fileHolder
string dateTimeFormat = Shared.Models.Stateless.Methods.IProperty.DateTimeFormat(); string dateTimeFormat = Shared.Models.Stateless.Methods.IProperty.DateTimeFormat();
DateTime dateTime = Shared.Models.Stateless.Methods.IProperty.GetMinimumDateTime(property); DateTime dateTime = Shared.Models.Stateless.Methods.IProperty.GetMinimumDateTime(item.Property);
string dateTimeValue = dateTime.ToString(dateTimeFormat); string dateTimeValue = dateTime.ToString(dateTimeFormat);
byte[] bytes = _ASCIIEncoding.GetBytes(dateTimeValue); byte[] bytes = _ASCIIEncoding.GetBytes(dateTimeValue);
if (_ASCIIEncoding.GetString(bytes, 0, bytes.Length) != dateTimeValue) if (_ASCIIEncoding.GetString(bytes, 0, bytes.Length) != dateTimeValue)
throw new Exception(); throw new Exception();
if (resize.Length == 3) if (resize.Length == 3)
results = SaveResizedSubfile3(subFile, resize, bytes, fileHolder); results = SaveResizedSubfile3(item, resize, returnAndDoNotWrite, bytes);
else if (resize.Length == 5) else if (resize.Length == 5)
results = SaveResizedSubfile5(subFile, resize, bytes, fileHolder); results = SaveResizedSubfile5(item, resize, returnAndDoNotWrite, bytes);
else else
throw new Exception(); throw new Exception();
if (fileHolder is not null && false)
{
#pragma warning disable CA1416
using Image image = Image.FromFile(fileHolder.FullName);
if (image.PropertyIdList.Contains((int)IExif.Tags.DateTimeDigitized))
{
string value;
DateTime checkDateTime;
PropertyItem? propertyItem = image.GetPropertyItem((int)IExif.Tags.DateTimeDigitized);
if (propertyItem?.Value is not null)
{
value = _ASCIIEncoding.GetString(propertyItem.Value, 0, propertyItem.Len - 1);
if (value.Length == dateTimeFormat.Length && DateTime.TryParseExact(value, dateTimeFormat, CultureInfo.InvariantCulture, DateTimeStyles.None, out checkDateTime))
_ = checkDateTime;
}
}
#pragma warning restore CA1416
}
return results; return results;
} }
public byte[] GetResizedBytes(string outputResolution, string cResultsFullGroupDirectory, List<Tuple<string, DateTime>> subFileTuples, Shared.Models.Item item, Shared.Models.Property property, Dictionary<string, int[]> imageResizes) public byte[] GetResizedBytes(string outputResolution, string cResultsFullGroupDirectory, List<Tuple<string, DateTime>> subFileTuples, Shared.Models.Item item, Dictionary<string, int[]> imageResizes)
{ {
byte[] results; byte[] results;
if (item.ImageFileHolder is null)
throw new NullReferenceException(nameof(item.ImageFileHolder));
if (!imageResizes.ContainsKey(outputResolution)) if (!imageResizes.ContainsKey(outputResolution))
throw new Exception(); throw new Exception();
int[] resize = imageResizes[outputResolution]; int[] resize = imageResizes[outputResolution];
int outputResolutionWidth = resize[_OutputResolutionWidthIndex]; int outputResolutionWidth = resize[_OutputResolutionWidthIndex];
int outputResolutionHeight = resize[_OutputResolutionHeightIndex]; int outputResolutionHeight = resize[_OutputResolutionHeightIndex];
int outputResolutionOrientation = resize[_OutputResolutionOrientationIndex]; int outputResolutionOrientation = resize[_OutputResolutionOrientationIndex];
results = SaveResizedSubfile(item.ImageFileHolder.FullName, property, resize, fileHolder: null); results = SaveResizedSubfile(item, resize, returnAndDoNotWrite: true);
subFileTuples.Add(new Tuple<string, DateTime>(nameof(C_Resize), DateTime.Now)); subFileTuples.Add(new Tuple<string, DateTime>(nameof(C_Resize), DateTime.Now));
return results; return results;
} }
@ -343,19 +333,19 @@ public class C_Resize
throw new NullReferenceException(nameof(item.ImageFileHolder)); throw new NullReferenceException(nameof(item.ImageFileHolder));
if (item.ResizedFileHolder is null) if (item.ResizedFileHolder is null)
throw new NullReferenceException(nameof(item.ResizedFileHolder)); throw new NullReferenceException(nameof(item.ResizedFileHolder));
Shared.Models.FileHolder fileHolder = item.ResizedFileHolder;
if (!imageResizes.ContainsKey(outputResolution)) if (!imageResizes.ContainsKey(outputResolution))
throw new Exception(); throw new Exception();
if (!fileHolder.Exists) FileInfo fileInfo = new(item.ResizedFileHolder.FullName);
if (!fileInfo.Exists)
{ {
FileInfo fileInfo = new(fileHolder.FullName);
if (fileInfo.Directory?.Parent is null) if (fileInfo.Directory?.Parent is null)
throw new Exception(); throw new Exception();
string parentCheck = Path.Combine(fileInfo.Directory.Parent.FullName, fileInfo.Name); string parentCheck = Path.Combine(fileInfo.Directory.Parent.FullName, fileInfo.Name);
if (File.Exists(parentCheck)) if (File.Exists(parentCheck))
{ {
File.Move(parentCheck, fileInfo.FullName); File.Move(parentCheck, fileInfo.FullName);
item.SetResizedFileHolder(_FilenameExtension, Shared.Models.Stateless.Methods.IFileHolder.Refresh(fileHolder)); item.SetResizedFileHolder(_FilenameExtension, Shared.Models.Stateless.Methods.IFileHolder.Refresh(item.ResizedFileHolder));
fileInfo.Refresh();
} }
} }
int[] resize = imageResizes[outputResolution]; int[] resize = imageResizes[outputResolution];
@ -365,9 +355,10 @@ public class C_Resize
int[] originalCollection = imageResizes[original]; int[] originalCollection = imageResizes[original];
if (outputResolutionWidth == originalCollection[_OutputResolutionWidthIndex] && outputResolutionHeight == originalCollection[_OutputResolutionHeightIndex] && outputResolutionOrientation == originalCollection[_OutputResolutionOrientationIndex]) if (outputResolutionWidth == originalCollection[_OutputResolutionWidthIndex] && outputResolutionHeight == originalCollection[_OutputResolutionHeightIndex] && outputResolutionOrientation == originalCollection[_OutputResolutionOrientationIndex])
{ {
if (!fileHolder.Exists) if (!fileInfo.Exists)
{ {
File.Copy(item.ImageFileHolder.FullName, fileHolder.FullName); File.Copy(item.ImageFileHolder.FullName, fileInfo.FullName);
item.SetResizedFileHolder(_FilenameExtension, Shared.Models.Stateless.Methods.IFileHolder.Refresh(item.ResizedFileHolder));
subFileTuples.Add(new Tuple<string, DateTime>(nameof(C_Resize), DateTime.Now)); subFileTuples.Add(new Tuple<string, DateTime>(nameof(C_Resize), DateTime.Now));
} }
} }
@ -378,13 +369,14 @@ public class C_Resize
List<DateTime> dateTimes = (from l in subFileTuples where changesFrom.Contains(l.Item1) select l.Item2).ToList(); List<DateTime> dateTimes = (from l in subFileTuples where changesFrom.Contains(l.Item1) select l.Item2).ToList();
if (_OverrideForResizeImages) if (_OverrideForResizeImages)
check = true; check = true;
else if (!fileHolder.Exists) else if (!fileInfo.Exists)
check = true; check = true;
else if (dateTimes.Any() && dateTimes.Max() > fileHolder.LastWriteTime) else if (dateTimes.Any() && dateTimes.Max() > fileInfo.LastWriteTime)
check = true; check = true;
if (check) if (check)
{ {
_ = SaveResizedSubfile(item.ImageFileHolder.FullName, item.Property, resize, fileHolder); _ = SaveResizedSubfile(item, resize, returnAndDoNotWrite: false);
item.SetResizedFileHolder(_FilenameExtension, Shared.Models.Stateless.Methods.IFileHolder.Refresh(item.ResizedFileHolder));
subFileTuples.Add(new Tuple<string, DateTime>(nameof(C_Resize), DateTime.Now)); subFileTuples.Add(new Tuple<string, DateTime>(nameof(C_Resize), DateTime.Now));
} }
} }
@ -551,6 +543,8 @@ public class C_Resize
} }
} }
} }
Shared.Models.FileHolder fileHolder = new(Path.Combine(AngleBracketCollection[0].Replace("<>", "()"), Path.GetFileName(item.ImageFileHolder.FullName)));
item.SetResizedFileHolder(_FilenameExtension, fileHolder);
return results; return results;
} }

View File

@ -5,26 +5,26 @@ namespace View_by_Distance.Shared.Models;
public class FileHolder : Properties.IFileHolder public class FileHolder : Properties.IFileHolder
{ {
protected readonly DateTime _CreationTime; protected readonly DateTime? _CreationTime;
protected readonly string? _DirectoryName; protected readonly string? _DirectoryName;
protected readonly bool _Exists; protected readonly bool _Exists;
protected readonly string _ExtensionLowered; protected readonly string _ExtensionLowered;
protected readonly string _FullName; protected readonly string _FullName;
protected readonly DateTime _LastWriteTime; protected readonly DateTime? _LastWriteTime;
protected readonly long? _Length; protected readonly long? _Length;
protected readonly string _Name; protected readonly string _Name;
protected readonly string _NameWithoutExtension; protected readonly string _NameWithoutExtension;
public DateTime CreationTime => _CreationTime; public DateTime? CreationTime => _CreationTime;
public string? DirectoryName => _DirectoryName; public string? DirectoryName => _DirectoryName;
public bool Exists => _Exists; public bool Exists => _Exists;
public string ExtensionLowered => _ExtensionLowered; public string ExtensionLowered => _ExtensionLowered;
public string FullName => _FullName; public string FullName => _FullName;
public DateTime LastWriteTime => _LastWriteTime; public DateTime? LastWriteTime => _LastWriteTime;
public long? Length => _Length; public long? Length => _Length;
public string Name => _Name; public string Name => _Name;
public string NameWithoutExtension => _NameWithoutExtension; public string NameWithoutExtension => _NameWithoutExtension;
public FileHolder(DateTime creationTime, string? directoryName, bool exists, string extensionLowered, string fullName, DateTime lastWriteTime, long? length, string name, string nameWithoutExtension) public FileHolder(DateTime? creationTime, string? directoryName, bool exists, string extensionLowered, string fullName, DateTime? lastWriteTime, long? length, string name, string nameWithoutExtension)
{ {
_CreationTime = creationTime; _CreationTime = creationTime;
_DirectoryName = directoryName; _DirectoryName = directoryName;
@ -37,36 +37,26 @@ public class FileHolder : Properties.IFileHolder
_NameWithoutExtension = nameWithoutExtension; _NameWithoutExtension = nameWithoutExtension;
} }
public FileHolder(string fileName) public FileHolder(FileInfo fileInfo)
{
if (fileInfo.Exists)
{ {
FileInfo fileInfo = new(fileName);
_CreationTime = fileInfo.CreationTime; _CreationTime = fileInfo.CreationTime;
_CreationTime = fileInfo.CreationTime; _CreationTime = fileInfo.CreationTime;
_LastWriteTime = fileInfo.LastWriteTime;
_Length = fileInfo.Length;
}
_DirectoryName = fileInfo.DirectoryName; _DirectoryName = fileInfo.DirectoryName;
_Exists = fileInfo.Exists; _Exists = fileInfo.Exists;
_ExtensionLowered = fileInfo.Extension.ToLower(); _ExtensionLowered = fileInfo.Extension.ToLower();
_FullName = fileInfo.FullName; _FullName = fileInfo.FullName;
_LastWriteTime = fileInfo.LastWriteTime;
if (fileInfo.Exists)
_Length = fileInfo.Length;
_Name = fileInfo.Name; _Name = fileInfo.Name;
_NameWithoutExtension = Path.GetFileNameWithoutExtension(fileInfo.FullName); _NameWithoutExtension = Path.GetFileNameWithoutExtension(fileInfo.FullName);
} }
public FileHolder(FileInfo fileInfo) public FileHolder(string fileName) :
{ this(new FileInfo(fileName))
_CreationTime = fileInfo.CreationTime; { }
_CreationTime = fileInfo.CreationTime;
_DirectoryName = fileInfo.DirectoryName;
_Exists = fileInfo.Exists;
_ExtensionLowered = fileInfo.Extension.ToLower();
_FullName = fileInfo.FullName;
_LastWriteTime = fileInfo.LastWriteTime;
if (fileInfo.Exists)
_Length = fileInfo.Length;
_Name = fileInfo.Name;
_NameWithoutExtension = Path.GetFileNameWithoutExtension(fileInfo.FullName);
}
public override string ToString() public override string ToString()
{ {

View File

@ -39,6 +39,24 @@ public class Location : Properties.ILocation, IEquatable<Location>
this(bottom, confidence, left, GetNormalizedPixelPercentage(bottom, height, left, right, top, width, zCount), right, top) => this(bottom, confidence, left, GetNormalizedPixelPercentage(bottom, height, left, right, top, width, zCount), right, top) =>
Check(_Bottom, height, _Left, _NormalizedPixelPercentage, _Right, _Top, width, zCount); Check(_Bottom, height, _Left, _NormalizedPixelPercentage, _Right, _Top, width, zCount);
public Location(double confidence, int factor, int height, Location location, int width, int zCount)
{
int x = (location.Right - location.Left) / factor;
int y = (location.Bottom - location.Top) / factor;
int bottom = Math.Min(location.Bottom + y, height);
int left = Math.Max(location.Left - x, 0);
int right = Math.Min(location.Right + x, width);
int top = Math.Max(location.Top - y, 0);
int normalizedPixelPercentage = GetNormalizedPixelPercentage(location.Bottom, height, location.Left, location.Right, location.Top, width, zCount);
Check(bottom, left, _NormalizedPixelPercentage, right, top, zCount);
_Confidence = confidence;
_Bottom = bottom;
_Left = left;
_NormalizedPixelPercentage = normalizedPixelPercentage;
_Right = right;
_Top = top;
}
public override bool Equals(object? obj) => Equals(obj as Location); public override bool Equals(object? obj) => Equals(obj as Location);
public override string ToString() public override string ToString()

View File

@ -46,4 +46,6 @@ public class Mapping : Properties.IMapping
public void SetFiltered() => _Filtered = true; public void SetFiltered() => _Filtered = true;
public void SetFiltered(bool value) => _Filtered = value;
} }

View File

@ -3,12 +3,12 @@ namespace View_by_Distance.Shared.Models.Properties;
public interface IFileHolder public interface IFileHolder
{ {
public DateTime CreationTime { get; } public DateTime? CreationTime { get; }
public string? DirectoryName { get; } public string? DirectoryName { get; }
public bool Exists { get; } public bool Exists { get; }
public string ExtensionLowered { get; } public string ExtensionLowered { get; }
public string FullName { get; } public string FullName { get; }
public DateTime LastWriteTime { get; } public DateTime? LastWriteTime { get; }
public long? Length { get; } public long? Length { get; }
public string Name { get; } public string Name { get; }
public string NameWithoutExtension { get; } public string NameWithoutExtension { get; }

View File

@ -0,0 +1,53 @@
using System.Text.Json;
using System.Text.Json.Serialization;
namespace View_by_Distance.Shared.Models;
public class SaveContainer
{
protected readonly string _CheckFile;
protected readonly string _Directory;
protected readonly FileHolder? _FaceFileHolder;
protected readonly FileHolder? _HiddenFaceFileHolder;
protected readonly string _Json;
protected readonly FileHolder? _FacePartsFileHolder;
protected readonly FileHolder? _ResizedFileHolder;
protected readonly string _ShortcutFile;
public string CheckFile => _CheckFile;
public string Directory => _Directory;
public FileHolder? FaceFileHolder => _FaceFileHolder;
public FileHolder? HiddenFaceFileHolder => _HiddenFaceFileHolder;
public string Json => _Json;
public FileHolder? FacePartsFileHolder => _FacePartsFileHolder;
public FileHolder? ResizedFileHolder => _ResizedFileHolder;
public string ShortcutFile => _ShortcutFile;
[JsonConstructor]
public SaveContainer(string checkFile, string directory, FileHolder? faceFileHolder, FileHolder? hiddenFaceFileHolder, string json, FileHolder? facePartsFileHolder, FileHolder? resizedFileHolder, string shortcutFile)
{
_CheckFile = checkFile;
_Directory = directory;
_FaceFileHolder = faceFileHolder;
_HiddenFaceFileHolder = hiddenFaceFileHolder;
_Json = json;
_FacePartsFileHolder = facePartsFileHolder;
_ResizedFileHolder = resizedFileHolder;
_ShortcutFile = shortcutFile;
}
public SaveContainer(string directory) :
this(string.Empty, directory, null, null, string.Empty, null, null, string.Empty)
{ }
public SaveContainer(string checkFile, string directory, string json) :
this(checkFile, directory, null, null, json, null, null, string.Empty)
{ }
public override string ToString()
{
string result = JsonSerializer.Serialize(this, new JsonSerializerOptions() { WriteIndented = true });
return result;
}
}

View File

@ -5,6 +5,7 @@ public interface IFaceDistance
// 637972153144596958 // 637972153144596958
// const int MaximumPer = 999; // const int MaximumPer = 999;
const int HiddenImageFactor = 2;
const int MaximumPer = 9999; const int MaximumPer = 9999;
const double Tolerance = 0.6d; const double Tolerance = 0.6d;

View File

@ -3,6 +3,7 @@
public interface IPersonBirthday public interface IPersonBirthday
{ {
const int FirstYear = 1500;
const string Format = "yyyy-MM-dd_HH"; const string Format = "yyyy-MM-dd_HH";
} }

View File

@ -7,6 +7,10 @@ public interface ILocation
static Models.Location? GetLocation(Models.Location? location, int height, int width, int zCount) => static Models.Location? GetLocation(Models.Location? location, int height, int width, int zCount) =>
location is null ? null : new(location.Confidence, height, location, width, zCount); location is null ? null : new(location.Confidence, height, location, width, zCount);
Models.Location? TestStatic_GetLocation(int factor, Models.Location? location, int height, int width, int zCount);
static Models.Location? GetLocation(int factor, Models.Location? location, int height, int width, int zCount) =>
location is null ? null : new(location.Confidence, factor, height, location, width, zCount);
int?[] TestStatic_GetInts(List<Models.Location> locations); int?[] TestStatic_GetInts(List<Models.Location> locations);
static int?[] GetInts(List<Models.Location> locations) => (from l in locations where l.NormalizedPixelPercentage is not null select l.NormalizedPixelPercentage).ToArray(); static int?[] GetInts(List<Models.Location> locations) => (from l in locations where l.NormalizedPixelPercentage is not null select l.NormalizedPixelPercentage).ToArray();

View File

@ -5,7 +5,7 @@ public interface IPath
string TestStatic_GetRelativePath(string path, int length); string TestStatic_GetRelativePath(string path, int length);
static string GetRelativePath(string path, int length) static string GetRelativePath(string path, int length)
=> XPath.GetRelativePath(path, length); => XPath.GetRelativePath(path, length, forceExtensionToLower: false);
bool TestStatic_DeleteEmptyDirectories(string rootDirectory); bool TestStatic_DeleteEmptyDirectories(string rootDirectory);
static bool DeleteEmptyDirectories(string rootDirectory) static bool DeleteEmptyDirectories(string rootDirectory)
@ -15,6 +15,10 @@ public interface IPath
static List<string> GetDirectoryNames(string directory) static List<string> GetDirectoryNames(string directory)
=> XPath.GetDirectoryNames(directory); => XPath.GetDirectoryNames(directory);
string TestStatic_GetRelativePath(string path, int length, bool forceExtensionToLower);
static string GetRelativePath(string path, int length, bool forceExtensionToLower)
=> XPath.GetRelativePath(path, length, forceExtensionToLower);
bool TestStatic_WriteAllText(string path, string contents, bool updateDateWhenMatches, bool compareBeforeWrite); bool TestStatic_WriteAllText(string path, string contents, bool updateDateWhenMatches, bool compareBeforeWrite);
static bool WriteAllText(string path, string contents, bool updateDateWhenMatches, bool compareBeforeWrite, DateTime? updateToWhenMatches = null) static bool WriteAllText(string path, string contents, bool updateDateWhenMatches, bool compareBeforeWrite, DateTime? updateToWhenMatches = null)
=> XPath.WriteAllText(path, contents, updateDateWhenMatches, compareBeforeWrite, updateToWhenMatches); => XPath.WriteAllText(path, contents, updateDateWhenMatches, compareBeforeWrite, updateToWhenMatches);

View File

@ -66,7 +66,7 @@ internal abstract class Person
Dictionary<DateTime, string[]> results = new(); Dictionary<DateTime, string[]> results = new();
string[] segments; string[] segments;
DateTime personKey; DateTime personKey;
DateTime incrementDate = new(1500, 1, 1); DateTime incrementDate = new(Stateless.IPersonBirthday.FirstYear, 1, 1);
string[] lines = File.ReadAllLines(knownPeopleFile); string[] lines = File.ReadAllLines(knownPeopleFile);
_ = incrementDate.AddDays(lines.Length); _ = incrementDate.AddDays(lines.Length);
System.Globalization.CultureInfo cultureInfo = System.Globalization.CultureInfo.InvariantCulture; System.Globalization.CultureInfo cultureInfo = System.Globalization.CultureInfo.InvariantCulture;
@ -83,6 +83,8 @@ internal abstract class Person
continue; continue;
results.Add(personKey, segments); results.Add(personKey, segments);
} }
if (results.Any())
{
int countBefore = results.Count; int countBefore = results.Count;
DateTime minimumDateTime = results.Keys.Min(); DateTime minimumDateTime = results.Keys.Min();
for (int i = 1; i < (1000 - countBefore); i++) for (int i = 1; i < (1000 - countBefore); i++)
@ -90,6 +92,7 @@ internal abstract class Person
personKey = minimumDateTime.AddDays(i * -1); personKey = minimumDateTime.AddDays(i * -1);
results.Add(personKey, new string[] { personKey.ToString(Stateless.IPerson.KeyFormat) }); results.Add(personKey, new string[] { personKey.ToString(Stateless.IPerson.KeyFormat) });
} }
}
return results.OrderBy(l => l.Key).ToDictionary(l => l.Key, l => l.Value); return results.OrderBy(l => l.Key).ToDictionary(l => l.Key, l => l.Value);
} }
@ -202,23 +205,21 @@ internal abstract class Person
Models.Person? person; Models.Person? person;
string localKnownPeopleFile; string localKnownPeopleFile;
DateTime dateTime = DateTime.MinValue; DateTime dateTime = DateTime.MinValue;
string directory = Path.Combine(storage.PeopleRootDirectory, "{}"); string peopleContentDirectory = Path.Combine(storage.PeopleRootDirectory, "()");
if (!Directory.Exists(directory)) string peopleSingletonDirectory = Path.Combine(storage.PeopleRootDirectory, "{}");
_ = Directory.CreateDirectory(directory); if (!Directory.Exists(peopleSingletonDirectory))
string? rootDirectoryParent = Path.GetDirectoryName(storage.RootDirectory); _ = Directory.CreateDirectory(peopleSingletonDirectory);
if (string.IsNullOrEmpty(rootDirectoryParent)) if (!Directory.Exists(peopleContentDirectory))
throw new NullReferenceException(nameof(rootDirectoryParent));
if (!Directory.Exists(rootDirectoryParent))
localKnownPeopleFile = string.Empty; localKnownPeopleFile = string.Empty;
else else
{ {
files = Directory.GetFiles(rootDirectoryParent, "*People*.txt", SearchOption.TopDirectoryOnly); files = Directory.GetFiles(peopleContentDirectory, "*People*.txt", SearchOption.TopDirectoryOnly);
if (files.Any()) if (files.Any())
localKnownPeopleFile = files[0]; localKnownPeopleFile = files[0];
else else
localKnownPeopleFile = string.Empty; localKnownPeopleFile = string.Empty;
} }
files = Directory.GetFiles(directory, "*.json", SearchOption.TopDirectoryOnly); files = Directory.GetFiles(peopleSingletonDirectory, "*.json", SearchOption.TopDirectoryOnly);
if (!files.Any() && string.IsNullOrEmpty(localKnownPeopleFile)) if (!files.Any() && string.IsNullOrEmpty(localKnownPeopleFile))
throw new Exception("Copy \"KnownPeople.txt\" file from server!"); throw new Exception("Copy \"KnownPeople.txt\" file from server!");
foreach (string file in files) foreach (string file in files)

View File

@ -3,9 +3,25 @@ namespace View_by_Distance.Shared.Models.Stateless.Methods;
internal abstract class XPath internal abstract class XPath
{ {
internal static string GetRelativePath(string path, int length) internal static string GetRelativePath(string path, int length, bool forceExtensionToLower)
{ {
string result = path[length..].Replace(@"\", "/"); string result;
if (forceExtensionToLower)
{
string extension = Path.GetExtension(path);
string extensionLowered = Path.GetExtension(path).ToLower();
if (extension != extensionLowered)
{
string? directoryName = Path.GetDirectoryName(path);
if (string.IsNullOrEmpty(directoryName))
throw new NullReferenceException(directoryName);
string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(path);
if (string.IsNullOrEmpty(fileNameWithoutExtension))
throw new NullReferenceException(fileNameWithoutExtension);
path = Path.Combine(directoryName, $"{fileNameWithoutExtension}{extensionLowered}");
}
}
result = path[length..].Replace(@"\", "/");
return result; return result;
} }

View File

@ -172,8 +172,10 @@ public class UnitTestResize
{ {
// string sourceFileName = "IMG_0067.jpg"; // string sourceFileName = "IMG_0067.jpg";
// string sourceDirectoryName = "Mackenzie Prom 2017"; // string sourceDirectoryName = "Mackenzie Prom 2017";
string sourceFileName = "Fall 2005 (113).jpg"; // string sourceFileName = "Fall 2005 (113).jpg";
string sourceDirectoryName = "=2005.3 Fall"; // string sourceDirectoryName = "=2005.3 Fall";
string sourceFileName = "12314542_10208270578946392_3555034423896018896_o.jpg";
string sourceDirectoryName = "Other";
Item item; Item item;
Model? model = null; Model? model = null;
bool reverse = false; bool reverse = false;
@ -242,10 +244,8 @@ public class UnitTestResize
} }
(int _, metadataCollection) = metadata.GetMetadataCollection(bResultsFullGroupDirectory, subFileTuples, parseExceptions, item); (int _, metadataCollection) = metadata.GetMetadataCollection(bResultsFullGroupDirectory, subFileTuples, parseExceptions, item);
imageResizeKeyValuePairs = resize.GetResizeKeyValuePairs(cResultsFullGroupDirectory, subFileTuples, parseExceptions, original, metadataCollection, item); imageResizeKeyValuePairs = resize.GetResizeKeyValuePairs(cResultsFullGroupDirectory, subFileTuples, parseExceptions, original, metadataCollection, item);
FileHolder resizedFileHolder = new(Path.Combine(resize.AngleBracketCollection[0].Replace("<>", "()"), Path.GetFileName(item.ImageFileHolder.FullName))); Assert.IsNotNull(item.ResizedFileHolder);
item.SetResizedFileHolder(resize.FilenameExtension, resizedFileHolder);
resize.SaveResizedSubfile(outputResolution, cResultsFullGroupDirectory, subFileTuples, item, original, imageResizeKeyValuePairs); resize.SaveResizedSubfile(outputResolution, cResultsFullGroupDirectory, subFileTuples, item, original, imageResizeKeyValuePairs);
item.SetResizedFileHolder(resize.FilenameExtension, IFileHolder.Refresh(resizedFileHolder));
} }
} }

View File

@ -206,11 +206,8 @@ public class UnitTestFace
} }
(int _, metadataCollection) = metadata.GetMetadataCollection(bResultsFullGroupDirectory, subFileTuples, parseExceptions, item); (int _, metadataCollection) = metadata.GetMetadataCollection(bResultsFullGroupDirectory, subFileTuples, parseExceptions, item);
imageResizeKeyValuePairs = resize.GetResizeKeyValuePairs(cResultsFullGroupDirectory, subFileTuples, parseExceptions, original, metadataCollection, item); imageResizeKeyValuePairs = resize.GetResizeKeyValuePairs(cResultsFullGroupDirectory, subFileTuples, parseExceptions, original, metadataCollection, item);
FileHolder resizedFileHolder = new(Path.Combine(resize.AngleBracketCollection[0].Replace("<>", "()"), Path.GetFileName(item.ImageFileHolder.FullName)));
item.SetResizedFileHolder(resize.FilenameExtension, resizedFileHolder);
resize.SaveResizedSubfile(outputResolution, cResultsFullGroupDirectory, subFileTuples, item, original, imageResizeKeyValuePairs);
item.SetResizedFileHolder(resize.FilenameExtension, IFileHolder.Refresh(resizedFileHolder));
Assert.IsNotNull(item.ResizedFileHolder); Assert.IsNotNull(item.ResizedFileHolder);
resize.SaveResizedSubfile(outputResolution, cResultsFullGroupDirectory, subFileTuples, item, original, imageResizeKeyValuePairs);
Image image = FaceRecognition.LoadImageFile(item.ResizedFileHolder.FullName); Image image = FaceRecognition.LoadImageFile(item.ResizedFileHolder.FullName);
Assert.IsNotNull(image); Assert.IsNotNull(image);
FaceRecognition faceRecognition = new(_Configuration.NumberOfTimesToUpsample, _Configuration.NumberOfJitters, predictorModel, model, modelParameter); FaceRecognition faceRecognition = new(_Configuration.NumberOfTimesToUpsample, _Configuration.NumberOfJitters, predictorModel, model, modelParameter);