Can-remap

This commit is contained in:
Mike Phares 2023-09-06 23:51:28 -07:00
parent b2e2a66101
commit 8d759ccefd
21 changed files with 563 additions and 447 deletions

View File

@ -324,7 +324,7 @@ public partial class E_Distance : IDistance<MetadataExtractor.Directory>
_DuplicateMappedFaceFiles.Clear();
}
public static void SaveFaceDistances(Property.Models.Configuration configuration, SortingContainer[] sortingContainers)
public static void SaveFaceDistances(Property.Models.Configuration configuration, ReadOnlyCollection<SortingContainer> sortingContainers)
{
string eDistanceContentCollectionDirectory = IResult.GetResultsDateGroupDirectory(configuration, nameof(E_Distance), "([])");
if (!Directory.Exists(eDistanceContentCollectionDirectory))
@ -341,9 +341,13 @@ public partial class E_Distance : IDistance<MetadataExtractor.Directory>
List<Face> faces = new();
foreach (Face face in distinctFilteredFaces)
{
if (face.Mapping?.MappingFromFilter is null)
if (face.Mapping?.MappingFromFilterPre is null)
throw new NotSupportedException();
if (face.Mapping.MappingFromFilter.IsUsed is not null && face.Mapping.MappingFromFilter.IsUsed.Value && face.Mapping.MappingFromFilter.IsFocusPerson is not null && !face.Mapping.MappingFromFilter.IsFocusPerson.Value)
if (face.Mapping.MappingFromFilterPre.InSkipCollection is not null && face.Mapping.MappingFromFilterPre.InSkipCollection.Value)
continue;
if (face.Mapping.MappingFromFilterPre.IsFocusModel is not null && !face.Mapping.MappingFromFilterPre.IsFocusModel.Value)
continue;
if (face.Mapping.MappingFromFilterPre.IsFocusRelativePath is not null && !face.Mapping.MappingFromFilterPre.IsFocusRelativePath.Value)
continue;
if (face.FaceEncoding is not null && face.FaceDistance?.Encoding is not null && face.FaceDistance.Encoding is FaceRecognitionDotNet.FaceEncoding _)
continue;
@ -390,7 +394,7 @@ public partial class E_Distance : IDistance<MetadataExtractor.Directory>
distance += 1;
continue;
}
sortingContainer = new(face.Mapping, sorting);
sortingContainer = new(sorting, face.Mapping);
results.Add(sortingContainer);
if (results.Count >= distanceLimits.SortingMaximumPerFaceShouldBeHigh)
break;
@ -399,11 +403,11 @@ public partial class E_Distance : IDistance<MetadataExtractor.Directory>
return results;
}
private static List<Sorting> GetSortingCollection(Map.Models.MapLogic mapLogic, ReadOnlyCollection<FaceDistance> faceDistanceEncodings, int i, FaceDistance faceDistanceEncoding, Face face)
private static List<Sorting> GetSortingCollection(Map.Models.MapLogic mapLogic, ReadOnlyCollection<FaceDistance> faceDistanceEncodings, int i, Face face, FaceDistance faceDistanceEncoding)
{
List<Sorting> results;
List<FaceDistance> faceDistanceLengths = FaceRecognition.FaceDistances(faceDistanceEncodings, faceDistanceEncoding);
results = mapLogic.GetSortingCollection(i, faceDistanceEncoding, face, faceDistanceLengths);
results = mapLogic.GetSortingCollection(i, face, faceDistanceEncoding, faceDistanceLengths);
return results;
}
@ -427,7 +431,7 @@ public partial class E_Distance : IDistance<MetadataExtractor.Directory>
return results;
}
public static FaceDistanceContainer[] FilteredFaceDistanceContainers(Map.Models.MapLogic mapLogic, ReadOnlyCollection<FaceDistanceContainer> faceDistanceContainers, long? skipOlderThan, DistanceLimits distanceLimits)
public static FaceDistanceContainer[] FilteredPostLoadFaceDistanceContainers(Map.Models.MapLogic mapLogic, ReadOnlyCollection<FaceDistanceContainer> faceDistanceContainers, long? skipOlderThan, DistanceLimits distanceLimits)
{
List<FaceDistanceContainer> results = new();
foreach (FaceDistanceContainer faceDistanceContainer in faceDistanceContainers)
@ -440,23 +444,24 @@ public partial class E_Distance : IDistance<MetadataExtractor.Directory>
continue;
if (faceDistanceContainer.Face.Mapping.MappingFromLocation.AreaPermyriad < distanceLimits.FaceAreaPermyriad)
continue;
if (faceDistanceContainer.Face.Mapping.MappingFromFilter.IsUsed is not null && faceDistanceContainer.Face.Mapping.MappingFromFilter.IsUsed.Value)
if (faceDistanceContainer.Face.Mapping.MappingFromFilterPre.InSkipCollection is not null && faceDistanceContainer.Face.Mapping.MappingFromFilterPre.InSkipCollection.Value)
throw new NotSupportedException(nameof(PreFilterSetFaceDistances));
if (faceDistanceContainer.Face.Mapping.MappingFromFilterPre.IsFocusModel is not null && faceDistanceContainer.Face.Mapping.MappingFromFilterPre.IsFocusModel.Value)
throw new NotSupportedException(nameof(PreFilterSetFaceDistances));
if (faceDistanceContainer.Face.Mapping.MappingFromFilterPre.IsFocusRelativePath is not null && faceDistanceContainer.Face.Mapping.MappingFromFilterPre.IsFocusRelativePath.Value)
throw new NotSupportedException(nameof(PreFilterSetFaceDistances));
if (faceDistanceContainer.Face.Mapping.MappingFromFilterPost.InSkipCollection is not null && faceDistanceContainer.Face.Mapping.MappingFromFilterPost.InSkipCollection.Value)
continue;
if (faceDistanceContainer.Face.Mapping.MappingFromFilter.IsFocusPerson is not null && !faceDistanceContainer.Face.Mapping.MappingFromFilter.IsFocusPerson.Value)
continue;
if (faceDistanceContainer.Face.Mapping.MappingFromFilter.IsFocusModel is not null && !faceDistanceContainer.Face.Mapping.MappingFromFilter.IsFocusModel.Value)
continue;
if (faceDistanceContainer.Face.Mapping.MappingFromFilter.IsFocusRelativePath is not null && !faceDistanceContainer.Face.Mapping.MappingFromFilter.IsFocusRelativePath.Value)
if (faceDistanceContainer.Face.Mapping.MappingFromFilterPost.IsFocusPerson is not null && !faceDistanceContainer.Face.Mapping.MappingFromFilterPost.IsFocusPerson.Value)
continue;
results.Add(faceDistanceContainer);
}
return results.ToArray();
}
public static SortingContainer[] SetFaceMappingSortingCollectionThenGetSortingContainers(int maxDegreeOfParallelism, Map.Models.Configuration mapConfiguration, long ticks, Map.Models.MapLogic mapLogic, IDistanceLimits distanceLimits, ReadOnlyCollection<FaceDistance> faceDistanceEncodings, FaceDistanceContainer[] filteredFaceDistanceContainers)
public static ReadOnlyCollection<SortingContainer> SetFaceMappingSortingCollectionThenGetSortedSortingContainers(int maxDegreeOfParallelism, Map.Models.Configuration mapConfiguration, long ticks, Map.Models.MapLogic mapLogic, IDistanceLimits distanceLimits, ReadOnlyCollection<FaceDistance> faceDistanceEncodings, FaceDistanceContainer[] filteredFaceDistanceContainers)
{
SortingContainer[] results;
List<SortingContainer> collection = new();
List<SortingContainer> results = new();
int totalSeconds = (int)Math.Floor(new TimeSpan(DateTime.Now.Ticks - ticks).TotalSeconds);
ParallelOptions parallelOptions = new() { MaxDegreeOfParallelism = maxDegreeOfParallelism };
string message = $") {filteredFaceDistanceContainers.Length:000} Get Sorting Containers Then Set Face Mapping Sorting Collection - {totalSeconds} total second(s)";
@ -465,28 +470,23 @@ public partial class E_Distance : IDistance<MetadataExtractor.Directory>
_ = Parallel.For(0, filteredFaceDistanceContainers.Length, parallelOptions, (i, state) =>
{
progressBar.Tick();
FaceDistance faceDistanceEncoding = filteredFaceDistanceContainers[i].FaceDistance;
Face face = filteredFaceDistanceContainers[i].Face;
List<Sorting> sortingCollection = GetSortingCollection(mapLogic, faceDistanceEncodings, i, faceDistanceEncoding, face);
FaceDistance faceDistanceEncoding = filteredFaceDistanceContainers[i].FaceDistance;
List<Sorting> sortingCollection = GetSortingCollection(mapLogic, faceDistanceEncodings, i, face, faceDistanceEncoding);
if (sortingCollection.Count == 0)
return;
List<SortingContainer> sortingContainers = GetSortingContainers(mapConfiguration, distanceLimits, face, faceDistanceEncoding, sortingCollection);
if (sortingContainers.Count > 0)
{
lock (collection)
collection.AddRange(sortingContainers);
lock (results)
results.AddRange(sortingContainers);
}
});
if (collection.Count == 0)
results = Array.Empty<SortingContainer>();
if (distanceLimits is not null && distanceLimits.RangeDaysDeltaTargetLessThenUpper)
results = Shared.Models.Stateless.Methods.ISortingContainer.Sort(results);
else
{
if (distanceLimits.RangeDaysDeltaTargetLessThenUpper)
results = Shared.Models.Stateless.Methods.ISortingContainer.Sort(collection);
else
results = Shared.Models.Stateless.Methods.ISortingContainer.SortUsingDaysDelta(collection);
}
return results;
results = Shared.Models.Stateless.Methods.ISortingContainer.SortUsingDaysDelta(results);
return new(results);
}
private static void WriteVsCodeFiles(string eDistanceContentDirectory, string? displayDirectoryName, string directory)

View File

