Alignment with AA

This commit is contained in:
Mike Phares 2024-12-28 19:36:44 -07:00
parent 17be39bef9
commit 75cfb2a0d9
22 changed files with 176 additions and 143 deletions

View File

@ -23,6 +23,9 @@
"Immich", "Immich",
"jfif", "jfif",
"JOSN", "JOSN",
"makernote",
"Makernote",
"Makernotes",
"mmod", "mmod",
"Nicéphore", "Nicéphore",
"Niépce", "Niépce",
@ -32,6 +35,8 @@
"permyriad", "permyriad",
"Phares", "Phares",
"Phgtv", "Phgtv",
"photoshop",
"Photoshop",
"RDHC", "RDHC",
"Rects", "Rects",
"resnet", "resnet",

32
.vscode/tasks.json vendored
View File

@ -79,6 +79,38 @@
"--no-restore" "--no-restore"
], ],
"problemMatcher": "$msCompile" "problemMatcher": "$msCompile"
},
{
"label": "buildShared",
"command": "dotnet",
"type": "process",
"args": [
"build",
"${workspaceFolder}/Shared/View-by-Distance.Shared.csproj",
"/property:GenerateFullPaths=true",
"/consoleloggerparameters:NoSummary",
"/property:WarningLevel=0",
"--verbosity",
"quiet",
"--no-restore"
],
"problemMatcher": "$msCompile"
},
{
"label": "buildMetadata",
"command": "dotnet",
"type": "process",
"args": [
"build",
"${workspaceFolder}/Metadata/Metadata.csproj",
"/property:GenerateFullPaths=true",
"/consoleloggerparameters:NoSummary",
"/property:WarningLevel=0",
"--verbosity",
"quiet",
"--no-restore"
],
"problemMatcher": "$msCompile"
} }
] ]
} }

View File

@ -21,7 +21,7 @@ public class DistanceLimits : IDistanceLimits
int faceDistancePermyriad, int faceDistancePermyriad,
int[] rangeDaysDeltaTolerance, int[] rangeDaysDeltaTolerance,
float[] rangeDistanceTolerance, float[] rangeDistanceTolerance,
float[] rangeFaceAreaPermyriadTolerance, float[] rangeFaceAreaTolerance,
float[] rangeFaceConfidence, float[] rangeFaceConfidence,
int sortingMaximumPerFaceShouldBeHigh, int sortingMaximumPerFaceShouldBeHigh,
int? useFiltersCounter = null) int? useFiltersCounter = null)
@ -33,7 +33,7 @@ public class DistanceLimits : IDistanceLimits
{ {
RangeDaysDeltaTolerance = rangeDaysDeltaTolerance[1]; RangeDaysDeltaTolerance = rangeDaysDeltaTolerance[1];
FaceConfidencePercent = faceConfidencePercent * rangeFaceConfidence[1]; FaceConfidencePercent = faceConfidencePercent * rangeFaceConfidence[1];
FaceAreaPermyriad = faceAreaPermyriad * rangeFaceAreaPermyriadTolerance[1]; FaceAreaPermyriad = faceAreaPermyriad * rangeFaceAreaTolerance[1];
FaceDistancePermyriad = faceDistancePermyriad * rangeDistanceTolerance[1]; FaceDistancePermyriad = faceDistancePermyriad * rangeDistanceTolerance[1];
} }
else else
@ -41,7 +41,7 @@ public class DistanceLimits : IDistanceLimits
RangeDaysDeltaTolerance = ((rangeDaysDeltaTolerance[2] - rangeDaysDeltaTolerance[0]) * 0.01 * useFiltersCounter.Value) + rangeDaysDeltaTolerance[1]; RangeDaysDeltaTolerance = ((rangeDaysDeltaTolerance[2] - rangeDaysDeltaTolerance[0]) * 0.01 * useFiltersCounter.Value) + rangeDaysDeltaTolerance[1];
FaceConfidencePercent = faceConfidencePercent * ((rangeFaceConfidence[2] - rangeFaceConfidence[0]) * 0.01 * useFiltersCounter.Value) + rangeFaceConfidence[1]; FaceConfidencePercent = faceConfidencePercent * ((rangeFaceConfidence[2] - rangeFaceConfidence[0]) * 0.01 * useFiltersCounter.Value) + rangeFaceConfidence[1];
FaceDistancePermyriad = faceDistancePermyriad * ((rangeDistanceTolerance[2] - rangeDistanceTolerance[0]) * 0.01 * useFiltersCounter.Value) + rangeDistanceTolerance[1]; FaceDistancePermyriad = faceDistancePermyriad * ((rangeDistanceTolerance[2] - rangeDistanceTolerance[0]) * 0.01 * useFiltersCounter.Value) + rangeDistanceTolerance[1];
FaceAreaPermyriad = faceAreaPermyriad * ((rangeFaceAreaPermyriadTolerance[2] - rangeFaceAreaPermyriadTolerance[0]) * 0.01 * useFiltersCounter.Value) + rangeFaceAreaPermyriadTolerance[1]; FaceAreaPermyriad = faceAreaPermyriad * ((rangeFaceAreaTolerance[2] - rangeFaceAreaTolerance[0]) * 0.01 * useFiltersCounter.Value) + rangeFaceAreaTolerance[1];
} }
} }

View File

