2023-02-11
This commit is contained in:
parent
0b8df86e6b
commit
3d5c5952b3
3
.vscode/settings.json
vendored
3
.vscode/settings.json
vendored
@ -40,5 +40,6 @@
|
||||
"files.exclude": {
|
||||
"**/.git": false
|
||||
},
|
||||
"coverage-gutters.coverageBaseDir": "./.vscode/ReportGenerator/Cobertura/*"
|
||||
"coverage-gutters.coverageBaseDir": "./.vscode/ReportGenerator/Cobertura/*",
|
||||
"extensions.ignoreRecommendations": true
|
||||
}
|
@ -1,9 +1,7 @@
|
||||
using ShellProgressBar;
|
||||
using System.Text.Json;
|
||||
using View_by_Distance.FaceRecognitionDotNet;
|
||||
using View_by_Distance.Map.Models;
|
||||
using View_by_Distance.Shared.Models;
|
||||
using View_by_Distance.Shared.Models.Properties;
|
||||
|
||||
namespace View_by_Distance.Distance.Models;
|
||||
|
||||
@ -15,19 +13,38 @@ public class MapLogicSupport : Shared.Models.Methods.IMapLogicSupport
|
||||
private int _Distance;
|
||||
private int _Confidence;
|
||||
|
||||
private readonly int _FaceConfidencePercent;
|
||||
private readonly int _FaceDistancePermyriad;
|
||||
private readonly int[] _RangeDaysDeltaTolerance;
|
||||
private readonly int[] _RangeFaceAreaPermilleTolerance;
|
||||
private readonly double _FaceAreaPermille;
|
||||
private readonly double _RangeDaysDeltaTolerance;
|
||||
private readonly double _FaceConfidencePercent;
|
||||
private readonly double _FaceDistancePermyriad;
|
||||
private readonly int _SortingMaximumPerFaceShouldBeHigh;
|
||||
private readonly bool _RangeDaysDeltaTargetLessThenUpper;
|
||||
|
||||
public MapLogicSupport(int faceConfidencePercent, int faceDistancePermyriad, int[] rangeDaysDeltaTolerance, int[] rangeFaceAreaPermilleTolerance, int sortingMaximumPerFaceShouldBeHigh)
|
||||
public MapLogicSupport(int faceConfidencePercent,
|
||||
int faceDistancePermyriad,
|
||||
int[] rangeDaysDeltaTolerance,
|
||||
double[] rangeDistanceTolerance,
|
||||
int[] rangeFaceAreaPermilleTolerance,
|
||||
double[] rangeFaceConfidence,
|
||||
int sortingMaximumPerFaceShouldBeHigh,
|
||||
int? useFiltersCounter = null)
|
||||
{
|
||||
_FaceConfidencePercent = faceConfidencePercent;
|
||||
_FaceDistancePermyriad = faceDistancePermyriad;
|
||||
_RangeDaysDeltaTolerance = rangeDaysDeltaTolerance;
|
||||
_RangeFaceAreaPermilleTolerance = rangeFaceAreaPermilleTolerance;
|
||||
_SortingMaximumPerFaceShouldBeHigh = sortingMaximumPerFaceShouldBeHigh;
|
||||
_RangeDaysDeltaTargetLessThenUpper = rangeDaysDeltaTolerance[1] > rangeDaysDeltaTolerance[2];
|
||||
if (useFiltersCounter is null)
|
||||
{
|
||||
_FaceAreaPermille = rangeFaceAreaPermilleTolerance[1];
|
||||
_RangeDaysDeltaTolerance = rangeDaysDeltaTolerance[1];
|
||||
_FaceConfidencePercent = faceConfidencePercent * rangeFaceConfidence[1];
|
||||
_FaceDistancePermyriad = faceDistancePermyriad * rangeDistanceTolerance[1];
|
||||
}
|
||||
else
|
||||
{
|
||||
_RangeDaysDeltaTolerance = ((rangeDaysDeltaTolerance[2] - rangeDaysDeltaTolerance[0]) * 0.01 * useFiltersCounter.Value) + rangeDaysDeltaTolerance[1];
|
||||
_FaceConfidencePercent = faceConfidencePercent * ((rangeFaceConfidence[2] - rangeFaceConfidence[0]) * 0.01 * useFiltersCounter.Value) + rangeFaceConfidence[1];
|
||||
_FaceAreaPermille = ((rangeFaceAreaPermilleTolerance[2] - rangeFaceAreaPermilleTolerance[0]) * 0.01 * useFiltersCounter.Value) + rangeFaceAreaPermilleTolerance[1];
|
||||
_FaceDistancePermyriad = faceDistancePermyriad * ((rangeDistanceTolerance[2] - rangeDistanceTolerance[0]) * 0.01 * useFiltersCounter.Value) + rangeDistanceTolerance[1];
|
||||
}
|
||||
}
|
||||
|
||||
public static void SaveFaceDistances(Property.Models.Configuration configuration, SortingContainer[] sortingContainers)
|
||||
@ -42,118 +59,33 @@ public class MapLogicSupport : Shared.Models.Methods.IMapLogicSupport
|
||||
File.WriteAllLines(eDistanceContentFileName, results);
|
||||
}
|
||||
|
||||
private List<SortingContainer> GetSortingContainers(Configuration mapConfiguration, Face face, FaceDistance faceDistanceEncoding, List<Sorting> sortingCollection, int? useFiltersCounter)
|
||||
private List<SortingContainer> GetSortingContainers(Configuration mapConfiguration, Face face, FaceDistance faceDistanceEncoding, List<Sorting> sortingCollection)
|
||||
{
|
||||
List<SortingContainer> results = new();
|
||||
SortingContainer sortingContainer;
|
||||
Sorting[] collection = Shared.Models.Stateless.Methods.ISorting.Sort(sortingCollection);
|
||||
double a;
|
||||
double b;
|
||||
double c;
|
||||
double d;
|
||||
double faceAreaPermille;
|
||||
double faceConfidencePercent;
|
||||
double faceDistancePermyriad;
|
||||
double rangeDaysDeltaTolerance;
|
||||
if (useFiltersCounter is null)
|
||||
{
|
||||
a = 1f;
|
||||
b = 1f;
|
||||
c = 1f;
|
||||
d = 1f;
|
||||
}
|
||||
else if (useFiltersCounter.Value < 5)
|
||||
{
|
||||
a = 1.25f;
|
||||
b = 0.8f;
|
||||
c = a;
|
||||
d = b;
|
||||
}
|
||||
else if (useFiltersCounter.Value < 9)
|
||||
{
|
||||
a = 1.5f;
|
||||
b = 0.667f;
|
||||
c = a;
|
||||
d = b;
|
||||
}
|
||||
else if (useFiltersCounter.Value < 13)
|
||||
{
|
||||
a = 1.75f;
|
||||
b = 0.571f;
|
||||
c = a;
|
||||
d = b;
|
||||
}
|
||||
else
|
||||
{
|
||||
a = 2f;
|
||||
b = 0.5f;
|
||||
c = a;
|
||||
d = b;
|
||||
}
|
||||
if (useFiltersCounter is null)
|
||||
{
|
||||
rangeDaysDeltaTolerance = _RangeDaysDeltaTolerance[1];
|
||||
faceDistancePermyriad = _FaceDistancePermyriad;
|
||||
faceConfidencePercent = _FaceConfidencePercent;
|
||||
faceAreaPermille = _RangeFaceAreaPermilleTolerance[1];
|
||||
}
|
||||
else if (useFiltersCounter.Value is 1 or 5 or 9 or 13)
|
||||
{
|
||||
rangeDaysDeltaTolerance = _RangeDaysDeltaTolerance[1] * a;
|
||||
faceDistancePermyriad = _FaceDistancePermyriad * c;
|
||||
faceConfidencePercent = _FaceConfidencePercent * d;
|
||||
faceAreaPermille = _RangeFaceAreaPermilleTolerance[1] * d;
|
||||
}
|
||||
else if (useFiltersCounter.Value is 2 or 6 or 10 or 14)
|
||||
{
|
||||
rangeDaysDeltaTolerance = _RangeDaysDeltaTolerance[1] * c;
|
||||
faceDistancePermyriad = _FaceDistancePermyriad * a;
|
||||
faceConfidencePercent = _FaceConfidencePercent * d;
|
||||
faceAreaPermille = _RangeFaceAreaPermilleTolerance[1] * d;
|
||||
}
|
||||
else if (useFiltersCounter.Value is 3 or 7 or 11 or 15)
|
||||
{
|
||||
rangeDaysDeltaTolerance = _RangeDaysDeltaTolerance[1] * c;
|
||||
faceDistancePermyriad = _FaceDistancePermyriad * c;
|
||||
faceConfidencePercent = _FaceConfidencePercent * b;
|
||||
faceAreaPermille = _RangeFaceAreaPermilleTolerance[1] * d;
|
||||
}
|
||||
else if (useFiltersCounter.Value is 4 or 8 or 12 or 16)
|
||||
{
|
||||
rangeDaysDeltaTolerance = _RangeDaysDeltaTolerance[1] * c;
|
||||
faceDistancePermyriad = _FaceDistancePermyriad * c;
|
||||
faceConfidencePercent = _FaceConfidencePercent * d;
|
||||
faceAreaPermille = _RangeFaceAreaPermilleTolerance[1] * b;
|
||||
}
|
||||
else
|
||||
{
|
||||
rangeDaysDeltaTolerance = int.MaxValue;
|
||||
faceDistancePermyriad = int.MaxValue;
|
||||
faceAreaPermille = 0;
|
||||
faceConfidencePercent = 0;
|
||||
}
|
||||
foreach (Sorting sorting in collection)
|
||||
{
|
||||
if (face.Mapping is null || faceDistanceEncoding.NormalizedRectangle is null)
|
||||
if (face.Mapping?.MappingFromLocation is null || faceDistanceEncoding.NormalizedRectangle is null)
|
||||
throw new NotSupportedException();
|
||||
if (!mapConfiguration.SaveSortingWithoutPerson && face.Mapping.MappingFromPerson is null)
|
||||
continue;
|
||||
if (sorting.DaysDelta > rangeDaysDeltaTolerance)
|
||||
if (sorting.DaysDelta > _RangeDaysDeltaTolerance)
|
||||
{
|
||||
_Days += 1;
|
||||
continue;
|
||||
}
|
||||
if (sorting.DistancePermyriad > faceDistancePermyriad)
|
||||
if (sorting.DistancePermyriad > _FaceDistancePermyriad)
|
||||
{
|
||||
_Distance += 1;
|
||||
continue;
|
||||
}
|
||||
if (face.Mapping.MappingFromLocation.ConfidencePercent < faceConfidencePercent)
|
||||
if (face.Mapping.MappingFromLocation.ConfidencePercent < _FaceConfidencePercent)
|
||||
{
|
||||
_Confidence += 1;
|
||||
continue;
|
||||
}
|
||||
if (face.Mapping.MappingFromLocation.AreaPermille < faceAreaPermille)
|
||||
if (face.Mapping.MappingFromLocation.AreaPermille < _FaceAreaPermille)
|
||||
{
|
||||
_Area += 1;
|
||||
continue;
|
||||
@ -182,7 +114,7 @@ public class MapLogicSupport : Shared.Models.Methods.IMapLogicSupport
|
||||
List<FaceDistanceContainer> collection = new();
|
||||
foreach (Face face in distinctFilteredFaces)
|
||||
{
|
||||
if (face.Mapping is null)
|
||||
if (face.Mapping?.MappingFromLocation is null)
|
||||
throw new NotSupportedException();
|
||||
if (face.FaceDistance?.Encoding is not FaceRecognitionDotNet.FaceEncoding faceEncoding)
|
||||
continue;
|
||||
@ -212,7 +144,7 @@ public class MapLogicSupport : Shared.Models.Methods.IMapLogicSupport
|
||||
return faceDistanceEncodings;
|
||||
}
|
||||
|
||||
public SortingContainer[] SetFaceMappingSortingCollectionThenGetSortingContainers(int maxDegreeOfParallelism, Configuration mapConfiguration, long ticks, MapLogic mapLogic, List<Face> distinctFilteredFaces, List<FaceDistanceContainer> missingFaceDistanceContainers, int? useFiltersCounter)
|
||||
public SortingContainer[] SetFaceMappingSortingCollectionThenGetSortingContainers(int maxDegreeOfParallelism, Configuration mapConfiguration, long ticks, MapLogic mapLogic, List<Face> distinctFilteredFaces, List<FaceDistanceContainer> missingFaceDistanceContainers)
|
||||
{
|
||||
SortingContainer[] results;
|
||||
List<SortingContainer> collection = new();
|
||||
@ -235,7 +167,7 @@ public class MapLogicSupport : Shared.Models.Methods.IMapLogicSupport
|
||||
List<Sorting> sortingCollection = GetSortingCollection(mapLogic, faceDistanceEncodings, i, faceDistanceEncoding);
|
||||
if (!sortingCollection.Any())
|
||||
return;
|
||||
List<SortingContainer> sortingContainers = GetSortingContainers(mapConfiguration, face, faceDistanceEncoding, sortingCollection, useFiltersCounter);
|
||||
List<SortingContainer> sortingContainers = GetSortingContainers(mapConfiguration, face, faceDistanceEncoding, sortingCollection);
|
||||
if (sortingContainers.Any())
|
||||
{
|
||||
lock (collection)
|
||||
@ -246,7 +178,7 @@ public class MapLogicSupport : Shared.Models.Methods.IMapLogicSupport
|
||||
results = Array.Empty<SortingContainer>();
|
||||
else
|
||||
{
|
||||
if (_RangeDaysDeltaTolerance[1] > _RangeDaysDeltaTolerance[2])
|
||||
if (_RangeDaysDeltaTargetLessThenUpper)
|
||||
results = Shared.Models.Stateless.Methods.ISortingContainer.Sort(collection);
|
||||
else
|
||||
results = Shared.Models.Stateless.Methods.ISortingContainer.SortUsingDaysDelta(collection);
|
||||
@ -272,7 +204,7 @@ public class MapLogicSupport : Shared.Models.Methods.IMapLogicSupport
|
||||
_ = Parallel.For(0, distinctFilteredFaces.Count, parallelOptions, (i, state) =>
|
||||
{
|
||||
Face face = distinctFilteredFaces[i];
|
||||
if (face.FaceEncoding is null || face.Mapping is null)
|
||||
if (face.FaceEncoding is null || face.Mapping?.MappingFromLocation is null)
|
||||
throw new NotSupportedException();
|
||||
if (face.FaceDistance?.Encoding is not null && face.FaceDistance.Encoding is FaceRecognitionDotNet.FaceEncoding faceEncoding)
|
||||
return;
|
||||
@ -284,62 +216,14 @@ public class MapLogicSupport : Shared.Models.Methods.IMapLogicSupport
|
||||
});
|
||||
}
|
||||
|
||||
void Shared.Models.Methods.IMapLogicSupport.SavePossiblyNewPersonContainers(IPropertyConfiguration propertyConfiguration, string personBirthdayFormat, char[] personCharacters, string facesFileNameExtension, string? a2PeopleSingletonDirectory, Dictionary<long, PersonContainer> personKeyToPersonContainer, List<(string[], PersonContainer)> possiblyNewPersonDisplayDirectoryNamesAndPersonContainer)
|
||||
{
|
||||
string json;
|
||||
string[] files;
|
||||
string checkFile;
|
||||
string[] segments;
|
||||
const int zero = 0;
|
||||
char personCharacter;
|
||||
string personKeyFormatted;
|
||||
string personDisplayDirectory;
|
||||
PersonBirthday personBirthday;
|
||||
string personDisplayDirectoryName;
|
||||
string checkPersonDisplayDirectory;
|
||||
string checkPersonKeyFormattedDirectory;
|
||||
JsonSerializerOptions jsonSerializerOptions = new() { WriteIndented = true };
|
||||
foreach ((string[] personDisplayDirectoryNames, PersonContainer personContainer) in possiblyNewPersonDisplayDirectoryNamesAndPersonContainer)
|
||||
{
|
||||
if (a2PeopleSingletonDirectory is null || personContainer.Key is null || personContainer.Birthdays is null || !personContainer.Birthdays.Any())
|
||||
continue;
|
||||
personBirthday = personContainer.Birthdays[zero];
|
||||
personDisplayDirectoryName = personDisplayDirectoryNames[^1];
|
||||
personDisplayDirectory = Path.Combine(personDisplayDirectoryNames);
|
||||
personKeyFormatted = Shared.Models.Stateless.Methods.IPersonBirthday.GetFormatted(personBirthdayFormat, personBirthday);
|
||||
segments = personDisplayDirectoryName.Split(personCharacters);
|
||||
if (segments.Length != 2)
|
||||
personCharacter = '_';
|
||||
else
|
||||
personCharacter = personDisplayDirectoryName[segments[zero].Length];
|
||||
checkPersonDisplayDirectory = Path.Combine(a2PeopleSingletonDirectory, personCharacter.ToString(), personDisplayDirectoryName);
|
||||
checkPersonKeyFormattedDirectory = Path.Combine(checkPersonDisplayDirectory, personKeyFormatted);
|
||||
if (Directory.Exists(checkPersonKeyFormattedDirectory))
|
||||
continue;
|
||||
_ = Directory.CreateDirectory(checkPersonKeyFormattedDirectory);
|
||||
checkFile = Path.Combine(checkPersonKeyFormattedDirectory, $"{personKeyFormatted}.json");
|
||||
json = JsonSerializer.Serialize(personContainer.Person, jsonSerializerOptions);
|
||||
_ = Shared.Models.Stateless.Methods.IPath.WriteAllText(checkFile, json, updateDateWhenMatches: false, compareBeforeWrite: true);
|
||||
if (!Directory.Exists(personDisplayDirectory))
|
||||
continue;
|
||||
files = Directory.GetFiles(personDisplayDirectory, $"*{facesFileNameExtension}", SearchOption.TopDirectoryOnly);
|
||||
foreach (string file in files)
|
||||
{
|
||||
checkFile = Path.Combine(checkPersonDisplayDirectory, Path.GetFileName(file));
|
||||
if (File.Exists(checkFile))
|
||||
continue;
|
||||
File.Copy(files[0], checkFile);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static Dictionary<int, Dictionary<int, Mapping>> GetIdToNormalizedRectangleToFace(Mapping[] mappingCollection)
|
||||
{
|
||||
Dictionary<int, Dictionary<int, Mapping>> results = new();
|
||||
Dictionary<int, Mapping>? keyValuePairs;
|
||||
foreach (Mapping mapping in mappingCollection)
|
||||
{
|
||||
if (mapping.MappingFromLocation is null)
|
||||
continue;
|
||||
if (!results.TryGetValue(mapping.MappingFromItem.Id, out keyValuePairs))
|
||||
{
|
||||
results.Add(mapping.MappingFromItem.Id, new());
|
||||
|
@ -598,7 +598,7 @@ public partial class DlibDotNet
|
||||
DateTime[] containerDateTimes;
|
||||
string deterministicHashCodeKey;
|
||||
MappingFromItem mappingFromItem;
|
||||
MappingFromLocation mappingFromLocation;
|
||||
MappingFromLocation? mappingFromLocation;
|
||||
List<MappingFromPhotoPrism>? mappingFromPhotoPrismCollection;
|
||||
foreach (Container container in containers)
|
||||
{
|
||||
@ -618,12 +618,15 @@ public partial class DlibDotNet
|
||||
foreach (Shared.Models.Face face in item.Faces)
|
||||
{
|
||||
if (face.FaceEncoding is null || face.Location is null || face.OutputResolution is null)
|
||||
continue;
|
||||
confidencePercent = Shared.Models.Stateless.Methods.ILocation.GetConfidencePercent(_Configuration.FaceConfidencePercent, _Configuration.RangeFaceConfidence, face.Location.Confidence);
|
||||
faceAreaPermille = Shared.Models.Stateless.Methods.IMapping.GetAreaPermille(_Configuration.FaceAreaPermille, face.Location, face.OutputResolution);
|
||||
normalizedRectangle = Shared.Models.Stateless.Methods.ILocation.GetNormalizedRectangle(face.Location, Shared.Models.Stateless.ILocation.Digits, face.OutputResolution);
|
||||
deterministicHashCodeKey = Shared.Models.Stateless.Methods.IMapping.GetDeterministicHashCodeKey(item.Property.Id.Value, face.Location, Shared.Models.Stateless.ILocation.Digits, face.OutputResolution);
|
||||
mappingFromLocation = new(faceAreaPermille, confidencePercent, deterministicHashCodeKey, normalizedRectangle);
|
||||
mappingFromLocation = null;
|
||||
else
|
||||
{
|
||||
confidencePercent = Shared.Models.Stateless.Methods.ILocation.GetConfidencePercent(_Configuration.FaceConfidencePercent, _Configuration.RangeFaceConfidence, face.Location.Confidence);
|
||||
faceAreaPermille = Shared.Models.Stateless.Methods.IMapping.GetAreaPermille(_Configuration.FaceAreaPermille, face.Location, face.OutputResolution);
|
||||
normalizedRectangle = Shared.Models.Stateless.Methods.ILocation.GetNormalizedRectangle(face.Location, Shared.Models.Stateless.ILocation.Digits, face.OutputResolution);
|
||||
deterministicHashCodeKey = Shared.Models.Stateless.Methods.IMapping.GetDeterministicHashCodeKey(item.Property.Id.Value, face.Location, Shared.Models.Stateless.ILocation.Digits, face.OutputResolution);
|
||||
mappingFromLocation = new(faceAreaPermille, confidencePercent, deterministicHashCodeKey, normalizedRectangle);
|
||||
}
|
||||
if (!fileNameToCollection.TryGetValue(mappingFromItem.RelativePath[1..], out mappingFromPhotoPrismCollection))
|
||||
mappingFromPhotoPrismCollection = null;
|
||||
mapping = new(mappingFromItem, mappingFromLocation, mappingFromPhotoPrismCollection);
|
||||
@ -695,7 +698,7 @@ public partial class DlibDotNet
|
||||
return items;
|
||||
}
|
||||
|
||||
private void MapLogic(string argZero, long ticks, Container[] containers, string a2PeopleSingletonDirectory, string dResultsFullGroupDirectory, string d2ResultsFullGroupDirectory, string fPhotoPrismContentDirectory, MapLogicSupport mapLogicSupport, MapLogic mapLogic, string outputResolution, Dictionary<long, List<int>> personKeyToIds, List<Shared.Models.Face> distinctFilteredFaces, Mapping[] mappingCollection, int totalNotMapped)
|
||||
private void MapLogic(string argZero, long ticks, Container[] containers, string a2PeopleSingletonDirectory, string dResultsFullGroupDirectory, string d2ResultsFullGroupDirectory, string fPhotoPrismContentDirectory, MapLogic mapLogic, string outputResolution, Dictionary<long, List<int>> personKeyToIds, List<Shared.Models.Face> distinctFilteredFaces, Mapping[] mappingCollection, int totalNotMapped)
|
||||
{
|
||||
int? useFiltersCounter = null;
|
||||
SortingContainer[] sortingContainers;
|
||||
@ -708,7 +711,7 @@ public partial class DlibDotNet
|
||||
if (_Configuration.SaveShortcutsForOutputResolutions.Contains(outputResolution))
|
||||
{
|
||||
List<Item> filteredItems = GetItems(argZero, containers);
|
||||
mapLogic.SaveShortcutsForOutputResolutionsDuringMapLogic(personKeyToIds, filteredItems, mappingCollection);
|
||||
mapLogic.SaveShortcutsForOutputResolutionsDuringMapLogic(personKeyToIds, dFacesContentDirectory, filteredItems, mappingCollection);
|
||||
}
|
||||
if (_Configuration.PersonCharactersCopyCount > 0 && !string.IsNullOrEmpty(_Configuration.PersonCharacters))
|
||||
mapLogic.CopyAtLeastOneMappedFiles(dFacesContentDirectory, a2PeopleSingletonDirectory, mappingCollection);
|
||||
@ -717,16 +720,19 @@ public partial class DlibDotNet
|
||||
mapLogic.SaveMapped(dFacesContentDirectory, d2FacePartsContentDirectory, personKeyToIds, mappingCollection, idToNormalizedRectangleToMapping, totalNotMapped);
|
||||
if (_Configuration.SaveFaceDistancesForOutputResolutions.Contains(outputResolution))
|
||||
{
|
||||
MapLogicSupport mapLogicSupport;
|
||||
MapLogicSupport.SetFaceDistances(_AppSettings.MaxDegreeOfParallelism, ticks, distinctFilteredFaces);
|
||||
List<Shared.Models.Face> distinctFurtherFilteredFaces = mapLogic.GetFurtherFilterBySkipCollection(distinctFilteredFaces);
|
||||
Dictionary<int, Dictionary<int, PersonContainer[]>> missingIdThenNormalizedRectangleToPersonContainers = mapLogic.GetMissing(idToNormalizedRectangleToMapping);
|
||||
List<FaceDistanceContainer> missingFaceDistanceContainers = _Distance.GetMissingFaceDistanceContainer(_AppSettings.MaxDegreeOfParallelism, ticks, dFacesCollectionDirectory, missingIdThenNormalizedRectangleToPersonContainers);
|
||||
sortingContainers = mapLogicSupport.SetFaceMappingSortingCollectionThenGetSortingContainers(_AppSettings.MaxDegreeOfParallelism, _MapConfiguration, ticks, mapLogic, distinctFurtherFilteredFaces, missingFaceDistanceContainers, useFiltersCounter);
|
||||
mapLogicSupport = new(_Configuration.FaceConfidencePercent, _Configuration.FaceDistancePermyriad, _Configuration.RangeDaysDeltaTolerance, _Configuration.RangeDistanceTolerance, _Configuration.RangeFaceAreaPermilleTolerance, _Configuration.RangeFaceConfidence, _Configuration.SortingMaximumPerFaceShouldBeHigh);
|
||||
sortingContainers = mapLogicSupport.SetFaceMappingSortingCollectionThenGetSortingContainers(_AppSettings.MaxDegreeOfParallelism, _MapConfiguration, ticks, mapLogic, distinctFurtherFilteredFaces, missingFaceDistanceContainers);
|
||||
if (!sortingContainers.Any())
|
||||
{
|
||||
for (useFiltersCounter = 1; useFiltersCounter < 17; useFiltersCounter++)
|
||||
{
|
||||
sortingContainers = mapLogicSupport.SetFaceMappingSortingCollectionThenGetSortingContainers(_AppSettings.MaxDegreeOfParallelism, _MapConfiguration, ticks, mapLogic, distinctFurtherFilteredFaces, missingFaceDistanceContainers, useFiltersCounter);
|
||||
mapLogicSupport = new(_Configuration.FaceConfidencePercent, _Configuration.FaceDistancePermyriad, _Configuration.RangeDaysDeltaTolerance, _Configuration.RangeDistanceTolerance, _Configuration.RangeFaceAreaPermilleTolerance, _Configuration.RangeFaceConfidence, _Configuration.SortingMaximumPerFaceShouldBeHigh, useFiltersCounter);
|
||||
sortingContainers = mapLogicSupport.SetFaceMappingSortingCollectionThenGetSortingContainers(_AppSettings.MaxDegreeOfParallelism, _MapConfiguration, ticks, mapLogic, distinctFurtherFilteredFaces, missingFaceDistanceContainers);
|
||||
if (sortingContainers.Any())
|
||||
break;
|
||||
}
|
||||
@ -734,7 +740,7 @@ public partial class DlibDotNet
|
||||
MapLogicSupport.SaveFaceDistances(_Configuration.PropertyConfiguration, sortingContainers);
|
||||
if (totalNotMapped > 0)
|
||||
{
|
||||
int updated = mapLogic.UpdateFromSortingContainers(sortingContainers);
|
||||
int updated = mapLogic.UpdateFromSortingContainers(mapLogicSupport, sortingContainers);
|
||||
List<SaveContainer> saveContainers = mapLogic.GetSaveContainers(dFacesContentDirectory, d2FacePartsContentDirectory, mappingCollection, idToNormalizedRectangleToMapping, useFiltersCounter, sortingContainers.Any());
|
||||
mapLogic.SaveContainers(totalNotMapped, updated, saveContainers);
|
||||
}
|
||||
@ -1043,14 +1049,13 @@ public partial class DlibDotNet
|
||||
propertyLogic = new(_AppSettings.MaxDegreeOfParallelism, _Configuration.PropertyConfiguration, _Resize.FileNameExtension, _Configuration.Reverse, aResultsFullGroupDirectory);
|
||||
}
|
||||
containers = Shared.Models.Stateless.Methods.IContainer.SortContainers(_Configuration.PropertyConfiguration, _Configuration.IgnoreRelativePaths, _ArgZeroIsConfigurationRootDirectory, argZero, containers);
|
||||
MapLogicSupport mapLogicSupport = new(_Configuration.FaceConfidencePercent, _Configuration.FaceDistancePermyriad, _Configuration.RangeDaysDeltaTolerance, _Configuration.RangeFaceAreaPermilleTolerance, _Configuration.SortingMaximumPerFaceShouldBeHigh);
|
||||
MapLogic? mapLogic = _Configuration.DistanceMoveUnableToMatch ? null : new(_AppSettings.MaxDegreeOfParallelism, _Configuration.PropertyConfiguration, _MapConfiguration, ticks, _PersonContainers, a2PeopleSingletonDirectory, eDistanceContentDirectory, mapLogicSupport);
|
||||
MapLogic? mapLogic = _Configuration.DistanceMoveUnableToMatch ? null : new(_AppSettings.MaxDegreeOfParallelism, _Configuration.PropertyConfiguration, _MapConfiguration, ticks, _PersonContainers, a2PeopleSingletonDirectory, eDistanceContentDirectory);
|
||||
personKeyToIds = mapLogic is null ? new() : mapLogic.GetPersonKeyToIds();
|
||||
fileNameToCollection = !Directory.Exists(fPhotoPrismSingletonDirectory) ? fileNameToCollection = new() : F_PhotoPrism.GetFileNameToCollection(fPhotoPrismSingletonDirectory);
|
||||
Dictionary<int, List<LocationContainer<MetadataExtractor.Directory>>> idToLocationContainers = GetDictionary(ticks, a2PeopleContentDirectory, eDistanceContentDirectory);
|
||||
FullDoWork(argZero, propertyRoot, ticks, aResultsFullGroupDirectory, bResultsFullGroupDirectory, t, containers, propertyLogic, metadata, eDistanceContentDirectory, fileNameToCollection, idToLocationContainers);
|
||||
_Distance.Clear();
|
||||
mapLogic ??= new(_AppSettings.MaxDegreeOfParallelism, _Configuration.PropertyConfiguration, _MapConfiguration, ticks, _PersonContainers, a2PeopleSingletonDirectory, eDistanceContentDirectory, mapLogicSupport);
|
||||
mapLogic ??= new(_AppSettings.MaxDegreeOfParallelism, _Configuration.PropertyConfiguration, _MapConfiguration, ticks, _PersonContainers, a2PeopleSingletonDirectory, eDistanceContentDirectory);
|
||||
SetMapping(fileNameToCollection, argZero, containers);
|
||||
if (!personKeyToIds.Any())
|
||||
personKeyToIds = mapLogic.GetPersonKeyToIds();
|
||||
@ -1076,7 +1081,7 @@ public partial class DlibDotNet
|
||||
&& outputResolution == _Configuration.OutputResolutions[0]
|
||||
&& _Configuration.LoadOrCreateThenSaveDistanceResultsForOutputResolutions.Contains(outputResolution)
|
||||
&& _Exceptions.Count == 0)
|
||||
MapLogic(argZero, ticks, containers, a2PeopleSingletonDirectory, dResultsFullGroupDirectory, d2ResultsFullGroupDirectory, fPhotoPrismContentDirectory, mapLogicSupport, mapLogic, outputResolution, personKeyToIds, distinctFilteredFaces, mappingCollection, totalNotMapped);
|
||||
MapLogic(argZero, ticks, containers, a2PeopleSingletonDirectory, dResultsFullGroupDirectory, d2ResultsFullGroupDirectory, fPhotoPrismContentDirectory, mapLogic, outputResolution, personKeyToIds, distinctFilteredFaces, mappingCollection, totalNotMapped);
|
||||
if (_Configuration.SaveRandomForOutputResolutions.Contains(outputResolution) && personKeyToIds.Any() && mappingCollection.Any())
|
||||
_Random.Random(_Configuration.PropertyConfiguration, outputResolution, personKeyToIds, mappingCollection);
|
||||
if (_IsEnvironment.Development)
|
||||
|
@ -55,15 +55,15 @@ public class Configuration
|
||||
public bool PropertiesChangedForMetadata { init; get; }
|
||||
public bool PropertiesChangedForResize { init; get; }
|
||||
public int[] RangeDaysDeltaTolerance { init; get; }
|
||||
public double[] RangeDistanceTolerance { init; get; }
|
||||
public int[] RangeFaceAreaPermilleTolerance { init; get; }
|
||||
public double[] RangeFaceConfidence { init; get; }
|
||||
public double[] RangeDistanceTolerance { init; get; }
|
||||
public bool Reverse { init; get; }
|
||||
public string[] SaveFaceDistancesForOutputResolutions { init; get; }
|
||||
public string[] SaveFaceLandmarkForOutputResolutions { init; get; }
|
||||
public string[] SaveFilteredOriginalImagesFromJLinksForOutputResolutions { init; get; }
|
||||
public bool SaveFullYearOfRandomFiles { init; get; }
|
||||
public string[] SaveMappedForOutputResolutions { init; get; }
|
||||
public string[] SaveFilteredOriginalImagesFromJLinksForOutputResolutions { init; get; }
|
||||
public string[] SaveRandomForOutputResolutions { init; get; }
|
||||
public bool SaveResizedSubfiles { init; get; }
|
||||
public string[] SaveShortcutsForOutputResolutions { init; get; }
|
||||
|
@ -25,14 +25,12 @@ public class MapLogic : Shared.Models.Methods.IMapLogic
|
||||
private readonly int _MaxDegreeOfParallelism;
|
||||
private readonly Configuration? _Configuration;
|
||||
private readonly string _EDistanceContentTicksDirectory;
|
||||
private readonly Shared.Models.Methods.IMapLogicSupport? _MapLogicSupport;
|
||||
private readonly Shared.Models.Properties.IPropertyConfiguration _PropertyConfiguration;
|
||||
|
||||
public MapLogic(int maxDegreeOfParallelism, Shared.Models.Properties.IPropertyConfiguration propertyConfiguration, Configuration? configuration, long ticks, PersonContainer[] personContainers, string a2PeopleSingletonDirectory, string eDistanceContentDirectory, Shared.Models.Methods.IMapLogicSupport? mapLogicSupport)
|
||||
public MapLogic(int maxDegreeOfParallelism, Shared.Models.Properties.IPropertyConfiguration propertyConfiguration, Configuration? configuration, long ticks, PersonContainer[] personContainers, string a2PeopleSingletonDirectory, string eDistanceContentDirectory)
|
||||
{
|
||||
_Ticks = ticks;
|
||||
_Configuration = configuration;
|
||||
_MapLogicSupport = mapLogicSupport;
|
||||
_Log = Serilog.Log.ForContext<MapLogic>();
|
||||
_PropertyConfiguration = propertyConfiguration;
|
||||
_MaxDegreeOfParallelism = maxDegreeOfParallelism;
|
||||
@ -60,16 +58,14 @@ public class MapLogic : Shared.Models.Methods.IMapLogic
|
||||
_ = Directory.CreateDirectory(eDistanceContentDirectory);
|
||||
if (!Directory.Exists(eDistanceContentTicksDirectory))
|
||||
_ = Directory.CreateDirectory(eDistanceContentTicksDirectory);
|
||||
if (configuration is not null && mapLogicSupport is not null)
|
||||
if (configuration is not null)
|
||||
{
|
||||
List<PersonContainer> personContainerCollection = new(personContainers);
|
||||
Stateless.MapLogic.Set(propertyConfiguration,
|
||||
configuration,
|
||||
Stateless.MapLogic.Set(configuration,
|
||||
ticks,
|
||||
personContainerCollection,
|
||||
a2PeopleSingletonDirectory,
|
||||
eDistanceContentDirectory,
|
||||
mapLogicSupport,
|
||||
personKeyToPersonContainer,
|
||||
notMappedPersonContainers,
|
||||
skipCollection,
|
||||
@ -185,6 +181,8 @@ public class MapLogic : Shared.Models.Methods.IMapLogic
|
||||
Dictionary<int, PersonContainer[]>? normalizedRectangleToPersonContainers;
|
||||
foreach (Mapping mapping in mappingCollection)
|
||||
{
|
||||
if (mapping.MappingFromLocation is null)
|
||||
continue;
|
||||
if (!_IdThenNormalizedRectangleToPersonContainers.TryGetValue(mapping.MappingFromItem.Id, out normalizedRectangleToPersonContainers))
|
||||
{
|
||||
if (_SkipCollection.TryGetValue(mapping.MappingFromItem.Id, out normalizedRectangles) && normalizedRectangles.Contains(mapping.MappingFromLocation.NormalizedRectangle))
|
||||
@ -335,7 +333,7 @@ public class MapLogic : Shared.Models.Methods.IMapLogic
|
||||
SaveContainer? result;
|
||||
string shortcutFile = string.Empty;
|
||||
string? facesDirectory = GetFacesDirectory(dFacesContentDirectory, mapping.MappingFromItem);
|
||||
if (facesDirectory is null)
|
||||
if (facesDirectory is null || mapping.MappingFromLocation is null)
|
||||
result = null;
|
||||
else
|
||||
{
|
||||
@ -446,6 +444,8 @@ public class MapLogic : Shared.Models.Methods.IMapLogic
|
||||
string forceSingleImageHumanized = nameof(Shared.Models.Stateless.IMapLogic.ForceSingleImage).Humanize(LetterCasing.Title);
|
||||
foreach (Mapping mapping in mappingCollection)
|
||||
{
|
||||
if (mapping.MappingFromLocation is null)
|
||||
continue;
|
||||
directoryName = Path.GetDirectoryName(mapping.MappingFromItem.RelativePath);
|
||||
if (directoryName is null)
|
||||
throw new NotSupportedException();
|
||||
@ -462,7 +462,7 @@ public class MapLogic : Shared.Models.Methods.IMapLogic
|
||||
{
|
||||
if (sortingContainersAny)
|
||||
continue;
|
||||
mapping.UpdateMappingFromUnknownPerson(new(mapping, new(mapping)));
|
||||
mapping.UpdateMappingFromUnknownPerson(new(mapping, new(mapping, mapping.MappingFromLocation)));
|
||||
if (mapping.SortingContainer is null)
|
||||
continue;
|
||||
}
|
||||
@ -626,13 +626,13 @@ public class MapLogic : Shared.Models.Methods.IMapLogic
|
||||
return results;
|
||||
}
|
||||
|
||||
public int UpdateFromSortingContainers(SortingContainer[] sortingContainers)
|
||||
public int UpdateFromSortingContainers(Shared.Models.Methods.IMapLogicSupport mapLogicSupport, SortingContainer[] sortingContainers)
|
||||
{
|
||||
if (_Configuration is null)
|
||||
throw new NullReferenceException(nameof(_Configuration));
|
||||
if (_MapLogicSupport is not null)
|
||||
if (mapLogicSupport is not null)
|
||||
{
|
||||
string counts = _MapLogicSupport.GetCounts();
|
||||
string counts = mapLogicSupport.GetCounts();
|
||||
_ = Directory.CreateDirectory(Path.Combine(_EDistanceContentTicksDirectory, counts));
|
||||
}
|
||||
int result = 0;
|
||||
@ -656,7 +656,7 @@ public class MapLogic : Shared.Models.Methods.IMapLogic
|
||||
foreach (SortingContainer sortingContainer in sortingContainers)
|
||||
{
|
||||
progressBar.Tick();
|
||||
if (sortingContainer.Mapping is null)
|
||||
if (sortingContainer.Mapping?.MappingFromLocation is null)
|
||||
throw new NotSupportedException();
|
||||
if (!idToNormalizedRectangleCollectionForA.ContainsKey(sortingContainer.Mapping.MappingFromItem.Id))
|
||||
idToNormalizedRectangleCollectionForA.Add(sortingContainer.Mapping.MappingFromItem.Id, new());
|
||||
@ -761,6 +761,8 @@ public class MapLogic : Shared.Models.Methods.IMapLogic
|
||||
if (!normalizedRectangleToMapping.ContainsKey(normalizedRectangle.Value))
|
||||
continue;
|
||||
mapping = normalizedRectangleToMapping[normalizedRectangle.Value];
|
||||
if (mapping.MappingFromLocation is null)
|
||||
continue;
|
||||
if (string.IsNullOrEmpty(personDisplayDirectory))
|
||||
throw new NotSupportedException();
|
||||
directoryName = Path.GetDirectoryName(mapping.MappingFromItem.RelativePath);
|
||||
@ -822,7 +824,7 @@ public class MapLogic : Shared.Models.Methods.IMapLogic
|
||||
directoryName = Path.GetDirectoryName(mapping.MappingFromItem.RelativePath);
|
||||
if (directoryName is null)
|
||||
throw new NotSupportedException();
|
||||
if (mapping.MappingFromPerson is null)
|
||||
if (mapping.MappingFromLocation is null || mapping.MappingFromPerson is null)
|
||||
continue;
|
||||
if (mapping.MappingFromItem.ResizedFileHolder.DirectoryName is null || !mapping.MappingFromItem.ResizedFileHolder.Exists)
|
||||
continue;
|
||||
@ -903,8 +905,6 @@ public class MapLogic : Shared.Models.Methods.IMapLogic
|
||||
{
|
||||
if (_Configuration is null)
|
||||
throw new NullReferenceException(nameof(_Configuration));
|
||||
if (_MapLogicSupport is null)
|
||||
throw new NullReferenceException(nameof(_MapLogicSupport));
|
||||
List<string> results = new();
|
||||
string[] files;
|
||||
string checkDirectory;
|
||||
@ -979,7 +979,7 @@ public class MapLogic : Shared.Models.Methods.IMapLogic
|
||||
throw new NotSupportedException();
|
||||
if (mapping.By is null or Shared.Models.Stateless.IMapLogic.Sorting)
|
||||
continue;
|
||||
if (mapping.MappingFromPerson?.ApproximateYears is null)
|
||||
if (mapping.MappingFromPerson?.ApproximateYears is null || mapping.MappingFromLocation is null)
|
||||
continue;
|
||||
if (string.IsNullOrEmpty(mapping.MappingFromPerson.SegmentB))
|
||||
throw new NotSupportedException();
|
||||
@ -1097,7 +1097,7 @@ public class MapLogic : Shared.Models.Methods.IMapLogic
|
||||
Dictionary<int, List<long>> idToPersonKeys = Stateless.Methods.IMapLogic.GetIdToPersonKeys(personKeyToIds);
|
||||
foreach (Mapping mapping in mappingCollection)
|
||||
{
|
||||
if (mapping.MappingFromItem.ImageFileHolder.DirectoryName is null || mapping.MappingFromPerson is null)
|
||||
if (mapping.MappingFromLocation is null || mapping.MappingFromItem.ImageFileHolder.DirectoryName is null || mapping.MappingFromPerson is null)
|
||||
continue;
|
||||
if (!idToLocationContainers.TryGetValue(mapping.MappingFromItem.Id, out locationContainers) || !locationContainers.Any())
|
||||
directories = MetadataExtractor.ImageMetadataReader.ReadMetadata(mapping.MappingFromItem.ResizedFileHolder.FullName);
|
||||
@ -1112,9 +1112,9 @@ public class MapLogic : Shared.Models.Methods.IMapLogic
|
||||
if (!string.IsNullOrEmpty(model) && !string.IsNullOrEmpty(model.Trim()))
|
||||
{
|
||||
model = Regex.Replace(model, @"[\\,\/,\:,\*,\?,\"",\<,\>,\|]", "_");
|
||||
directory = Path.Combine(eDistanceContentDirectory, "Model Shortcuts", model, Path.GetFileName(mapping.MappingFromItem.ImageFileHolder.DirectoryName));
|
||||
directory = Path.Combine($"{eDistanceContentDirectory}---", "Model Shortcuts", model, Path.GetFileName(mapping.MappingFromItem.ImageFileHolder.DirectoryName));
|
||||
fileName = Path.Combine(directory, $"{mapping.MappingFromItem.ImageFileHolder.Name}.lnk");
|
||||
results.Add(new(mapping.MappingFromItem.ImageFileHolder.FullName, directory, mapping.MappingFromItem.MinimumDateTime, fileName, mapping.MappingFromLocation.DeterministicHashCodeKey));
|
||||
results.Add(new(mapping.MappingFromItem.ImageFileHolder.FullName, directory, mapping.MappingFromItem.MinimumDateTime, fileName, mapping.MappingFromLocation.DeterministicHashCodeKey, MakeAllHidden: false));
|
||||
}
|
||||
if (!idToPersonKeys.TryGetValue(mapping.MappingFromItem.Id, out personKeys))
|
||||
continue;
|
||||
@ -1122,12 +1122,12 @@ public class MapLogic : Shared.Models.Methods.IMapLogic
|
||||
if (!personKeys.Contains(mapping.MappingFromPerson.PersonBirthday.Value.Ticks))
|
||||
continue;
|
||||
personKeyFormatted = IPersonBirthday.GetFormatted(_Configuration.PersonBirthdayFormat, mapping.MappingFromPerson.PersonBirthday);
|
||||
directory = Path.Combine(eDistanceContentDirectory, "Person Key Shortcuts", personKeyFormatted, Path.GetFileName(mapping.MappingFromItem.ImageFileHolder.DirectoryName));
|
||||
directory = Path.Combine($"{eDistanceContentDirectory}---", "Person Key Shortcuts", personKeyFormatted, Path.GetFileName(mapping.MappingFromItem.ImageFileHolder.DirectoryName));
|
||||
fileName = Path.Combine(directory, $"{mapping.MappingFromItem.ImageFileHolder.Name}.lnk");
|
||||
results.Add(new(mapping.MappingFromItem.ImageFileHolder.FullName, directory, mapping.MappingFromItem.MinimumDateTime, fileName, mapping.MappingFromLocation.DeterministicHashCodeKey));
|
||||
directory = Path.Combine(eDistanceContentDirectory, "Name Shortcuts", mapping.MappingFromPerson.DisplayDirectoryName, Path.GetFileName(mapping.MappingFromItem.ImageFileHolder.DirectoryName));
|
||||
results.Add(new(mapping.MappingFromItem.ImageFileHolder.FullName, directory, mapping.MappingFromItem.MinimumDateTime, fileName, mapping.MappingFromLocation.DeterministicHashCodeKey, MakeAllHidden: false));
|
||||
directory = Path.Combine($"{eDistanceContentDirectory}---", "Name Shortcuts", mapping.MappingFromPerson.DisplayDirectoryName, Path.GetFileName(mapping.MappingFromItem.ImageFileHolder.DirectoryName));
|
||||
fileName = Path.Combine(directory, $"{mapping.MappingFromItem.ImageFileHolder.Name}.lnk");
|
||||
results.Add(new(mapping.MappingFromItem.ImageFileHolder.FullName, directory, mapping.MappingFromItem.MinimumDateTime, fileName, mapping.MappingFromLocation.DeterministicHashCodeKey));
|
||||
results.Add(new(mapping.MappingFromItem.ImageFileHolder.FullName, directory, mapping.MappingFromItem.MinimumDateTime, fileName, mapping.MappingFromLocation.DeterministicHashCodeKey, MakeAllHidden: false));
|
||||
}
|
||||
return results;
|
||||
}
|
||||
@ -1151,9 +1151,12 @@ public class MapLogic : Shared.Models.Methods.IMapLogic
|
||||
hiddenFile = $"{s.FileName}.lvs";
|
||||
if (File.Exists(hiddenFile))
|
||||
continue;
|
||||
File.WriteAllLines(hiddenFile, new string[] { s.FullName, s.Description });
|
||||
File.SetAttributes(hiddenFile, FileAttributes.Hidden);
|
||||
File.SetLastWriteTime(hiddenFile, s.DateTime);
|
||||
if (s.Description is not null)
|
||||
{
|
||||
File.WriteAllLines(hiddenFile, new string[] { s.FullName, s.Description });
|
||||
File.SetAttributes(hiddenFile, FileAttributes.Hidden);
|
||||
File.SetLastWriteTime(hiddenFile, s.DateTime);
|
||||
}
|
||||
if (File.Exists(s.FileName))
|
||||
continue;
|
||||
try
|
||||
@ -1168,15 +1171,17 @@ public class MapLogic : Shared.Models.Methods.IMapLogic
|
||||
}
|
||||
}
|
||||
|
||||
private (List<(string, DateTime[])>, List<SaveShortcutsForOutputResolutions>) GetCollectionForSaveShortcutsForOutputResolutionsDuringMapLogic(Dictionary<long, List<int>> personKeyToIds, List<Item> filteredItems, Mapping[] mappingCollection)
|
||||
private (List<(string, DateTime[])>, List<SaveShortcutsForOutputResolutions>) GetCollectionForSaveShortcutsForOutputResolutionsDuringMapLogic(Dictionary<long, List<int>> personKeyToIds, string dFacesContentDirectory, List<Item> filteredItems, Mapping[] mappingCollection)
|
||||
{
|
||||
if (_Configuration is null)
|
||||
throw new NullReferenceException(nameof(_Configuration));
|
||||
long personKey;
|
||||
string fileName;
|
||||
string fullName;
|
||||
string directory;
|
||||
string? directoryName;
|
||||
string personDirectory;
|
||||
string? facesDirectory;
|
||||
string personKeyFormatted;
|
||||
List<string> distinct = new();
|
||||
List<SaveShortcutsForOutputResolutions> collection = new();
|
||||
@ -1185,9 +1190,11 @@ public class MapLogic : Shared.Models.Methods.IMapLogic
|
||||
{
|
||||
if (item.ResizedFileHolder is null)
|
||||
continue;
|
||||
if (item.Faces.Any(l => l.FaceEncoding is not null))
|
||||
continue;
|
||||
foreach (Face face in item.Faces)
|
||||
{
|
||||
if (face.FaceEncoding is null || face.Location is null || face.OutputResolution is null || face.Mapping is null)
|
||||
if (face.Mapping is null)
|
||||
continue;
|
||||
directoryName = Path.GetDirectoryName(face.Mapping.MappingFromItem.RelativePath);
|
||||
if (directoryName is null)
|
||||
@ -1197,7 +1204,7 @@ public class MapLogic : Shared.Models.Methods.IMapLogic
|
||||
directory = Path.Combine(item.ResizedFileHolder.DirectoryName, $"{_PropertyConfiguration.ResultAllInOne}Shortcuts", _PropertyConfiguration.ResultAllInOne);
|
||||
personDirectory = Path.Combine(directory, "No Faces");
|
||||
fileName = Path.Combine(personDirectory, $"{item.ResizedFileHolder.Name}.lnk");
|
||||
collection.Add(new(item.ResizedFileHolder.FullName, personDirectory, item.ImageFileHolder.LastWriteTime.Value, fileName, face.Mapping.MappingFromItem.Id.ToString()));
|
||||
collection.Add(new(item.ResizedFileHolder.FullName, personDirectory, item.ImageFileHolder.LastWriteTime.Value, fileName, face.Mapping.MappingFromItem.Id.ToString(), MakeAllHidden: false));
|
||||
if (face.Mapping.MappingFromItem.ContainerDateTimes.Any() && !distinct.Contains(item.ResizedFileHolder.DirectoryName))
|
||||
{
|
||||
distinct.Add(item.ResizedFileHolder.DirectoryName);
|
||||
@ -1222,7 +1229,13 @@ public class MapLogic : Shared.Models.Methods.IMapLogic
|
||||
directory = Path.Combine(mapping.MappingFromItem.ResizedFileHolder.DirectoryName, $"{_PropertyConfiguration.ResultAllInOne}Shortcuts", _PropertyConfiguration.ResultAllInOne);
|
||||
personDirectory = Path.Combine(directory, "Unknown");
|
||||
fileName = Path.Combine(personDirectory, $"{mapping.MappingFromItem.ResizedFileHolder.Name}.lnk");
|
||||
collection.Add(new(mapping.MappingFromItem.ResizedFileHolder.FullName, personDirectory, mapping.MappingFromItem.MinimumDateTime, fileName, mapping.MappingFromLocation.DeterministicHashCodeKey));
|
||||
collection.Add(new(mapping.MappingFromItem.ResizedFileHolder.FullName, personDirectory, mapping.MappingFromItem.MinimumDateTime, fileName, mapping.MappingFromLocation?.DeterministicHashCodeKey, MakeAllHidden: false));
|
||||
facesDirectory = GetFacesDirectory(dFacesContentDirectory, mapping.MappingFromItem);
|
||||
if (facesDirectory is null || mapping.MappingFromLocation is null)
|
||||
continue;
|
||||
fullName = Path.Combine(facesDirectory, $"{mapping.MappingFromLocation.DeterministicHashCodeKey}{mapping.MappingFromItem.ImageFileHolder.ExtensionLowered}{_Configuration.FacesFileNameExtension}");
|
||||
fileName = Path.Combine(personDirectory, $"{mapping.MappingFromLocation.DeterministicHashCodeKey}{mapping.MappingFromItem.ResizedFileHolder.ExtensionLowered}{_Configuration.FacesFileNameExtension}.lnk");
|
||||
collection.Add(new(fullName, personDirectory, mapping.MappingFromItem.MinimumDateTime, fileName, mapping.MappingFromLocation.DeterministicHashCodeKey, MakeAllHidden: true));
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -1243,20 +1256,20 @@ public class MapLogic : Shared.Models.Methods.IMapLogic
|
||||
else
|
||||
personDirectory = Path.Combine(directory, mapping.MappingFromPerson.DisplayDirectoryName, $"{personKeyToIds[personKey].Count} Face(s)");
|
||||
fileName = Path.Combine(directory, $"{mapping.MappingFromItem.ResizedFileHolder.Name}.lnk");
|
||||
collection.Add(new(mapping.MappingFromItem.ResizedFileHolder.FullName, personDirectory, mapping.MappingFromItem.MinimumDateTime, fileName, mapping.MappingFromLocation.DeterministicHashCodeKey));
|
||||
collection.Add(new(mapping.MappingFromItem.ResizedFileHolder.FullName, personDirectory, mapping.MappingFromItem.MinimumDateTime, fileName, mapping.MappingFromLocation?.DeterministicHashCodeKey, MakeAllHidden: false));
|
||||
}
|
||||
}
|
||||
return new(directoriesAndDateTimes, collection);
|
||||
}
|
||||
|
||||
public void SaveShortcutsForOutputResolutionsDuringMapLogic(Dictionary<long, List<int>> personKeyToIds, List<Item> filteredItems, Mapping[] mappingCollection)
|
||||
public void SaveShortcutsForOutputResolutionsDuringMapLogic(Dictionary<long, List<int>> personKeyToIds, string dFacesContentDirectory, List<Item> filteredItems, Mapping[] mappingCollection)
|
||||
{
|
||||
if (_Configuration is null)
|
||||
throw new NullReferenceException(nameof(_Configuration));
|
||||
WindowsShortcut windowsShortcut;
|
||||
List<(string, DateTime[])> directoriesAndDateTimes;
|
||||
List<SaveShortcutsForOutputResolutions> collection;
|
||||
(directoriesAndDateTimes, collection) = GetCollectionForSaveShortcutsForOutputResolutionsDuringMapLogic(personKeyToIds, filteredItems, mappingCollection);
|
||||
(directoriesAndDateTimes, collection) = GetCollectionForSaveShortcutsForOutputResolutionsDuringMapLogic(personKeyToIds, dFacesContentDirectory, filteredItems, mappingCollection);
|
||||
string[] directories = (from l in collection select l.Directory).Distinct().ToArray();
|
||||
foreach (string directory in directories)
|
||||
{
|
||||
@ -1274,6 +1287,8 @@ public class MapLogic : Shared.Models.Methods.IMapLogic
|
||||
windowsShortcut = new() { Path = s.FullName, Description = s.Description };
|
||||
windowsShortcut.Save(s.FileName);
|
||||
windowsShortcut.Dispose();
|
||||
if (s.MakeAllHidden)
|
||||
File.SetAttributes(s.FileName, FileAttributes.Hidden);
|
||||
File.SetLastWriteTime(s.FileName, s.DateTime);
|
||||
}
|
||||
catch (Exception)
|
||||
@ -1306,7 +1321,7 @@ public class MapLogic : Shared.Models.Methods.IMapLogic
|
||||
List<int>? normalizedRectangles;
|
||||
foreach (Face face in distinctFilteredFaces)
|
||||
{
|
||||
if (face.Mapping is null)
|
||||
if (face.Mapping?.MappingFromLocation is null)
|
||||
continue;
|
||||
if (_SkipCollection.TryGetValue(face.Mapping.MappingFromItem.Id, out normalizedRectangles) && normalizedRectangles.Contains(face.Mapping.MappingFromLocation.NormalizedRectangle))
|
||||
continue;
|
||||
|
@ -1,5 +1,6 @@
|
||||
using Humanizer;
|
||||
using ShellProgressBar;
|
||||
using System.Text.Json;
|
||||
using View_by_Distance.Shared.Models;
|
||||
using View_by_Distance.Shared.Models.Stateless.Methods;
|
||||
using WindowsShortcutFactory;
|
||||
@ -503,7 +504,57 @@ internal abstract class MapLogic
|
||||
}
|
||||
}
|
||||
|
||||
internal static void Set(Shared.Models.Properties.IPropertyConfiguration propertyConfiguration, Configuration? configuration, long ticks, List<PersonContainer> personContainers, string? a2PeopleContentDirectory, string eDistanceContentDirectory, Shared.Models.Methods.IMapLogicSupport mapLogicSupport, Dictionary<long, PersonContainer> personKeyToPersonContainer, List<PersonContainer> notMappedPersonContainers, Dictionary<int, List<int>> skipCollection, Dictionary<int, Dictionary<int, PersonContainer[]>> idThenNormalizedRectangleToPersonContainers)
|
||||
static void SavePossiblyNewPersonContainers(string personBirthdayFormat, char[] personCharacters, string facesFileNameExtension, string? a2PeopleSingletonDirectory, List<(string[], PersonContainer)> possiblyNewPersonDisplayDirectoryNamesAndPersonContainer)
|
||||
{
|
||||
string json;
|
||||
string[] files;
|
||||
string checkFile;
|
||||
string[] segments;
|
||||
const int zero = 0;
|
||||
char personCharacter;
|
||||
string personKeyFormatted;
|
||||
string personDisplayDirectory;
|
||||
PersonBirthday personBirthday;
|
||||
string personDisplayDirectoryName;
|
||||
string checkPersonDisplayDirectory;
|
||||
string checkPersonKeyFormattedDirectory;
|
||||
JsonSerializerOptions jsonSerializerOptions = new() { WriteIndented = true };
|
||||
foreach ((string[] personDisplayDirectoryNames, PersonContainer personContainer) in possiblyNewPersonDisplayDirectoryNamesAndPersonContainer)
|
||||
{
|
||||
if (a2PeopleSingletonDirectory is null || personContainer.Key is null || personContainer.Birthdays is null || !personContainer.Birthdays.Any())
|
||||
continue;
|
||||
personBirthday = personContainer.Birthdays[zero];
|
||||
personDisplayDirectoryName = personDisplayDirectoryNames[^1];
|
||||
personDisplayDirectory = Path.Combine(personDisplayDirectoryNames);
|
||||
personKeyFormatted = IPersonBirthday.GetFormatted(personBirthdayFormat, personBirthday);
|
||||
segments = personDisplayDirectoryName.Split(personCharacters);
|
||||
if (segments.Length != 2)
|
||||
personCharacter = '_';
|
||||
else
|
||||
personCharacter = personDisplayDirectoryName[segments[zero].Length];
|
||||
checkPersonDisplayDirectory = Path.Combine(a2PeopleSingletonDirectory, personCharacter.ToString(), personDisplayDirectoryName);
|
||||
checkPersonKeyFormattedDirectory = Path.Combine(checkPersonDisplayDirectory, personKeyFormatted);
|
||||
if (Directory.Exists(checkPersonKeyFormattedDirectory))
|
||||
continue;
|
||||
_ = Directory.CreateDirectory(checkPersonKeyFormattedDirectory);
|
||||
checkFile = Path.Combine(checkPersonKeyFormattedDirectory, $"{personKeyFormatted}.json");
|
||||
json = JsonSerializer.Serialize(personContainer.Person, jsonSerializerOptions);
|
||||
_ = IPath.WriteAllText(checkFile, json, updateDateWhenMatches: false, compareBeforeWrite: true);
|
||||
if (!Directory.Exists(personDisplayDirectory))
|
||||
continue;
|
||||
files = Directory.GetFiles(personDisplayDirectory, $"*{facesFileNameExtension}", SearchOption.TopDirectoryOnly);
|
||||
foreach (string file in files)
|
||||
{
|
||||
checkFile = Path.Combine(checkPersonDisplayDirectory, Path.GetFileName(file));
|
||||
if (File.Exists(checkFile))
|
||||
continue;
|
||||
File.Copy(files[0], checkFile);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal static void Set(Configuration? configuration, long ticks, List<PersonContainer> personContainers, string? a2PeopleContentDirectory, string eDistanceContentDirectory, Dictionary<long, PersonContainer> personKeyToPersonContainer, List<PersonContainer> notMappedPersonContainers, Dictionary<int, List<int>> skipCollection, Dictionary<int, Dictionary<int, PersonContainer[]>> idThenNormalizedRectangleToPersonContainers)
|
||||
{
|
||||
if (configuration is null)
|
||||
throw new NullReferenceException(nameof(configuration));
|
||||
@ -543,7 +594,7 @@ internal abstract class MapLogic
|
||||
notMappedPersonContainers.AddRange(GetNotMappedPersonContainers(configuration, personContainers, personKeys, personKeyCollection));
|
||||
AppendToSkipCollection(skipCollection, idThenNormalizedRectangleToPersonContainers, incorrectIdThenNormalizedRectangleToPersonContainers);
|
||||
if (possiblyNewPersonDisplayDirectoryNamesAndPersonContainer.Any())
|
||||
mapLogicSupport.SavePossiblyNewPersonContainers(propertyConfiguration, configuration.PersonBirthdayFormat, configuration.PersonCharacters.ToArray(), configuration.FacesFileNameExtension, a2PeopleContentDirectory, personKeyToPersonContainer, possiblyNewPersonDisplayDirectoryNamesAndPersonContainer);
|
||||
SavePossiblyNewPersonContainers(configuration.PersonBirthdayFormat, configuration.PersonCharacters.ToArray(), configuration.FacesFileNameExtension, a2PeopleContentDirectory, possiblyNewPersonDisplayDirectoryNamesAndPersonContainer);
|
||||
}
|
||||
|
||||
private static string GetMappingSegmentB(long ticks, PersonBirthday personBirthday, int? approximateYears, long minimumDateTimeTicks, bool? isWrongYear)
|
||||
@ -587,6 +638,8 @@ internal abstract class MapLogic
|
||||
internal static SaveContainer GetDebugSaveContainer(string directory, SortingContainer sortingContainer, Mapping mapping)
|
||||
{
|
||||
SaveContainer result;
|
||||
if (sortingContainer.Mapping.MappingFromLocation is null)
|
||||
throw new NullReferenceException(nameof(sortingContainer.Mapping.MappingFromLocation));
|
||||
FileHolder faceFileHolder = new($"C:/{sortingContainer.Sorting.Id}.{sortingContainer.Sorting.NormalizedRectangle}");
|
||||
string shortcutFile = Path.Combine(directory, $"{sortingContainer.Mapping.MappingFromLocation.DeterministicHashCodeKey}{sortingContainer.Mapping.MappingFromItem.ImageFileHolder.ExtensionLowered}.debug.lnk");
|
||||
result = new(directory, faceFileHolder, mapping.MappingFromItem.ResizedFileHolder, shortcutFile);
|
||||
|
@ -109,7 +109,7 @@ public class F_PhotoPrism
|
||||
foreach (Face face in distinctFilteredFaces)
|
||||
{
|
||||
collection.Clear();
|
||||
normalizedRectangle = face.Mapping?.MappingFromLocation.NormalizedRectangle;
|
||||
normalizedRectangle = face.Mapping?.MappingFromLocation?.NormalizedRectangle;
|
||||
if (normalizedRectangle is null)
|
||||
continue;
|
||||
if (face.FaceEncoding is null || face.Location is null || face.OutputResolution is null || face.Mapping is null)
|
||||
|
@ -123,14 +123,14 @@ public class Mapping : Properties.IMapping
|
||||
protected SortingContainer? _SortingContainer;
|
||||
public int? By => _By;
|
||||
public MappingFromItem MappingFromItem { init; get; }
|
||||
public MappingFromLocation MappingFromLocation { init; get; }
|
||||
public MappingFromLocation? MappingFromLocation { init; get; }
|
||||
public List<MappingFromPhotoPrism>? MappingFromPhotoPrismCollection { init; get; }
|
||||
public MappingFromPerson? MappingFromPerson => _MappingFromPerson;
|
||||
public string? SegmentC => _SegmentC;
|
||||
public SortingContainer? SortingContainer => _SortingContainer;
|
||||
|
||||
[JsonConstructor]
|
||||
public Mapping(int? by, MappingFromItem mappingFromItem, MappingFromLocation mappingFromLocation, List<MappingFromPhotoPrism>? mappingFromPhotoPrismCollection, MappingFromPerson? mappingFromPerson, string? segmentC, SortingContainer? sortingContainer)
|
||||
public Mapping(int? by, MappingFromItem mappingFromItem, MappingFromLocation? mappingFromLocation, List<MappingFromPhotoPrism>? mappingFromPhotoPrismCollection, MappingFromPerson? mappingFromPerson, string? segmentC, SortingContainer? sortingContainer)
|
||||
{
|
||||
_By = by;
|
||||
_SegmentC = segmentC;
|
||||
@ -141,7 +141,7 @@ public class Mapping : Properties.IMapping
|
||||
_SortingContainer = sortingContainer;
|
||||
}
|
||||
|
||||
public Mapping(MappingFromItem mappingFromItem, MappingFromLocation mappingFromLocation, List<MappingFromPhotoPrism>? mappingFromPhotoPrismCollection) :
|
||||
public Mapping(MappingFromItem mappingFromItem, MappingFromLocation? mappingFromLocation, List<MappingFromPhotoPrism>? mappingFromPhotoPrismCollection) :
|
||||
this(null, mappingFromItem, mappingFromLocation, mappingFromPhotoPrismCollection, null, null, null)
|
||||
{ }
|
||||
|
||||
|
@ -4,6 +4,5 @@ public interface IMapLogicSupport
|
||||
{
|
||||
|
||||
string GetCounts();
|
||||
void SavePossiblyNewPersonContainers(Properties.IPropertyConfiguration propertyConfiguration, string personBirthdayFormat, char[] personCharacters, string facesFileNameExtension, string? a2PeopleContentDirectory, Dictionary<long, PersonContainer> personKeyToPersonContainer, List<(string[], PersonContainer)> possiblyNewPersonDisplayDirectoryNamesAndPersonContainer);
|
||||
|
||||
}
|
@ -47,7 +47,7 @@ public interface IMapping
|
||||
public int? By { get; }
|
||||
public string? SegmentC { get; }
|
||||
public MappingFromItem MappingFromItem { init; get; }
|
||||
public MappingFromLocation MappingFromLocation { init; get; }
|
||||
public MappingFromLocation? MappingFromLocation { init; get; }
|
||||
public List<MappingFromPhotoPrism>? MappingFromPhotoPrismCollection { init; get; }
|
||||
public MappingFromPerson? MappingFromPerson { get; }
|
||||
public SortingContainer? SortingContainer { get; }
|
||||
|
@ -1,4 +1,4 @@
|
||||
namespace View_by_Distance.Shared.Models;
|
||||
|
||||
public record SaveShortcutsForOutputResolutions(string FullName, string Directory, DateTime DateTime, string FileName, string Description)
|
||||
public record SaveShortcutsForOutputResolutions(string FullName, string Directory, DateTime DateTime, string FileName, string? Description, bool MakeAllHidden)
|
||||
{ }
|
@ -22,8 +22,8 @@ public record class Sorting : Properties.ISorting
|
||||
Older = older;
|
||||
}
|
||||
|
||||
public Sorting(Mapping mapping) :
|
||||
this(0, 0, mapping.MappingFromItem.Id, mapping.MappingFromLocation.NormalizedRectangle, false)
|
||||
public Sorting(Mapping mapping, MappingFromLocation mappingFromLocation) :
|
||||
this(0, 0, mapping.MappingFromItem.Id, mappingFromLocation.NormalizedRectangle, false)
|
||||
{ }
|
||||
|
||||
public override string ToString()
|
||||
|
@ -17,7 +17,7 @@ public record class SortingContainer : Properties.ISortingContainer
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
string result = string.Concat(Mapping.MappingFromItem.Id, '\t', Mapping.MappingFromLocation.NormalizedRectangle, '\t', Sorting.Id, '\t', Sorting.NormalizedRectangle, '\t', Sorting.Older, '\t', '\t', Sorting.DistancePermyriad, '\t', Sorting.DaysDelta);
|
||||
string result = string.Concat(Mapping.MappingFromItem.Id, '\t', Mapping.MappingFromLocation?.NormalizedRectangle, '\t', Sorting.Id, '\t', Sorting.NormalizedRectangle, '\t', Sorting.Older, '\t', '\t', Sorting.DistancePermyriad, '\t', Sorting.DaysDelta);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user