@ -338,7 +338,7 @@ public partial class DlibDotNet
}
_Distance.Clear();
ReadOnlyCollection<Shared.Models.Face> distinctFilteredFaces = Map.Models.Stateless.Methods.IMapLogic.GetFaces(distinctFilteredItems);
ReadOnlyCollection<Mapping> distinctFilteredMappingCollection = SetCreationTimeAndGetMappings(_Configuration.PropertyConfiguration, eDistanceContentDirectory, containers, mapLogic, distinctItems: true);
ReadOnlyCollection<Mapping> distinctFilteredMappingCollection = GetMappings(_Configuration.PropertyConfiguration, eDistanceContentDirectory, containers, mapLogic, distinctItems: true);
if (runToDoCollectionFirst)
{
string json = JsonSerializer.Serialize(distinctFilteredMappingCollection);
@ -556,7 +556,7 @@ public partial class DlibDotNet
}
}
private ReadOnlyCollection<Mapping> SetCreationTimeAndGetMappings(Property.Models.Configuration propertyConfiguration, string eDistanceContentDirectory, Container[] containers, MapLogic mapLogic, bool distinctItems)
private ReadOnlyCollection<Mapping> GetMappings(Property.Models.Configuration propertyConfiguration, string eDistanceContentDirectory, Container[] containers, MapLogic mapLogic, bool distinctItems)
{
ReadOnlyCollection<Mapping> results;
int count = 0;
@ -570,7 +570,6 @@ public partial class DlibDotNet
IEnumerable<Item> filteredItems;
MappingFromItem mappingFromItem;
List<Mapping> mappingCollection = new();
ReadOnlyCollection<string>? locationContainersFiles = null;
foreach (Container container in containers)
{
if (container.Items.Count == 0)
@ -600,15 +599,10 @@ public partial class DlibDotNet
continue;
anyValidFaces = true;
mappingCollection.Add(face.Mapping);
if (face.Mapping.MappingFromPerson is null || face.Mapping.MappingFromPerson.LocationContainersFiles.Count == 0)
continue;
Map.Models.Stateless.Methods.IMapLogic.SetCreationTime(face.Mapping.MappingFromItem, face.Mapping.MappingFromPerson);
if (_Configuration.MoveToDecade && _Configuration.LocationContainerDistanceTolerance is null)
Map.Models.Stateless.Methods.IMapLogic.MoveToDecade(propertyConfiguration, face.Mapping.MappingFromItem, face.Mapping.MappingFromPerson);
}
if (!anyValidFaces)
{
(mapping, notMapped) = GetMapping(mapLogic, locationContainersFiles, item, isFocusRelativePath, mappingFromItem);
(mapping, notMapped) = GetMappingAndUpdateMappingFromPerson(mapLogic, item, isFocusRelativePath, mappingFromItem);
mappingCollection.Add(mapping);
}
}
@ -728,7 +722,7 @@ public partial class DlibDotNet
if (_Configuration.SaveMappedForOutputResolutions.Contains(outputResolution))
mapLogic.SaveMapped(dFacesContentDirectory, d2FacePartsContentDirectory, d2FacePartsContentCollectionDirectory, personKeyToIds, distinctFilteredMappingCollection, idToWholePercentagesToMapping);
if (_Configuration.SaveFaceDistancesForOutputResolutions.Contains(outputResolution))
SaveFaceDistances(ticks, mapLogic, distinctFilteredFaces, distinctFilteredMappingCollection, dFacesContentDirectory, d2FacePartsContentDirectory, d2FacePartsContentCollectionDirectory, idToWholePercentagesToMapping);
SaveFaceDistances(ticks, mapLogic, distinctFilteredFaces, dFacesContentDirectory, d2FacePartsContentDirectory, d2FacePartsContentCollectionDirectory, idToWholePercentagesToMapping);
}
private bool? GetIsFocusModel(Shared.Models.Property? property)
@ -776,12 +770,11 @@ public partial class DlibDotNet
return result;
}
private int GetNotMappedCountAndSetMapping(MapLogic mapLogic, Item item, bool? isFocusRelativePath, ReadOnlyCollection<LocationContainer<MetadataExtractor.Directory>> locationContainers, MappingFromItem mappingFromItem, List<MappingFromPhotoPrism>? mappingFromPhotoPrismCollection, List<Shared.Models.Face> faces)
private int GetNotMappedCountAndUpdateMappingFromPersonThenSetMapping(MapLogic mapLogic, Item item, bool? isFocusRelativePath, ReadOnlyCollection<LocationContainer<MetadataExtractor.Directory>> locationContainers, MappingFromItem mappingFromItem, List<MappingFromPhotoPrism>? mappingFromPhotoPrismCollection, List<Shared.Models.Face> faces)
{
int result;
double? α;
int? eyeα;
bool? isUsed;
bool? canReMap;
bool? eyeReview;
Mapping mapping;
@ -792,12 +785,10 @@ public partial class DlibDotNet
bool? inSkipCollection;
int wholePercentRectangle;
string deterministicHashCodeKey;
MappingFromFilter mappingFromFilter;
MappingFromLocation? mappingFromLocation;
MappingFromFilterPre mappingFromFilterPre;
MappingFromFilterPost mappingFromFilterPost;
bool? isFocusModel = GetIsFocusModel(item.Property);
bool ignoreXMatches = _JLinkResolvedDirectories.Count > 0;
long[] jLinkResolvedPersonKeys = _JLinkResolvedDirectories.Select(l => l.PersonKey).ToArray();
ReadOnlyDictionary<int, ReadOnlyCollection<PersonContainer>>? wholePercentagesToPersonContainers;
ReadOnlyCollection<string> locationContainersFiles = new((from l in locationContainers select l.File).ToArray());
@ -807,13 +798,11 @@ public partial class DlibDotNet
if (item.Property?.Id is null || face.FaceEncoding is null || face.Location is null || face.OutputResolution is null)
{
canReMap = null;
isUsed = null;
isFocusPerson = null;
inSkipCollection = null;
mappingFromLocation = null;
mappingFromFilterPost = new(canReMap, inSkipCollection, isFocusPerson);
mappingFromFilterPre = new(inSkipCollection, isFocusModel, isFocusRelativePath);
mappingFromFilter = new(isFocusModel, isFocusPerson, isFocusRelativePath, inSkipCollection, isUsed);
}
else
{
@ -832,14 +821,11 @@ public partial class DlibDotNet
inSkipCollection = mapLogic.InSkipCollection(item.Property.Id.Value, mappingFromLocation);
mappingFromFilterPre = new(inSkipCollection, isFocusModel, isFocusRelativePath);
canReMap = Map.Models.Stateless.Methods.IMapLogic.CanReMap(jLinkResolvedPersonKeys, wholePercentagesToPersonContainers, mappingFromLocation);
isUsed = mapLogic.IsUsed(ignoreXMatches, item.Property.Id.Value, wholePercentagesToPersonContainers, mappingFromLocation);
isFocusPerson = mapLogic.IsFocusPersonOld(_Configuration.SkipPersonWithMoreThen, _JLinkResolvedDirectories, wholePercentagesToPersonContainers, mappingFromLocation);
mappingFromFilter = new(isFocusModel, isFocusPerson, isFocusRelativePath, inSkipCollection, isUsed);
isFocusPerson = mapLogic.IsFocusPerson(_Configuration.SkipPersonWithMoreThen, jLinkResolvedPersonKeys, wholePercentagesToPersonContainers, mappingFromLocation);
mappingFromFilterPost = new(canReMap, inSkipCollection, isFocusPerson);
}
mapping = new(mappingFromFilter, mappingFromFilterPost, mappingFromFilterPre, mappingFromItem, mappingFromLocation, mappingFromPhotoPrismCollection);
notMapped += mapLogic.UpdateMappingFromPerson(locationContainersFiles, wholePercentagesToPersonContainers, mapping);
mapping = new(mappingFromFilterPost, mappingFromFilterPre, mappingFromItem, mappingFromLocation, mappingFromPhotoPrismCollection);
notMapped += mapLogic.UpdateMappingFromPerson(wholePercentagesToPersonContainers, mapping);
face.SetMapping(mapping);
}
result = notMapped;
@ -862,6 +848,8 @@ public partial class DlibDotNet
configuration.PersonCharacters.ToArray(),
configuration.RangeDaysDeltaTolerance,
configuration.RangeDistanceTolerance,
configuration.ReMap,
configuration.SaveIndividually,
configuration.SaveSortingWithoutPerson,
configuration.SkipNotSkipDirectories,
configuration.SortingMaximumPerKey,
@ -872,10 +860,9 @@ public partial class DlibDotNet
return result;
}
private (Mapping, int) GetMapping(MapLogic mapLogic, ReadOnlyCollection<string>? locationContainersFiles, Item item, bool? isFocusRelativePath, MappingFromItem mappingFromItem)
private (Mapping, int) GetMappingAndUpdateMappingFromPerson(MapLogic mapLogic, Item item, bool? isFocusRelativePath, MappingFromItem mappingFromItem)
{
Mapping result;
bool? isUsed;
bool? canReMap;
int? eyeα = null;
bool? isFocusPerson;
@ -885,24 +872,20 @@ public partial class DlibDotNet
int faceAreaPermyriad = 0;
int wholePercentRectangle;
string deterministicHashCodeKey;
MappingFromFilter mappingFromFilter;
MappingFromLocation? mappingFromLocation;
MappingFromFilterPre mappingFromFilterPre;
MappingFromFilterPost mappingFromFilterPost;
bool? isFocusModel = GetIsFocusModel(item.Property);
bool ignoreXMatches = _JLinkResolvedDirectories.Count > 0;
long[] jLinkResolvedPersonKeys = _JLinkResolvedDirectories.Select(l => l.PersonKey).ToArray();
ReadOnlyDictionary<int, ReadOnlyCollection<PersonContainer>>? wholePercentagesToPersonContainers = mapLogic.GetWholePercentagesToPersonContainers(item.Property?.Id);
if (item.Property?.Id is null)
{
isUsed = null;
canReMap = null;
isFocusPerson = null;
inSkipCollection = null;
mappingFromLocation = null;
mappingFromFilterPost = new(canReMap, inSkipCollection, isFocusPerson);
mappingFromFilterPre = new(inSkipCollection, isFocusModel, isFocusRelativePath);
mappingFromFilter = new(isFocusModel, isFocusPerson, isFocusRelativePath, inSkipCollection, isUsed);
}
else
{
@ -912,14 +895,11 @@ public partial class DlibDotNet
inSkipCollection = mapLogic.InSkipCollection(item.Property.Id.Value, mappingFromLocation);
mappingFromFilterPre = new(inSkipCollection, isFocusModel, isFocusRelativePath);
canReMap = Map.Models.Stateless.Methods.IMapLogic.CanReMap(jLinkResolvedPersonKeys, wholePercentagesToPersonContainers, mappingFromLocation);
isUsed = mapLogic.IsUsed(ignoreXMatches, item.Property.Id.Value, wholePercentagesToPersonContainers, mappingFromLocation);
isFocusPerson = mapLogic.IsFocusPersonOld(_Configuration.SkipPersonWithMoreThen, _JLinkResolvedDirectories, wholePercentagesToPersonContainers, mappingFromLocation);
mappingFromFilter = new(isFocusModel, isFocusPerson, isFocusRelativePath, inSkipCollection, isUsed);
isFocusPerson = mapLogic.IsFocusPerson(_Configuration.SkipPersonWithMoreThen, jLinkResolvedPersonKeys, wholePercentagesToPersonContainers, mappingFromLocation);
mappingFromFilterPost = new(canReMap, inSkipCollection, isFocusPerson);
}
result = new(mappingFromFilter, mappingFromFilterPost, mappingFromFilterPre, mappingFromItem, mappingFromLocation, mappingFromPhotoPrismCollection: null);
int notMapped = mapLogic.UpdateMappingFromPerson(locationContainersFiles, wholePercentagesToPersonContainers, result);
result = new(mappingFromFilterPost, mappingFromFilterPre, mappingFromItem, mappingFromLocation, mappingFromPhotoPrismCollection: null);
int notMapped = mapLogic.UpdateMappingFromPerson(wholePercentagesToPersonContainers, result);
return (result, notMapped);
}
@ -998,6 +978,7 @@ public partial class DlibDotNet
throw new NullReferenceException(nameof(property));
item.SetResizedFileHolder(_Resize.FileNameExtension, resizedFileHolder);
MappingFromItem mappingFromItem = IMappingFromItem.GetMappingFromItem(containerDateTimes, item, resizedFileHolder);
Map.Models.Stateless.Methods.IMapLogic.SetCreationTimeMaybeMoveToDecade(_Configuration.PropertyConfiguration, _Configuration.MoveToDecade && _Configuration.LocationContainerDistanceTolerance is null, mappingFromItem, locationContainers);
(int metadataGroups, metadataCollection) = metadata.GetMetadataCollection(subFileTuples, parseExceptions, changesFrom, mappingFromItem);
if (_AppSettings.MaxDegreeOfParallelism < 2)
ticks = LogDelta(ticks, nameof(B_Metadata.GetMetadataCollection));
@ -1022,7 +1003,7 @@ public partial class DlibDotNet
faces = _Faces.GetFaces(outputResolution, dResultsFullGroupDirectory, subFileTuples, parseExceptions, property, mappingFromItem, outputResolutionToResize, locationContainers, mappingFromPhotoPrismCollection);
if (_AppSettings.MaxDegreeOfParallelism < 2)
ticks = LogDelta(ticks, nameof(D_Face.GetFaces));
result = GetNotMappedCountAndSetMapping(mapLogic, item, isFocusRelativePath, locationContainers, mappingFromItem, mappingFromPhotoPrismCollection, faces);
result = GetNotMappedCountAndUpdateMappingFromPersonThenSetMapping(mapLogic, item, isFocusRelativePath, locationContainers, mappingFromItem, mappingFromPhotoPrismCollection, faces);
List<(Shared.Models.Face, FileInfo?, string, bool Saved)> faceCollection = _Faces.SaveFaces(_FaceParts.FileNameExtension, dResultsFullGroupDirectory, subFileTuples, parseExceptions, mappingFromItem, faces);
if (_Configuration.CopyFacesAndSaveFaceLandmarkForOutputResolutions.Contains(outputResolution))
_FaceParts.CopyFacesAndSaveFaceLandmarkImage(facePartsCollectionDirectory, mappingFromItem, faceCollection);
@ -1069,7 +1050,6 @@ public partial class DlibDotNet
throw new NullReferenceException(nameof(_Log));
int result = 0;
int exceptionsCount = 0;
bool ignoreXMatches = _JLinkResolvedDirectories.Count > 0;
ParallelOptions parallelOptions = new() { MaxDegreeOfParallelism = maxDegreeOfParallelism };
DateTime[] containerDateTimes = Shared.Models.Stateless.Methods.IContainer.GetContainerDateTimes(filteredItems);
ProgressBarOptions options = new() { ProgressCharacter = '─', ProgressBarOnBottom = true, DisableBottomPercentage = true };
@ -1164,49 +1144,53 @@ public partial class DlibDotNet
return new(cResultsFullGroupDirectory, c2ResultsFullGroupDirectory, dResultsFullGroupDirectory, d2ResultsFullGroupDirectory);
}
private void SaveFaceDistances(long ticks, MapLogic mapLogic, ReadOnlyCollection<Mapping> mappingCollection, string dFacesContentDirectory, string d2FacePartsContentDirectory, string d2FacePartsContentCollectionDirectory, ReadOnlyDictionary<int, ReadOnlyDictionary<int, Mapping>> idToWholePercentagesToMapping, ReadOnlyCollection<FaceDistance> faceDistanceEncodings, ReadOnlyCollection<FaceDistanceContainer> faceDistanceContainers)
private void SaveFaceDistances(long ticks, MapLogic mapLogic, string dFacesContentDirectory, string d2FacePartsContentDirectory, string d2FacePartsContentCollectionDirectory, ReadOnlyDictionary<int, ReadOnlyDictionary<int, Mapping>> idToWholePercentagesToMapping, ReadOnlyCollection<FaceDistance> faceDistanceEncodings, ReadOnlyCollection<FaceDistanceContainer> faceDistanceContainers)
{
if (_Log is null)
throw new NullReferenceException(nameof(_Log));
int? useFiltersCounter = null;
DistanceLimits distanceLimits;
SortingContainer[] sortingContainers;
ReadOnlyCollection<SortingContainer> sortingContainers;
FaceDistanceContainer[] filteredFaceDistanceContainers;
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);
filteredFaceDistanceContainers = E_Distance.FilteredFaceDistanceContainers(mapLogic, faceDistanceContainers, skipOlderThan, distanceLimits);
filteredFaceDistanceContainers = E_Distance.FilteredPostLoadFaceDistanceContainers(mapLogic, faceDistanceContainers, skipOlderThan, distanceLimits);
if (filteredFaceDistanceContainers.Length == 0)
_Log.Information("All images have been filtered!");
else
{
sortingContainers = E_Distance.SetFaceMappingSortingCollectionThenGetSortingContainers(_AppSettings.MaxDegreeOfParallelism, _MapConfiguration, ticks, mapLogic, distanceLimits, faceDistanceEncodings, filteredFaceDistanceContainers);
if (sortingContainers.Length == 0)
sortingContainers = E_Distance.SetFaceMappingSortingCollectionThenGetSortedSortingContainers(_AppSettings.MaxDegreeOfParallelism, _MapConfiguration, ticks, mapLogic, distanceLimits, faceDistanceEncodings, filteredFaceDistanceContainers);
if (sortingContainers.Count == 0)
{
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);
filteredFaceDistanceContainers = E_Distance.FilteredFaceDistanceContainers(mapLogic, faceDistanceContainers, skipOlderThan, distanceLimits);
filteredFaceDistanceContainers = E_Distance.FilteredPostLoadFaceDistanceContainers(mapLogic, faceDistanceContainers, skipOlderThan, distanceLimits);
if (filteredFaceDistanceContainers.Length == 0)
_Log.Information("All images have been filtered!");
else
{
sortingContainers = E_Distance.SetFaceMappingSortingCollectionThenGetSortingContainers(_AppSettings.MaxDegreeOfParallelism, _MapConfiguration, ticks, mapLogic, distanceLimits, faceDistanceEncodings, filteredFaceDistanceContainers);
if (sortingContainers.Length == 0)
sortingContainers = E_Distance.SetFaceMappingSortingCollectionThenGetSortedSortingContainers(_AppSettings.MaxDegreeOfParallelism, _MapConfiguration, ticks, mapLogic, distanceLimits, faceDistanceEncodings, filteredFaceDistanceContainers);
if (sortingContainers.Count == 0)
break;
}
}
}
sortingContainers = mapLogic.GetFilterSortingContainers(dFacesContentDirectory, d2FacePartsContentDirectory, d2FacePartsContentCollectionDirectory, idToWholePercentagesToMapping, distanceLimits, sortingContainers);
if (sortingContainers.Count > 0)
E_Distance.SaveFaceDistances(_Configuration.PropertyConfiguration, sortingContainers);
if (filteredFaceDistanceContainers.Length > 0)
{
int updated = sortingContainers.Length == 0 ? 0 : mapLogic.UpdateFromSortingContainers(_Configuration.SaveIndividually, idToWholePercentagesToMapping, distanceLimits, sortingContainers);
List<SaveContainer> saveContainers = mapLogic.GetSaveContainers(_Configuration.SaveIndividually, dFacesContentDirectory, d2FacePartsContentDirectory, d2FacePartsContentCollectionDirectory, mappingCollection, idToWholePercentagesToMapping, useFiltersCounter, sortingContainers.Length > 0);
mapLogic.SaveContainers(_Configuration.SaveIndividually, updated, saveContainers);
int updated = sortingContainers.Count == 0 ? 0 : mapLogic.UpdateFromSortingContainers(dFacesContentDirectory, d2FacePartsContentDirectory, d2FacePartsContentCollectionDirectory, idToWholePercentagesToMapping, sortingContainers);
List<SaveContainer> saveContainers;
saveContainers = mapLogic.GetSaveContainers(dFacesContentDirectory, d2FacePartsContentDirectory, d2FacePartsContentCollectionDirectory, idToWholePercentagesToMapping, distanceLimits, useFiltersCounter, sortingContainers);
if (saveContainers.Count > 0)
mapLogic.SaveContainers(updated, saveContainers);
}
}
}
private void SaveFaceDistances(long ticks, MapLogic mapLogic, ReadOnlyCollection<Shared.Models.Face> distinctFilteredFaces, ReadOnlyCollection<Mapping> mappingCollection, string dFacesContentDirectory, string d2FacePartsContentDirectory, string d2FacePartsContentCollectionDirectory, ReadOnlyDictionary<int, ReadOnlyDictionary<int, Mapping>> idToWholePercentagesToMapping)
private void SaveFaceDistances(long ticks, MapLogic mapLogic, ReadOnlyCollection<Shared.Models.Face> distinctFilteredFaces, string dFacesContentDirectory, string d2FacePartsContentDirectory, string d2FacePartsContentCollectionDirectory, ReadOnlyDictionary<int, ReadOnlyDictionary<int, Mapping>> idToWholePercentagesToMapping)
{
E_Distance.PreFilterSetFaceDistances(_AppSettings.MaxDegreeOfParallelism, ticks, distinctFilteredFaces);
ReadOnlyCollection<FaceDistanceContainer> faceDistanceContainers = E_Distance.GetFaceDistanceContainers(distinctFilteredFaces);
@ -1219,7 +1203,7 @@ public partial class DlibDotNet
continue;
faceDistanceEncodings.Add(faceDistanceContainer.FaceDistance);
}
SaveFaceDistances(ticks, mapLogic, mappingCollection, dFacesContentDirectory, d2FacePartsContentDirectory, d2FacePartsContentCollectionDirectory, idToWholePercentagesToMapping, new(faceDistanceEncodings), faceDistanceContainers);
SaveFaceDistances(ticks, mapLogic, dFacesContentDirectory, d2FacePartsContentDirectory, d2FacePartsContentCollectionDirectory, idToWholePercentagesToMapping, new(faceDistanceEncodings), faceDistanceContainers);
}
}

