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

View File

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

View File

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

View File

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

View File

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

View File

@ -1,9 +1,11 @@
using Humanizer; using Humanizer;
using ShellProgressBar; using ShellProgressBar;
using System.Buffers;
using System.Collections.ObjectModel; using System.Collections.ObjectModel;
using System.Globalization; using System.Globalization;
using System.Text.Json; using System.Text.Json;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
using View_by_Distance.Map.Models.Stateless.Methods;
using View_by_Distance.Shared.Models; using View_by_Distance.Shared.Models;
using View_by_Distance.Shared.Models.Stateless.Methods; using View_by_Distance.Shared.Models.Stateless.Methods;
using WindowsShortcutFactory; using WindowsShortcutFactory;
@ -13,26 +15,10 @@ namespace View_by_Distance.Map.Models;
public partial class MapLogic : Shared.Models.Methods.IMapLogic 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("[\\\\,\\/,\\:,\\*,\\?,\\\",\\<,\\>,\\|]")] [GeneratedRegex("[\\\\,\\/,\\:,\\*,\\?,\\\",\\<,\\>,\\|]")]
private static partial Regex FileSystemSafe(); 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) if (_Configuration is null)
throw new NullReferenceException(nameof(_Configuration)); throw new NullReferenceException(nameof(_Configuration));
@ -79,7 +65,7 @@ public partial class MapLogic : Shared.Models.Methods.IMapLogic
} }
else else
continue; continue;
if (saveIndividually) if (_Configuration.SaveIndividually)
{ {
fileName = Path.GetFileName(checkFile); fileName = Path.GetFileName(checkFile);
if (distinct.Contains(fileName)) if (distinct.Contains(fileName))
@ -89,7 +75,7 @@ public partial class MapLogic : Shared.Models.Methods.IMapLogic
if (File.Exists(checkFile)) if (File.Exists(checkFile))
continue; continue;
File.Copy(sourceFile, checkFile); File.Copy(sourceFile, checkFile);
if (saveIndividually) if (_Configuration.SaveIndividually)
continue; continue;
if (saveContainer.MakeAllHidden) if (saveContainer.MakeAllHidden)
File.SetAttributes(checkFile, FileAttributes.Hidden); File.SetAttributes(checkFile, FileAttributes.Hidden);
@ -148,7 +134,6 @@ public partial class MapLogic : Shared.Models.Methods.IMapLogic
if (_Configuration is null) if (_Configuration is null)
throw new NullReferenceException(nameof(_Configuration)); throw new NullReferenceException(nameof(_Configuration));
int season; int season;
long personKey;
string fileName; string fileName;
string directory; string directory;
string weekOfYear; string weekOfYear;
@ -158,7 +143,7 @@ public partial class MapLogic : Shared.Models.Methods.IMapLogic
List<long>? personKeys; List<long>? personKeys;
string personKeyFormatted; string personKeyFormatted;
Calendar calendar = new CultureInfo("en-US").Calendar; 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) foreach (Mapping mapping in mappingCollection)
{ {
dateTime = mapping.MappingFromItem.GetDateTimeOriginalThenMinimumDateTime(); dateTime = mapping.MappingFromItem.GetDateTimeOriginalThenMinimumDateTime();
@ -182,10 +167,9 @@ public partial class MapLogic : Shared.Models.Methods.IMapLogic
continue; continue;
if (!idToPersonKeys.TryGetValue(mapping.MappingFromItem.Id, out personKeys)) if (!idToPersonKeys.TryGetValue(mapping.MappingFromItem.Id, out personKeys))
continue; continue;
personKey = mapping.MappingFromPerson.PersonBirthday.Value.Ticks; if (!personKeys.Contains(mapping.MappingFromPerson.PersonKey))
if (!personKeys.Contains(mapping.MappingFromPerson.PersonBirthday.Value.Ticks))
continue; 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); directory = Path.Combine($"{eDistanceContentDirectory}---", "Person Key Shortcuts", personKeyFormatted, directoryName);
fileName = Path.Combine(directory, $"{mapping.MappingFromItem.ImageFileHolder.Name}.lnk"); fileName = Path.Combine(directory, $"{mapping.MappingFromItem.ImageFileHolder.Name}.lnk");
results.Add(new(mapping.MappingFromItem.ImageFileHolder.FullName, directory, mapping.MappingFromItem.GetDateTimeOriginalThenMinimumDateTime(), fileName, description, MakeAllHidden: false)); 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); 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; int result = 0;
long personKey; if (mapping.MappingFromLocation is not null)
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 (wholePercentagesToPersonContainers is null)
{
if (mapping.MappingFromFilter.InSkipCollection is not null && mapping.MappingFromFilter.InSkipCollection.Value)
continue;
result += 1; result += 1;
continue; else
}
if (!wholePercentagesToPersonContainers.TryGetValue(mapping.MappingFromLocation.WholePercentages, out personContainers))
{ {
if (mapping.MappingFromFilter.InSkipCollection is not null && mapping.MappingFromFilter.InSkipCollection.Value) ReadOnlyCollection<PersonContainer>? personContainers;
continue; if (!wholePercentagesToPersonContainers.TryGetValue(mapping.MappingFromLocation.WholePercentages, out personContainers))
result += 1; result += 1;
continue; else
} {
foreach (PersonContainer personContainer in personContainers) const int zero = 0;
{ string mappingSegmentB;
if (personContainer.Key is null || personContainer.Birthdays is null || personContainer.Birthdays.Length == 0) PersonBirthday personBirthday;
continue; foreach (PersonContainer personContainer in personContainers)
personBirthday = personContainer.Birthdays[zero]; {
personKey = personBirthday.Value.Ticks; if (personContainer.Key is null || personContainer.Birthdays is null || personContainer.Birthdays.Length == 0)
mappingSegmentB = Stateless.MapLogic.GetMappingSegmentB(_Ticks, personBirthday, personContainer.ApproximateYears, mapping.MappingFromItem); continue;
if (locationContainersFiles is null) personBirthday = personContainer.Birthdays[zero];
if (mapping.MappingFromPerson is null || mapping.MappingFromPerson.LocationContainersFiles.Count == 0) mappingSegmentB = Stateless.MapLogic.GetMappingSegmentB(_Ticks, personBirthday, personContainer.ApproximateYears, mapping.MappingFromItem);
locationContainersFiles = new(Array.Empty<string>()); mapping.UpdateMappingFromPerson(personContainer.ApproximateYears, personContainer.DisplayDirectoryName, personContainer.Key.Value, mappingSegmentB);
else }
locationContainersFiles = mapping.MappingFromPerson.LocationContainersFiles; }
mapping.UpdateMappingFromPerson(locationContainersFiles, personContainer.ApproximateYears, personContainer.DisplayDirectoryName, personBirthday, mappingSegmentB);
} }
} }
return result; return result;
@ -498,6 +469,55 @@ public partial class MapLogic : Shared.Models.Methods.IMapLogic
return (ticks, directory); 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) 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) if (_Configuration is null)
@ -506,20 +526,17 @@ public partial class MapLogic : Shared.Models.Methods.IMapLogic
string by; string by;
long? ticks; long? ticks;
List<int>? ids; List<int>? ids;
long personKey;
bool isByMapping; bool isByMapping;
bool isBySorting; bool isBySorting;
Sorting? sorting;
string checkFile; string checkFile;
string? directory; string? directory;
Mapping? question;
string shortcutFile; string shortcutFile;
Mapping? keyMapping;
string facesDirectory; string facesDirectory;
string? directoryName;
string personDirectory; string personDirectory;
FileHolder faceFileHolder; FileHolder faceFileHolder;
string facePartsDirectory; string facePartsDirectory;
string personKeyFormatted;
List<int> distinct = new();
SaveContainer? saveContainer; SaveContainer? saveContainer;
FileHolder facePartsFileHolder; FileHolder facePartsFileHolder;
FileHolder hiddenFaceFileHolder; FileHolder hiddenFaceFileHolder;
@ -530,82 +547,62 @@ public partial class MapLogic : Shared.Models.Methods.IMapLogic
{ {
if (mapping.MappingFromLocation is null) if (mapping.MappingFromLocation is null)
continue; continue;
directoryName = Path.GetDirectoryName(mapping.MappingFromItem.RelativePath); if (mapping.MappingFromFilterPre.InSkipCollection is not null && mapping.MappingFromFilterPre.InSkipCollection.Value)
if (directoryName is null) continue;
throw new NotSupportedException(); if (mapping.MappingFromFilterPre.IsFocusModel is not null && !mapping.MappingFromFilterPre.IsFocusModel.Value)
if (mapping.MappingFromFilter.InSkipCollection is not null && mapping.MappingFromFilter.InSkipCollection.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; continue;
(by, isByMapping, isBySorting) = Stateless.MapLogic.Get(useFiltersCounter, saveIndividually, sortingContainersAny, forceSingleImageHumanized, mapping); (by, isByMapping, isBySorting) = Stateless.MapLogic.Get(useFiltersCounter, saveIndividually, sortingContainersAny, forceSingleImageHumanized, mapping);
if (isByMapping && !saveMapped) if (isByMapping && !saveMapped)
continue; continue;
if (mapping.MappingFromPerson is null) if (!isBySorting || mapping.SortingContainer is null)
{ (sorting, question) = (null, 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);
}
else else
{ {
if (string.IsNullOrEmpty(mapping.MappingFromPerson.SegmentB)) sorting = mapping.SortingContainer.Sorting;
if (!idToWholePercentagesToMapping.TryGetValue(sorting.Id, out wholePercentagesToMapping))
throw new NotSupportedException(); throw new NotSupportedException();
if (string.IsNullOrEmpty(mapping.MappingFromPerson.DisplayDirectoryName)) if (!wholePercentagesToMapping.TryGetValue(sorting.WholePercentages, out question))
throw new NotSupportedException(); throw new NotSupportedException();
personKey = mapping.MappingFromPerson.PersonBirthday.Value.Ticks; if (!PreAndPostContinue(_Configuration, idToWholePercentagesToMapping, sorting, mapping, question))
personKeyFormatted = IPersonBirthday.GetFormatted(_Configuration.PersonBirthdayFormat, mapping.MappingFromPerson.PersonBirthday); continue;
if (string.IsNullOrEmpty(mapping.SegmentC)) }
directory = Path.Combine(_EDistanceContentTicksDirectory, by, personKeyFormatted, mapping.MappingFromPerson.SegmentB); (directory, ticks, personDirectory) = Get(_Configuration, saveIndividually, by, mapping, padLeft);
else if (saveIndividually) if (string.IsNullOrEmpty(directory))
directory = Path.Combine(_EDistanceContentTicksDirectory, by, mapping.SegmentC.PadLeft(padLeft, '0'), personKeyFormatted, mapping.MappingFromPerson.SegmentB); throw new NotSupportedException();
else if (mapping.MappingFromPerson is not null)
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 (saveIndividually) if (saveIndividually)
{ {
directory = Path.Combine(directory, mapping.MappingFromItem.Id.ToString()); directory = Path.Combine(directory, mapping.MappingFromItem.Id.ToString());
results.Add(new(Path.Combine(directory, mapping.MappingFromPerson.DisplayDirectoryName))); 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(Path.Combine(directory, mapping.MappingFromPerson.DisplayDirectoryName, $"{ids.Count} Face(s)")));
} }
results.Add(new(personDirectory));
if (!isBySorting || mapping.SortingContainer is null)
keyMapping = null;
else else
{ {
if (!idToWholePercentagesToMapping.TryGetValue(mapping.SortingContainer.Sorting.Id, out wholePercentagesToMapping)) if (!_Configuration.SaveSortingWithoutPerson)
continue; continue;
if (!wholePercentagesToMapping.TryGetValue(mapping.SortingContainer.Sorting.WholePercentages, out keyMapping)) if (ticks is null)
continue; 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; continue;
if (saveIndividually && keyMapping.MappingFromLocation.WholePercentages == mapping.MappingFromLocation.WholePercentages) if (saveIndividually && question.MappingFromLocation.WholePercentages == mapping.MappingFromLocation.WholePercentages)
results.Add(new(Path.Combine(directory, "Maybe"))); results.Add(new(Path.Combine(directory, "Maybe")));
} }
facesDirectory = Stateless.MapLogic.GetFacesDirectory(_PropertyConfiguration, dFacesContentDirectory, mapping.MappingFromItem); 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}")); 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}")); 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); 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); results.Add(saveContainer);
} }
return results; 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) 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) if (_Configuration is null)
@ -677,42 +643,55 @@ public partial class MapLogic : Shared.Models.Methods.IMapLogic
int? updated = null; int? updated = null;
bool saveMapped = true; bool saveMapped = true;
int? useFiltersCounter = null; int? useFiltersCounter = null;
bool saveIndividually = false;
string mappingDirectory = Path.Combine(_EDistanceContentTicksDirectory, nameof(Shared.Models.Stateless.IMapLogic.Mapping)); 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); 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)) if (!string.IsNullOrEmpty(_EDistanceContentTicksDirectory) && Directory.Exists(mappingDirectory))
Stateless.MapLogic.SaveMappingShortcuts(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) if (_Configuration is null)
throw new NullReferenceException(nameof(_Configuration)); throw new NullReferenceException(nameof(_Configuration));
List<Sorting> results = new(); List<Sorting> results = new();
Sorting sorting; Sorting sorting;
FaceDistance faceDistanceLength; FaceDistance faceDistanceLength;
List<int>? wholePercentagesCollection;
bool skipNotSkipCollectionAny = _SkipNotSkipCollection.Count > 0;
for (int j = 0; j < faceDistanceLengths.Count; j++) for (int j = 0; j < faceDistanceLengths.Count; j++)
{ {
if (faceDistanceEncoding.WholePercentages is null) if (faceDistanceEncoding.WholePercentages is null)
throw new NotSupportedException(); throw new NotSupportedException();
if (face.Mapping?.MappingFromFilter is null) if (face.Mapping?.MappingFromFilterPost is null)
throw new NotSupportedException(); throw new NotSupportedException();
if (j == i) if (j == i)
continue; continue;
if (faceDistanceEncoding.Id is not null && _SkipCollection.TryGetValue(faceDistanceEncoding.Id.Value, out wholePercentagesCollection) && wholePercentagesCollection.Contains(faceDistanceEncoding.WholePercentages.Value)) if (face.Mapping.MappingFromFilterPre.InSkipCollection is not null && face.Mapping.MappingFromFilterPre.InSkipCollection.Value)
continue; throw new NotSupportedException(nameof(Shared.Models.Methods.IDistance<object>));
if (faceDistanceEncoding.Id is not null && skipNotSkipCollectionAny && (!_SkipNotSkipCollection.TryGetValue(faceDistanceEncoding.Id.Value, out wholePercentagesCollection) || !wholePercentagesCollection.Contains(faceDistanceEncoding.WholePercentages.Value))) if (face.Mapping.MappingFromFilterPre.IsFocusModel is not null && face.Mapping.MappingFromFilterPre.IsFocusModel.Value)
continue; throw new NotSupportedException(nameof(Shared.Models.Methods.IDistance<object>));
if (face.Mapping.MappingFromFilter.IsUsed is not null && face.Mapping.MappingFromFilter.IsUsed.Value) if (face.Mapping.MappingFromFilterPre.IsFocusRelativePath is not null && face.Mapping.MappingFromFilterPre.IsFocusRelativePath.Value)
continue; 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]; faceDistanceLength = faceDistanceLengths[j];
if (faceDistanceLength.WholePercentages is null || faceDistanceLength.Length is null) if (faceDistanceLength.WholePercentages is null || faceDistanceLength.Length is null)
throw new NotSupportedException(); throw new NotSupportedException();
if (faceDistanceLength.Length == 0) if (faceDistanceLength.Length == 0)
continue; 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); sorting = ISorting.Get(_Configuration.FaceDistancePermyriad, faceDistanceEncoding, faceDistanceLength);
if (sorting.DistancePermyriad == 0) if (sorting.DistancePermyriad == 0)
continue; continue;
@ -727,7 +706,49 @@ public partial class MapLogic : Shared.Models.Methods.IMapLogic
return results; 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) if (_Configuration is null)
throw new NullReferenceException(nameof(_Configuration)); throw new NullReferenceException(nameof(_Configuration));
@ -736,91 +757,173 @@ public partial class MapLogic : Shared.Models.Methods.IMapLogic
string counts = distanceLimits.GetCounts(); string counts = distanceLimits.GetCounts();
_ = Directory.CreateDirectory(Path.Combine(_EDistanceContentTicksDirectory, counts)); _ = Directory.CreateDirectory(Path.Combine(_EDistanceContentTicksDirectory, counts));
} }
int result = 0; List<SaveContainer> results = new();
string key; string by;
Mapping? mapping; long? ticks;
const int zero = 0; bool isBySorting;
string mappingSegmentB; string checkFile;
string personKeyFormatted; Mapping? question;
PersonBirthday personBirthday; string? directory;
List<int>? wholePercentagesCollectionForA; string shortcutFile;
List<int>? wholePercentagesCollectionForB; string facesDirectory;
Dictionary<string, int> keyToCount = new(); string personDirectory;
Dictionary<string, string> keyToSegmentC = new(); bool isCounterPersonYear;
ReadOnlyCollection<PersonContainer>? personContainers; string facePartsDirectory;
ReadOnlyDictionary<int, Mapping>? wholePercentagesToMapping; FileHolder? faceFileHolder;
Dictionary<int, List<int>> idToWholePercentagesCollectionForA = new(); SaveContainer? saveContainer;
Dictionary<int, List<int>> idToWholePercentagesCollectionForB = new(); FileHolder? facePartsFileHolder;
int totalSeconds = (int)Math.Floor(new TimeSpan(DateTime.Now.Ticks - _Ticks).TotalSeconds); FileHolder? hiddenFaceFileHolder;
ReadOnlyDictionary<int, ReadOnlyCollection<PersonContainer>>? wholePercentagesToPersonContainers; int padLeft = _Configuration.FaceDistancePermyriad.ToString().Length;
string message = $") {sortingContainers.Length:000} Update From Sorting Container(s) - {totalSeconds} total second(s)"; string forceSingleImageHumanized = nameof(Shared.Models.Stateless.IMapLogic.ForceSingleImage).Humanize(LetterCasing.Title);
ProgressBarOptions options = new() { ProgressCharacter = '─', ProgressBarOnBottom = true, DisableBottomPercentage = true };
using ProgressBar progressBar = new(sortingContainers.Length, message, options);
foreach (SortingContainer sortingContainer in sortingContainers) foreach (SortingContainer sortingContainer in sortingContainers)
{ {
progressBar.Tick(); if (sortingContainer.Question is null)
if (sortingContainer.Mapping?.MappingFromLocation is null)
throw new NotSupportedException(); throw new NotSupportedException();
if (!idToWholePercentagesCollectionForA.TryGetValue(sortingContainer.Mapping.MappingFromItem.Id, out wholePercentagesCollectionForA)) 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;
(directory, ticks, personDirectory) = Get(_Configuration, _Configuration.SaveIndividually, by, question, padLeft);
if (string.IsNullOrEmpty(directory))
throw new NotSupportedException();
if (question.MappingFromPerson is not null)
{ {
idToWholePercentagesCollectionForA.Add(sortingContainer.Mapping.MappingFromItem.Id, new()); if (_Configuration.SaveIndividually)
if (!idToWholePercentagesCollectionForA.TryGetValue(sortingContainer.Mapping.MappingFromItem.Id, out wholePercentagesCollectionForA)) {
throw new Exception(); directory = Path.Combine(directory, question.MappingFromItem.Id.ToString());
} results.Add(new(Path.Combine(directory, question.MappingFromPerson.DisplayDirectoryName)));
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)
continue;
if (wholePercentagesCollectionForA.Contains(sortingContainer.Mapping.MappingFromLocation.WholePercentages))
continue;
sortingContainer.Mapping.UpdateMappingFromUnknownPerson(saveIndividually, sortingContainer);
wholePercentagesCollectionForA.Add(sortingContainer.Mapping.MappingFromLocation.WholePercentages);
result += 1;
} }
else else
{ {
if (wholePercentagesCollectionForB.Contains(sortingContainer.Mapping.MappingFromLocation.WholePercentages)) if (!_Configuration.SaveSortingWithoutPerson)
throw new NotSupportedException();
if (ticks is null)
continue; continue;
foreach (PersonContainer personContainer in personContainers) if (_Configuration.SaveIndividually)
{ {
if (personContainer.Key is null || personContainer.Birthdays is null || personContainer.Birthdays.Length == 0) directory = Path.Combine(directory, question.MappingFromItem.Id.ToString());
continue; results.Add(new(Path.Combine(directory, $"X+{ticks}")));
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)
{
keyToCount[key] = 0;
keyToSegmentC[key] = sortingContainer.Sorting.DistancePermyriad.ToString();
}
if (!idToWholePercentagesToMapping.TryGetValue(sortingContainer.Sorting.Id, out wholePercentagesToMapping))
continue;
if (!wholePercentagesToMapping.TryGetValue(sortingContainer.Sorting.WholePercentages, out mapping))
continue;
if (mapping.MappingFromPerson is null)
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;
} }
} }
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)
{
saveContainer = GetMatchSaveContainer(dFacesContentDirectory, d2FacePartsContentDirectory, directory, question);
if (saveContainer is not null)
results.Add(saveContainer);
}
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;
results.Add(extraSaveContainer);
}
results.Add(saveContainer);
} }
return result; 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 (!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;
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 new(results);
} }
private (string, PersonBirthday?) GetPersonBirthday(string[] directoryNames) private (string, PersonBirthday?) GetPersonBirthday(string[] directoryNames)
@ -950,7 +1053,7 @@ public partial class MapLogic : Shared.Models.Methods.IMapLogic
throw new NotSupportedException(); throw new NotSupportedException();
if (string.IsNullOrEmpty(mapping.MappingFromPerson.DisplayDirectoryName)) if (string.IsNullOrEmpty(mapping.MappingFromPerson.DisplayDirectoryName))
throw new NotSupportedException(); 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") if (personKeyFormatted == "1501-04-10_00")
continue; continue;
if (!personKeyFormattedCollection.Contains(personKeyFormatted)) if (!personKeyFormattedCollection.Contains(personKeyFormatted))
@ -985,7 +1088,6 @@ public partial class MapLogic : Shared.Models.Methods.IMapLogic
if (_Configuration is null) if (_Configuration is null)
throw new NullReferenceException(nameof(_Configuration)); throw new NullReferenceException(nameof(_Configuration));
SaveContainer? saveContainer; SaveContainer? saveContainer;
bool saveIndividually = false;
List<SaveContainer> saveContainers = new(); List<SaveContainer> saveContainers = new();
(int, FileHolder, int, string, string, string, string)[] collection = GetCollectionForSaveFilteredOriginalImagesFromJLinks(jLinks, a2PeopleContentDirectory, personContainers, mappingCollection, personKeyToIds); (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) 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); saveContainer = new(imageFileHolder, checkFile, directory);
saveContainers.Add(saveContainer); saveContainers.Add(saveContainer);
} }
SaveContainers(saveIndividually, null, saveContainers); SaveContainers(null, saveContainers);
} }
public void SaveShortcutsForOutputResolutionsPreMapLogic(string eDistanceContentDirectory, ReadOnlyDictionary<long, List<int>> personKeyToIds, ReadOnlyCollection<Mapping> mappingCollection) 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) if (_Configuration is null)
throw new NullReferenceException(nameof(_Configuration)); throw new NullReferenceException(nameof(_Configuration));
long personKey;
string fileName; string fileName;
string fullName; string fullName;
string directory; string directory;
@ -1109,18 +1210,17 @@ public partial class MapLogic : Shared.Models.Methods.IMapLogic
throw new NotSupportedException(); throw new NotSupportedException();
if (string.IsNullOrEmpty(mapping.MappingFromPerson.DisplayDirectoryName)) if (string.IsNullOrEmpty(mapping.MappingFromPerson.DisplayDirectoryName))
throw new NotSupportedException(); throw new NotSupportedException();
personKeyFormatted = IPersonBirthday.GetFormatted(_Configuration.PersonBirthdayFormat, mapping.MappingFromPerson.PersonBirthday); personKeyFormatted = IPersonBirthday.GetFormatted(_Configuration.PersonBirthdayFormat, mapping.MappingFromPerson.PersonKey);
personKey = mapping.MappingFromPerson.PersonBirthday.Value.Ticks;
if (mapping.MappingFromItem.ContainerDateTimes.Length > 0 && !distinct.Contains(mapping.MappingFromItem.ResizedFileHolder.DirectoryName)) if (mapping.MappingFromItem.ContainerDateTimes.Length > 0 && !distinct.Contains(mapping.MappingFromItem.ResizedFileHolder.DirectoryName))
{ {
distinct.Add(mapping.MappingFromItem.ResizedFileHolder.DirectoryName); distinct.Add(mapping.MappingFromItem.ResizedFileHolder.DirectoryName);
directoriesAndDateTimes.Add(new(mapping.MappingFromItem.ResizedFileHolder.DirectoryName, mapping.MappingFromItem.ContainerDateTimes)); directoriesAndDateTimes.Add(new(mapping.MappingFromItem.ResizedFileHolder.DirectoryName, mapping.MappingFromItem.ContainerDateTimes));
} }
directory = Path.Combine(mapping.MappingFromItem.ResizedFileHolder.DirectoryName, $"{_PropertyConfiguration.ResultAllInOne}Shortcuts", personKeyFormatted); 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); personDirectory = Path.Combine(directory, mapping.MappingFromPerson.DisplayDirectoryName);
else 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"); 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)); 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; 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) public void LookForAbandoned(Property.Models.Configuration propertyConfiguration, string bResultsFullGroupDirectory, Container[] containers, string cResultsFullGroupDirectory, string dResultsFullGroupDirectory, string d2ResultsFullGroupDirectory)
{ {
string[] directories; 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); string result = GetMappingSegmentB(ticks, personBirthday, approximateYears, dateTimeOriginalThenMinimumDateTime.Ticks, isWrongYear);
return result; 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(); List<TicksDirectory> results = new();
float? totalDays; float? totalDays;
@ -333,7 +341,7 @@ internal abstract class MapLogic
lastDirectoryTicks = directoryTicks; lastDirectoryTicks = directoryTicks;
} }
string[] compare = (from l in results where l.TotalDays is not null and < 9.95f select l.Directory).ToArray(); 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)}>"); throw new Exception($"Please Consolidate <{string.Join(Environment.NewLine, compare)}>");
return results; return results;
} }
@ -701,7 +709,7 @@ internal abstract class MapLogic
OpenPossibleDuplicates(configuration, duplicates); OpenPossibleDuplicates(configuration, duplicates);
else else
{ {
if (delete.Count > 5) if (delete.Count > 8)
throw new Exception("Something maybe wrong!"); throw new Exception("Something maybe wrong!");
foreach (string file in delete) foreach (string file in delete)
{ {
@ -900,7 +908,7 @@ internal abstract class MapLogic
results.Clear(); results.Clear();
distinct.Clear(); distinct.Clear();
directoryNumber = 0; directoryNumber = 0;
ticksDirectories = UpdateDateVerifyAndGetTicksDirectories(eDistanceContentDirectory); ticksDirectories = UpdateDateVerifyAndGetTicksDirectories(configuration, eDistanceContentDirectory);
totalSeconds = (int)Math.Floor(new TimeSpan(DateTime.Now.Ticks - ticks).TotalSeconds); 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)"; message = $"{i}) {ticksDirectories.Count:000} compile from and clean ticks Director(ies) - B - {totalSeconds} total second(s)";
progressBar = new(ticksDirectories.Count, message, options); progressBar = new(ticksDirectories.Count, message, options);
@ -1351,46 +1359,44 @@ internal abstract class MapLogic
return result; 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; 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; string shortcutFile;
if (mappingFromPerson is null) if (sortingContainer?.Source.MappingFromLocation is null)
shortcutFile = Path.Combine(directory, $"{sortingContainer.Mapping.MappingFromLocation.DeterministicHashCodeKey}{sortingContainer.Mapping.MappingFromItem.ImageFileHolder.ExtensionLowered}.{sortingContainer.Sorting.DistancePermyriad}.lnk"); 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 else
shortcutFile = Path.Combine(directory, $"{sortingContainer.Mapping.MappingFromLocation.DeterministicHashCodeKey}{sortingContainer.Mapping.MappingFromItem.ImageFileHolder.ExtensionLowered}.{sortingContainer.Sorting.DistancePermyriad}.lnk"); shortcutFile = Path.Combine(directory, $"{sortingContainer.Source.MappingFromLocation.DeterministicHashCodeKey}{sortingContainer.Source.MappingFromItem.ImageFileHolder.ExtensionLowered}.{sortingContainer.Sorting.DistancePermyriad}.lnk");
result = new(directory, faceFileHolder, mapping.MappingFromItem.ResizedFileHolder, shortcutFile); result = new(directory, faceFileHolder, sortingContainer.Source.MappingFromItem.ResizedFileHolder, shortcutFile);
return result; 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? result;
SaveContainer? saveContainer; SaveContainer? saveContainer;
if (sortingContainer.Mapping.MappingFromLocation is null) if (keyMapping.MappingFromLocation is null)
throw new NullReferenceException(nameof(sortingContainer.Mapping.MappingFromLocation));
if (mapping.MappingFromLocation is null)
(result, saveContainer) = (null, null); (result, saveContainer) = (null, null);
else else
{ {
string? facePartsContentCollectionFile = GetFacePartsContentCollectionFile(facePartsFileNameExtension, d2FacePartsContentCollectionDirectory, mapping.MappingFromItem); string? facePartsContentCollectionFile = GetFacePartsContentCollectionFile(facePartsFileNameExtension, d2FacePartsContentCollectionDirectory, keyMapping.MappingFromItem);
if (facePartsContentCollectionFile is null || !File.Exists(facePartsContentCollectionFile)) if (facePartsContentCollectionFile is null || !File.Exists(facePartsContentCollectionFile))
result = null; result = null;
else 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)); result = new(checkFile, directory, new(facePartsContentCollectionFile));
} }
string facesDirectory = GetFacesDirectory(propertyConfiguration, dFacesContentDirectory, mapping.MappingFromItem); string facesDirectory = GetFacesDirectory(propertyConfiguration, dFacesContentDirectory, keyMapping.MappingFromItem);
FileHolder faceFileHolder = new(Path.Combine(facesDirectory, $"{mapping.MappingFromLocation.DeterministicHashCodeKey}{mapping.MappingFromItem.ImageFileHolder.ExtensionLowered}{facesFileNameExtension}")); FileHolder faceFileHolder = new(Path.Combine(facesDirectory, $"{keyMapping.MappingFromLocation.DeterministicHashCodeKey}{keyMapping.MappingFromItem.ImageFileHolder.ExtensionLowered}{facesFileNameExtension}"));
if (!faceFileHolder.Exists) if (!faceFileHolder.Exists)
saveContainer = null; saveContainer = null;
else 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); saveContainer = new(checkFile, directory, faceFileHolder);
} }
} }
@ -1578,19 +1584,20 @@ internal abstract class MapLogic
{ {
isByMapping = mapping.By == Shared.Models.Stateless.IMapLogic.Mapping; isByMapping = mapping.By == Shared.Models.Stateless.IMapLogic.Mapping;
isBySorting = mapping.By == Shared.Models.Stateless.IMapLogic.Sorting; 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) if (isBySorting && mapping.MappingFromPerson is null)
by = saveIndividually ? nameof(Shared.Models.Stateless.IMapLogic.Individually) : $"{nameof(Shared.Models.Stateless.IMapLogic.Sorting)} Without Person"; by = saveIndividually ? nameof(Shared.Models.Stateless.IMapLogic.Individually) : $"{nameof(Shared.Models.Stateless.IMapLogic.Sorting)} Without Person";
else if (isBySorting && useFiltersCounter.HasValue) 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 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.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.Sorting => saveIndividually ? nameof(Shared.Models.Stateless.IMapLogic.Individually) : nameof(Shared.Models.Stateless.IMapLogic.Sorting),
Shared.Models.Stateless.IMapLogic.ForceSingleImage => forceSingleImageHumanized, Shared.Models.Stateless.IMapLogic.ForceSingleImage => forceSingleImageHumanized,
_ => throw new NotImplementedException() _ => throw new NotImplementedException()
}; }}{(!isDefaultName ? "-A" : "-Z")}";
} }
} }
return new(by, isByMapping, isBySorting); return new(by, isByMapping, isBySorting);
@ -1675,24 +1682,26 @@ internal abstract class MapLogic
return new(results); return new(results);
} }
internal static void SetCreationTime(MappingFromItem mappingFromItem, MappingFromPerson mappingFromPerson) internal static string GetDecade(MappingFromItem mappingFromItem)
{ {
DateTime dateTime; string result;
FileInfo fileInfo; string year;
foreach (string locationContainersFile in mappingFromPerson.LocationContainersFiles) if (mappingFromItem.DateTimeOriginal is null)
{ {
fileInfo = new(locationContainersFile); year = mappingFromItem.MinimumDateTime.Year.ToString();
if (!fileInfo.Exists) result = year[3] > '4' ? $"#{year[..3]}+" : $"#{year[..3]}-";
continue;
dateTime = mappingFromItem.DateTimeOriginal is null ? mappingFromItem.MinimumDateTime : mappingFromItem.DateTimeOriginal.Value;
if (fileInfo.CreationTime != dateTime)
File.SetCreationTime(locationContainersFile, dateTime);
} }
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; FileInfo fileInfo;
string halfDecade; string halfDecade;
string checkDirectory; string checkDirectory;
@ -1702,12 +1711,17 @@ internal abstract class MapLogic
string personNameDirectoryName; string personNameDirectoryName;
string? personKeyFormattedDirectory; string? personKeyFormattedDirectory;
string? personKeyFormattedDirectoryName; 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) if (!fileInfo.Exists)
continue; 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)) if (string.IsNullOrEmpty(personNameDirectory))
continue; continue;
personNameDirectoryName = Path.GetFileName(personNameDirectory); personNameDirectoryName = Path.GetFileName(personNameDirectory);
@ -1721,22 +1735,13 @@ internal abstract class MapLogic
personKeyFormattedDirectoryName = Path.GetFileName(personKeyFormattedDirectory); personKeyFormattedDirectoryName = Path.GetFileName(personKeyFormattedDirectory);
if (personKeyFormattedDirectoryName.Length != propertyConfiguration.PersonBirthdayFormat.Length) if (personKeyFormattedDirectoryName.Length != propertyConfiguration.PersonBirthdayFormat.Length)
break; break;
if (mappingFromItem.DateTimeOriginal is null) halfDecade = GetDecade(mappingFromItem);
{
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]}-";
}
if (halfDecade == yearDirectoryName) if (halfDecade == yearDirectoryName)
continue; continue;
checkDirectory = Path.Combine(personKeyFormattedDirectory, halfDecade, personNameDirectoryName); checkDirectory = Path.Combine(personKeyFormattedDirectory, halfDecade, personNameDirectoryName);
if (!Directory.Exists(checkDirectory)) if (!Directory.Exists(checkDirectory))
_ = Directory.CreateDirectory(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)) if (!wholePercentagesToPersonContainers.TryGetValue(mappingFromLocation.WholePercentages, out personContainers))
result = null; result = null;
else 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; 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) => 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); MapLogic.GetJLinkDirectories(genealogicalDataCommunicationFile, jLinks, personBirthdayFormat, personCharacters, a2PeopleSingletonDirectory, a2PeopleContentDirectory);
void TestStatic_SetCreationTime(Shared.Models.MappingFromItem mappingFromItem, Shared.Models.MappingFromPerson mappingFromPerson) => void TestStatic_SetCreationTimeMaybeMoveToDecade(Property.Models.Configuration propertyConfiguration, bool moveToDecade, Shared.Models.MappingFromItem mappingFromItem, ReadOnlyCollection<Shared.Models.LocationContainer<MetadataExtractor.Directory>> locationContainers) =>
SetCreationTime(mappingFromItem, mappingFromPerson); SetCreationTimeMaybeMoveToDecade(propertyConfiguration, moveToDecade, mappingFromItem, locationContainers);
static void SetCreationTime(Shared.Models.MappingFromItem mappingFromItem, Shared.Models.MappingFromPerson mappingFromPerson) => static void SetCreationTimeMaybeMoveToDecade(Property.Models.Configuration propertyConfiguration, bool moveToDecade, Shared.Models.MappingFromItem mappingFromItem, ReadOnlyCollection<Shared.Models.LocationContainer<MetadataExtractor.Directory>> locationContainers) =>
MapLogic.SetCreationTime(mappingFromItem, mappingFromPerson); MapLogic.SetCreationTimeMaybeMoveToDecade(propertyConfiguration, moveToDecade, mappingFromItem, locationContainers);
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);
bool? TestStatic_CanReMap(long[] jLinkResolvedPersonKeys, ReadOnlyDictionary<int, ReadOnlyCollection<Shared.Models.PersonContainer>>? wholePercentagesToPersonContainers, Shared.Models.MappingFromLocation mappingFromLocation) => bool? TestStatic_CanReMap(long[] jLinkResolvedPersonKeys, ReadOnlyDictionary<int, ReadOnlyCollection<Shared.Models.PersonContainer>>? wholePercentagesToPersonContainers, Shared.Models.MappingFromLocation mappingFromLocation) =>
CanReMap(jLinkResolvedPersonKeys, wholePercentagesToPersonContainers, mappingFromLocation); CanReMap(jLinkResolvedPersonKeys, wholePercentagesToPersonContainers, mappingFromLocation);
static bool? CanReMap(long[] jLinkResolvedPersonKeys, ReadOnlyDictionary<int, ReadOnlyCollection<Shared.Models.PersonContainer>>? wholePercentagesToPersonContainers, Shared.Models.MappingFromLocation mappingFromLocation) => static bool? CanReMap(long[] jLinkResolvedPersonKeys, ReadOnlyDictionary<int, ReadOnlyCollection<Shared.Models.PersonContainer>>? wholePercentagesToPersonContainers, Shared.Models.MappingFromLocation mappingFromLocation) =>
MapLogic.CanReMap(jLinkResolvedPersonKeys, wholePercentagesToPersonContainers, 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) - [merge-kristy-files](tasks/merge-kristy-files.md)
- [review-location-container-distance-tolerance](tasks/review-location-container-distance-tolerance.md) - [review-location-container-distance-tolerance](tasks/review-location-container-distance-tolerance.md)
- [can-re-map](tasks/can-re-map.md)
## Done ## 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;
using System.Text.Json.Serialization; using System.Text.Json.Serialization;
@ -15,7 +14,6 @@ public class Mapping : Properties.IMapping
public MappingFromFilterPost MappingFromFilterPost { init; get; } public MappingFromFilterPost MappingFromFilterPost { init; get; }
public MappingFromFilterPre MappingFromFilterPre { init; get; } public MappingFromFilterPre MappingFromFilterPre { init; get; }
public MappingFromItem MappingFromItem { init; get; } public MappingFromItem MappingFromItem { init; get; }
public MappingFromFilter MappingFromFilter { init; get; }
public MappingFromLocation? MappingFromLocation { init; get; } public MappingFromLocation? MappingFromLocation { init; get; }
public MappingFromPerson? MappingFromPerson => _MappingFromPerson; public MappingFromPerson? MappingFromPerson => _MappingFromPerson;
public List<MappingFromPhotoPrism>? MappingFromPhotoPrismCollection { init; get; } public List<MappingFromPhotoPrism>? MappingFromPhotoPrismCollection { init; get; }
@ -23,11 +21,10 @@ public class Mapping : Properties.IMapping
public SortingContainer? SortingContainer => _SortingContainer; public SortingContainer? SortingContainer => _SortingContainer;
[JsonConstructor] [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; _By = by;
_SegmentC = segmentC; _SegmentC = segmentC;
MappingFromFilter = mappingFromFilter;
MappingFromFilterPost = mappingFromFilterPost; MappingFromFilterPost = mappingFromFilterPost;
MappingFromFilterPre = mappingFromFilterPre; MappingFromFilterPre = mappingFromFilterPre;
MappingFromItem = mappingFromItem; MappingFromItem = mappingFromItem;
@ -37,8 +34,8 @@ public class Mapping : Properties.IMapping
_SortingContainer = sortingContainer; _SortingContainer = sortingContainer;
} }
public Mapping(MappingFromFilter mappingFromFilter, MappingFromFilterPost mappingFromFilterPost, MappingFromFilterPre mappingFromFilterPre, MappingFromItem mappingFromItem, MappingFromLocation? mappingFromLocation, List<MappingFromPhotoPrism>? mappingFromPhotoPrismCollection) : public Mapping(MappingFromFilterPost mappingFromFilterPost, MappingFromFilterPre mappingFromFilterPre, MappingFromItem mappingFromItem, MappingFromLocation? mappingFromLocation, List<MappingFromPhotoPrism>? mappingFromPhotoPrismCollection) :
this(null, mappingFromFilter, mappingFromFilterPost, mappingFromFilterPre, mappingFromItem, mappingFromLocation, null, mappingFromPhotoPrismCollection, null, null) this(null, mappingFromFilterPost, mappingFromFilterPre, mappingFromItem, mappingFromLocation, null, mappingFromPhotoPrismCollection, null, null)
{ } { }
public override string ToString() public override string ToString()
@ -54,19 +51,19 @@ public class Mapping : Properties.IMapping
_SegmentC = !saveIndividually ? null : sortingContainer.Sorting.DistancePermyriad.ToString(); _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; _SortingContainer = null;
_By = Stateless.IMapLogic.Mapping; _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; _SegmentC = segmentC;
_By = Stateless.IMapLogic.Sorting; _By = Stateless.IMapLogic.Sorting;
_SortingContainer = sortingContainer; _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;
using System.Text.Json.Serialization; using System.Text.Json.Serialization;
@ -6,8 +5,7 @@ namespace View_by_Distance.Shared.Models;
public record MappingFromPerson(int? ApproximateYears, public record MappingFromPerson(int? ApproximateYears,
string DisplayDirectoryName, string DisplayDirectoryName,
ReadOnlyCollection<string> LocationContainersFiles, long PersonKey,
PersonBirthday PersonBirthday,
string SegmentB) string SegmentB)
{ {

View File

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

View File

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

View File

@ -3,7 +3,8 @@ namespace View_by_Distance.Shared.Models.Properties;
public interface ISortingContainer public interface ISortingContainer
{ {
public Mapping Mapping { init; get; } public Mapping? Question { init; get; }
public Sorting Sorting { 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 record class Sorting : Properties.ISorting
{ {
public bool CanReMap { init; get; } public bool? CanReMap { init; get; }
public int DaysDelta { init; get; } public int DaysDelta { init; get; }
public int DistancePermyriad { init; get; } public int DistancePermyriad { init; get; }
public int Id { init; get; } public int Id { init; get; }
@ -14,7 +14,7 @@ public record class Sorting : Properties.ISorting
public int WholePercentages { init; get; } public int WholePercentages { init; get; }
[JsonConstructor] [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; CanReMap = canReMap;
DaysDelta = daysDelta; DaysDelta = daysDelta;
@ -25,7 +25,7 @@ public record class Sorting : Properties.ISorting
} }
public Sorting(Mapping mapping, MappingFromLocation mappingFromLocation) : 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() public override string ToString()

View File

@ -5,19 +5,25 @@ namespace View_by_Distance.Shared.Models;
public record class SortingContainer : Properties.ISortingContainer public record class SortingContainer : Properties.ISortingContainer
{ {
public Mapping Mapping { init; get; } public Mapping? Question { init; get; }
public Sorting Sorting { init; get; } public Sorting Sorting { init; get; }
public Mapping Source { init; get; }
[JsonConstructor] [JsonConstructor]
public SortingContainer(Mapping mapping, Sorting sorting) public SortingContainer(Mapping? question, Sorting sorting, Mapping source)
{ {
Mapping = mapping; Question = question;
Sorting = sorting; Sorting = sorting;
Source = source;
} }
public SortingContainer(Sorting sorting, Mapping source) :
this(null, sorting, source)
{ }
public override string ToString() 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; return result;
} }

View File

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

View File

@ -3,11 +3,11 @@ namespace View_by_Distance.Shared.Models.Stateless.Methods;
public interface ISortingContainer public interface ISortingContainer
{ // ... { // ...
Models.SortingContainer[] TestStatic_Sort(List<Models.SortingContainer> collection) => List<Models.SortingContainer> TestStatic_Sort(List<Models.SortingContainer> collection) =>
Sort(collection); Sort(collection);
static Models.SortingContainer[] Sort(List<Models.SortingContainer> collection) => static List<Models.SortingContainer> Sort(List<Models.SortingContainer> collection) =>
(from l in collection orderby l.Sorting.DistancePermyriad select l).ToArray(); (from l in collection orderby l.Sorting.DistancePermyriad select l).ToList();
static Models.SortingContainer[] SortUsingDaysDelta(List<Models.SortingContainer> collection) => static List<Models.SortingContainer> SortUsingDaysDelta(List<Models.SortingContainer> collection) =>
(from l in collection orderby l.Sorting.DistancePermyriad, l.Sorting.DaysDelta select l).ToArray(); (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); TimeSpan timeSpan = new(faceDistanceLength.DateTimeOriginalThenMinimumDateTime.Ticks - faceDistanceEncoding.DateTimeOriginalThenMinimumDateTime.Ticks);
bool older = timeSpan.TotalMilliseconds < 0; bool older = timeSpan.TotalMilliseconds < 0;
int daysDelta = (int)Math.Round(Math.Abs(timeSpan.TotalDays), 0); int daysDelta = (int)Math.Round(Math.Abs(timeSpan.TotalDays), 0);
bool? canReMap = faceDistanceLength.MappingFromFilterPost?.CanReMap;
int distancePermyriad = (int)(faceDistanceLength.Length.Value * faceDistancePermyriad); 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); result = new(canReMap, daysDelta, distancePermyriad, faceDistanceLength.Id.Value, older, faceDistanceLength.WholePercentages.Value);
return result; return result;
} }