@ -113,7 +113,7 @@ public partial class DlibDotNet : IDlibDotNet, IDisposable
(ImageCodecInfo imageCodecInfo, EncoderParameters encoderParameters, string filenameExtension) = C_Resize.GetJpegLowQuality(); (ImageCodecInfo imageCodecInfo, EncoderParameters encoderParameters, string filenameExtension) = C_Resize.GetJpegLowQuality();
_FaceParts = new D2_FaceParts(_Configuration.PropertyConfiguration, imageCodecInfo, encoderParameters, filenameExtension, configuration.CheckDFaceAndUpWriteDates, configuration.OverrideForFaceLandmarkImages); _FaceParts = new D2_FaceParts(_Configuration.PropertyConfiguration, imageCodecInfo, encoderParameters, filenameExtension, configuration.CheckDFaceAndUpWriteDates, configuration.OverrideForFaceLandmarkImages);
} }
_DistanceLimits = new(_Configuration.FaceAreaPermyriad, _Configuration.FaceConfidencePercent, _Configuration.FaceDistancePermyriad, _Configuration.RangeDaysDeltaTolerance, _Configuration.RangeDistanceTolerance, _Configuration.RangeFaceAreaPermyriadTolerance, _Configuration.RangeFaceConfidence, _Configuration.SortingMaximumPerFaceShouldBeHigh); _DistanceLimits = new(_Configuration.FaceAreaPermyriad, _Configuration.FaceConfidencePercent, _Configuration.FaceDistancePermyriad, _Configuration.RangeDaysDeltaTolerance, _Configuration.RangeDistanceTolerance, _Configuration.RangeFaceAreaTolerance, _Configuration.RangeFaceConfidence, _Configuration.SortingMaximumPerFaceShouldBeHigh);
_MapConfiguration = Get(configuration, _DistanceLimits, _Faces.FileNameExtension, _Faces.HiddenFileNameExtension, _FaceParts.FileNameExtension); _MapConfiguration = Get(configuration, _DistanceLimits, _Faces.FileNameExtension, _Faces.HiddenFileNameExtension, _FaceParts.FileNameExtension);
_Distance = new(configuration.DistanceMoveUnableToMatch, configuration.DistanceRenameToMatch, configuration.FaceConfidencePercent, configuration.RangeDistanceTolerance, configuration.RectangleIntersectMinimums); _Distance = new(configuration.DistanceMoveUnableToMatch, configuration.DistanceRenameToMatch, configuration.FaceConfidencePercent, configuration.RangeDistanceTolerance, configuration.RectangleIntersectMinimums);
if (_PropertyRootExistedBefore || !_ArgZeroIsConfigurationRootDirectory) if (_PropertyRootExistedBefore || !_ArgZeroIsConfigurationRootDirectory)
@ -183,8 +183,8 @@ public partial class DlibDotNet : IDlibDotNet, IDisposable
throw new NullReferenceException(nameof(configuration.RangeDaysDeltaTolerance)); throw new NullReferenceException(nameof(configuration.RangeDaysDeltaTolerance));
if (configuration.RangeDistanceTolerance.Length != 3) if (configuration.RangeDistanceTolerance.Length != 3)
throw new NullReferenceException(nameof(configuration.RangeDistanceTolerance)); throw new NullReferenceException(nameof(configuration.RangeDistanceTolerance));
if (configuration.RangeFaceAreaPermyriadTolerance.Length != 3) if (configuration.RangeFaceAreaTolerance.Length != 3)
throw new NullReferenceException(nameof(configuration.RangeFaceAreaPermyriadTolerance)); throw new NullReferenceException(nameof(configuration.RangeFaceAreaTolerance));
if (configuration.RangeFaceConfidence.Length != 3) if (configuration.RangeFaceConfidence.Length != 3)
throw new NullReferenceException(nameof(configuration.RangeFaceConfidence)); throw new NullReferenceException(nameof(configuration.RangeFaceConfidence));
if (configuration.LocationContainerDistanceTolerance is null && !string.IsNullOrEmpty(configuration.LocationContainerDebugDirectory)) if (configuration.LocationContainerDistanceTolerance is null && !string.IsNullOrEmpty(configuration.LocationContainerDebugDirectory))
@ -929,7 +929,7 @@ public partial class DlibDotNet : IDlibDotNet, IDisposable
results = []; results = [];
else else
{ {
DistanceLimits distanceLimits = new(_Configuration.FaceAreaPermyriad, _Configuration.FaceConfidencePercent, _Configuration.FaceDistancePermyriad, _Configuration.RangeDaysDeltaTolerance, _Configuration.RangeDistanceTolerance, _Configuration.RangeFaceAreaPermyriadTolerance, _Configuration.RangeFaceConfidence, _Configuration.SortingMaximumPerFaceShouldBeHigh); DistanceLimits distanceLimits = new(_Configuration.FaceAreaPermyriad, _Configuration.FaceConfidencePercent, _Configuration.FaceDistancePermyriad, _Configuration.RangeDaysDeltaTolerance, _Configuration.RangeDistanceTolerance, _Configuration.RangeFaceAreaTolerance, _Configuration.RangeFaceConfidence, _Configuration.SortingMaximumPerFaceShouldBeHigh);
List<LocationContainer> postFiltered = E_Distance.GetPostFilterLocationContainer(mapLogic, preFiltered, distanceLimits); List<LocationContainer> postFiltered = E_Distance.GetPostFilterLocationContainer(mapLogic, preFiltered, distanceLimits);
if (postFiltered.Count == 0) if (postFiltered.Count == 0)
results = []; results = [];
@ -1385,7 +1385,7 @@ public partial class DlibDotNet : IDlibDotNet, IDisposable
ReadOnlyCollection<SortingContainer> sortingContainers; ReadOnlyCollection<SortingContainer> sortingContainers;
FaceDistanceContainer[] filteredFaceDistanceContainers; FaceDistanceContainer[] filteredFaceDistanceContainers;
long? skipOlderThan = _Configuration.SkipOlderThanDays is null ? null : new DateTime(ticks).AddDays(-_Configuration.SkipOlderThanDays.Value).Ticks; long? skipOlderThan = _Configuration.SkipOlderThanDays is null ? null : new DateTime(ticks).AddDays(-_Configuration.SkipOlderThanDays.Value).Ticks;
distanceLimits = new(_Configuration.FaceAreaPermyriad, _Configuration.FaceConfidencePercent, _Configuration.FaceDistancePermyriad, _Configuration.RangeDaysDeltaTolerance, _Configuration.RangeDistanceTolerance, _Configuration.RangeFaceAreaPermyriadTolerance, _Configuration.RangeFaceConfidence, _Configuration.SortingMaximumPerFaceShouldBeHigh); distanceLimits = new(_Configuration.FaceAreaPermyriad, _Configuration.FaceConfidencePercent, _Configuration.FaceDistancePermyriad, _Configuration.RangeDaysDeltaTolerance, _Configuration.RangeDistanceTolerance, _Configuration.RangeFaceAreaTolerance, _Configuration.RangeFaceConfidence, _Configuration.SortingMaximumPerFaceShouldBeHigh);
filteredFaceDistanceContainers = E_Distance.FilteredPostLoadFaceDistanceContainers(mapLogic, faceDistanceContainers, skipOlderThan, distanceLimits); filteredFaceDistanceContainers = E_Distance.FilteredPostLoadFaceDistanceContainers(mapLogic, faceDistanceContainers, skipOlderThan, distanceLimits);
if (filteredFaceDistanceContainers.Length == 0) if (filteredFaceDistanceContainers.Length == 0)
_Logger?.LogInformation("All images have been filtered!"); _Logger?.LogInformation("All images have been filtered!");
@ -1396,7 +1396,7 @@ public partial class DlibDotNet : IDlibDotNet, IDisposable
{ {
for (useFiltersCounter = 1; useFiltersCounter < _Configuration.UseFilterTries; useFiltersCounter++) for (useFiltersCounter = 1; useFiltersCounter < _Configuration.UseFilterTries; useFiltersCounter++)
{ {
distanceLimits = new(_Configuration.FaceAreaPermyriad, _Configuration.FaceConfidencePercent, _Configuration.FaceDistancePermyriad, _Configuration.RangeDaysDeltaTolerance, _Configuration.RangeDistanceTolerance, _Configuration.RangeFaceAreaPermyriadTolerance, _Configuration.RangeFaceConfidence, _Configuration.SortingMaximumPerFaceShouldBeHigh, useFiltersCounter); distanceLimits = new(_Configuration.FaceAreaPermyriad, _Configuration.FaceConfidencePercent, _Configuration.FaceDistancePermyriad, _Configuration.RangeDaysDeltaTolerance, _Configuration.RangeDistanceTolerance, _Configuration.RangeFaceAreaTolerance, _Configuration.RangeFaceConfidence, _Configuration.SortingMaximumPerFaceShouldBeHigh, useFiltersCounter);
filteredFaceDistanceContainers = E_Distance.FilteredPostLoadFaceDistanceContainers(mapLogic, faceDistanceContainers, skipOlderThan, distanceLimits); filteredFaceDistanceContainers = E_Distance.FilteredPostLoadFaceDistanceContainers(mapLogic, faceDistanceContainers, skipOlderThan, distanceLimits);
if (filteredFaceDistanceContainers.Length == 0) if (filteredFaceDistanceContainers.Length == 0)
_Logger?.LogInformation("All images have been filtered!"); _Logger?.LogInformation("All images have been filtered!");

View File

@ -64,7 +64,7 @@ public record Configuration(Property.Models.Configuration PropertyConfiguration,
int RadomUseBirthdayMinimum, int RadomUseBirthdayMinimum,
int[] RangeDaysDeltaTolerance, int[] RangeDaysDeltaTolerance,
float[] RangeDistanceTolerance, float[] RangeDistanceTolerance,
float[] RangeFaceAreaPermyriadTolerance, float[] RangeFaceAreaTolerance,
float[] RangeFaceConfidence, float[] RangeFaceConfidence,
float[] RectangleIntersectMinimums, float[] RectangleIntersectMinimums,
bool ReMap, bool ReMap,

View File

@ -264,7 +264,7 @@ public partial class MapLogic : Shared.Models.Methods.IMapLogic
{ {
List<string> personKeyFormattedCollection = []; List<string> personKeyFormattedCollection = [];
Dictionary<string, string> personKeyFormattedToNewestPersonKeyFormatted = []; Dictionary<string, string> personKeyFormattedToNewestPersonKeyFormatted = [];
Stateless.MapLogic.SetPersonCollections(configuration, personContainers, personKeyFormattedToNewestPersonKeyFormatted, personKeyFormattedCollection); Stateless.MapLogic.SetPersonCollectionsAfterSetSkipCollections(configuration, personContainers, personKeyFormattedToNewestPersonKeyFormatted, personKeyFormattedCollection);
readOnlyPersonKeyFormattedCollection = new(personKeyFormattedCollection); readOnlyPersonKeyFormattedCollection = new(personKeyFormattedCollection);
readOnlyPersonKeyFormattedToNewestPersonKeyFormatted = new(personKeyFormattedToNewestPersonKeyFormatted); readOnlyPersonKeyFormattedToNewestPersonKeyFormatted = new(personKeyFormattedToNewestPersonKeyFormatted);
} }
@ -1265,6 +1265,7 @@ public partial class MapLogic : Shared.Models.Methods.IMapLogic
{ {
if (_Configuration is null) if (_Configuration is null)
throw new NullReferenceException(nameof(_Configuration)); throw new NullReferenceException(nameof(_Configuration));
int? updated = null;
FileHolder fileHolder; FileHolder fileHolder;
SaveContainer? saveContainer; SaveContainer? saveContainer;
List<SaveContainer> saveContainers = []; List<SaveContainer> saveContainers = [];
@ -1277,7 +1278,7 @@ public partial class MapLogic : Shared.Models.Methods.IMapLogic
saveContainer = new(fileHolder, filteredOriginalImage.CheckFile, filteredOriginalImage.Directory); saveContainer = new(fileHolder, filteredOriginalImage.CheckFile, filteredOriginalImage.Directory);
saveContainers.Add(saveContainer); saveContainers.Add(saveContainer);
} }
SaveContainers(null, saveContainers); SaveContainers(updated, saveContainers);
} }
public void SaveShortcutsForOutputResolutionsPreMapLogic(string eDistanceContentDirectory, ReadOnlyDictionary<long, List<int>> personKeyToIds, ReadOnlyCollection<Mapping> distinctValidImageMappingCollection) public void SaveShortcutsForOutputResolutionsPreMapLogic(string eDistanceContentDirectory, ReadOnlyDictionary<long, List<int>> personKeyToIds, ReadOnlyCollection<Mapping> distinctValidImageMappingCollection)

View File

@ -64,21 +64,22 @@ internal abstract class FaceFileLogic
exifDirectory = Metadata.Models.Stateless.Methods.IMetadata.GetExifDirectory(mappedFile.FilePath); exifDirectory = Metadata.Models.Stateless.Methods.IMetadata.GetExifDirectory(mappedFile.FilePath);
RectangleF? rectangle = ILocation.GetPercentagesRectangle(configuration.LocationDigits, wholePercentages.Value); RectangleF? rectangle = ILocation.GetPercentagesRectangle(configuration.LocationDigits, wholePercentages.Value);
personDisplayDirectoryName = mappedFile.PersonDisplayDirectoryName is null ? configuration.MappingDefaultName : mappedFile.PersonDisplayDirectoryName; personDisplayDirectoryName = mappedFile.PersonDisplayDirectoryName is null ? configuration.MappingDefaultName : mappedFile.PersonDisplayDirectoryName;
LocationContainer locationContainer = new(dateOnly,
exifDirectory,
mappedFile.DirectoryNumber,
personDisplayDirectoryName,
null,
null,
mappedFile.FilePath,
fromDistanceContent,
id.Value,
null,
null,
mappedFile.PersonKey,
rectangle,
wholePercentages.Value);
lock (locationContainers) lock (locationContainers)
locationContainers.Add(new(dateOnly, locationContainers.Add(locationContainer);
exifDirectory,
mappedFile.DirectoryNumber,
personDisplayDirectoryName,
null,
null,
mappedFile.FilePath,
fromDistanceContent,
id.Value,
null,
null,
mappedFile.PersonKey,
rectangle,
wholePercentages.Value));
} }
private static ReadOnlyDictionary<int, ReadOnlyDictionary<int, LocationContainer>> GetReadOnly(Dictionary<int, Dictionary<int, LocationContainer>> keyValuePairs) private static ReadOnlyDictionary<int, ReadOnlyDictionary<int, LocationContainer>> GetReadOnly(Dictionary<int, Dictionary<int, LocationContainer>> keyValuePairs)
@ -93,33 +94,26 @@ internal abstract class FaceFileLogic
{ {
Dictionary<int, Dictionary<int, LocationContainer>> results = []; Dictionary<int, Dictionary<int, LocationContainer>> results = [];
List<LocationContainer> locationContainers = []; List<LocationContainer> locationContainers = [];
List<string> personKeyFormattedCollection = [];
Dictionary<int, LocationContainer>? keyValuePairs; Dictionary<int, LocationContainer>? keyValuePairs;
Dictionary<int, List<(string, int)>> skipCollection = []; Dictionary<int, List<(string, int)>> skipCollection = [];
Dictionary<int, List<(string, int)>> skipNotSkipCollection = []; Dictionary<int, List<(string, int)>> skipNotSkipCollection = [];
ReadOnlyCollection<string> readOnlyPersonKeyFormattedCollection; Dictionary<string, string> personKeyFormattedToNewestPersonKeyFormatted = [];
ReadOnlyDictionary<string, string> readOnlyPersonKeyFormattedToNewestPersonKeyFormatted;
SetSkipCollections(configuration, personContainers, a2PeopleSingletonDirectory, skipCollection, skipNotSkipCollection); SetSkipCollections(configuration, personContainers, a2PeopleSingletonDirectory, skipCollection, skipNotSkipCollection);
{ SetPersonCollectionsAfterSetSkipCollections(configuration, personContainers, personKeyFormattedToNewestPersonKeyFormatted, personKeyFormattedCollection);
List<string> personKeyFormattedCollection = []; List<Record> records = DistanceLogic.DeleteEmptyDirectoriesAndGetCollection(propertyConfiguration, configuration, ticks, eDistanceContentDirectory, personKeyFormattedToNewestPersonKeyFormatted.AsReadOnly(), personKeyFormattedCollection.AsReadOnly());
Dictionary<string, string> personKeyFormattedToNewestPersonKeyFormatted = [];
SetPersonCollections(configuration, personContainers, personKeyFormattedToNewestPersonKeyFormatted, personKeyFormattedCollection);
readOnlyPersonKeyFormattedCollection = new(personKeyFormattedCollection);
readOnlyPersonKeyFormattedToNewestPersonKeyFormatted = new(personKeyFormattedToNewestPersonKeyFormatted);
}
List<Record> records = DistanceLogic.DeleteEmptyDirectoriesAndGetCollection(propertyConfiguration, configuration, ticks, eDistanceContentDirectory, readOnlyPersonKeyFormattedToNewestPersonKeyFormatted, readOnlyPersonKeyFormattedCollection);
List<MappedFile> mappedFiles = GetMappedFiles(propertyConfiguration, configuration, personContainers, records); List<MappedFile> mappedFiles = GetMappedFiles(propertyConfiguration, configuration, personContainers, records);
if (mappedFiles.Count > 0) if (mappedFiles.Count > 0)
{ {
int totalSeconds = (int)Math.Floor(new TimeSpan(DateTime.Now.Ticks - ticks).TotalSeconds); int totalSeconds = (int)Math.Floor(new TimeSpan(DateTime.Now.Ticks - ticks).TotalSeconds);
string message = $") Building Mapped Face Files Collection - {totalSeconds} total second(s)"; string message = $") Building Mapped Face Files Collection - {totalSeconds} total second(s)";
ParallelOptions parallelOptions = new() { MaxDegreeOfParallelism = maxDegreeOfParallelism }; ParallelOptions parallelOptions = new() { MaxDegreeOfParallelism = maxDegreeOfParallelism };
ReadOnlyDictionary<int, List<(string, int)>> readOnlySkipNotSkipCollection = new(skipCollection);
ProgressBarOptions options = new() { ProgressCharacter = '─', ProgressBarOnBottom = true, DisableBottomPercentage = true }; ProgressBarOptions options = new() { ProgressCharacter = '─', ProgressBarOnBottom = true, DisableBottomPercentage = true };
using ProgressBar progressBar = new(mappedFiles.Count, message, options); using ProgressBar progressBar = new(mappedFiles.Count, message, options);
_ = Parallel.For(0, mappedFiles.Count, parallelOptions, (i, state) => _ = Parallel.For(0, mappedFiles.Count, parallelOptions, (i, state) =>
{ {
progressBar.Tick(); progressBar.Tick();
MappedParallelFor(propertyConfiguration, configuration, readOnlySkipNotSkipCollection, locationContainers, mappedFiles[i]); MappedParallelFor(propertyConfiguration, configuration, skipCollection.AsReadOnly(), locationContainers, mappedFiles[i]);
}); });
} }
foreach (LocationContainer locationContainer in locationContainers) foreach (LocationContainer locationContainer in locationContainers)
@ -176,21 +170,22 @@ internal abstract class FaceFileLogic
RectangleF? rectangle = ILocation.GetPercentagesRectangle(configuration.LocationDigits, wholePercentages.Value); RectangleF? rectangle = ILocation.GetPercentagesRectangle(configuration.LocationDigits, wholePercentages.Value);
if (rectangle is null) if (rectangle is null)
return; return;
LocationContainer locationContainer = new(dateOnly,
exifDirectory,
null,
null,
null,
faceFile,
filePath,
fromDistanceContent,
filePath.Id.Value,
null,
null,
null,
rectangle,
wholePercentages.Value);
lock (locationContainers) lock (locationContainers)
locationContainers.Add(new(dateOnly, locationContainers.Add(locationContainer);
exifDirectory,
null,
null,
null,
faceFile,
filePath,
fromDistanceContent,
filePath.Id.Value,
null,
null,
null,
rectangle,
wholePercentages.Value));
} }
internal static List<LocationContainer> GetAvailable(int maxDegreeOfParallelism, Configuration configuration, IFaceD dFace, long ticks, ReadOnlyCollection<FilePath> filePaths) internal static List<LocationContainer> GetAvailable(int maxDegreeOfParallelism, Configuration configuration, IFaceD dFace, long ticks, ReadOnlyCollection<FilePath> filePaths)

View File

@ -83,7 +83,7 @@ internal abstract class MapLogic
} }
} }
internal static void SetPersonCollections(Configuration configuration, ReadOnlyCollection<PersonContainer> personContainers, Dictionary<string, string> personKeyFormattedToNewestPersonKeyFormatted, List<string> personKeyFormattedCollection) internal static void SetPersonCollectionsAfterSetSkipCollections(Configuration configuration, ReadOnlyCollection<PersonContainer> personContainers, Dictionary<string, string> personKeyFormattedToNewestPersonKeyFormatted, List<string> personKeyFormattedCollection)
{ {
string personKeyFormatted; string personKeyFormatted;
string newestPersonKeyFormatted; string newestPersonKeyFormatted;
@ -418,7 +418,7 @@ internal abstract class MapLogic
if (check) if (check)
continue; continue;
personBirthday = IPersonBirthday.GetPersonBirthday(personKey + (oneHour * 2)); personBirthday = IPersonBirthday.GetPersonBirthday(personKey + (oneHour * 2));
personContainer = new(approximateYears, [personBirthday], new(personDisplayDirectoryAllFilePaths), configuration.MappingDefaultName, personKey); personContainer = PersonContainer.Get(approximateYears, [personBirthday], new(personDisplayDirectoryAllFilePaths), configuration.MappingDefaultName, personKey);
results.Add(personContainer); results.Add(personContainer);
if (results.Count > 99) if (results.Count > 99)
break; break;
@ -535,21 +535,22 @@ internal abstract class MapLogic
exifDirectory = Metadata.Models.Stateless.Methods.IMetadata.GetExifDirectory(mappedFile.FilePath); exifDirectory = Metadata.Models.Stateless.Methods.IMetadata.GetExifDirectory(mappedFile.FilePath);
RectangleF? rectangle = ILocation.GetPercentagesRectangle(configuration.LocationDigits, wholePercentages.Value); RectangleF? rectangle = ILocation.GetPercentagesRectangle(configuration.LocationDigits, wholePercentages.Value);
personDisplayDirectoryName = mappedFile.PersonDisplayDirectoryName is null ? configuration.MappingDefaultName : mappedFile.PersonDisplayDirectoryName; personDisplayDirectoryName = mappedFile.PersonDisplayDirectoryName is null ? configuration.MappingDefaultName : mappedFile.PersonDisplayDirectoryName;
LocationContainer locationContainer = new(dateOnly,
exifDirectory,
mappedFile.DirectoryNumber,
personDisplayDirectoryName,
null,
null,
mappedFile.FilePath,
fromDistanceContent,
id.Value,
null,
null,
mappedFile.PersonKey,
rectangle,
wholePercentages.Value);
lock (locationContainers) lock (locationContainers)
locationContainers.Add(new(dateOnly, locationContainers.Add(locationContainer);
exifDirectory,
mappedFile.DirectoryNumber,
personDisplayDirectoryName,
null,
null,
mappedFile.FilePath,
fromDistanceContent,
id.Value,
null,
null,
mappedFile.PersonKey,
rectangle,
wholePercentages.Value));
} }
private static void LookForPossibleDuplicates(Configuration configuration, ReadOnlyCollection<LocationContainer> locationContainers) private static void LookForPossibleDuplicates(Configuration configuration, ReadOnlyCollection<LocationContainer> locationContainers)
@ -739,7 +740,7 @@ internal abstract class MapLogic
group = IPerson.GetHourGroup(personKeyFormattedIdThenWholePercentages.PersonDisplayDirectoryName, personBirthday.Value.Hour); group = IPerson.GetHourGroup(personKeyFormattedIdThenWholePercentages.PersonDisplayDirectoryName, personBirthday.Value.Hour);
(status, sex, first) = IPerson.GetPersonHour(personKeyFormattedIdThenWholePercentages.PersonDisplayDirectoryName, personBirthday.Value.Hour); (status, sex, first) = IPerson.GetPersonHour(personKeyFormattedIdThenWholePercentages.PersonDisplayDirectoryName, personBirthday.Value.Hour);
personDirectory = new(matches.First(), group, status, sex, first); personDirectory = new(matches.First(), group, status, sex, first);
personContainer = new(configuration.PersonCharacters.ToArray(), personBirthday, personDisplayDirectoryName, personDirectory); personContainer = PersonContainer.Get(configuration.PersonCharacters.ToArray(), personBirthday, personDisplayDirectoryName, personDirectory);
personKeyFormattedToPersonContainer.Add(personKeyFormattedIdThenWholePercentages.PersonKeyFormatted, personContainer); personKeyFormattedToPersonContainer.Add(personKeyFormattedIdThenWholePercentages.PersonKeyFormatted, personContainer);
} }
if (personContainer.Key is null) if (personContainer.Key is null)
@ -839,9 +840,9 @@ internal abstract class MapLogic
continue; continue;
personBirthday = IPersonBirthday.GetPersonBirthday(keyValuePair.Key); personBirthday = IPersonBirthday.GetPersonBirthday(keyValuePair.Key);
if (!personKeyToPersonContainerCollection.TryGetValue(keyValuePair.Key, out collection)) if (!personKeyToPersonContainerCollection.TryGetValue(keyValuePair.Key, out collection))
personContainer = new(approximateYears, personBirthday, displayDirectoryName, keyValuePair.Key); personContainer = PersonContainer.Get(approximateYears, personBirthday, displayDirectoryName, keyValuePair.Key);
else else
personContainer = new(approximateYears, personBirthday, collection[zero].PersonDirectory, displayDirectoryName, keyValuePair.Key); personContainer = PersonContainer.Get(approximateYears, personBirthday, collection[zero].PersonDirectory, displayDirectoryName, keyValuePair.Key);
personKeyToPersonContainer.Add(keyValuePair.Key, personContainer); personKeyToPersonContainer.Add(keyValuePair.Key, personContainer);
} }
} }