View File

@ -66,6 +66,7 @@ public class Configuration
public float[]? RangeFaceAreaTolerance { get; set; }
public float[]? RangeFaceConfidence { get; set; }
public float[]? RectangleIntersectMinimums { get; set; }
public bool? ReMap { get; set; }
public bool? Reverse { get; set; }
public string[]? SaveBlurHashForOutputResolutions { get; set; }
public string[]? SaveFaceDistancesForOutputResolutions { get; set; }
@ -163,6 +164,7 @@ public class Configuration
// if (configuration?.RangeFaceAreaTolerance is null) throw new NullReferenceException(nameof(configuration.RangeFaceAreaTolerance));
// if (configuration?.RangeFaceConfidence is null) throw new NullReferenceException(nameof(configuration.RangeFaceConfidence));
// if (configuration?.RectangleIntersectMinimums is null) throw new NullReferenceException(nameof(configuration.RectangleIntersectMinimums));
if (configuration?.ReMap is null) throw new NullReferenceException(nameof(configuration.ReMap));
if (configuration?.Reverse is null) throw new NullReferenceException(nameof(configuration.Reverse));
// if (configuration?.SaveBlurHashForOutputResolutions is null) throw new NullReferenceException(nameof(configuration.SaveBlurHashForOutputResolutions));
// if (configuration?.SaveFaceDistancesForOutputResolutions is null) throw new NullReferenceException(nameof(configuration.SaveFaceDistancesForOutputResolutions));
@ -247,6 +249,7 @@ public class Configuration
configuration.RangeFaceAreaTolerance ?? Array.Empty<float>(),
configuration.RangeFaceConfidence ?? Array.Empty<float>(),
configuration.RectangleIntersectMinimums ?? Array.Empty<float>(),
configuration.ReMap.Value,
configuration.Reverse.Value,
configuration.SaveBlurHashForOutputResolutions ?? Array.Empty<string>(),
configuration.SaveFaceDistancesForOutputResolutions ?? Array.Empty<string>(),

View File

@ -60,6 +60,7 @@ public record Configuration(Property.Models.Configuration PropertyConfiguration,
float[] RangeFaceAreaPermyriadTolerance,
float[] RangeFaceConfidence,
float[] RectangleIntersectMinimums,
bool ReMap,
bool Reverse,
string[] SaveBlurHashForOutputResolutions,
string[] SaveFaceDistancesForOutputResolutions,

View File

@ -30,7 +30,6 @@ internal class F_Random
{
Dictionary<string, List<string>> results = new();
string key;
long personKey;
DateTime dateTime;
List<long>? personKeys;
List<string>? relativePaths;
@ -40,12 +39,11 @@ internal class F_Random
continue;
if (!idToPersonKeys.TryGetValue(mapping.MappingFromItem.Id, out personKeys))
continue;
if (Shared.Models.Stateless.Methods.IPersonBirthday.IsCounterPersonBirthday(mapping.MappingFromPerson.PersonBirthday))
if (Shared.Models.Stateless.Methods.IPersonBirthday.IsCounterPersonYear(mapping.MappingFromPerson.PersonKey))
continue;
if (!personKeys.Contains(mapping.MappingFromPerson.PersonBirthday.Value.Ticks))
if (!personKeys.Contains(mapping.MappingFromPerson.PersonKey))
continue;
personKey = mapping.MappingFromPerson.PersonBirthday.Value.Ticks;
dateTime = new(personKey);
dateTime = new(mapping.MappingFromPerson.PersonKey);
key = dateTime.ToString(dateFormat);
if (!results.TryGetValue(key, out relativePaths))
{

View File

@ -13,6 +13,8 @@ public record Configuration(bool DeletePossibleDuplicates,
char[] PersonCharacters,
int[] RangeDaysDeltaTolerance,
float[] RangeDistanceTolerance,
bool ReMap,
bool SaveIndividually,
bool SaveSortingWithoutPerson,
string[] SkipNotSkipDirectories,
int SortingMaximumPerKey,

View File

@ -1,9 +1,11 @@
using Humanizer;
using ShellProgressBar;
using System.Buffers;
using System.Collections.ObjectModel;
using System.Globalization;
using System.Text.Json;
using System.Text.RegularExpressions;
using View_by_Distance.Map.Models.Stateless.Methods;
using View_by_Distance.Shared.Models;
using View_by_Distance.Shared.Models.Stateless.Methods;
using WindowsShortcutFactory;
@ -13,26 +15,10 @@ namespace View_by_Distance.Map.Models;
public partial class MapLogic : Shared.Models.Methods.IMapLogic
{
private bool IsUsed(bool ignoreXMatches, int id, ReadOnlyDictionary<int, ReadOnlyCollection<PersonContainer>>? wholePercentagesToPersonContainers, int wholePercentages)
{
bool result;
List<int>? wholePercentagesCollection;
ReadOnlyCollection<PersonContainer>? personContainers;
result = _SkipCollection.TryGetValue(id, out wholePercentagesCollection) && wholePercentagesCollection.Contains(wholePercentages);
if (!result && wholePercentagesToPersonContainers is not null)
if (wholePercentagesToPersonContainers.TryGetValue(wholePercentages, out personContainers))
if (!ignoreXMatches || !personContainers.Any(l => IPerson.IsDefaultName(l)))
result = true;
return result;
}
public bool IsUsed(bool ignoreXMatches, int id, ReadOnlyDictionary<int, ReadOnlyCollection<PersonContainer>>? wholePercentagesToPersonContainers, MappingFromLocation mappingFromLocation) =>
IsUsed(ignoreXMatches, id, wholePercentagesToPersonContainers, mappingFromLocation.WholePercentages);
[GeneratedRegex("[\\\\,\\/,\\:,\\*,\\?,\\\",\\<,\\>,\\|]")]
private static partial Regex FileSystemSafe();
public void SaveContainers(bool saveIndividually, int? updated, List<SaveContainer> saveContainers)
public void SaveContainers(int? updated, List<SaveContainer> saveContainers)
{
if (_Configuration is null)
throw new NullReferenceException(nameof(_Configuration));
@ -79,7 +65,7 @@ public partial class MapLogic : Shared.Models.Methods.IMapLogic
}
else
continue;
if (saveIndividually)
if (_Configuration.SaveIndividually)
{
fileName = Path.GetFileName(checkFile);
if (distinct.Contains(fileName))
@ -89,7 +75,7 @@ public partial class MapLogic : Shared.Models.Methods.IMapLogic
if (File.Exists(checkFile))
continue;
File.Copy(sourceFile, checkFile);
if (saveIndividually)
if (_Configuration.SaveIndividually)
continue;
if (saveContainer.MakeAllHidden)
File.SetAttributes(checkFile, FileAttributes.Hidden);
@ -148,7 +134,6 @@ public partial class MapLogic : Shared.Models.Methods.IMapLogic
if (_Configuration is null)
throw new NullReferenceException(nameof(_Configuration));
int season;
long personKey;
string fileName;
string directory;
string weekOfYear;
@ -158,7 +143,7 @@ public partial class MapLogic : Shared.Models.Methods.IMapLogic
List<long>? personKeys;
string personKeyFormatted;
Calendar calendar = new CultureInfo("en-US").Calendar;
ReadOnlyDictionary<int, List<long>> idToPersonKeys = Stateless.Methods.IMapLogic.GetIdToPersonKeys(personKeyToIds);
ReadOnlyDictionary<int, List<long>> idToPersonKeys = IMapLogic.GetIdToPersonKeys(personKeyToIds);
foreach (Mapping mapping in mappingCollection)
{
dateTime = mapping.MappingFromItem.GetDateTimeOriginalThenMinimumDateTime();
@ -182,10 +167,9 @@ public partial class MapLogic : Shared.Models.Methods.IMapLogic
continue;
if (!idToPersonKeys.TryGetValue(mapping.MappingFromItem.Id, out personKeys))
continue;
personKey = mapping.MappingFromPerson.PersonBirthday.Value.Ticks;
if (!personKeys.Contains(mapping.MappingFromPerson.PersonBirthday.Value.Ticks))
if (!personKeys.Contains(mapping.MappingFromPerson.PersonKey))
continue;
personKeyFormatted = IPersonBirthday.GetFormatted(_Configuration.PersonBirthdayFormat, mapping.MappingFromPerson.PersonBirthday);
personKeyFormatted = IPersonBirthday.GetFormatted(_Configuration.PersonBirthdayFormat, mapping.MappingFromPerson.PersonKey);
directory = Path.Combine($"{eDistanceContentDirectory}---", "Person Key Shortcuts", personKeyFormatted, directoryName);
fileName = Path.Combine(directory, $"{mapping.MappingFromItem.ImageFileHolder.Name}.lnk");
results.Add(new(mapping.MappingFromItem.ImageFileHolder.FullName, directory, mapping.MappingFromItem.GetDateTimeOriginalThenMinimumDateTime(), fileName, description, MakeAllHidden: false));
@ -399,45 +383,32 @@ public partial class MapLogic : Shared.Models.Methods.IMapLogic
return new(result, wholePercentagesToPersonContainers);
}
public int UpdateMappingFromPerson(ReadOnlyCollection<string>? locationContainersFiles, ReadOnlyDictionary<int, ReadOnlyCollection<PersonContainer>>? wholePercentagesToPersonContainers, Mapping mapping)
public int UpdateMappingFromPerson(ReadOnlyDictionary<int, ReadOnlyCollection<PersonContainer>>? wholePercentagesToPersonContainers, Mapping mapping)
{
int result = 0;
long personKey;
if (mapping.MappingFromLocation is not null)
{
if (wholePercentagesToPersonContainers is null)
result += 1;
else
{
ReadOnlyCollection<PersonContainer>? personContainers;
if (!wholePercentagesToPersonContainers.TryGetValue(mapping.MappingFromLocation.WholePercentages, out personContainers))
result += 1;
else
{
const int zero = 0;
string mappingSegmentB;
PersonBirthday personBirthday;
ReadOnlyCollection<PersonContainer>? personContainers;
for (int i = 1; i < 2; i++)
{
if (mapping.MappingFromLocation is null)
continue;
if (wholePercentagesToPersonContainers is null)
{
if (mapping.MappingFromFilter.InSkipCollection is not null && mapping.MappingFromFilter.InSkipCollection.Value)
continue;
result += 1;
continue;
}
if (!wholePercentagesToPersonContainers.TryGetValue(mapping.MappingFromLocation.WholePercentages, out personContainers))
{
if (mapping.MappingFromFilter.InSkipCollection is not null && mapping.MappingFromFilter.InSkipCollection.Value)
continue;
result += 1;
continue;
}
foreach (PersonContainer personContainer in personContainers)
{
if (personContainer.Key is null || personContainer.Birthdays is null || personContainer.Birthdays.Length == 0)
continue;
personBirthday = personContainer.Birthdays[zero];
personKey = personBirthday.Value.Ticks;
mappingSegmentB = Stateless.MapLogic.GetMappingSegmentB(_Ticks, personBirthday, personContainer.ApproximateYears, mapping.MappingFromItem);
if (locationContainersFiles is null)
if (mapping.MappingFromPerson is null || mapping.MappingFromPerson.LocationContainersFiles.Count == 0)
locationContainersFiles = new(Array.Empty<string>());
else
locationContainersFiles = mapping.MappingFromPerson.LocationContainersFiles;
mapping.UpdateMappingFromPerson(locationContainersFiles, personContainer.ApproximateYears, personContainer.DisplayDirectoryName, personBirthday, mappingSegmentB);
mapping.UpdateMappingFromPerson(personContainer.ApproximateYears, personContainer.DisplayDirectoryName, personContainer.Key.Value, mappingSegmentB);
}
}
}
}
return result;
@ -498,6 +469,55 @@ public partial class MapLogic : Shared.Models.Methods.IMapLogic
return (ticks, directory);
}
private static bool PreAndPostContinue(Configuration configuration, ReadOnlyDictionary<int, ReadOnlyDictionary<int, Mapping>> idToWholePercentagesToMapping, Sorting sorting, Mapping mapping, Mapping keyMapping)
{
bool result = true;
if (result && mapping.MappingFromFilterPre.InSkipCollection is not null && mapping.MappingFromFilterPre.InSkipCollection.Value)
result = false;
if (result && mapping.MappingFromFilterPre.IsFocusModel is not null && !mapping.MappingFromFilterPre.IsFocusModel.Value)
result = false;
if (result && mapping.MappingFromFilterPre.IsFocusRelativePath is not null && !mapping.MappingFromFilterPre.IsFocusRelativePath.Value)
result = false;
if (result && mapping.MappingFromFilterPost.InSkipCollection is not null && mapping.MappingFromFilterPost.InSkipCollection.Value)
result = false;
if (result && mapping.MappingFromFilterPost.IsFocusPerson is not null && !mapping.MappingFromFilterPost.IsFocusPerson.Value)
result = false;
if (result && keyMapping.MappingFromFilterPost.CanReMap is not null && !configuration.ReMap)
result = false;
if (result && keyMapping.MappingFromFilterPost.CanReMap is not null && (!keyMapping.MappingFromFilterPost.CanReMap.Value || (mapping.MappingFromPerson is not null && IPerson.IsDefaultName(mapping.MappingFromPerson.DisplayDirectoryName))))
result = false;
if (result && keyMapping.MappingFromFilterPost.InSkipCollection is not null && keyMapping.MappingFromFilterPost.InSkipCollection.Value)
result = false;
if (result && keyMapping.MappingFromFilterPost.IsFocusPerson is not null && keyMapping.MappingFromFilterPost.IsFocusPerson.Value)
result = false;
return result;
}
private (string?, long?, string) Get(Configuration configuration, bool saveIndividually, string by, Mapping question, int padLeft)
{
long? ticks;
string? directory;
string personDirectory;
if (question.MappingFromPerson is null)
{
(ticks, directory) = GetDirectory(configuration, saveIndividually, padLeft, question.SegmentC, by, question.MappingFromItem);
personDirectory = directory is null ? string.Empty : Path.Combine(directory, $"X+{ticks}");
}
else
{
ticks = null;
string personKeyFormatted = IPersonBirthday.GetFormatted(configuration.PersonBirthdayFormat, question.MappingFromPerson.PersonKey);
if (string.IsNullOrEmpty(question.SegmentC))
directory = Path.Combine(_EDistanceContentTicksDirectory, by, personKeyFormatted, question.MappingFromPerson.SegmentB);
else if (saveIndividually)
directory = Path.Combine(_EDistanceContentTicksDirectory, by, question.SegmentC.PadLeft(padLeft, '0'), personKeyFormatted, question.MappingFromPerson.SegmentB);
else
directory = Path.Combine(_EDistanceContentTicksDirectory, by, personKeyFormatted, question.MappingFromPerson.SegmentB, question.SegmentC);
personDirectory = Path.Combine(directory, question.MappingFromPerson.DisplayDirectoryName, "lnk");
}
return (directory, ticks, personDirectory);
}
private List<SaveContainer> GetSaveContainers(string dFacesContentDirectory, string d2FacePartsContentDirectory, string d2FacePartsContentCollectionDirectory, ReadOnlyCollection<Mapping> mappingCollection, ReadOnlyDictionary<int, ReadOnlyDictionary<int, Mapping>> idToWholePercentagesToMapping, ReadOnlyDictionary<long, List<int>> personKeyToIds, int? useFiltersCounter, bool saveMapped, bool saveIndividually, bool sortingContainersAny)
{
if (_Configuration is null)
@ -506,20 +526,17 @@ public partial class MapLogic : Shared.Models.Methods.IMapLogic
string by;
long? ticks;
List<int>? ids;
long personKey;
bool isByMapping;
bool isBySorting;
Sorting? sorting;
string checkFile;
string? directory;
Mapping? question;
string shortcutFile;
Mapping? keyMapping;
string facesDirectory;
string? directoryName;
string personDirectory;
FileHolder faceFileHolder;
string facePartsDirectory;
string personKeyFormatted;
List<int> distinct = new();
SaveContainer? saveContainer;
FileHolder facePartsFileHolder;
FileHolder hiddenFaceFileHolder;
@ -530,82 +547,62 @@ public partial class MapLogic : Shared.Models.Methods.IMapLogic
{
if (mapping.MappingFromLocation is null)
continue;
directoryName = Path.GetDirectoryName(mapping.MappingFromItem.RelativePath);
if (directoryName is null)
throw new NotSupportedException();
if (mapping.MappingFromFilter.InSkipCollection is not null && mapping.MappingFromFilter.InSkipCollection.Value)
if (mapping.MappingFromFilterPre.InSkipCollection is not null && mapping.MappingFromFilterPre.InSkipCollection.Value)
continue;
if (mapping.MappingFromFilterPre.IsFocusModel is not null && !mapping.MappingFromFilterPre.IsFocusModel.Value)
continue;
if (mapping.MappingFromFilterPre.IsFocusRelativePath is not null && !mapping.MappingFromFilterPre.IsFocusRelativePath.Value)
continue;
if (mapping.MappingFromFilterPost.InSkipCollection is not null && mapping.MappingFromFilterPost.InSkipCollection.Value)
continue;
if (mapping.MappingFromFilterPost.IsFocusPerson is not null && !mapping.MappingFromFilterPost.IsFocusPerson.Value)
continue;
(by, isByMapping, isBySorting) = Stateless.MapLogic.Get(useFiltersCounter, saveIndividually, sortingContainersAny, forceSingleImageHumanized, mapping);
if (isByMapping && !saveMapped)
continue;
if (mapping.MappingFromPerson is null)
{
if (!_Configuration.SaveSortingWithoutPerson)
continue;
if (mapping.SortingContainer is null)
{
if (sortingContainersAny)
continue;
mapping.UpdateMappingFromUnknownPerson(saveIndividually, new(mapping, new(mapping, mapping.MappingFromLocation)));
if (mapping.SortingContainer is null)
continue;
}
if (distinct.Contains(mapping.MappingFromItem.Id))
continue;
if (distinct.Contains(mapping.SortingContainer.Sorting.Id))
continue;
(ticks, directory) = GetDirectory(_Configuration, saveIndividually, padLeft, mapping.SegmentC, by, mapping.MappingFromItem);
if (ticks is null || string.IsNullOrEmpty(directory))
continue;
personDirectory = Path.Combine(directory, $"X+{ticks}");
if (saveIndividually)
{
directory = Path.Combine(directory, mapping.MappingFromItem.Id.ToString());
results.Add(new(Path.Combine(directory, $"X+{ticks}")));
}
distinct.Add(mapping.MappingFromItem.Id);
distinct.Add(mapping.SortingContainer.Sorting.Id);
}
if (!isBySorting || mapping.SortingContainer is null)
(sorting, question) = (null, null);
else
{
if (string.IsNullOrEmpty(mapping.MappingFromPerson.SegmentB))
sorting = mapping.SortingContainer.Sorting;
if (!idToWholePercentagesToMapping.TryGetValue(sorting.Id, out wholePercentagesToMapping))
throw new NotSupportedException();
if (string.IsNullOrEmpty(mapping.MappingFromPerson.DisplayDirectoryName))
if (!wholePercentagesToMapping.TryGetValue(sorting.WholePercentages, out question))
throw new NotSupportedException();
personKey = mapping.MappingFromPerson.PersonBirthday.Value.Ticks;
personKeyFormatted = IPersonBirthday.GetFormatted(_Configuration.PersonBirthdayFormat, mapping.MappingFromPerson.PersonBirthday);
if (string.IsNullOrEmpty(mapping.SegmentC))
directory = Path.Combine(_EDistanceContentTicksDirectory, by, personKeyFormatted, mapping.MappingFromPerson.SegmentB);
else if (saveIndividually)
directory = Path.Combine(_EDistanceContentTicksDirectory, by, mapping.SegmentC.PadLeft(padLeft, '0'), personKeyFormatted, mapping.MappingFromPerson.SegmentB);
else
directory = Path.Combine(_EDistanceContentTicksDirectory, by, personKeyFormatted, mapping.MappingFromPerson.SegmentB, mapping.SegmentC);
if (isByMapping)
personDirectory = Path.Combine(directory, mapping.MappingFromPerson.DisplayDirectoryName);
else if (mapping.By is not null)
personDirectory = Path.Combine(directory, mapping.MappingFromPerson.DisplayDirectoryName, "lnk");
else
personDirectory = Path.Combine(directory, mapping.MappingFromPerson.DisplayDirectoryName[..1], "lnk");
if (!PreAndPostContinue(_Configuration, idToWholePercentagesToMapping, sorting, mapping, question))
continue;
}
(directory, ticks, personDirectory) = Get(_Configuration, saveIndividually, by, mapping, padLeft);
if (string.IsNullOrEmpty(directory))
throw new NotSupportedException();
if (mapping.MappingFromPerson is not null)
{
if (saveIndividually)
{
directory = Path.Combine(directory, mapping.MappingFromItem.Id.ToString());
results.Add(new(Path.Combine(directory, mapping.MappingFromPerson.DisplayDirectoryName)));
}
if (isByMapping && personKeyToIds.TryGetValue(personKey, out ids))
if (isByMapping && personKeyToIds.TryGetValue(mapping.MappingFromPerson.PersonKey, out ids))
results.Add(new(Path.Combine(directory, mapping.MappingFromPerson.DisplayDirectoryName, $"{ids.Count} Face(s)")));
}
results.Add(new(personDirectory));
if (!isBySorting || mapping.SortingContainer is null)
keyMapping = null;
else
{
if (!idToWholePercentagesToMapping.TryGetValue(mapping.SortingContainer.Sorting.Id, out wholePercentagesToMapping))
if (!_Configuration.SaveSortingWithoutPerson)
continue;
if (!wholePercentagesToMapping.TryGetValue(mapping.SortingContainer.Sorting.WholePercentages, out keyMapping))
if (ticks is null)
continue;
if (keyMapping.MappingFromLocation is null)
if (saveIndividually)
{
directory = Path.Combine(directory, mapping.MappingFromItem.Id.ToString());
results.Add(new(Path.Combine(directory, $"X+{ticks}")));
}
}
results.Add(new(personDirectory));
if (question is not null)
{
if (question.MappingFromLocation is null)
continue;
if (saveIndividually && keyMapping.MappingFromLocation.WholePercentages == mapping.MappingFromLocation.WholePercentages)
if (saveIndividually && question.MappingFromLocation.WholePercentages == mapping.MappingFromLocation.WholePercentages)
results.Add(new(Path.Combine(directory, "Maybe")));
}
facesDirectory = Stateless.MapLogic.GetFacesDirectory(_PropertyConfiguration, dFacesContentDirectory, mapping.MappingFromItem);
@ -633,43 +630,12 @@ public partial class MapLogic : Shared.Models.Methods.IMapLogic
hiddenFaceFileHolder = new(Path.Combine(facesDirectory, $"{mapping.MappingFromLocation.DeterministicHashCodeKey}{mapping.MappingFromItem.ImageFileHolder.ExtensionLowered}{_Configuration.FacesHiddenFileNameExtension}"));
facePartsFileHolder = new(Path.Combine(facePartsDirectory, $"{mapping.MappingFromLocation.DeterministicHashCodeKey}{mapping.MappingFromItem.ImageFileHolder.ExtensionLowered}{_Configuration.FacePartsFileNameExtension}"));
saveContainer = new(checkFile, directory, faceFileHolder, hiddenFaceFileHolder, facePartsFileHolder, mapping.MappingFromItem.ResizedFileHolder, shortcutFile);
if (!isByMapping && mapping.By is not null && mapping.MappingFromPerson?.LocationContainersFiles.Count > 0 && IPerson.IsDefaultName(mapping.MappingFromPerson))
results.Add(new(Path.GetDirectoryName(personDirectory) ?? personDirectory, mapping.MappingFromPerson.LocationContainersFiles[0]));
}
results.Add(saveContainer);
if (!isBySorting || mapping.SortingContainer is null || keyMapping is null)
continue;
if (!saveIndividually && isBySorting && mapping.MappingFromPerson is null)
{
saveContainer = GetMatchSaveContainer(dFacesContentDirectory, d2FacePartsContentDirectory, directory, keyMapping);
if (saveContainer is not null)
results.Add(saveContainer);
}
if (!saveIndividually)
saveContainer = Stateless.MapLogic.GetDebugSaveContainer(directory, mapping.MappingFromPerson, mapping.SortingContainer, keyMapping);
else
{
(saveContainer, SaveContainer? extraSaveContainer) = Stateless.MapLogic.GetContainers(_Configuration.FacesFileNameExtension, _Configuration.FacePartsFileNameExtension, _PropertyConfiguration, dFacesContentDirectory, d2FacePartsContentCollectionDirectory, directory, mapping.SortingContainer, keyMapping);
if (saveContainer is null || extraSaveContainer is null)
continue;
results.Add(extraSaveContainer);
}
results.Add(saveContainer);
}
return results;
}
public List<SaveContainer> GetSaveContainers(bool saveIndividually, string dFacesContentDirectory, string d2FacePartsContentDirectory, string d2FacePartsContentCollectionDirectory, ReadOnlyCollection<Mapping> mappingCollection, ReadOnlyDictionary<int, ReadOnlyDictionary<int, Mapping>> idToWholePercentagesToMapping, int? useFiltersCounter, bool sortingContainersAny)
{
if (_Configuration is null)
throw new NullReferenceException(nameof(_Configuration));
List<SaveContainer> results;
bool saveMapped = false;
ReadOnlyDictionary<long, List<int>> personKeyToIds = new(new Dictionary<long, List<int>>());
results = GetSaveContainers(dFacesContentDirectory, d2FacePartsContentDirectory, d2FacePartsContentCollectionDirectory, mappingCollection, idToWholePercentagesToMapping, personKeyToIds, useFiltersCounter, saveMapped, saveIndividually, sortingContainersAny);
return results;
}
public void SaveMapped(string dFacesContentDirectory, string d2FacePartsContentDirectory, string d2FacePartsContentCollectionDirectory, ReadOnlyDictionary<long, List<int>> personKeyToIds, ReadOnlyCollection<Mapping> mappingCollection, ReadOnlyDictionary<int, ReadOnlyDictionary<int, Mapping>> idToWholePercentagesToMapping)
{
if (_Configuration is null)
@ -677,42 +643,55 @@ public partial class MapLogic : Shared.Models.Methods.IMapLogic
int? updated = null;
bool saveMapped = true;
int? useFiltersCounter = null;
bool saveIndividually = false;
string mappingDirectory = Path.Combine(_EDistanceContentTicksDirectory, nameof(Shared.Models.Stateless.IMapLogic.Mapping));
List<SaveContainer> saveContainers = GetSaveContainers(dFacesContentDirectory, d2FacePartsContentDirectory, d2FacePartsContentCollectionDirectory, mappingCollection, idToWholePercentagesToMapping, personKeyToIds, useFiltersCounter, saveMapped, sortingContainersAny: true, saveIndividually: false);
SaveContainers(saveIndividually, updated, saveContainers);
SaveContainers(updated, saveContainers);
if (!string.IsNullOrEmpty(_EDistanceContentTicksDirectory) && Directory.Exists(mappingDirectory))
Stateless.MapLogic.SaveMappingShortcuts(mappingDirectory);
}
public List<Sorting> GetSortingCollection(int i, FaceDistance faceDistanceEncoding, Face face, List<FaceDistance> faceDistanceLengths)
public List<Sorting> GetSortingCollection(int i, Face face, FaceDistance faceDistanceEncoding, List<FaceDistance> faceDistanceLengths)
{
if (_Configuration is null)
throw new NullReferenceException(nameof(_Configuration));
List<Sorting> results = new();
Sorting sorting;
FaceDistance faceDistanceLength;
List<int>? wholePercentagesCollection;
bool skipNotSkipCollectionAny = _SkipNotSkipCollection.Count > 0;
for (int j = 0; j < faceDistanceLengths.Count; j++)
{
if (faceDistanceEncoding.WholePercentages is null)
throw new NotSupportedException();
if (face.Mapping?.MappingFromFilter is null)
if (face.Mapping?.MappingFromFilterPost is null)
throw new NotSupportedException();
if (j == i)
continue;
if (faceDistanceEncoding.Id is not null && _SkipCollection.TryGetValue(faceDistanceEncoding.Id.Value, out wholePercentagesCollection) && wholePercentagesCollection.Contains(faceDistanceEncoding.WholePercentages.Value))
continue;
if (faceDistanceEncoding.Id is not null && skipNotSkipCollectionAny && (!_SkipNotSkipCollection.TryGetValue(faceDistanceEncoding.Id.Value, out wholePercentagesCollection) || !wholePercentagesCollection.Contains(faceDistanceEncoding.WholePercentages.Value)))
continue;
if (face.Mapping.MappingFromFilter.IsUsed is not null && face.Mapping.MappingFromFilter.IsUsed.Value)
continue;
if (face.Mapping.MappingFromFilterPre.InSkipCollection is not null && face.Mapping.MappingFromFilterPre.InSkipCollection.Value)
throw new NotSupportedException(nameof(Shared.Models.Methods.IDistance<object>));
if (face.Mapping.MappingFromFilterPre.IsFocusModel is not null && face.Mapping.MappingFromFilterPre.IsFocusModel.Value)
throw new NotSupportedException(nameof(Shared.Models.Methods.IDistance<object>));
if (face.Mapping.MappingFromFilterPre.IsFocusRelativePath is not null && face.Mapping.MappingFromFilterPre.IsFocusRelativePath.Value)
throw new NotSupportedException(nameof(Shared.Models.Methods.IDistance<object>));
if (face.Mapping.MappingFromFilterPost.InSkipCollection is not null && face.Mapping.MappingFromFilterPost.InSkipCollection.Value)
throw new NotSupportedException(nameof(Shared.Models.Methods.IDistance<object>));
if (face.Mapping.MappingFromFilterPost.IsFocusPerson is not null && !face.Mapping.MappingFromFilterPost.IsFocusPerson.Value)
throw new NotSupportedException(nameof(Shared.Models.Methods.IDistance<object>));
if (face.Mapping.MappingFromFilterPost.InSkipCollection is not null && face.Mapping.MappingFromFilterPost.InSkipCollection.Value)
throw new NotSupportedException(nameof(Shared.Models.Methods.IDistance<object>));
faceDistanceLength = faceDistanceLengths[j];
if (faceDistanceLength.WholePercentages is null || faceDistanceLength.Length is null)
throw new NotSupportedException();
if (faceDistanceLength.Length == 0)
continue;
if (faceDistanceLength.MappingFromFilterPost is null)
throw new NotSupportedException();
if (faceDistanceLength.MappingFromFilterPost.CanReMap is not null && !_Configuration.ReMap)
continue;
if (faceDistanceLength.MappingFromFilterPost.CanReMap is not null && !faceDistanceLength.MappingFromFilterPost.CanReMap.Value)
continue;
if (faceDistanceLength.MappingFromFilterPost.InSkipCollection is not null && faceDistanceLength.MappingFromFilterPost.InSkipCollection.Value)
continue;
if (faceDistanceLength.MappingFromFilterPost.IsFocusPerson is not null && !faceDistanceLength.MappingFromFilterPost.IsFocusPerson.Value)
continue;
sorting = ISorting.Get(_Configuration.FaceDistancePermyriad, faceDistanceEncoding, faceDistanceLength);
if (sorting.DistancePermyriad == 0)
continue;
@ -727,7 +706,49 @@ public partial class MapLogic : Shared.Models.Methods.IMapLogic
return results;
}
public int UpdateFromSortingContainers(bool saveIndividually, ReadOnlyDictionary<int, ReadOnlyDictionary<int, Mapping>> idToWholePercentagesToMapping, Shared.Models.Methods.IDistanceLimits distanceLimits, SortingContainer[] sortingContainers)
public int UpdateFromSortingContainers(string dFacesContentDirectory, string d2FacePartsContentDirectory, string d2FacePartsContentCollectionDirectory, ReadOnlyDictionary<int, ReadOnlyDictionary<int, Mapping>> idToWholePercentagesToMapping, ReadOnlyCollection<SortingContainer> sortingContainers)
{
if (_Configuration is null)
throw new NullReferenceException(nameof(_Configuration));
int result = 0;
string key;
string segmentB;
string? segmentC;
string personKeyFormatted;
MappingFromPerson mappingFromPerson;
Dictionary<string, int> keyToCount = new();
foreach (SortingContainer sortingContainer in sortingContainers)
{
if (sortingContainer.Question is null)
throw new NotSupportedException();
if (sortingContainer.Source.MappingFromPerson is null)
{
sortingContainer.Question.UpdateMappingFromUnknownPerson(_Configuration.SaveIndividually, sortingContainer);
result += 1;
}
else
{
mappingFromPerson = sortingContainer.Source.MappingFromPerson;
personKeyFormatted = IPersonBirthday.GetFormatted(_Configuration.PersonBirthdayFormat, mappingFromPerson.PersonKey);
segmentB = IMapLogic.GetDecade(sortingContainer.Question.MappingFromItem);
key = string.Concat(personKeyFormatted, '\t', segmentB);
if (!keyToCount.ContainsKey(key))
keyToCount.Add(key, new());
if (!keyToCount.ContainsKey(key))
keyToCount.Add(key, 0);
keyToCount[key]++;
if (!_Configuration.SaveIndividually && keyToCount[key] < _Configuration.SortingMaximumPerKey)
segmentC = null;
else
segmentC = sortingContainer.Sorting.DistancePermyriad.ToString();
sortingContainer.Question.UpdateMappingFromPerson(mappingFromPerson.ApproximateYears, mappingFromPerson.DisplayDirectoryName, mappingFromPerson.PersonKey, segmentB, segmentC, sortingContainer);
result += 1;
}
}
return result;
}
public List<SaveContainer> GetSaveContainers(string dFacesContentDirectory, string d2FacePartsContentDirectory, string d2FacePartsContentCollectionDirectory, ReadOnlyDictionary<int, ReadOnlyDictionary<int, Mapping>> idToWholePercentagesToMapping, Shared.Models.Methods.IDistanceLimits distanceLimits, int? useFiltersCounter, ReadOnlyCollection<SortingContainer> sortingContainers)
{
if (_Configuration is null)
throw new NullReferenceException(nameof(_Configuration));
@ -736,91 +757,173 @@ public partial class MapLogic : Shared.Models.Methods.IMapLogic
string counts = distanceLimits.GetCounts();
_ = Directory.CreateDirectory(Path.Combine(_EDistanceContentTicksDirectory, counts));
}
int result = 0;
string key;
Mapping? mapping;
const int zero = 0;
string mappingSegmentB;
string personKeyFormatted;
PersonBirthday personBirthday;
List<int>? wholePercentagesCollectionForA;
List<int>? wholePercentagesCollectionForB;
Dictionary<string, int> keyToCount = new();
Dictionary<string, string> keyToSegmentC = new();
ReadOnlyCollection<PersonContainer>? personContainers;
ReadOnlyDictionary<int, Mapping>? wholePercentagesToMapping;
Dictionary<int, List<int>> idToWholePercentagesCollectionForA = new();
Dictionary<int, List<int>> idToWholePercentagesCollectionForB = new();
int totalSeconds = (int)Math.Floor(new TimeSpan(DateTime.Now.Ticks - _Ticks).TotalSeconds);
ReadOnlyDictionary<int, ReadOnlyCollection<PersonContainer>>? wholePercentagesToPersonContainers;
string message = $") {sortingContainers.Length:000} Update From Sorting Container(s) - {totalSeconds} total second(s)";
ProgressBarOptions options = new() { ProgressCharacter = '─', ProgressBarOnBottom = true, DisableBottomPercentage = true };
using ProgressBar progressBar = new(sortingContainers.Length, message, options);
List<SaveContainer> results = new();
string by;
long? ticks;
bool isBySorting;
string checkFile;
Mapping? question;
string? directory;
string shortcutFile;
string facesDirectory;
string personDirectory;
bool isCounterPersonYear;
string facePartsDirectory;
FileHolder? faceFileHolder;
SaveContainer? saveContainer;
FileHolder? facePartsFileHolder;
FileHolder? hiddenFaceFileHolder;
int padLeft = _Configuration.FaceDistancePermyriad.ToString().Length;
string forceSingleImageHumanized = nameof(Shared.Models.Stateless.IMapLogic.ForceSingleImage).Humanize(LetterCasing.Title);
foreach (SortingContainer sortingContainer in sortingContainers)
{
progressBar.Tick();
if (sortingContainer.Mapping?.MappingFromLocation is null)
if (sortingContainer.Question is null)
throw new NotSupportedException();
if (!idToWholePercentagesCollectionForA.TryGetValue(sortingContainer.Mapping.MappingFromItem.Id, out wholePercentagesCollectionForA))
{
idToWholePercentagesCollectionForA.Add(sortingContainer.Mapping.MappingFromItem.Id, new());
if (!idToWholePercentagesCollectionForA.TryGetValue(sortingContainer.Mapping.MappingFromItem.Id, out wholePercentagesCollectionForA))
throw new Exception();
}
if (!idToWholePercentagesCollectionForB.TryGetValue(sortingContainer.Mapping.MappingFromItem.Id, out wholePercentagesCollectionForB))
{
idToWholePercentagesCollectionForB.Add(sortingContainer.Mapping.MappingFromItem.Id, new());
if (!idToWholePercentagesCollectionForB.TryGetValue(sortingContainer.Mapping.MappingFromItem.Id, out wholePercentagesCollectionForB))
throw new Exception();
}
if (!_IdThenWholePercentagesToPersonContainers.TryGetValue(sortingContainer.Sorting.Id, out wholePercentagesToPersonContainers) || !wholePercentagesToPersonContainers.TryGetValue(sortingContainer.Sorting.WholePercentages, out personContainers))
{
if (!_Configuration.SaveSortingWithoutPerson)
isCounterPersonYear = sortingContainer.Source.MappingFromPerson is not null && IPersonBirthday.IsCounterPersonYear(sortingContainer.Source.MappingFromPerson.PersonKey);
(by, _, isBySorting) = Stateless.MapLogic.Get(useFiltersCounter, _Configuration.SaveIndividually, sortingContainers.Count > 0, forceSingleImageHumanized, sortingContainer.Question);
question = sortingContainer.Question.MappingFromPerson is null ? sortingContainer.Source : sortingContainer.Question;
if (question is null)
throw new NotSupportedException();
if (question.MappingFromLocation is null)
continue;
if (wholePercentagesCollectionForA.Contains(sortingContainer.Mapping.MappingFromLocation.WholePercentages))
continue;
sortingContainer.Mapping.UpdateMappingFromUnknownPerson(saveIndividually, sortingContainer);
wholePercentagesCollectionForA.Add(sortingContainer.Mapping.MappingFromLocation.WholePercentages);
result += 1;
(directory, ticks, personDirectory) = Get(_Configuration, _Configuration.SaveIndividually, by, question, padLeft);
if (string.IsNullOrEmpty(directory))
throw new NotSupportedException();
if (question.MappingFromPerson is not null)
{
if (_Configuration.SaveIndividually)
{
directory = Path.Combine(directory, question.MappingFromItem.Id.ToString());
results.Add(new(Path.Combine(directory, question.MappingFromPerson.DisplayDirectoryName)));
}
}
else
{
if (wholePercentagesCollectionForB.Contains(sortingContainer.Mapping.MappingFromLocation.WholePercentages))
if (!_Configuration.SaveSortingWithoutPerson)
throw new NotSupportedException();
if (ticks is null)
continue;
foreach (PersonContainer personContainer in personContainers)
if (_Configuration.SaveIndividually)
{
if (personContainer.Key is null || personContainer.Birthdays is null || personContainer.Birthdays.Length == 0)
continue;
personBirthday = personContainer.Birthdays[zero];
personKeyFormatted = IPersonBirthday.GetFormatted(_Configuration.PersonBirthdayFormat, personBirthday);
mappingSegmentB = Stateless.MapLogic.GetMappingSegmentB(_Ticks, personBirthday, personContainer.ApproximateYears, sortingContainer.Mapping.MappingFromItem);
key = string.Concat(personKeyFormatted, '\t', mappingSegmentB);
if (!keyToCount.ContainsKey(key))
keyToCount.Add(key, new());
if (!keyToCount.ContainsKey(key))
keyToCount.Add(key, 0);
if (!keyToSegmentC.ContainsKey(key))
keyToSegmentC.Add(key, string.Empty);
keyToCount[key]++;
if (saveIndividually || keyToCount[key] > _Configuration.SortingMaximumPerKey)
directory = Path.Combine(directory, question.MappingFromItem.Id.ToString());
results.Add(new(Path.Combine(directory, $"X+{ticks}")));
}
}
results.Add(new(personDirectory));
if (_Configuration.SaveIndividually && question.MappingFromLocation.WholePercentages == question.MappingFromLocation.WholePercentages)
results.Add(new(Path.Combine(directory, "Maybe")));
facesDirectory = Stateless.MapLogic.GetFacesDirectory(_PropertyConfiguration, dFacesContentDirectory, question.MappingFromItem);
faceFileHolder = new(Path.Combine(facesDirectory, $"{question.MappingFromLocation.DeterministicHashCodeKey}{question.MappingFromItem.ImageFileHolder.ExtensionLowered}{_Configuration.FacesFileNameExtension}"));
facePartsDirectory = Stateless.MapLogic.GetFacePartsDirectory(_PropertyConfiguration, d2FacePartsContentDirectory, question.MappingFromItem);
shortcutFile = Path.Combine(personDirectory, $"{question.MappingFromLocation.DeterministicHashCodeKey}{question.MappingFromItem.ImageFileHolder.ExtensionLowered}.lnk");
checkFile = Path.Combine(directory, $"{question.MappingFromLocation.DeterministicHashCodeKey}{question.MappingFromItem.ImageFileHolder.ExtensionLowered}");
hiddenFaceFileHolder = new(Path.Combine(facesDirectory, $"{question.MappingFromLocation.DeterministicHashCodeKey}{question.MappingFromItem.ImageFileHolder.ExtensionLowered}{_Configuration.FacesHiddenFileNameExtension}"));
facePartsFileHolder = new(Path.Combine(facePartsDirectory, $"{question.MappingFromLocation.DeterministicHashCodeKey}{question.MappingFromItem.ImageFileHolder.ExtensionLowered}{_Configuration.FacePartsFileNameExtension}"));
saveContainer = new(checkFile, directory, faceFileHolder, hiddenFaceFileHolder, facePartsFileHolder, question.MappingFromItem.ResizedFileHolder, shortcutFile);
results.Add(saveContainer);
if (!_Configuration.SaveIndividually && isBySorting && question.MappingFromPerson is null)
{
keyToCount[key] = 0;
keyToSegmentC[key] = sortingContainer.Sorting.DistancePermyriad.ToString();
saveContainer = GetMatchSaveContainer(dFacesContentDirectory, d2FacePartsContentDirectory, directory, question);
if (saveContainer is not null)
results.Add(saveContainer);
}
if (!idToWholePercentagesToMapping.TryGetValue(sortingContainer.Sorting.Id, out wholePercentagesToMapping))
if (!_Configuration.SaveIndividually)
saveContainer = Stateless.MapLogic.GetDebugSaveContainer(sortingContainer, directory, question);
else
{
(saveContainer, SaveContainer? extraSaveContainer) = Stateless.MapLogic.GetContainers(_Configuration.FacesFileNameExtension, _Configuration.FacePartsFileNameExtension, _PropertyConfiguration, dFacesContentDirectory, d2FacePartsContentCollectionDirectory, directory, question);
if (saveContainer is null || extraSaveContainer is null)
continue;
if (!wholePercentagesToMapping.TryGetValue(sortingContainer.Sorting.WholePercentages, out mapping))
results.Add(extraSaveContainer);
}
results.Add(saveContainer);
}
return results;
}
public ReadOnlyCollection<SortingContainer> GetFilterSortingContainers(string dFacesContentDirectory, string d2FacePartsContentDirectory, string d2FacePartsContentCollectionDirectory, ReadOnlyDictionary<int, ReadOnlyDictionary<int, Mapping>> idToWholePercentagesToMapping, Shared.Models.Methods.IDistanceLimits distanceLimits, ReadOnlyCollection<SortingContainer> sortingContainers)
{
if (_Configuration is null)
throw new NullReferenceException(nameof(_Configuration));
if (distanceLimits is not null)
{
string counts = distanceLimits.GetCounts();
_ = Directory.CreateDirectory(Path.Combine(_EDistanceContentTicksDirectory, counts));
}
List<SortingContainer> results = new();
Sorting sorting;
Mapping? keyMapping;
List<int>? wholePercentagesCollection;
MappingFromFilterPre mappingFromFilterPre;
Dictionary<string, int> keyToCount = new();
MappingFromFilterPost mappingFromFilterPost;
ReadOnlyCollection<PersonContainer>? personContainers;
ReadOnlyDictionary<int, Mapping>? wholePercentagesToMapping;
Dictionary<int, List<int>> idToWholePercentagesCollection = new();
int totalSeconds = (int)Math.Floor(new TimeSpan(DateTime.Now.Ticks - _Ticks).TotalSeconds);
ReadOnlyDictionary<int, ReadOnlyCollection<PersonContainer>>? wholePercentagesToPersonContainers;
string message = $") {sortingContainers.Count:000} Filter Sorting Container(s) - {totalSeconds} total second(s)";
ProgressBarOptions options = new() { ProgressCharacter = '─', ProgressBarOnBottom = true, DisableBottomPercentage = true };
using ProgressBar progressBar = new(sortingContainers.Count, message, options);
foreach (SortingContainer sortingContainer in sortingContainers)
{
progressBar.Tick();
if (sortingContainer.Source?.MappingFromLocation is null)
throw new NotSupportedException();
mappingFromFilterPre = sortingContainer.Source.MappingFromFilterPre;
mappingFromFilterPost = sortingContainer.Source.MappingFromFilterPost;
if (sortingContainer.Source.MappingFromFilterPre.InSkipCollection is not null && sortingContainer.Source.MappingFromFilterPre.InSkipCollection.Value)
throw new NotSupportedException(nameof(GetSortingCollection));
if (sortingContainer.Source.MappingFromFilterPre.IsFocusModel is not null && sortingContainer.Source.MappingFromFilterPre.IsFocusModel.Value)
throw new NotSupportedException(nameof(GetSortingCollection));
if (sortingContainer.Source.MappingFromFilterPre.IsFocusRelativePath is not null && sortingContainer.Source.MappingFromFilterPre.IsFocusRelativePath.Value)
throw new NotSupportedException(nameof(GetSortingCollection));
if (sortingContainer.Source.MappingFromFilterPost.InSkipCollection is not null && sortingContainer.Source.MappingFromFilterPost.InSkipCollection.Value)
throw new NotSupportedException(nameof(GetSortingCollection));
if (sortingContainer.Source.MappingFromFilterPost.InSkipCollection is not null && sortingContainer.Source.MappingFromFilterPost.InSkipCollection.Value)
throw new NotSupportedException(nameof(GetSortingCollection));
if (sortingContainer.Source.MappingFromFilterPost.IsFocusPerson is not null && !sortingContainer.Source.MappingFromFilterPost.IsFocusPerson.Value)
throw new NotSupportedException(nameof(GetSortingCollection));
sorting = sortingContainer.Sorting;
if (!idToWholePercentagesToMapping.TryGetValue(sorting.Id, out wholePercentagesToMapping))
throw new NotSupportedException();
if (!wholePercentagesToMapping.TryGetValue(sorting.WholePercentages, out keyMapping))
throw new NotSupportedException();
if (keyMapping.MappingFromFilterPost.CanReMap is not null && !_Configuration.ReMap)
throw new NotSupportedException(nameof(GetSortingCollection));
if (keyMapping.MappingFromFilterPost.CanReMap is not null && !keyMapping.MappingFromFilterPost.CanReMap.Value)
throw new NotSupportedException(nameof(GetSortingCollection));
if (!PreAndPostContinue(_Configuration, idToWholePercentagesToMapping, sorting, sortingContainer.Source, keyMapping))
continue;
if (mapping.MappingFromPerson is null)
if (!idToWholePercentagesCollection.TryGetValue(sorting.Id, out wholePercentagesCollection))
{
idToWholePercentagesCollection.Add(sorting.Id, new());
if (!idToWholePercentagesCollection.TryGetValue(sorting.Id, out wholePercentagesCollection))
throw new Exception();
}
if (sortingContainer.Source.MappingFromPerson is null)
{
if (!_Configuration.SaveSortingWithoutPerson)
continue;
sortingContainer.Mapping.UpdateMappingFromPerson(personContainer.ApproximateYears, personContainer.DisplayDirectoryName, personBirthday, mappingSegmentB, keyToSegmentC[key], sortingContainer, mapping.MappingFromPerson.LocationContainersFiles);
wholePercentagesCollectionForB.Add(sortingContainer.Mapping.MappingFromLocation.WholePercentages);
result += 1;
break;
if (wholePercentagesCollection.Contains(sorting.WholePercentages))
continue;
keyMapping.UpdateMappingFromUnknownPerson(_Configuration.SaveIndividually, sortingContainer);
wholePercentagesCollection.Add(sorting.WholePercentages);
results.Add(new(keyMapping, sortingContainer.Sorting, sortingContainer.Source));
}
else
{
if (wholePercentagesCollection.Contains(sorting.WholePercentages))
continue;
if (keyMapping.MappingFromFilterPost.CanReMap is not null && (IPerson.IsDefaultName(sortingContainer.Source.MappingFromPerson.DisplayDirectoryName) || _IdThenWholePercentagesToPersonContainers.TryGetValue(sorting.Id, out wholePercentagesToPersonContainers) && wholePercentagesToPersonContainers.TryGetValue(sorting.WholePercentages, out personContainers) && personContainers.Any(l => l.Key == sortingContainer.Source.MappingFromPerson.PersonKey)))
continue;
if (sortingContainer.Source.MappingFromPerson is null)
throw new NotSupportedException();
wholePercentagesCollection.Add(sorting.WholePercentages);
results.Add(new(keyMapping, sortingContainer.Sorting, sortingContainer.Source));
}
}
}
return result;
return new(results);
}
private (string, PersonBirthday?) GetPersonBirthday(string[] directoryNames)
@ -950,7 +1053,7 @@ public partial class MapLogic : Shared.Models.Methods.IMapLogic
throw new NotSupportedException();
if (string.IsNullOrEmpty(mapping.MappingFromPerson.DisplayDirectoryName))
throw new NotSupportedException();
personKeyFormatted = IPersonBirthday.GetFormatted(_Configuration.PersonBirthdayFormat, mapping.MappingFromPerson.PersonBirthday);
personKeyFormatted = IPersonBirthday.GetFormatted(_Configuration.PersonBirthdayFormat, mapping.MappingFromPerson.PersonKey);
if (personKeyFormatted == "1501-04-10_00")
continue;
if (!personKeyFormattedCollection.Contains(personKeyFormatted))
@ -985,7 +1088,6 @@ public partial class MapLogic : Shared.Models.Methods.IMapLogic
if (_Configuration is null)
throw new NullReferenceException(nameof(_Configuration));
SaveContainer? saveContainer;
bool saveIndividually = false;
List<SaveContainer> saveContainers = new();
(int, FileHolder, int, string, string, string, string)[] collection = GetCollectionForSaveFilteredOriginalImagesFromJLinks(jLinks, a2PeopleContentDirectory, personContainers, mappingCollection, personKeyToIds);
foreach ((int id, FileHolder imageFileHolder, int approximateYears, string personKeyFormatted, string directory, string personDirectory, string checkFile) in collection)
@ -995,7 +1097,7 @@ public partial class MapLogic : Shared.Models.Methods.IMapLogic
saveContainer = new(imageFileHolder, checkFile, directory);
saveContainers.Add(saveContainer);
}
SaveContainers(saveIndividually, null, saveContainers);
SaveContainers(null, saveContainers);
}
public void SaveShortcutsForOutputResolutionsPreMapLogic(string eDistanceContentDirectory, ReadOnlyDictionary<long, List<int>> personKeyToIds, ReadOnlyCollection<Mapping> mappingCollection)
@ -1041,7 +1143,6 @@ public partial class MapLogic : Shared.Models.Methods.IMapLogic
{
if (_Configuration is null)
throw new NullReferenceException(nameof(_Configuration));
long personKey;
string fileName;
string fullName;
string directory;
@ -1109,18 +1210,17 @@ public partial class MapLogic : Shared.Models.Methods.IMapLogic
throw new NotSupportedException();
if (string.IsNullOrEmpty(mapping.MappingFromPerson.DisplayDirectoryName))
throw new NotSupportedException();
personKeyFormatted = IPersonBirthday.GetFormatted(_Configuration.PersonBirthdayFormat, mapping.MappingFromPerson.PersonBirthday);
personKey = mapping.MappingFromPerson.PersonBirthday.Value.Ticks;
personKeyFormatted = IPersonBirthday.GetFormatted(_Configuration.PersonBirthdayFormat, mapping.MappingFromPerson.PersonKey);
if (mapping.MappingFromItem.ContainerDateTimes.Length > 0 && !distinct.Contains(mapping.MappingFromItem.ResizedFileHolder.DirectoryName))
{
distinct.Add(mapping.MappingFromItem.ResizedFileHolder.DirectoryName);
directoriesAndDateTimes.Add(new(mapping.MappingFromItem.ResizedFileHolder.DirectoryName, mapping.MappingFromItem.ContainerDateTimes));
}
directory = Path.Combine(mapping.MappingFromItem.ResizedFileHolder.DirectoryName, $"{_PropertyConfiguration.ResultAllInOne}Shortcuts", personKeyFormatted);
if (!personKeyToIds.ContainsKey(personKey))
if (!personKeyToIds.ContainsKey(mapping.MappingFromPerson.PersonKey))
personDirectory = Path.Combine(directory, mapping.MappingFromPerson.DisplayDirectoryName);
else
personDirectory = Path.Combine(directory, mapping.MappingFromPerson.DisplayDirectoryName, $"{personKeyToIds[personKey].Count} Face(s)");
personDirectory = Path.Combine(directory, mapping.MappingFromPerson.DisplayDirectoryName, $"{personKeyToIds[mapping.MappingFromPerson.PersonKey].Count} Face(s)");
fileName = Path.Combine(directory, $"{mapping.MappingFromItem.ResizedFileHolder.Name}.lnk");
collection.Add(new(mapping.MappingFromItem.ResizedFileHolder.FullName, personDirectory, mapping.MappingFromItem.GetDateTimeOriginalThenMinimumDateTime(), fileName, mapping.MappingFromLocation?.DeterministicHashCodeKey, MakeAllHidden: false));
}
@ -1215,38 +1315,6 @@ public partial class MapLogic : Shared.Models.Methods.IMapLogic
return result;
}
public bool? IsFocusPersonOld(int? skipPersonWithMoreThen, List<(string Directory, long PersonKey)> jLinkResolvedDirectories, ReadOnlyDictionary<int, ReadOnlyCollection<PersonContainer>>? wholePercentagesToPersonContainers, MappingFromLocation mappingFromLocation)
{
bool? result;
ReadOnlyCollection<PersonContainer>? personContainers;
if (skipPersonWithMoreThen is null && jLinkResolvedDirectories.Count == 0)
result = null;
else if (wholePercentagesToPersonContainers is null)
result = null;
else if (!wholePercentagesToPersonContainers.TryGetValue(mappingFromLocation.WholePercentages, out personContainers))
result = null;
else
{
result = false;
foreach (PersonContainer personContainer in personContainers)
{
if (personContainer.Key is null)
continue;
if (skipPersonWithMoreThen is not null && _PersonKeyToCount.TryGetValue(personContainer.Key.Value, out int count) && count > 2 && count < skipPersonWithMoreThen.Value)
{
result = true;
break;
}
if (jLinkResolvedDirectories.Any(l => personContainer.Key.Value == l.PersonKey))
{
result = true;
break;
}
}
}
return result;
}
public void LookForAbandoned(Property.Models.Configuration propertyConfiguration, string bResultsFullGroupDirectory, Container[] containers, string cResultsFullGroupDirectory, string dResultsFullGroupDirectory, string d2ResultsFullGroupDirectory)
{
string[] directories;

View File

@ -115,7 +115,15 @@ internal abstract class MapLogic
}
}
internal static string GetMappingSegmentB(long ticks, PersonBirthday personBirthday, int? approximateYears, DateTime dateTimeOriginalThenMinimumDateTime, bool? isWrongYear)
internal static string GetMappingSegmentB(long ticks, long personKey, int? approximateYears, MappingFromItem mappingFromItem)
{
string result;
PersonBirthday personBirthday = IPersonBirthday.GetPersonBirthday(personKey);
result = GetMappingSegmentB(ticks, personBirthday, approximateYears, mappingFromItem.GetDateTimeOriginalThenMinimumDateTime(), mappingFromItem.IsWrongYear);
return result;
}
private static string GetMappingSegmentB(long ticks, PersonBirthday personBirthday, int? approximateYears, DateTime dateTimeOriginalThenMinimumDateTime, bool? isWrongYear)
{
string result = GetMappingSegmentB(ticks, personBirthday, approximateYears, dateTimeOriginalThenMinimumDateTime.Ticks, isWrongYear);
return result;
@ -285,7 +293,7 @@ internal abstract class MapLogic
}
}
private static List<TicksDirectory> UpdateDateVerifyAndGetTicksDirectories(string eDistanceContentDirectory)
private static List<TicksDirectory> UpdateDateVerifyAndGetTicksDirectories(Configuration configuration, string eDistanceContentDirectory)
{
List<TicksDirectory> results = new();
float? totalDays;
@ -333,7 +341,7 @@ internal abstract class MapLogic
lastDirectoryTicks = directoryTicks;
}
string[] compare = (from l in results where l.TotalDays is not null and < 9.95f select l.Directory).ToArray();
if (compare.Length > 0)
if (compare.Length > 0 && configuration.ReMap)
throw new Exception($"Please Consolidate <{string.Join(Environment.NewLine, compare)}>");
return results;
}
@ -701,7 +709,7 @@ internal abstract class MapLogic
OpenPossibleDuplicates(configuration, duplicates);
else
{
if (delete.Count > 5)
if (delete.Count > 8)
throw new Exception("Something maybe wrong!");
foreach (string file in delete)
{
@ -900,7 +908,7 @@ internal abstract class MapLogic
results.Clear();
distinct.Clear();
directoryNumber = 0;
ticksDirectories = UpdateDateVerifyAndGetTicksDirectories(eDistanceContentDirectory);
ticksDirectories = UpdateDateVerifyAndGetTicksDirectories(configuration, eDistanceContentDirectory);
totalSeconds = (int)Math.Floor(new TimeSpan(DateTime.Now.Ticks - ticks).TotalSeconds);
message = $"{i}) {ticksDirectories.Count:000} compile from and clean ticks Director(ies) - B - {totalSeconds} total second(s)";
progressBar = new(ticksDirectories.Count, message, options);
@ -1351,46 +1359,44 @@ internal abstract class MapLogic
return result;
}
internal static SaveContainer GetDebugSaveContainer(string directory, MappingFromPerson? mappingFromPerson, SortingContainer sortingContainer, Mapping mapping)
internal static SaveContainer GetDebugSaveContainer(SortingContainer sortingContainer, string directory, Mapping keyMapping)
{
SaveContainer result;
if (sortingContainer.Mapping.MappingFromLocation is null)
throw new NullReferenceException(nameof(sortingContainer.Mapping.MappingFromLocation));
FileHolder faceFileHolder = new($"C:/{sortingContainer.Sorting.Id}.{sortingContainer.Sorting.WholePercentages}");
string shortcutFile;
if (mappingFromPerson is null)
shortcutFile = Path.Combine(directory, $"{sortingContainer.Mapping.MappingFromLocation.DeterministicHashCodeKey}{sortingContainer.Mapping.MappingFromItem.ImageFileHolder.ExtensionLowered}.{sortingContainer.Sorting.DistancePermyriad}.lnk");
if (sortingContainer?.Source.MappingFromLocation is null)
throw new NullReferenceException(nameof(sortingContainer.Source.MappingFromLocation));
FileHolder faceFileHolder = new($"C:/{sortingContainer.Sorting.Id}.{sortingContainer.Sorting.WholePercentages}");
if (keyMapping.MappingFromPerson is not null && keyMapping.MappingFromLocation is not null)
shortcutFile = Path.Combine(directory, $"{keyMapping.MappingFromLocation.DeterministicHashCodeKey}{keyMapping.MappingFromItem.ImageFileHolder.ExtensionLowered}.{sortingContainer.Sorting.DistancePermyriad}.lnk");
else
shortcutFile = Path.Combine(directory, $"{sortingContainer.Mapping.MappingFromLocation.DeterministicHashCodeKey}{sortingContainer.Mapping.MappingFromItem.ImageFileHolder.ExtensionLowered}.{sortingContainer.Sorting.DistancePermyriad}.lnk");
result = new(directory, faceFileHolder, mapping.MappingFromItem.ResizedFileHolder, shortcutFile);
shortcutFile = Path.Combine(directory, $"{sortingContainer.Source.MappingFromLocation.DeterministicHashCodeKey}{sortingContainer.Source.MappingFromItem.ImageFileHolder.ExtensionLowered}.{sortingContainer.Sorting.DistancePermyriad}.lnk");
result = new(directory, faceFileHolder, sortingContainer.Source.MappingFromItem.ResizedFileHolder, shortcutFile);
return result;
}
internal static (SaveContainer?, SaveContainer?) GetContainers(string facesFileNameExtension, string facePartsFileNameExtension, Shared.Models.Properties.IPropertyConfiguration propertyConfiguration, string dFacesContentDirectory, string d2FacePartsContentCollectionDirectory, string directory, SortingContainer sortingContainer, Mapping mapping)
internal static (SaveContainer?, SaveContainer?) GetContainers(string facesFileNameExtension, string facePartsFileNameExtension, Shared.Models.Properties.IPropertyConfiguration propertyConfiguration, string dFacesContentDirectory, string d2FacePartsContentCollectionDirectory, string directory, Mapping keyMapping)
{
SaveContainer? result;
SaveContainer? saveContainer;
if (sortingContainer.Mapping.MappingFromLocation is null)
throw new NullReferenceException(nameof(sortingContainer.Mapping.MappingFromLocation));
if (mapping.MappingFromLocation is null)
if (keyMapping.MappingFromLocation is null)
(result, saveContainer) = (null, null);
else
{
string? facePartsContentCollectionFile = GetFacePartsContentCollectionFile(facePartsFileNameExtension, d2FacePartsContentCollectionDirectory, mapping.MappingFromItem);
string? facePartsContentCollectionFile = GetFacePartsContentCollectionFile(facePartsFileNameExtension, d2FacePartsContentCollectionDirectory, keyMapping.MappingFromItem);
if (facePartsContentCollectionFile is null || !File.Exists(facePartsContentCollectionFile))
result = null;
else
{
string checkFile = Path.Combine(directory, $"{mapping.MappingFromItem.ImageFileHolder.Name}{facePartsFileNameExtension}");
string checkFile = Path.Combine(directory, $"{keyMapping.MappingFromItem.ImageFileHolder.Name}{facePartsFileNameExtension}");
result = new(checkFile, directory, new(facePartsContentCollectionFile));
}
string facesDirectory = GetFacesDirectory(propertyConfiguration, dFacesContentDirectory, mapping.MappingFromItem);
FileHolder faceFileHolder = new(Path.Combine(facesDirectory, $"{mapping.MappingFromLocation.DeterministicHashCodeKey}{mapping.MappingFromItem.ImageFileHolder.ExtensionLowered}{facesFileNameExtension}"));
string facesDirectory = GetFacesDirectory(propertyConfiguration, dFacesContentDirectory, keyMapping.MappingFromItem);
FileHolder faceFileHolder = new(Path.Combine(facesDirectory, $"{keyMapping.MappingFromLocation.DeterministicHashCodeKey}{keyMapping.MappingFromItem.ImageFileHolder.ExtensionLowered}{facesFileNameExtension}"));
if (!faceFileHolder.Exists)
saveContainer = null;
else
{
string checkFile = Path.Combine(directory, $"{mapping.MappingFromLocation.DeterministicHashCodeKey}{mapping.MappingFromItem.ImageFileHolder.ExtensionLowered}{facesFileNameExtension}");
string checkFile = Path.Combine(directory, $"{keyMapping.MappingFromLocation.DeterministicHashCodeKey}{keyMapping.MappingFromItem.ImageFileHolder.ExtensionLowered}{facesFileNameExtension}");
saveContainer = new(checkFile, directory, faceFileHolder);
}
}
@ -1578,19 +1584,20 @@ internal abstract class MapLogic
{
isByMapping = mapping.By == Shared.Models.Stateless.IMapLogic.Mapping;
isBySorting = mapping.By == Shared.Models.Stateless.IMapLogic.Sorting;
bool isDefaultName = mapping.MappingFromPerson is not null && IPerson.IsDefaultName(mapping.MappingFromPerson.DisplayDirectoryName);
if (isBySorting && mapping.MappingFromPerson is null)
by = saveIndividually ? nameof(Shared.Models.Stateless.IMapLogic.Individually) : $"{nameof(Shared.Models.Stateless.IMapLogic.Sorting)} Without Person";
else if (isBySorting && useFiltersCounter.HasValue)
by = $"{nameof(Shared.Models.Stateless.IMapLogic.Sorting)} Modified Filters - {useFiltersCounter.Value}";
by = $"{nameof(Shared.Models.Stateless.IMapLogic.Sorting)}{(!isDefaultName ? "-A" : "-Z")} Modified Filters - {useFiltersCounter.Value}";
else
{
by = mapping.By.Value switch
by = $"{mapping.By.Value switch
{
Shared.Models.Stateless.IMapLogic.Mapping => nameof(Shared.Models.Stateless.IMapLogic.Mapping),
Shared.Models.Stateless.IMapLogic.Sorting => saveIndividually ? nameof(Shared.Models.Stateless.IMapLogic.Individually) : nameof(Shared.Models.Stateless.IMapLogic.Sorting),
Shared.Models.Stateless.IMapLogic.ForceSingleImage => forceSingleImageHumanized,
_ => throw new NotImplementedException()
};
}}{(!isDefaultName ? "-A" : "-Z")}";
}
}
return new(by, isByMapping, isBySorting);
@ -1675,24 +1682,26 @@ internal abstract class MapLogic
return new(results);
}
internal static void SetCreationTime(MappingFromItem mappingFromItem, MappingFromPerson mappingFromPerson)
internal static string GetDecade(MappingFromItem mappingFromItem)
{
DateTime dateTime;
FileInfo fileInfo;
foreach (string locationContainersFile in mappingFromPerson.LocationContainersFiles)
string result;
string year;
if (mappingFromItem.DateTimeOriginal is null)
{
fileInfo = new(locationContainersFile);
if (!fileInfo.Exists)
continue;
dateTime = mappingFromItem.DateTimeOriginal is null ? mappingFromItem.MinimumDateTime : mappingFromItem.DateTimeOriginal.Value;
if (fileInfo.CreationTime != dateTime)
File.SetCreationTime(locationContainersFile, dateTime);
year = mappingFromItem.MinimumDateTime.Year.ToString();
result = year[3] > '4' ? $"#{year[..3]}+" : $"#{year[..3]}-";
}
else
{
year = mappingFromItem.DateTimeOriginal.Value.Year.ToString();
result = year[3] > '4' ? $"^{year[..3]}+" : $"^{year[..3]}-";
}
return result;
}
internal static void MoveToDecade(Property.Models.Configuration propertyConfiguration, MappingFromItem mappingFromItem, MappingFromPerson mappingFromPerson)
internal static void SetCreationTimeMaybeMoveToDecade(Property.Models.Configuration propertyConfiguration, bool moveToDecade, MappingFromItem mappingFromItem, ReadOnlyCollection<LocationContainer<MetadataExtractor.Directory>> locationContainers)
{
string year;
DateTime dateTime;
FileInfo fileInfo;
string halfDecade;
string checkDirectory;
@ -1702,12 +1711,17 @@ internal abstract class MapLogic
string personNameDirectoryName;
string? personKeyFormattedDirectory;
string? personKeyFormattedDirectoryName;
foreach (string locationContainersFile in mappingFromPerson.LocationContainersFiles)
foreach (LocationContainer<MetadataExtractor.Directory> locationContainer in locationContainers)
{
fileInfo = new(locationContainersFile);
fileInfo = new(locationContainer.File);
if (!fileInfo.Exists)
continue;
personNameDirectory = Path.GetDirectoryName(locationContainersFile);
dateTime = mappingFromItem.DateTimeOriginal is null ? mappingFromItem.MinimumDateTime : mappingFromItem.DateTimeOriginal.Value;
if (fileInfo.CreationTime != dateTime)
File.SetCreationTime(locationContainer.File, dateTime);
if (!moveToDecade)
continue;
personNameDirectory = Path.GetDirectoryName(locationContainer.File);
if (string.IsNullOrEmpty(personNameDirectory))
continue;
personNameDirectoryName = Path.GetFileName(personNameDirectory);
@ -1721,22 +1735,13 @@ internal abstract class MapLogic
personKeyFormattedDirectoryName = Path.GetFileName(personKeyFormattedDirectory);
if (personKeyFormattedDirectoryName.Length != propertyConfiguration.PersonBirthdayFormat.Length)
break;
if (mappingFromItem.DateTimeOriginal is null)
{
year = mappingFromItem.MinimumDateTime.Year.ToString();
halfDecade = year[3] > '4' ? $"#{year[..3]}+" : $"#{year[..3]}-";
}
else
{
year = mappingFromItem.DateTimeOriginal.Value.Year.ToString();
halfDecade = year[3] > '4' ? $"^{year[..3]}+" : $"^{year[..3]}-";
}
halfDecade = GetDecade(mappingFromItem);
if (halfDecade == yearDirectoryName)
continue;
checkDirectory = Path.Combine(personKeyFormattedDirectory, halfDecade, personNameDirectoryName);
if (!Directory.Exists(checkDirectory))
_ = Directory.CreateDirectory(checkDirectory);
File.Move(locationContainersFile, Path.Combine(checkDirectory, Path.GetFileName(locationContainersFile)));
File.Move(locationContainer.File, Path.Combine(checkDirectory, Path.GetFileName(locationContainer.File)));
}
}
@ -1815,7 +1820,16 @@ internal abstract class MapLogic
if (!wholePercentagesToPersonContainers.TryGetValue(mappingFromLocation.WholePercentages, out personContainers))
result = null;
else
result = personContainers.Any(l => IPerson.IsDefaultName(l) && l.Key is not null && IPersonBirthday.IsCounterPersonYear(new DateTime(l.Key.Value).Year) && !jLinkResolvedPersonKeys.Contains(l.Key.Value));
{
result = false;
foreach (PersonContainer personContainer in personContainers)
{
if (!IPerson.IsDefaultName(personContainer) || personContainer.Key is null || !IPersonBirthday.IsCounterPersonYear(new DateTime(personContainer.Key.Value).Year) || jLinkResolvedPersonKeys.Contains(personContainer.Key.Value))
continue;
result = true;
break;
}
}
}
return result;
}