View File

@ -502,12 +502,12 @@ internal abstract class Exif
result = new(aviDirectories, result = new(aviDirectories,
exifBaseDirectories, exifBaseDirectories,
fileMetadataDirectories, fileMetadataDirectories,
filePath,
gifHeaderDirectories, gifHeaderDirectories,
gpsDirectories, gpsDirectories,
size?.Height, size?.Height,
jpegDirectories, jpegDirectories,
makernoteDirectories, makernoteDirectories,
filePath.Name,
photoshopDirectories, photoshopDirectories,
pngDirectories, pngDirectories,
quickTimeMovieHeaderDirectories, quickTimeMovieHeaderDirectories,

View File

@ -34,7 +34,7 @@
<SupportedPlatform Include="browser" /> <SupportedPlatform Include="browser" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="CliWrap" Version="3.6.7" /> <PackageReference Include="CliWrap" Version="3.7.0" />
<PackageReference Include="Humanizer.Core" Version="2.14.1" /> <PackageReference Include="Humanizer.Core" Version="2.14.1" />
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="9.0.0" /> <PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="9.0.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.UserSecrets" Version="9.0.0" /> <PackageReference Include="Microsoft.Extensions.Configuration.UserSecrets" Version="9.0.0" />

View File

@ -6,12 +6,12 @@ namespace View_by_Distance.Shared.Models;
public record ExifDirectory(AviDirectory[] AviDirectories, public record ExifDirectory(AviDirectory[] AviDirectories,
ExifDirectoryBase[] ExifBaseDirectories, ExifDirectoryBase[] ExifBaseDirectories,
FileMetadataDirectory[] FileMetadataDirectories, FileMetadataDirectory[] FileMetadataDirectories,
FilePath FilePath,
GifHeaderDirectory[] GifHeaderDirectories, GifHeaderDirectory[] GifHeaderDirectories,
GpsDirectory[] GpsDirectories, GpsDirectory[] GpsDirectories,
int? Height, int? Height,
JpegDirectory[] JpegDirectories, JpegDirectory[] JpegDirectories,
MakernoteDirectory[] MakernoteDirectories, MakernoteDirectory[] MakernoteDirectories,
string OriginalFileName,
PhotoshopDirectory[] PhotoshopDirectories, PhotoshopDirectory[] PhotoshopDirectories,
PngDirectory[] PngDirectories, PngDirectory[] PngDirectories,
QuickTimeMovieHeaderDirectory[] QuickTimeMovieHeaderDirectories, QuickTimeMovieHeaderDirectory[] QuickTimeMovieHeaderDirectories,

View File

@ -40,8 +40,14 @@ public record class FaceDistance : Properties.IFaceDistance
public override string ToString() public override string ToString()
{ {
string result = JsonSerializer.Serialize(this, new JsonSerializerOptions() { WriteIndented = true }); string result = JsonSerializer.Serialize(this, FaceDistanceSourceGenerationContext.Default.FaceDistance);
return result; return result;
} }
} }
[JsonSourceGenerationOptions(WriteIndented = true)]
[JsonSerializable(typeof(FaceDistance))]
internal partial class FaceDistanceSourceGenerationContext : JsonSerializerContext
{
}

View File

@ -3,23 +3,19 @@ using System.Text.Json.Serialization;
namespace View_by_Distance.Shared.Models; namespace View_by_Distance.Shared.Models;
public class PersonBirthday : Properties.IPersonBirthday public record PersonBirthday(DateTime Value)
{ {
protected readonly DateTime _Value; // {{1}}SingletonValue
public DateTime Value => _Value; // {{1}}SingletonValue
[JsonConstructor]
public PersonBirthday
(
DateTime value
) => _Value = value; // {{1}}SingletonValue
public override string ToString() public override string ToString()
{ {
string result = JsonSerializer.Serialize(this, new JsonSerializerOptions() { WriteIndented = true }); string result = JsonSerializer.Serialize(this, PersonBirthdaySourceGenerationContext.Default.PersonBirthday);
return result; return result;
} // ... }
} }
[JsonSourceGenerationOptions(WriteIndented = true, DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull)]
[JsonSerializable(typeof(PersonBirthday))]
public partial class PersonBirthdaySourceGenerationContext : JsonSerializerContext
{
}

View File

@ -4,53 +4,45 @@ using System.Text.Json.Serialization;
namespace View_by_Distance.Shared.Models; namespace View_by_Distance.Shared.Models;
public class PersonContainer : Properties.IPersonContainer public record PersonContainer(int? ApproximateYears,
PersonBirthday[]? Birthdays,
ReadOnlyCollection<FilePath> DisplayDirectoryAllFilePaths,
string DisplayDirectoryName,
long? Key,
PersonDirectory? PersonDirectory)
{ {
public int? ApproximateYears { init; get; }
public PersonBirthday[]? Birthdays { init; get; }
public ReadOnlyCollection<FilePath> DisplayDirectoryAllFilePaths { init; get; }
public string DisplayDirectoryName { init; get; }
public long? Key { init; get; }
public bool? KeyIsMaxBirthday { init; get; }
public PersonDirectory? PersonDirectory { init; get; }
[JsonConstructor]
public PersonContainer(int? approximateYears, PersonBirthday[]? birthdays, ReadOnlyCollection<FilePath> displayDirectoryAllFiles, string displayDirectoryName, long? key, PersonDirectory? personDirectory)
{
ApproximateYears = approximateYears;
Birthdays = birthdays;
DisplayDirectoryAllFilePaths = displayDirectoryAllFiles;
DisplayDirectoryName = displayDirectoryName;
Key = key;
PersonDirectory = personDirectory;
KeyIsMaxBirthday = birthdays is null || key is null ? null : key.Value == birthdays.First().Value.Ticks;
}
public PersonContainer(char[] personCharacters, PersonBirthday birthday, string displayDirectoryName, PersonDirectory personDirectory) :
this(Stateless.Methods.IAge.GetApproximateYears(personCharacters, displayDirectoryName), [birthday], new([]), displayDirectoryName, birthday.Value.Ticks, personDirectory)
{ }
public PersonContainer(int? approximateYears, PersonBirthday birthdays, string displayDirectoryName, long key) :
this(approximateYears, [birthdays], new([]), displayDirectoryName, key, null)
{ }
public PersonContainer(int? approximateYears, PersonBirthday birthdays, PersonDirectory? personDirectory, string displayDirectoryName, long key) :
this(approximateYears, [birthdays], new([]), displayDirectoryName, key, personDirectory)
{ }
public PersonContainer(int? approximateYears, ReadOnlyCollection<FilePath> displayDirectoryAllFiles, string displayDirectoryName, PersonDirectory? personDirectory) :
this(approximateYears, null, displayDirectoryAllFiles, displayDirectoryName, null, personDirectory)
{ }
public PersonContainer(int? approximateYears, PersonBirthday[]? birthdays, ReadOnlyCollection<FilePath> displayDirectoryAllFiles, string displayDirectoryName, long? key) :
this(approximateYears, birthdays, displayDirectoryAllFiles, displayDirectoryName, key, null)
{ }
public override string ToString() public override string ToString()
{ {
string result = JsonSerializer.Serialize(this, new JsonSerializerOptions() { WriteIndented = true }); string result = JsonSerializer.Serialize(this, PersonContainerSourceGenerationContext.Default.PersonContainer);
return result; return result;
} }
public static PersonContainer Get(int? approximateYears, PersonBirthday[]? birthdays, ReadOnlyCollection<FilePath> displayDirectoryAllFilePaths, string displayDirectoryName, long? key, PersonDirectory? personDirectory) =>
new(approximateYears, birthdays, displayDirectoryAllFilePaths, displayDirectoryName, key, personDirectory);
public static PersonContainer Get(char[] personCharacters, PersonBirthday birthday, string displayDirectoryName, PersonDirectory personDirectory) =>
new(Stateless.Methods.IAge.GetApproximateYears(personCharacters, displayDirectoryName), [birthday], new([]), displayDirectoryName, birthday.Value.Ticks, personDirectory);
public static PersonContainer Get(int? approximateYears, PersonBirthday birthdays, string displayDirectoryName, long key) =>
new(approximateYears, [birthdays], new([]), displayDirectoryName, key, null);
public static PersonContainer Get(int? approximateYears, PersonBirthday birthdays, PersonDirectory? personDirectory, string displayDirectoryName, long key) =>
new(approximateYears, [birthdays], new([]), displayDirectoryName, key, personDirectory);
public static PersonContainer Get(int? approximateYears, ReadOnlyCollection<FilePath> displayDirectoryAllFilePaths, string displayDirectoryName, PersonDirectory? personDirectory) =>
new(approximateYears, null, displayDirectoryAllFilePaths, displayDirectoryName, null, personDirectory);
public static PersonContainer Get(int? approximateYears, PersonBirthday[]? birthdays, ReadOnlyCollection<FilePath> displayDirectoryAllFilePaths, string displayDirectoryName, long? key) =>
new(approximateYears, birthdays, displayDirectoryAllFilePaths, displayDirectoryName, key, null);
public static bool? IsKeyIsMaxBirthday(PersonContainer personContainer) =>
personContainer.Birthdays is null || personContainer.Key is null ? null : personContainer.Key.Value == personContainer.Birthdays.First().Value.Ticks;
}
[JsonSourceGenerationOptions(WriteIndented = true, DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull)]
[JsonSerializable(typeof(PersonContainer))]
public partial class PersonContainerSourceGenerationContext : JsonSerializerContext
{
} }

View File

@ -1,4 +1,5 @@
using System.Text.Json; using System.Text.Json;
using System.Text.Json.Serialization;
namespace View_by_Distance.Shared.Models; namespace View_by_Distance.Shared.Models;
@ -7,8 +8,14 @@ public record PersonDirectory(char Char, string Group, char Status, char Sex, ch
public override string ToString() public override string ToString()
{ {
string result = JsonSerializer.Serialize(this, new JsonSerializerOptions() { WriteIndented = true }); string result = JsonSerializer.Serialize(this, PersonDirectorySourceGenerationContext.Default.PersonDirectory);
return result; return result;
} }
} }
[JsonSourceGenerationOptions(WriteIndented = true, DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull)]
[JsonSerializable(typeof(PersonDirectory))]
public partial class PersonDirectorySourceGenerationContext : JsonSerializerContext
{
}

View File

@ -95,11 +95,9 @@ internal abstract class PersonBirthday
foreach (string personKeyDirectory in personKeyDirectories) foreach (string personKeyDirectory in personKeyDirectories)
{ {
personKeyFormatted = Path.GetFileName(personKeyDirectory); personKeyFormatted = Path.GetFileName(personKeyDirectory);
if (!DateTime.TryParseExact(personKeyFormatted, "MM.dd.yyyy", CultureInfo.InvariantCulture, DateTimeStyles.None, out DateTime birthday)) if (DateTime.TryParseExact(personKeyFormatted, "MM.dd.yyyy", CultureInfo.InvariantCulture, DateTimeStyles.None, out DateTime birthday))
personBirthday = IPersonBirthday.GetPersonBirthday(personBirthdayFormat, personKeyFormatted);
else
// (personBirthday, personKeyFormatted) = Person.Get(personBirthdayFormat, personDisplayDirectory, personKeyDirectory, birthday);
continue; continue;
personBirthday = IPersonBirthday.GetPersonBirthday(personBirthdayFormat, personKeyFormatted);
if (personBirthday is null) if (personBirthday is null)
continue; continue;
if (!IPersonBirthday.IsCounterPersonBirthday(personBirthday) && ((!personKeyDirectory.Contains('#') && (personDisplayDirectoryName.Contains('~') || personDisplayDirectoryName.Contains('#'))) || (personKeyDirectory.Contains('#') && !personDisplayDirectoryName.Contains('#')))) if (!IPersonBirthday.IsCounterPersonBirthday(personBirthday) && ((!personKeyDirectory.Contains('#') && (personDisplayDirectoryName.Contains('~') || personDisplayDirectoryName.Contains('#'))) || (personKeyDirectory.Contains('#') && !personDisplayDirectoryName.Contains('#'))))

View File

@ -215,7 +215,7 @@ internal abstract class PersonContainer
else else
{ {
personDisplayDirectoryAllFilePaths = GetFilePaths(facesFileNameExtension, propertyConfiguration, personDisplayDirectory); personDisplayDirectoryAllFilePaths = GetFilePaths(facesFileNameExtension, propertyConfiguration, personDisplayDirectory);
personContainer = new(approximateYears, new(personDisplayDirectoryAllFilePaths), personDisplayDirectoryName, personDirectory); personContainer = Models.PersonContainer.Get(approximateYears, new(personDisplayDirectoryAllFilePaths), personDisplayDirectoryName, personDirectory);
results.Add(personContainer); results.Add(personContainer);
} }
} }

View File

@ -56,7 +56,7 @@ public record Configuration(Property.Models.Configuration PropertyConfiguration,
int RadomUseBirthdayMinimum, int RadomUseBirthdayMinimum,
int[] RangeDaysDeltaTolerance, int[] RangeDaysDeltaTolerance,
float[] RangeDistanceTolerance, float[] RangeDistanceTolerance,
float[] RangeFaceAreaPermyriadTolerance, float[] RangeFaceAreaTolerance,
float[] RangeFaceConfidence, float[] RangeFaceConfidence,
float[] RectangleIntersectMinimums, float[] RectangleIntersectMinimums,
bool Reverse, bool Reverse,

View File

@ -33,8 +33,8 @@
<PackageReference Include="Microsoft.Extensions.Configuration.UserSecrets" Version="9.0.0" /> <PackageReference Include="Microsoft.Extensions.Configuration.UserSecrets" Version="9.0.0" />
<PackageReference Include="Microsoft.Extensions.Hosting" Version="9.0.0" /> <PackageReference Include="Microsoft.Extensions.Hosting" Version="9.0.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.12.0" /> <PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.12.0" />
<PackageReference Include="MSTest.TestAdapter" Version="3.6.3" /> <PackageReference Include="MSTest.TestAdapter" Version="3.7.0" />
<PackageReference Include="MSTest.TestFramework" Version="3.6.3" /> <PackageReference Include="MSTest.TestFramework" Version="3.7.0" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\BlurHash\BlurHash.csproj" /> <ProjectReference Include="..\BlurHash\BlurHash.csproj" />

View File

@ -55,7 +55,7 @@ public record Configuration(Property.Models.Configuration PropertyConfiguration,
int RadomUseBirthdayMinimum, int RadomUseBirthdayMinimum,
int[] RangeDaysDeltaTolerance, int[] RangeDaysDeltaTolerance,
float[] RangeDistanceTolerance, float[] RangeDistanceTolerance,
float[] RangeFaceAreaPermyriadTolerance, float[] RangeFaceAreaTolerance,
float[] RangeFaceConfidence, float[] RangeFaceConfidence,
float[] RectangleIntersectMinimums, float[] RectangleIntersectMinimums,
bool Reverse, bool Reverse,

View File

@ -32,8 +32,8 @@
<PackageReference Include="Microsoft.Extensions.Configuration.UserSecrets" Version="9.0.0" /> <PackageReference Include="Microsoft.Extensions.Configuration.UserSecrets" Version="9.0.0" />
<PackageReference Include="Microsoft.Extensions.Hosting" Version="9.0.0" /> <PackageReference Include="Microsoft.Extensions.Hosting" Version="9.0.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.12.0" /> <PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.12.0" />
<PackageReference Include="MSTest.TestAdapter" Version="3.6.3" /> <PackageReference Include="MSTest.TestAdapter" Version="3.7.0" />
<PackageReference Include="MSTest.TestFramework" Version="3.6.3" /> <PackageReference Include="MSTest.TestFramework" Version="3.7.0" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\BlurHash\BlurHash.csproj" /> <ProjectReference Include="..\BlurHash\BlurHash.csproj" />

View File

@ -33,7 +33,7 @@
<SupportedPlatform Include="browser" /> <SupportedPlatform Include="browser" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="SkiaSharp" Version="2.88.9" /> <PackageReference Include="SkiaSharp" Version="3.116.1" />
<PackageReference Include="System.Drawing.Common" Version="8.0.10" /> <PackageReference Include="System.Drawing.Common" Version="8.0.10" />
<PackageReference Include="System.Text.Json" Version="9.0.0" /> <PackageReference Include="System.Text.Json" Version="9.0.0" />
</ItemGroup> </ItemGroup>