View File

@ -35,19 +35,19 @@ public interface IMapLogic
static List<(string, long)> GetJLinkDirectories(string genealogicalDataCommunicationFile, string[] jLinks, string personBirthdayFormat, char[] personCharacters, string a2PeopleSingletonDirectory, string a2PeopleContentDirectory) =>
MapLogic.GetJLinkDirectories(genealogicalDataCommunicationFile, jLinks, personBirthdayFormat, personCharacters, a2PeopleSingletonDirectory, a2PeopleContentDirectory);
void TestStatic_SetCreationTime(Shared.Models.MappingFromItem mappingFromItem, Shared.Models.MappingFromPerson mappingFromPerson) =>
SetCreationTime(mappingFromItem, mappingFromPerson);
static void SetCreationTime(Shared.Models.MappingFromItem mappingFromItem, Shared.Models.MappingFromPerson mappingFromPerson) =>
MapLogic.SetCreationTime(mappingFromItem, mappingFromPerson);
void TestStatic_MoveToDecade(Property.Models.Configuration propertyConfiguration, Shared.Models.MappingFromItem mappingFromItem, Shared.Models.MappingFromPerson mappingFromPerson) =>
MoveToDecade(propertyConfiguration, mappingFromItem, mappingFromPerson);
static void MoveToDecade(Property.Models.Configuration propertyConfiguration, Shared.Models.MappingFromItem mappingFromItem, Shared.Models.MappingFromPerson mappingFromPerson) =>
MapLogic.MoveToDecade(propertyConfiguration, mappingFromItem, mappingFromPerson);
void TestStatic_SetCreationTimeMaybeMoveToDecade(Property.Models.Configuration propertyConfiguration, bool moveToDecade, Shared.Models.MappingFromItem mappingFromItem, ReadOnlyCollection<Shared.Models.LocationContainer<MetadataExtractor.Directory>> locationContainers) =>
SetCreationTimeMaybeMoveToDecade(propertyConfiguration, moveToDecade, mappingFromItem, locationContainers);
static void SetCreationTimeMaybeMoveToDecade(Property.Models.Configuration propertyConfiguration, bool moveToDecade, Shared.Models.MappingFromItem mappingFromItem, ReadOnlyCollection<Shared.Models.LocationContainer<MetadataExtractor.Directory>> locationContainers) =>
MapLogic.SetCreationTimeMaybeMoveToDecade(propertyConfiguration, moveToDecade, mappingFromItem, locationContainers);
bool? TestStatic_CanReMap(long[] jLinkResolvedPersonKeys, ReadOnlyDictionary<int, ReadOnlyCollection<Shared.Models.PersonContainer>>? wholePercentagesToPersonContainers, Shared.Models.MappingFromLocation mappingFromLocation) =>
CanReMap(jLinkResolvedPersonKeys, wholePercentagesToPersonContainers, mappingFromLocation);
static bool? CanReMap(long[] jLinkResolvedPersonKeys, ReadOnlyDictionary<int, ReadOnlyCollection<Shared.Models.PersonContainer>>? wholePercentagesToPersonContainers, Shared.Models.MappingFromLocation mappingFromLocation) =>
MapLogic.CanReMap(jLinkResolvedPersonKeys, wholePercentagesToPersonContainers, mappingFromLocation);
string TestStatic_GetDecade(Shared.Models.MappingFromItem mappingFromItem) =>
GetDecade(mappingFromItem);
static string GetDecade(Shared.Models.MappingFromItem mappingFromItem) =>
MapLogic.GetDecade(mappingFromItem);
}

View File

@ -37,6 +37,7 @@ taskTemplate: '^+^_${overdue ? ''^R'' : ''''}${name}^: ${relations ? (''\n^-^/^g
- [merge-kristy-files](tasks/merge-kristy-files.md)
- [review-location-container-distance-tolerance](tasks/review-location-container-distance-tolerance.md)
- [can-re-map](tasks/can-re-map.md)
## Done

View File

@ -0,0 +1,41 @@
---
created: 2023-09-06T01:48:53.593Z
updated: 2023-09-06T01:48:53.588Z
assigned: ""
progress: 0
tags: []
started: 2023-09-06T01:48:53.593Z
---
# CanReMap
```csharp
DlibDotNet.GetMappingAndUpdateMappingFromPerson;
private (Mapping, int) GetMappingAndUpdateMappingFromPerson(MapLogic mapLogic, Item item, bool? isFocusRelativePath, MappingFromItem mappingFromItem)
// ... Done
E_Distance.PreFilterSetFaceDistances;
public static void PreFilterSetFaceDistances(int maxDegreeOfParallelism, long ticks, ReadOnlyCollection<Face> distinctFilteredFaces)
// ... Done
E_Distance.FilteredPostLoadFaceDistanceContainers;
public static FaceDistanceContainer[] FilteredPostLoadFaceDistanceContainers(Map.Models.MapLogic mapLogic, ReadOnlyCollection<FaceDistanceContainer> faceDistanceContainers, long? skipOlderThan, DistanceLimits distanceLimits)
// ... Done
E_Distance.SetFaceMappingSortingCollectionThenGetSortedSortingContainers
=> MapLogic.GetSortingCollection;
public List<Sorting> GetSortingCollection(int i, Face face, FaceDistance faceDistanceEncoding, List<FaceDistance> faceDistanceLengths)
// ...
MapLogic.GetFilterSortingContainers;
public ReadOnlyCollection<SortingContainer> GetFilterSortingContainers(string dFacesContentDirectory, string d2FacePartsContentDirectory, string d2FacePartsContentCollectionDirectory, ReadOnlyDictionary<int, ReadOnlyDictionary<int, Mapping>> idToWholePercentagesToMapping, Shared.Models.Methods.IDistanceLimits distanceLimits, ReadOnlyCollection<SortingContainer> sortingContainers)
// ...
E_Distance.SaveFaceDistances;
public static void SaveFaceDistances(Property.Models.Configuration configuration, ReadOnlyCollection<SortingContainer> sortingContainers)
// ...
MapLogic.UpdateFromSortingContainers;
public int UpdateFromSortingContainers(string dFacesContentDirectory, string d2FacePartsContentDirectory, string d2FacePartsContentCollectionDirectory, ReadOnlyDictionary<int, ReadOnlyDictionary<int, Mapping>> idToWholePercentagesToMapping, ReadOnlyCollection<SortingContainer> sortingContainers)
// ...
MapLogic.GetSaveContainers;
public List<SaveContainer> GetSaveContainers(string dFacesContentDirectory, string d2FacePartsContentDirectory, string d2FacePartsContentCollectionDirectory, ReadOnlyDictionary<int, ReadOnlyDictionary<int, Mapping>> idToWholePercentagesToMapping, Shared.Models.Methods.IDistanceLimits distanceLimits, int? useFiltersCounter, ReadOnlyCollection<SortingContainer> sortingContainers)
// ...
MapLogic.SaveContainers;
public void SaveContainers(int? updated, List<SaveContainer> saveContainers)
// ...
```

View File

@ -1,4 +1,3 @@
using System.Collections.ObjectModel;
using System.Text.Json;
using System.Text.Json.Serialization;
@ -15,7 +14,6 @@ public class Mapping : Properties.IMapping
public MappingFromFilterPost MappingFromFilterPost { init; get; }
public MappingFromFilterPre MappingFromFilterPre { init; get; }
public MappingFromItem MappingFromItem { init; get; }
public MappingFromFilter MappingFromFilter { init; get; }
public MappingFromLocation? MappingFromLocation { init; get; }
public MappingFromPerson? MappingFromPerson => _MappingFromPerson;
public List<MappingFromPhotoPrism>? MappingFromPhotoPrismCollection { init; get; }
@ -23,11 +21,10 @@ public class Mapping : Properties.IMapping
public SortingContainer? SortingContainer => _SortingContainer;
[JsonConstructor]
public Mapping(int? by, MappingFromFilter mappingFromFilter, MappingFromFilterPost mappingFromFilterPost, MappingFromFilterPre mappingFromFilterPre, MappingFromItem mappingFromItem, MappingFromLocation? mappingFromLocation, MappingFromPerson? mappingFromPerson, List<MappingFromPhotoPrism>? mappingFromPhotoPrismCollection, string? segmentC, SortingContainer? sortingContainer)
public Mapping(int? by, MappingFromFilterPost mappingFromFilterPost, MappingFromFilterPre mappingFromFilterPre, MappingFromItem mappingFromItem, MappingFromLocation? mappingFromLocation, MappingFromPerson? mappingFromPerson, List<MappingFromPhotoPrism>? mappingFromPhotoPrismCollection, string? segmentC, SortingContainer? sortingContainer)
{
_By = by;
_SegmentC = segmentC;
MappingFromFilter = mappingFromFilter;
MappingFromFilterPost = mappingFromFilterPost;
MappingFromFilterPre = mappingFromFilterPre;
MappingFromItem = mappingFromItem;
@ -37,8 +34,8 @@ public class Mapping : Properties.IMapping
_SortingContainer = sortingContainer;
}
public Mapping(MappingFromFilter mappingFromFilter, MappingFromFilterPost mappingFromFilterPost, MappingFromFilterPre mappingFromFilterPre, MappingFromItem mappingFromItem, MappingFromLocation? mappingFromLocation, List<MappingFromPhotoPrism>? mappingFromPhotoPrismCollection) :
this(null, mappingFromFilter, mappingFromFilterPost, mappingFromFilterPre, mappingFromItem, mappingFromLocation, null, mappingFromPhotoPrismCollection, null, null)
public Mapping(MappingFromFilterPost mappingFromFilterPost, MappingFromFilterPre mappingFromFilterPre, MappingFromItem mappingFromItem, MappingFromLocation? mappingFromLocation, List<MappingFromPhotoPrism>? mappingFromPhotoPrismCollection) :
this(null, mappingFromFilterPost, mappingFromFilterPre, mappingFromItem, mappingFromLocation, null, mappingFromPhotoPrismCollection, null, null)
{ }
public override string ToString()
@ -54,19 +51,19 @@ public class Mapping : Properties.IMapping
_SegmentC = !saveIndividually ? null : sortingContainer.Sorting.DistancePermyriad.ToString();
}
public void UpdateMappingFromPerson(ReadOnlyCollection<string> locationContainersFiles, int? approximateYears, string displayDirectoryName, PersonBirthday personBirthday, string segmentB)
public void UpdateMappingFromPerson(int? approximateYears, string displayDirectoryName, long personKey, string segmentB)
{
_SortingContainer = null;
_By = Stateless.IMapLogic.Mapping;
_MappingFromPerson = new(approximateYears, displayDirectoryName, locationContainersFiles, personBirthday, segmentB);
_MappingFromPerson = new(approximateYears, displayDirectoryName, personKey, segmentB);
}
public void UpdateMappingFromPerson(int? approximateYears, string displayDirectoryName, PersonBirthday personBirthday, string segmentB, string segmentC, SortingContainer sortingContainer, ReadOnlyCollection<string> locationContainersFiles)
public void UpdateMappingFromPerson(int? approximateYears, string displayDirectoryName, long personKey, string segmentB, string? segmentC, SortingContainer sortingContainer)
{
_SegmentC = segmentC;
_By = Stateless.IMapLogic.Sorting;
_SortingContainer = sortingContainer;
_MappingFromPerson = new(approximateYears, displayDirectoryName, locationContainersFiles, personBirthday, segmentB);
_MappingFromPerson = new(approximateYears, displayDirectoryName, personKey, segmentB);
}
}

View File

@ -1,4 +1,3 @@
using System.Collections.ObjectModel;
using System.Text.Json;
using System.Text.Json.Serialization;
@ -6,8 +5,7 @@ namespace View_by_Distance.Shared.Models;
public record MappingFromPerson(int? ApproximateYears,
string DisplayDirectoryName,
ReadOnlyCollection<string> LocationContainersFiles,
PersonBirthday PersonBirthday,
long PersonKey,
string SegmentB)
{

View File

@ -6,7 +6,6 @@ public interface IMapping
public int? By { get; }
public MappingFromFilterPost MappingFromFilterPost { init; get; }
public MappingFromFilterPre MappingFromFilterPre { init; get; }
public MappingFromItem MappingFromItem { init; get; }
public MappingFromLocation? MappingFromLocation { init; get; }
public MappingFromPerson? MappingFromPerson { get; }
public List<MappingFromPhotoPrism>? MappingFromPhotoPrismCollection { init; get; }

View File

@ -3,7 +3,7 @@ namespace View_by_Distance.Shared.Models.Properties;
public interface ISorting
{
public bool CanReMap { init; get; }
public bool? CanReMap { init; get; }
public int DaysDelta { init; get; }
public int DistancePermyriad { init; get; }
public int Id { init; get; }

View File

@ -3,7 +3,8 @@ namespace View_by_Distance.Shared.Models.Properties;
public interface ISortingContainer
{
public Mapping Mapping { init; get; }
public Mapping? Question { init; get; }
public Sorting Sorting { init; get; }
public Mapping Source { init; get; }
}

View File

@ -6,7 +6,7 @@ namespace View_by_Distance.Shared.Models;
public record class Sorting : Properties.ISorting
{
public bool CanReMap { init; get; }
public bool? CanReMap { init; get; }
public int DaysDelta { init; get; }
public int DistancePermyriad { init; get; }
public int Id { init; get; }
@ -14,7 +14,7 @@ public record class Sorting : Properties.ISorting
public int WholePercentages { init; get; }
[JsonConstructor]
public Sorting(bool canReMap, int daysDelta, int distancePermyriad, int id, bool older, int wholePercentages)
public Sorting(bool? canReMap, int daysDelta, int distancePermyriad, int id, bool older, int wholePercentages)
{
CanReMap = canReMap;
DaysDelta = daysDelta;
@ -25,7 +25,7 @@ public record class Sorting : Properties.ISorting
}
public Sorting(Mapping mapping, MappingFromLocation mappingFromLocation) :
this(false, 0, 0, mapping.MappingFromItem.Id, false, mappingFromLocation.WholePercentages)
this(null, 0, 0, mapping.MappingFromItem.Id, false, mappingFromLocation.WholePercentages)
{ }
public override string ToString()

View File

@ -5,19 +5,25 @@ namespace View_by_Distance.Shared.Models;
public record class SortingContainer : Properties.ISortingContainer
{
public Mapping Mapping { init; get; }
public Mapping? Question { init; get; }
public Sorting Sorting { init; get; }
public Mapping Source { init; get; }
[JsonConstructor]
public SortingContainer(Mapping mapping, Sorting sorting)
public SortingContainer(Mapping? question, Sorting sorting, Mapping source)
{
Mapping = mapping;
Question = question;
Sorting = sorting;
Source = source;
}
public SortingContainer(Sorting sorting, Mapping source) :
this(null, sorting, source)
{ }
public override string ToString()
{
string result = string.Concat(Mapping.MappingFromItem.Id, '\t', Mapping.MappingFromLocation?.WholePercentages, '\t', Sorting.Id, '\t', Sorting.WholePercentages, '\t', Sorting.Older, '\t', '\t', Sorting.DistancePermyriad, '\t', Sorting.DaysDelta);
string result = string.Concat(Source.MappingFromItem.Id, '\t', Source.MappingFromLocation?.WholePercentages, '\t', Sorting.Id, '\t', Sorting.WholePercentages, '\t', Sorting.Older, '\t', '\t', Sorting.DistancePermyriad, '\t', Sorting.DaysDelta);
return result;
}

View File

@ -16,6 +16,9 @@ public interface IPersonBirthday
static bool IsCounterPersonBirthday(Models.PersonBirthday personBirthday) =>
personBirthday.Value.Year < 1809;
static bool IsCounterPersonYear(long personKey) =>
new DateTime(personKey).Year < 1809;
static bool IsCounterPersonYear(int year) =>
year < 1809;

View File

@ -3,11 +3,11 @@ namespace View_by_Distance.Shared.Models.Stateless.Methods;
public interface ISortingContainer
{ // ...
Models.SortingContainer[] TestStatic_Sort(List<Models.SortingContainer> collection) =>
List<Models.SortingContainer> TestStatic_Sort(List<Models.SortingContainer> collection) =>
Sort(collection);
static Models.SortingContainer[] Sort(List<Models.SortingContainer> collection) =>
(from l in collection orderby l.Sorting.DistancePermyriad select l).ToArray();
static Models.SortingContainer[] SortUsingDaysDelta(List<Models.SortingContainer> collection) =>
(from l in collection orderby l.Sorting.DistancePermyriad, l.Sorting.DaysDelta select l).ToArray();
static List<Models.SortingContainer> Sort(List<Models.SortingContainer> collection) =>
(from l in collection orderby l.Sorting.DistancePermyriad select l).ToList();
static List<Models.SortingContainer> SortUsingDaysDelta(List<Models.SortingContainer> collection) =>
(from l in collection orderby l.Sorting.DistancePermyriad, l.Sorting.DaysDelta select l).ToList();
}

View File

@ -15,8 +15,8 @@ internal abstract class Sorting
TimeSpan timeSpan = new(faceDistanceLength.DateTimeOriginalThenMinimumDateTime.Ticks - faceDistanceEncoding.DateTimeOriginalThenMinimumDateTime.Ticks);
bool older = timeSpan.TotalMilliseconds < 0;
int daysDelta = (int)Math.Round(Math.Abs(timeSpan.TotalDays), 0);
bool? canReMap = faceDistanceLength.MappingFromFilterPost?.CanReMap;
int distancePermyriad = (int)(faceDistanceLength.Length.Value * faceDistancePermyriad);
bool canReMap = faceDistanceLength.MappingFromFilterPost?.CanReMap is not null && faceDistanceLength.MappingFromFilterPost.CanReMap.Value;
result = new(canReMap, daysDelta, distancePermyriad, faceDistanceLength.Id.Value, older, faceDistanceLength.WholePercentages.Value);
return result;
}