MoveToDecade
This commit is contained in:
Mike Phares 2023-08-06 17:19:06 -07:00
parent 6d17380430
commit d4cbea3835
41 changed files with 974 additions and 637 deletions

View File

@ -59,7 +59,7 @@ public class DeleteByRelative
throw new NullReferenceException(nameof(alongSideDirectory));
string deleteLog = Path.Combine(alongSideDirectory, $"{directoryName}-{ticks}.tsv");
File.WriteAllLines(deleteLog, deleteFiles);
if (deleteFiles.Any())
if (deleteFiles.Count > 0)
{
log.Information($"Ready to delete {deleteFiles.Count} file(s)? See <{deleteLog}>");
for (int y = 0; y < int.MaxValue; y++)

View File

@ -1,4 +1,5 @@
using ShellProgressBar;
using System.Collections.ObjectModel;
using System.Text.Json;
using View_by_Distance.Distance.Models.Stateless;
using View_by_Distance.FaceRecognitionDotNet;
@ -122,7 +123,7 @@ public partial class E_Distance
(Face, double?)[] results;
List<(Face Face, double? Length)> collection = GetValues(mappingFromItem, intersectFaces, modelsFaceEncoding);
results = (from l in collection where l.Length < _RangeDistanceToleranceAverage orderby l.Length select l).Take(1).ToArray();
if (results.Any())
if (results.Length > 0)
{
(Face _, double? length) = results.First();
_Debug.Add(length);
@ -199,7 +200,7 @@ public partial class E_Distance
}
}
public void LookForMatchFacesAndPossiblyRename(string facesFileNameExtension, MappingFromItem mappingFromItem, List<Face> faces, List<LocationContainer<MetadataExtractor.Directory>> locationContainers)
public void LookForMatchFacesAndPossiblyRename(string facesFileNameExtension, MappingFromItem mappingFromItem, List<Face> faces, ReadOnlyCollection<LocationContainer<MetadataExtractor.Directory>> locationContainers)
{
string? json;
string fileName;
@ -219,7 +220,7 @@ public partial class E_Distance
if (locationContainer.FromDistanceContent && _DuplicateMappedFaceFiles.Contains(fileName))
continue;
checkFaces.Clear();
if (!locationContainer.Directories.Any())
if (locationContainer.Directories.Count == 0)
{
if (locationContainer.FromDistanceContent)
throw new NullReferenceException(nameof(locationContainer.Directories));
@ -232,7 +233,7 @@ public partial class E_Distance
MoveUnableToMatch(locationContainer.File);
continue;
}
if (filteredFaces.Any())
if (filteredFaces.Length > 0)
checkFaces.AddRange(GetMatchingFacesByFaceEncoding(filteredFaces, json));
if (checkFaces.Count == 1)
_Debug.Add(0);
@ -242,14 +243,14 @@ public partial class E_Distance
modelsFaceEncoding = JsonSerializer.Deserialize<Shared.Models.FaceEncoding>(json);
if (modelsFaceEncoding is null)
throw new NotSupportedException();
if (filteredFaces.Any())
if (filteredFaces.Length > 0)
{
intersectFaces = Shared.Models.Stateless.Methods.ILocation.FilterByIntersect(filteredFaces, _RectangleIntersectMinimum, locationContainer.WholePercentages);
if (intersectFaces.Any())
if (intersectFaces.Count > 0)
checkFaces.AddRange(GetClosestFaceByDistanceIgnoringTolerance(mappingFromItem, intersectFaces, modelsFaceEncoding));
}
}
if (!checkFaces.Any())
if (checkFaces.Count == 0)
{
if (_DistanceMoveUnableToMatch)
MoveUnableToMatch(locationContainer.File);
@ -279,7 +280,7 @@ public partial class E_Distance
{
lock (_AllMappedFaceFiles)
matches = (from l in _AllMappedFaceFiles where l != locationContainer.File && Path.GetFileName(l) == fileName select l).ToArray();
if (locationContainer.FromDistanceContent && matches.Any())
if (locationContainer.FromDistanceContent && matches.Length > 0)
AppendMatchingDuplicates(locationContainer.File, matches);
}
if (!locationContainer.FromDistanceContent)
@ -296,14 +297,14 @@ public partial class E_Distance
if (_Log is null)
throw new NullReferenceException(nameof(_Log));
double?[] debug = (from l in _Debug where l is null or not 0 select l).ToArray();
if (debug.Any())
if (debug.Length > 0)
{
string debugMessage = $"{_Debug.Count - debug.Length} - {debug.Min()} - {_Debug.Max()}";
_Log.Info(debugMessage);
}
if (_DuplicateMappedFaceFiles.Any())
if (_DuplicateMappedFaceFiles.Count > 0)
_Log.Info($"Renamed {_DuplicateMappedFaceFiles.Count} to *.dup file(s)");
if (_Moved.Any() || _Renamed.Any())
if (_Moved.Count > 0 || _Renamed.Count > 0)
throw new NotImplementedException("Restart!");
_Debug.Clear();
_Moved.Clear();
@ -313,7 +314,7 @@ public partial class E_Distance
_DuplicateMappedFaceFiles.Clear();
}
public List<FaceDistanceContainer> GetMissingFaceDistanceContainer(int maxDegreeOfParallelism, long ticks, string dFacesCollectionDirectory, Dictionary<int, Dictionary<int, PersonContainer[]>> missingIdThenWholePercentagesToPersonContainers)
public List<FaceDistanceContainer> GetMissingFaceDistanceContainer(int maxDegreeOfParallelism, long ticks, string dFacesCollectionDirectory, Dictionary<int, ReadOnlyDictionary<int, ReadOnlyCollection<PersonContainer>>> missingIdThenWholePercentagesToPersonContainers)
{
List<FaceDistanceContainer> results = new();
string[] files;
@ -324,7 +325,7 @@ public partial class E_Distance
FaceDistance faceDistance;
List<(int id, string json)> collection = new();
FaceDistanceContainer faceDistanceContainer;
foreach (KeyValuePair<int, Dictionary<int, PersonContainer[]>> keyValuePair in missingIdThenWholePercentagesToPersonContainers)
foreach (KeyValuePair<int, ReadOnlyDictionary<int, ReadOnlyCollection<PersonContainer>>> keyValuePair in missingIdThenWholePercentagesToPersonContainers)
{
files = Directory.GetFiles(dFacesCollectionDirectory, $"{keyValuePair.Key}*.json", SearchOption.TopDirectoryOnly);
if (files.Length != 1)
@ -530,16 +531,16 @@ public partial class E_Distance
FaceDistance faceDistanceEncoding = filteredFaceDistanceContainers[i].FaceDistance;
Face face = filteredFaceDistanceContainers[i].Face;
List<Sorting> sortingCollection = GetSortingCollection(mapLogic, faceDistanceEncodings, i, faceDistanceEncoding);
if (!sortingCollection.Any())
if (sortingCollection.Count == 0)
return;
List<SortingContainer> sortingContainers = GetSortingContainers(mapConfiguration, distanceLimits, face, faceDistanceEncoding, sortingCollection);
if (sortingContainers.Any())
if (sortingContainers.Count > 0)
{
lock (collection)
collection.AddRange(sortingContainers);
}
});
if (!collection.Any())
if (collection.Count == 0)
results = Array.Empty<SortingContainer>();
else
{

View File

@ -125,7 +125,7 @@ public partial class DragDropExplorer : Form
{
try
{
if (e.Data is null || e.Data.GetData(DataFormats.FileDrop) is not string[] paths || !paths.Any())
if (e.Data is null || e.Data.GetData(DataFormats.FileDrop) is not string[] paths || paths.Length == 0)
{
_FirstTextBox.Text = string.Empty;
_PathTextBox.Text = string.Empty;

View File

@ -179,7 +179,7 @@ public partial class DragDropMove : Form
{
try
{
if (e.Data is not null && e.Data.GetData(DataFormats.FileDrop) is string[] paths && paths.Any())
if (e.Data is not null && e.Data.GetData(DataFormats.FileDrop) is string[] paths && paths.Length > 0)
MovePaths(paths);
else
{

View File

@ -1,3 +1,4 @@
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.Drawing;
using System.Drawing.Imaging;
@ -239,7 +240,7 @@ public class D_Face
List<(Location Location, FaceRecognitionDotNet.FaceEncoding? FaceEncoding, Dictionary<FacePart, FacePoint[]>? FaceParts)> collection;
FaceRecognition faceRecognition = new(_PropertyConfiguration.NumberOfJitters.Value, _PropertyConfiguration.NumberOfTimesToUpsample.Value, _Model, _ModelParameter, _PredictorModel);
collection = faceRecognition.GetCollection(unknownImage, locations, includeFaceEncoding: true, includeFaceParts: true);
if (!collection.Any())
if (collection.Count == 0)
results.Add(new(property, outputResolutionWidth, outputResolutionHeight, outputResolutionOrientation, location: null));
else
{
@ -268,7 +269,7 @@ public class D_Face
#pragma warning restore CA1416
private static List<LocationContainer<MetadataExtractor.Directory>> GetLocationContainers(string outputResolution, List<LocationContainer<MetadataExtractor.Directory>> locationContainers, Dictionary<string, int[]> outputResolutionToResize, List<Shared.Models.Face> faces)
private static List<LocationContainer<MetadataExtractor.Directory>> GetLocationContainers(string outputResolution, ReadOnlyCollection<LocationContainer<MetadataExtractor.Directory>> locationContainers, Dictionary<string, int[]> outputResolutionToResize, List<Shared.Models.Face> faces)
{
List<LocationContainer<MetadataExtractor.Directory>> results = new();
string? json;
@ -309,12 +310,12 @@ public class D_Face
results.Add(new(locationContainer.FromDistanceContent, locationContainer.File, locationContainer.PersonKey, locationContainer.Id, locationContainer.WholePercentages, locationContainer.Directories, rectangle.Value, location));
}
}
if (results.Any())
if (results.Count > 0)
outputResolutionCheck = null;
return results;
}
public List<Shared.Models.Face> GetFaces(string outputResolution, string dResultsFullGroupDirectory, List<Tuple<string, DateTime>> subFileTuples, List<string> parseExceptions, Shared.Models.Property property, MappingFromItem mappingFromItem, Dictionary<string, int[]> outputResolutionToResize, List<LocationContainer<MetadataExtractor.Directory>>? locationContainers, List<MappingFromPhotoPrism>? mappingFromPhotoPrismCollection)
public List<Shared.Models.Face> GetFaces(string outputResolution, string dResultsFullGroupDirectory, List<Tuple<string, DateTime>> subFileTuples, List<string> parseExceptions, Shared.Models.Property property, MappingFromItem mappingFromItem, Dictionary<string, int[]> outputResolutionToResize, ReadOnlyCollection<LocationContainer<MetadataExtractor.Directory>>? locationContainers, List<MappingFromPhotoPrism>? mappingFromPhotoPrismCollection)
{
List<Shared.Models.Face>? results;
if (string.IsNullOrEmpty(dResultsFullGroupDirectory))
@ -339,7 +340,7 @@ public class D_Face
results = null;
else if (!fileInfo.Exists)
results = null;
else if (_CheckDFaceAndUpWriteDates && dateTimes.Any() && dateTimes.Max() > fileInfo.LastWriteTime)
else if (_CheckDFaceAndUpWriteDates && dateTimes.Count > 0 && dateTimes.Max() > fileInfo.LastWriteTime)
results = null;
else
{
@ -366,14 +367,14 @@ public class D_Face
locations = (from l in collection where l is not null select l.Location).ToList();
else
locations = Shared.Models.Stateless.Methods.ILocation.GetLocations(collection, results, mappingFromPhotoPrismCollection, _RectangleIntersectMinimum);
if (results is null || (locations is not null && locations.Any()))
if (results is null || (locations is not null && locations.Count > 0))
{
results = GetFaces(outputResolution, property, mappingFromItem, outputResolutionToResize, locations);
if (!results.Any())
if (results.Count == 0)
File.Move(mappingFromItem.ResizedFileHolder.FullName, $"{mappingFromItem.ResizedFileHolder.FullName}.err");
else
{
bool updateDateWhenMatches = dateTimes.Any() && fileInfo.Exists && dateTimes.Max() > fileInfo.LastWriteTime;
bool updateDateWhenMatches = dateTimes.Count > 0 && fileInfo.Exists && dateTimes.Max() > fileInfo.LastWriteTime;
DateTime? dateTime = !updateDateWhenMatches ? null : dateTimes.Max();
json = JsonSerializer.Serialize(results, _WriteIndentedAndWhenWritingNull);
if (Shared.Models.Stateless.Methods.IPath.WriteAllText(fileInfo.FullName, json, updateDateWhenMatches, compareBeforeWrite: true, updateToWhenMatches: dateTime))
@ -419,7 +420,7 @@ public class D_Face
save = true;
else if (!fileInfo.Exists)
save = true;
else if (_CheckDFaceAndUpWriteDates && dateTimes.Any() && dateTimes.Max() > fileInfo.LastWriteTime)
else if (_CheckDFaceAndUpWriteDates && dateTimes.Count > 0 && dateTimes.Max() > fileInfo.LastWriteTime)
save = true;
results.Add(new(face, fileInfo, Path.Combine(directory, $"{deterministicHashCodeKey}{mappingFromItem.ImageFileHolder.ExtensionLowered}{_HiddenFileNameExtension}"), save));
}

View File

@ -96,7 +96,7 @@ internal sealed class FaceRecognitionModelV1
throw new ApplicationException();
}
if (faceChipsArray.Any())
if (faceChipsArray.Count > 0)
{
foreach (Array<Matrix<RgbPixel>>? array in faceChipsArray)
{

View File

@ -128,7 +128,7 @@ public partial class DlibDotNet
_ = Shared.Models.Stateless.Methods.IPath.DeleteEmptyDirectories(Path.Combine(peopleRootDirectory, propertyConfiguration.ResultSingleton));
string a2PeopleContentDirectory = Property.Models.Stateless.IResult.GetResultsDateGroupDirectory(configuration.PropertyConfiguration, nameof(A2_People), "([])");
personContainers = new(IPersonContainer.GetPersonContainers(storage, configuration.PersonBirthdayFormat, configuration.PersonCharacters.ToArray(), _Faces.FileNameExtension));
if (configuration.JLinks.Length > 0)
if (configuration.JLinks.Where(l => !string.IsNullOrEmpty(l)).Any())
{
string a2PeopleSingletonDirectory = Property.Models.Stateless.IResult.GetResultsDateGroupDirectory(configuration.PropertyConfiguration, nameof(A2_People), "{}");
_JLinkResolvedDirectories.AddRange(Map.Models.Stateless.Methods.IMapLogic.GetJLinkDirectories(configuration.GenealogicalDataCommunicationFile, configuration.JLinks, configuration.PersonBirthdayFormat, configuration.PersonCharacters.ToArray(), a2PeopleSingletonDirectory, a2PeopleContentDirectory));
@ -201,7 +201,7 @@ public partial class DlibDotNet
private static void Verify(Models.Configuration configuration)
{
if (!configuration.OutputResolutions.Any() || string.IsNullOrEmpty(configuration.OutputResolutions[0]) || !configuration.ValidResolutions.Contains(configuration.OutputResolutions[0]))
if (configuration.OutputResolutions.Length == 0 || string.IsNullOrEmpty(configuration.OutputResolutions[0]) || !configuration.ValidResolutions.Contains(configuration.OutputResolutions[0]))
throw new NullReferenceException($"{nameof(configuration.OutputResolutions)} must be fileNameToCollection valid outputResolution!");
if ((from l in configuration.OutputResolutions where !configuration.ValidResolutions.Contains(l) select false).Any())
throw new Exception($"One or more {nameof(configuration.OutputResolutions)} are not in the ValidResolutions list!");
@ -228,7 +228,7 @@ public partial class DlibDotNet
private void VerifyExtra(List<string> args, Property.Models.Configuration propertyConfiguration, Models.Configuration configuration)
{
string[] sourceDirectoryNames;
if (!args.Any())
if (args.Count == 0)
sourceDirectoryNames = Array.Empty<string>();
else
{
@ -249,7 +249,7 @@ public partial class DlibDotNet
}
}
string[] resizeMatch = (from l in sourceDirectoryNames where configuration.ValidResolutions.Contains(l) select l).ToArray();
if (resizeMatch.Any())
if (resizeMatch.Length > 0)
throw new Exception("Input directory should be the source and not fileNameToCollection resized directory!");
if (configuration.LocationDigits != Shared.Models.Stateless.ILocation.Digits)
throw new Exception("Configuration has to match interface!");
@ -294,7 +294,7 @@ public partial class DlibDotNet
return result;
}
private void SetMapping(MapLogic mapLogic, Item item, bool? isFocusRelativePath, bool? isIgnoreRelativePath, MappingFromItem mappingFromItem, List<MappingFromPhotoPrism>? mappingFromPhotoPrismCollection, List<Shared.Models.Face> faces)
private void SetMapping(MapLogic mapLogic, Item item, bool? isFocusRelativePath, bool? isIgnoreRelativePath, ReadOnlyCollection<LocationContainer<MetadataExtractor.Directory>> locationContainers, MappingFromItem mappingFromItem, List<MappingFromPhotoPrism>? mappingFromPhotoPrismCollection, List<Shared.Models.Face> faces)
{
double? α;
int? eyeα;
@ -311,6 +311,7 @@ public partial class DlibDotNet
MappingFromLocation? mappingFromLocation;
bool? isFocusModel = GetIsFocusModel(item.Property);
bool ignoreXMatches = _JLinkResolvedDirectories.Count > 0;
ReadOnlyCollection<string> locationContainersFiles = new((from l in locationContainers select l.File).ToArray());
foreach (Shared.Models.Face face in faces)
{
if (item.Property?.Id is null || face.FaceEncoding is null || face.Location is null || face.OutputResolution is null)
@ -337,16 +338,16 @@ public partial class DlibDotNet
mappingFromLocation = new(faceAreaPermyriad, confidencePercent, deterministicHashCodeKey, eyeα, eyeReview, wholePercentRectangle);
isUsed = mapLogic.IsUsed(ignoreXMatches, item.Property.Id.Value, mappingFromLocation);
inSkipCollection = mapLogic.InSkipCollection(item.Property.Id.Value, mappingFromLocation);
isFocusPerson = mapLogic.IsFocusPerson(_JLinkResolvedDirectories, item.Property.Id.Value, mappingFromLocation);
isFocusPerson = mapLogic.IsFocusPerson(_Configuration.SkipPersonWithMoreThen, _JLinkResolvedDirectories, item.Property.Id.Value, mappingFromLocation);
mappingFromFilter = new(isFocusModel, isFocusPerson, isFocusRelativePath, isIgnoreRelativePath, inSkipCollection, isUsed);
}
mapping = new(mappingFromItem, mappingFromFilter, mappingFromLocation, mappingFromPhotoPrismCollection);
_ = mapLogic.UpdateMappingFromPerson(mapping);
_ = mapLogic.UpdateMappingFromPerson(locationContainersFiles, mapping);
face.SetMapping(mapping);
}
}
private Mapping GetMapping(MapLogic mapLogic, Item item, bool? isFocusRelativePath, bool? isIgnoreRelativePath, MappingFromItem mappingFromItem, List<(string, long)> jLinkResolvedDirectories)
private Mapping GetMapping(MapLogic mapLogic, Item item, bool? isFocusRelativePath, bool? isIgnoreRelativePath, MappingFromItem mappingFromItem)
{
Mapping result;
bool? isUsed;
@ -361,7 +362,7 @@ public partial class DlibDotNet
MappingFromFilter mappingFromFilter;
MappingFromLocation? mappingFromLocation;
bool? isFocusModel = GetIsFocusModel(item.Property);
bool ignoreXMatches = jLinkResolvedDirectories.Count > 0;
bool ignoreXMatches = _JLinkResolvedDirectories.Count > 0;
if (item.Property?.Id is null)
{
isUsed = null;
@ -377,7 +378,7 @@ public partial class DlibDotNet
mappingFromLocation = new(faceAreaPermyriad, confidencePercent, deterministicHashCodeKey, eyeα, eyeReview, wholePercentRectangle);
isUsed = mapLogic.IsUsed(ignoreXMatches, item.Property.Id.Value, mappingFromLocation);
inSkipCollection = mapLogic.InSkipCollection(item.Property.Id.Value, mappingFromLocation);
isFocusPerson = mapLogic.IsFocusPerson(jLinkResolvedDirectories, item.Property.Id.Value, mappingFromLocation);
isFocusPerson = mapLogic.IsFocusPerson(_Configuration.SkipPersonWithMoreThen, _JLinkResolvedDirectories, item.Property.Id.Value, mappingFromLocation);
mappingFromFilter = new(isFocusModel, isFocusPerson, isFocusRelativePath, isIgnoreRelativePath, inSkipCollection, isUsed);
}
result = new(mappingFromItem, mappingFromFilter, mappingFromLocation, mappingFromPhotoPrismCollection: null);
@ -408,7 +409,6 @@ public partial class DlibDotNet
private void FullParallelForWork(A_Property propertyLogic,
B_Metadata metadata,
ReadOnlyDictionary<int, List<LocationContainer<MetadataExtractor.Directory>>> idToLocationContainers,
MapLogic mapLogic,
string outputResolution,
bool outputResolutionHasNumber,
@ -434,6 +434,7 @@ public partial class DlibDotNet
List<KeyValuePair<string, string>> metadataCollection;
string[] changesFrom = new string[] { nameof(A_Property) };
FileHolder resizedFileHolder = _Resize.GetResizedFileHolder(cResultsFullGroupDirectory, item, outputResolutionHasNumber);
ReadOnlyCollection<LocationContainer<MetadataExtractor.Directory>> locationContainers = mapLogic.GetLocationContainers(item);
if (item.Property is null || item.Property.Id is null || item.Any())
{
LogItemPropertyIsNull(item);
@ -495,17 +496,12 @@ public partial class DlibDotNet
else
{
List<MappingFromPhotoPrism>? mappingFromPhotoPrismCollection;
List<LocationContainer<MetadataExtractor.Directory>>? locationContainers;
if (item.Property?.Id is null)
locationContainers = null;
else
_ = idToLocationContainers.TryGetValue(item.Property.Id.Value, out locationContainers);
if (!fileNameToCollection.TryGetValue(mappingFromItem.Id, out mappingFromPhotoPrismCollection))
mappingFromPhotoPrismCollection = null;
faces = _Faces.GetFaces(outputResolution, dResultsFullGroupDirectory, subFileTuples, parseExceptions, property, mappingFromItem, outputResolutionToResize, locationContainers, mappingFromPhotoPrismCollection);
if (_AppSettings.MaxDegreeOfParallelism < 2)
ticks = LogDelta(ticks, nameof(D_Face.GetFaces));
SetMapping(mapLogic, item, isFocusRelativePath, isIgnoreRelativePath, mappingFromItem, mappingFromPhotoPrismCollection, faces);
SetMapping(mapLogic, item, isFocusRelativePath, isIgnoreRelativePath, locationContainers, mappingFromItem, mappingFromPhotoPrismCollection, faces);
List<(Shared.Models.Face, FileInfo?, string, bool Saved)> faceCollection = _Faces.SaveFaces(_FaceParts.FileNameExtension, dResultsFullGroupDirectory, subFileTuples, parseExceptions, mappingFromItem, faces);
if (_Configuration.CopyFacesAndSaveFaceLandmarkForOutputResolutions.Contains(outputResolution))
_FaceParts.CopyFacesAndSaveFaceLandmarkImage(facePartsCollectionDirectory, mappingFromItem, faceCollection);
@ -535,7 +531,6 @@ public partial class DlibDotNet
private int FullParallelWork(int maxDegreeOfParallelism,
A_Property propertyLogic,
B_Metadata metadata,
ReadOnlyDictionary<int, List<LocationContainer<MetadataExtractor.Directory>>> idToLocationContainers,
MapLogic mapLogic,
string outputResolution,
bool outputResolutionHasNumber,
@ -558,7 +553,7 @@ public partial class DlibDotNet
string focusRelativePath = Path.GetFullPath(string.Concat(_Configuration.PropertyConfiguration.RootDirectory, _Configuration.FocusDirectory));
bool? isFocusRelativePath = string.IsNullOrEmpty(_Configuration.FocusDirectory) ? null : container.SourceDirectory.StartsWith(focusRelativePath);
string facePartsCollectionDirectory = _Configuration.CopyFacesAndSaveFaceLandmarkForOutputResolutions.Contains(outputResolution) ? _FaceParts.GetFacePartsDirectory(_Configuration.PropertyConfiguration, d2ResultsFullGroupDirectory, item: filteredItems.First(), includeNameWithoutExtension: false) : string.Empty;
bool? isIgnoreRelativePath = !_Configuration.IgnoreRelativePaths.Any() ? null : _Configuration.IgnoreRelativePaths.Any(l => container.SourceDirectory.Contains(l)) && Shared.Models.Stateless.Methods.IContainer.IsIgnoreRelativePath(_Configuration.PropertyConfiguration, _Configuration.IgnoreRelativePaths, container.SourceDirectory);
bool? isIgnoreRelativePath = _Configuration.IgnoreRelativePaths.Length == 0 ? null : _Configuration.IgnoreRelativePaths.Any(l => container.SourceDirectory.Contains(l)) && Shared.Models.Stateless.Methods.IContainer.IsIgnoreRelativePath(_Configuration.PropertyConfiguration, _Configuration.IgnoreRelativePaths, container.SourceDirectory);
using ProgressBar progressBar = new(filteredItems.Length, message, options);
_ = Parallel.For(0, filteredItems.Length, parallelOptions, (i, state) =>
{
@ -566,7 +561,6 @@ public partial class DlibDotNet
{
FullParallelForWork(propertyLogic,
metadata,
idToLocationContainers,
mapLogic,
outputResolution,
outputResolutionHasNumber,
@ -582,7 +576,7 @@ public partial class DlibDotNet
isFocusRelativePath,
isIgnoreRelativePath,
facePartsCollectionDirectory);
if (i == 0 || sourceDirectoryChanges.Any())
if (i == 0 || sourceDirectoryChanges.Count > 0)
progressBar.Tick();
}
catch (Exception ex)
@ -619,7 +613,7 @@ public partial class DlibDotNet
if (duplicates.Contains(metadataIdLines[i].Id))
metadataIdLines.RemoveAt(i);
}
if (metadataIdLines.Any())
if (metadataIdLines.Count > 0)
{
text = string.Join(Environment.NewLine, from l in metadataIdLines orderby l.Id select l.Line);
_ = Shared.Models.Stateless.Methods.IPath.WriteAllText(fileInfo.FullName, text, updateDateWhenMatches: true, compareBeforeWrite: true);
@ -683,7 +677,7 @@ public partial class DlibDotNet
return new(cResultsFullGroupDirectory, c2ResultsFullGroupDirectory, dResultsFullGroupDirectory, d2ResultsFullGroupDirectory);
}
private void FullDoWork(string argZero, string propertyRoot, long ticks, string aResultsFullGroupDirectory, string bResultsFullGroupDirectory, int t, Container[] containers, A_Property propertyLogic, B_Metadata metadata, Dictionary<int, List<MappingFromPhotoPrism>> fileNameToCollection, ReadOnlyDictionary<int, List<LocationContainer<MetadataExtractor.Directory>>> idToLocationContainers, MapLogic mapLogic)
private void FullDoWork(string argZero, string propertyRoot, long ticks, string aResultsFullGroupDirectory, string bResultsFullGroupDirectory, int t, Container[] containers, A_Property propertyLogic, B_Metadata metadata, Dictionary<int, List<MappingFromPhotoPrism>> fileNameToCollection, MapLogic mapLogic)
{
if (_Log is null)
throw new NullReferenceException(nameof(_Log));
@ -715,12 +709,12 @@ public partial class DlibDotNet
for (int i = 0; i < containers.Length; i++)
{
container = containers[i];
if (!container.Items.Any())
if (container.Items.Count == 0)
continue;
if (!_ArgZeroIsConfigurationRootDirectory && !container.SourceDirectory.StartsWith(argZero))
continue;
filteredItems = Shared.Models.Stateless.Methods.IContainer.GetFilterItems(_Configuration.PropertyConfiguration, container);
if (!filteredItems.Any())
if (filteredItems.Length == 0)
continue;
sourceDirectoryChanges.Clear();
anyNullOrNoIsUniqueFileName = filteredItems.Any(l => !l.IsUniqueFileName);
@ -732,7 +726,6 @@ public partial class DlibDotNet
exceptionCount = FullParallelWork(maxDegreeOfParallelism,
propertyLogic,
metadata,
idToLocationContainers,
mapLogic,
outputResolution,
outputResolutionHasNumber,
@ -749,7 +742,7 @@ public partial class DlibDotNet
_Exceptions.Add(container.SourceDirectory);
continue;
}
if (Directory.GetFiles(propertyRoot, "*.txt", SearchOption.TopDirectoryOnly).Any())
if (Directory.GetFiles(propertyRoot, "*.txt", SearchOption.TopDirectoryOnly).Length > 0)
{
for (int y = 0; y < int.MaxValue; y++)
{
@ -786,7 +779,7 @@ public partial class DlibDotNet
{
distanceLimits = new(_Configuration.FaceAreaPermyriad, _Configuration.FaceConfidencePercent, _Configuration.FaceDistancePermyriad, _Configuration.RangeDaysDeltaTolerance, _Configuration.RangeDistanceTolerance, _Configuration.RangeFaceAreaTolerance, _Configuration.RangeFaceConfidence, _Configuration.SortingMaximumPerFaceShouldBeHigh, useFiltersCounter);
filteredFaceDistanceContainers = E_Distance.FilteredFaceDistanceContainers(mapLogic, faceDistanceContainers, skipOlderThan, distanceLimits);
if (filteredFaceDistanceContainers.Any())
if (filteredFaceDistanceContainers.Length == 0)
_Log.Information("All images have been filtered!");
else
{
@ -800,7 +793,7 @@ public partial class DlibDotNet
if (filteredFaceDistanceContainers.Length > 0)
{
int updated = mapLogic.UpdateFromSortingContainers(_Configuration.SaveIndividually, distanceLimits, sortingContainers);
List<SaveContainer> saveContainers = mapLogic.GetSaveContainers(_Configuration.SaveIndividually, dFacesContentDirectory, d2FacePartsContentDirectory, d2FacePartsContentCollectionDirectory, mappingCollection, idToWholePercentagesToMapping, useFiltersCounter, sortingContainers.Any());
List<SaveContainer> saveContainers = mapLogic.GetSaveContainers(_Configuration.SaveIndividually, dFacesContentDirectory, d2FacePartsContentDirectory, d2FacePartsContentCollectionDirectory, mappingCollection, idToWholePercentagesToMapping, useFiltersCounter, sortingContainers.Length > 0);
mapLogic.SaveContainers(_Configuration.SaveIndividually, filteredFaceDistanceContainers.Length, updated, saveContainers);
}
}
@ -810,10 +803,10 @@ public partial class DlibDotNet
{
E_Distance.SetFaceDistances(_AppSettings.MaxDegreeOfParallelism, ticks, distinctFilteredFaces);
FaceDistanceContainer[] faceDistanceContainers = E_Distance.GetFaceDistanceContainers(distinctFilteredFaces);
Dictionary<int, Dictionary<int, PersonContainer[]>> missingIdThenWholePercentagesToPersonContainers = mapLogic.GetMissing(idToWholePercentagesToMapping);
Dictionary<int, ReadOnlyDictionary<int, ReadOnlyCollection<PersonContainer>>> missingIdThenWholePercentagesToPersonContainers = mapLogic.GetMissing(idToWholePercentagesToMapping);
List<FaceDistanceContainer> missingFaceDistanceContainers = _Distance.GetMissingFaceDistanceContainer(_AppSettings.MaxDegreeOfParallelism, ticks, dFacesCollectionDirectory, missingIdThenWholePercentagesToPersonContainers);
List<FaceDistance> faceDistanceEncodings = E_Distance.GetFaceDistanceEncodings(faceDistanceContainers, missingFaceDistanceContainers);
if (faceDistanceContainers.Any())
if (faceDistanceContainers.Length > 0)
SaveFaceDistances(ticks, mapLogic, mappingCollection, dFacesContentDirectory, d2FacePartsContentDirectory, d2FacePartsContentCollectionDirectory, idToWholePercentagesToMapping, faceDistanceEncodings, faceDistanceContainers);
}
@ -823,7 +816,7 @@ public partial class DlibDotNet
string d2FacePartsContentDirectory = Path.Combine(d2ResultsFullGroupDirectory, _Configuration.PropertyConfiguration.ResultContent);
string d2FacePartsContentCollectionDirectory = Path.Combine(d2ResultsFullGroupDirectory, "[()]");
string dFacesCollectionDirectory = Path.Combine(dResultsFullGroupDirectory, _Configuration.PropertyConfiguration.ResultCollection, _Configuration.PropertyConfiguration.ResultAllInOne);
if (distinctFilteredMappingCollection.Any())
if (distinctFilteredMappingCollection.Length > 0)
{
Shared.Models.Stateless.Methods.IPath.ChangeDateForEmptyDirectories(d2FacePartsContentDirectory, ticks);
if (Directory.Exists(d2FacePartsContentCollectionDirectory))
@ -852,7 +845,7 @@ public partial class DlibDotNet
string result;
if (_Log is null)
throw new NullReferenceException(nameof(_Log));
if (!files.Any())
if (files.Length == 0)
throw new NotSupportedException();
string? sourceDirectory = Path.GetDirectoryName(files.First());
if (string.IsNullOrEmpty(sourceDirectory))
@ -893,108 +886,6 @@ public partial class DlibDotNet
return result;
}
private static void LookForAbandoned(List<int> distinctFilteredIds, string directory, string directoryName)
{
string fileNameWithoutExtension;
bool nameWithoutExtensionIsIdFormat;
List<string> renameCollection = new();
bool nameWithoutExtensionIsPaddedIdFormat;
int sortOrderOnlyLengthIndex = IDirectory.GetSortOrderOnlyLengthIndex();
string[] distinctFilteredIdsValues = distinctFilteredIds.Select(l => l.ToString()).ToArray();
string[] files = Directory.GetFiles(directory, "*", SearchOption.AllDirectories);
foreach (string file in files)
{
fileNameWithoutExtension = Path.GetFileNameWithoutExtension(Path.GetFileNameWithoutExtension(Path.GetFileNameWithoutExtension(file)));
nameWithoutExtensionIsIdFormat = Shared.Models.Stateless.Methods.IProperty.NameWithoutExtensionIsIdFormat(fileNameWithoutExtension);
nameWithoutExtensionIsPaddedIdFormat = IDirectory.NameWithoutExtensionIsPaddedIdFormat(fileNameWithoutExtension, sortOrderOnlyLengthIndex);
if (!nameWithoutExtensionIsIdFormat && !nameWithoutExtensionIsPaddedIdFormat)
continue;
if (distinctFilteredIdsValues.Contains(fileNameWithoutExtension))
continue;
renameCollection.Add(file);
}
if (renameCollection.Any())
{
if (directoryName.Length == 2)
IDirectory.MoveFiles(renameCollection, directoryName, $"{directoryName[0]}abd{directoryName[^1]}");
else if (directoryName.Length == 4)
IDirectory.MoveFiles(renameCollection, directoryName, $"{directoryName[..2]}abd{directoryName[^2..]}");
else
throw new NotSupportedException();
}
}
private static void LookForAbandoned(string bResultsFullGroupDirectory, List<int> distinctFilteredIds)
{
string[] directories = Directory.GetDirectories(bResultsFullGroupDirectory, "*", SearchOption.TopDirectoryOnly);
foreach (string directory in directories)
{
string? directoryName = Path.GetFileName(directory);
if (string.IsNullOrEmpty(directoryName) || (directoryName.Length != 2 && directoryName.Length != 4))
continue;
LookForAbandoned(distinctFilteredIds, directory, directoryName);
}
}
private void LookForAbandoned(ReadOnlyDictionary<int, List<LocationContainer<MetadataExtractor.Directory>>> idToLocationContainers, List<int> distinctFilteredIds)
{
List<string> renameCollection = new();
foreach (KeyValuePair<int, List<LocationContainer<MetadataExtractor.Directory>>> keyValuePair in idToLocationContainers)
{
if (distinctFilteredIds.Contains(keyValuePair.Key))
continue;
foreach (LocationContainer<MetadataExtractor.Directory> locationContainer in keyValuePair.Value)
{
if (locationContainer.File.Contains('!'))
continue;
renameCollection.Add(locationContainer.File);
}
}
if (renameCollection.Any())
IDirectory.MoveFiles(renameCollection, _Configuration.PropertyConfiguration.ResultContent, "(abd)");
}
private void LookForAbandoned(string bResultsFullGroupDirectory, Container[] containers, ReadOnlyDictionary<int, List<LocationContainer<MetadataExtractor.Directory>>> idToLocationContainers)
{
string[] directories;
string? directoryName;
string cResultsFullGroupDirectory;
string dResultsFullGroupDirectory;
string c2ResultsFullGroupDirectory;
string d2ResultsFullGroupDirectory;
List<int> distinctFilteredIds = Shared.Models.Stateless.Methods.IContainer.GetFilteredDistinctIds(_Configuration.PropertyConfiguration, containers);
LookForAbandoned(idToLocationContainers, distinctFilteredIds);
LookForAbandoned(bResultsFullGroupDirectory, distinctFilteredIds);
foreach (string outputResolution in _Configuration.OutputResolutions)
{
(cResultsFullGroupDirectory, c2ResultsFullGroupDirectory, dResultsFullGroupDirectory, d2ResultsFullGroupDirectory) = GetResultsFullGroupDirectories(outputResolution);
directories = Directory.GetDirectories(cResultsFullGroupDirectory, "*", SearchOption.TopDirectoryOnly);
foreach (string directory in directories)
{
directoryName = Path.GetFileName(directory);
if (string.IsNullOrEmpty(directoryName) || (directoryName.Length != 2 && directoryName.Length != 4))
continue;
LookForAbandoned(distinctFilteredIds, directory, directoryName);
}
directories = Directory.GetDirectories(dResultsFullGroupDirectory, "*", SearchOption.TopDirectoryOnly);
foreach (string directory in directories)
{
directoryName = Path.GetFileName(directory);
if (string.IsNullOrEmpty(directoryName) || (directoryName.Length != 2 && directoryName.Length != 4))
continue;
LookForAbandoned(distinctFilteredIds, directory, directoryName);
}
directories = Directory.GetDirectories(d2ResultsFullGroupDirectory, "*", SearchOption.TopDirectoryOnly);
foreach (string directory in directories)
{
directoryName = Path.GetFileName(directory);
if (string.IsNullOrEmpty(directoryName) || (directoryName.Length != 2 && directoryName.Length != 4))
continue;
LookForAbandoned(distinctFilteredIds, directory, directoryName);
}
}
}
private Mapping[] GetMappings(Property.Models.Configuration propertyConfiguration, Container[] containers, MapLogic mapLogic, bool distinctItems)
{
Mapping[] results;
@ -1011,7 +902,7 @@ public partial class DlibDotNet
List<Mapping> mappingCollection = new();
foreach (Container container in containers)
{
if (!container.Items.Any())
if (container.Items.Count == 0)
continue;
filteredItems = Shared.Models.Stateless.Methods.IContainer.GetFilterItems(propertyConfiguration, container);
if (!filteredItems.Any())
@ -1019,7 +910,7 @@ public partial class DlibDotNet
containerDateTimes = Shared.Models.Stateless.Methods.IContainer.GetContainerDateTimes(filteredItems);
focusRelativePath = Path.GetFullPath(string.Concat(_Configuration.PropertyConfiguration.RootDirectory, _Configuration.FocusDirectory));
isFocusRelativePath = string.IsNullOrEmpty(_Configuration.FocusDirectory) ? null : container.SourceDirectory.StartsWith(focusRelativePath);
isIgnoreRelativePath = !_Configuration.IgnoreRelativePaths.Any() ? null : _Configuration.IgnoreRelativePaths.Any(l => container.SourceDirectory.Contains(l)) && Shared.Models.Stateless.Methods.IContainer.IsIgnoreRelativePath(_Configuration.PropertyConfiguration, _Configuration.IgnoreRelativePaths, container.SourceDirectory);
isIgnoreRelativePath = _Configuration.IgnoreRelativePaths.Length == 0 ? null : _Configuration.IgnoreRelativePaths.Any(l => container.SourceDirectory.Contains(l)) && Shared.Models.Stateless.Methods.IContainer.IsIgnoreRelativePath(_Configuration.PropertyConfiguration, _Configuration.IgnoreRelativePaths, container.SourceDirectory);
foreach (Item item in filteredItems)
{
if (item.Property?.Id is null || item.ResizedFileHolder is null)
@ -1042,7 +933,7 @@ public partial class DlibDotNet
}
if (!anyValidFaces)
{
mapping = GetMapping(mapLogic, item, isFocusRelativePath, isIgnoreRelativePath, mappingFromItem, _JLinkResolvedDirectories);
mapping = GetMapping(mapLogic, item, isFocusRelativePath, isIgnoreRelativePath, mappingFromItem);
mappingCollection.Add(mapping);
}
}
@ -1071,7 +962,7 @@ public partial class DlibDotNet
if (!found)
notFound.Add(item);
}
if (notFound.Any())
if (notFound.Count > 0)
throw new NotSupportedException();
#endif
string model;
@ -1140,6 +1031,44 @@ public partial class DlibDotNet
}
}
private static bool GetRunToDoCollectionFirst(long ticks, string rootDirectory, FileSystemInfo fileSystemInfo)
{
bool result = false;
string[] directories;
string seasonDirectory;
DirectoryInfo directoryInfo;
DateTime dateTime = new(ticks);
(int season, string seasonName) = Shared.Models.Stateless.Methods.IProperty.GetSeason(dateTime.DayOfYear);
string[] checkDirectories = new string[]
{
Path.Combine(rootDirectory, "Ancestry"),
Path.Combine(rootDirectory, "Facebook"),
Path.Combine(rootDirectory, "LinkedIn"),
rootDirectory,
};
foreach (string checkDirectory in checkDirectories)
{
if (!Directory.Exists(checkDirectory))
_ = Directory.CreateDirectory(checkDirectory);
seasonDirectory = Path.Combine(checkDirectory, $"{dateTime.Year}.{season} {seasonName} {Path.GetFileName(checkDirectory)}");
if (!Directory.Exists(seasonDirectory))
_ = Directory.CreateDirectory(seasonDirectory);
if (result)
continue;
directories = Directory.GetDirectories(checkDirectory, "*", SearchOption.TopDirectoryOnly);
foreach (string directory in directories)
{
directoryInfo = new(directory);
if (directoryInfo.LastWriteTime > fileSystemInfo.LastWriteTime)
{
result = true;
break;
}
}
}
return result;
}
private void Search(long ticks, ReadOnlyCollection<PersonContainer> personContainers, string argZero, string propertyRoot)
{
int t;
@ -1170,8 +1099,8 @@ public partial class DlibDotNet
a2PeopleContentDirectory = Property.Models.Stateless.IResult.GetResultsDateGroupDirectory(_Configuration.PropertyConfiguration, nameof(A2_People), "([])");
eDistanceContentDirectory = Property.Models.Stateless.IResult.GetResultsDateGroupDirectory(_Configuration.PropertyConfiguration, nameof(E_Distance), _Configuration.PropertyConfiguration.ResultContent);
string a2PeopleSingletonDirectory = Property.Models.Stateless.IResult.GetResultsDateGroupDirectory(_Configuration.PropertyConfiguration, nameof(A2_People), _Configuration.PropertyConfiguration.ResultSingleton);
TimeSpan eLastWriteTimeTimeSpan = new(ticks - new DirectoryInfo(eDistanceContentDirectory).LastWriteTime.Ticks);
if (eLastWriteTimeTimeSpan.TotalDays > 1)
bool runToDoCollectionFirst = GetRunToDoCollectionFirst(ticks, _Configuration.PropertyConfiguration.RootDirectory, new DirectoryInfo(eDistanceContentDirectory));
if (runToDoCollectionFirst)
mapLogic = null;
else
mapLogic = new(_AppSettings.MaxDegreeOfParallelism, _Configuration.PropertyConfiguration, _MapConfiguration, personContainers, ticks, a2PeopleSingletonDirectory, eDistanceContentDirectory);
@ -1180,7 +1109,7 @@ public partial class DlibDotNet
if (outputResolution.Any(l => char.IsNumber(l)))
continue;
configurationOutputResolutionsHas = true;
if (eLastWriteTimeTimeSpan.TotalDays < 1)
if (!runToDoCollectionFirst)
break;
ProgressBar progressBar;
(cResultsFullGroupDirectory, _, _, _) = GetResultsFullGroupDirectories(outputResolution);
@ -1249,16 +1178,21 @@ public partial class DlibDotNet
B_Metadata metadata = new(_Configuration.PropertyConfiguration, _Configuration.ForceMetadataLastWriteTimeToCreationTime, _Configuration.PropertiesChangedForMetadata, bResultsFullGroupDirectory);
mapLogic ??= new(_AppSettings.MaxDegreeOfParallelism, _Configuration.PropertyConfiguration, _MapConfiguration, personContainers, ticks, a2PeopleSingletonDirectory, eDistanceContentDirectory);
containers = Shared.Models.Stateless.Methods.IContainer.SortContainers(_Configuration.PropertyConfiguration, _Configuration.IgnoreRelativePaths, _ArgZeroIsConfigurationRootDirectory, argZero, containers);
ReadOnlyDictionary<int, List<LocationContainer<MetadataExtractor.Directory>>> idToLocationContainers = mapLogic.GetIdToLocationContainers();
FullDoWork(argZero, propertyRoot, ticks, aResultsFullGroupDirectory, bResultsFullGroupDirectory, t, containers, propertyLogic, metadata, fileNameToCollection, idToLocationContainers, mapLogic);
if (_Configuration.LookForAbandoned)
LookForAbandoned(bResultsFullGroupDirectory, containers, idToLocationContainers);
_Distance.Clear();
FullDoWork(argZero, propertyRoot, ticks, aResultsFullGroupDirectory, bResultsFullGroupDirectory, t, containers, propertyLogic, metadata, fileNameToCollection, mapLogic);
List<Item> distinctFilteredItems = Shared.Models.Stateless.Methods.IContainer.GetItems(_Configuration.PropertyConfiguration, containers, distinctItems: true, filterItems: true);
if (_Configuration.LookForAbandoned)
{
foreach (string outputResolution in _Configuration.OutputResolutions)
{
(cResultsFullGroupDirectory, _, dResultsFullGroupDirectory, d2ResultsFullGroupDirectory) = GetResultsFullGroupDirectories(outputResolution);
mapLogic.LookForAbandoned(_Configuration.PropertyConfiguration, bResultsFullGroupDirectory, containers, cResultsFullGroupDirectory, dResultsFullGroupDirectory, d2ResultsFullGroupDirectory);
}
}
_Distance.Clear();
Verify(eDistanceContentDirectory, distinctFilteredItems);
List<Shared.Models.Face> distinctFilteredFaces = Map.Models.Stateless.Methods.IMapLogic.GetFaces(distinctFilteredItems);
Mapping[] distinctFilteredMappingCollection = GetMappings(_Configuration.PropertyConfiguration, containers, mapLogic, distinctItems: true);
int totalNotMapped = mapLogic.UpdateMappingFromPerson(distinctFilteredMappingCollection);
int totalNotMapped = mapLogic.UpdateMappingFromPerson(_Configuration.PropertyConfiguration, distinctFilteredMappingCollection);
string json = JsonSerializer.Serialize(distinctFilteredMappingCollection);
File.WriteAllText(Path.Combine(eDistanceContentDirectory, $"{ticks}.json"), json);
foreach (string outputResolution in _Configuration.OutputResolutions)
@ -1268,7 +1202,7 @@ public partial class DlibDotNet
personKeyToIds = mapLogic.GetPersonKeyToIds();
if (!string.IsNullOrEmpty(a2PeopleContentDirectory) && _Configuration.SaveShortcutsForOutputResolutions.Contains(outputResolution))
mapLogic.SaveShortcutsForOutputResolutionsPreMapLogic(eDistanceContentDirectory, personKeyToIds, distinctFilteredMappingCollection);
if (!string.IsNullOrEmpty(a2PeopleContentDirectory) && _Configuration.JLinks.Length > 0 && _Configuration.SaveFilteredOriginalImagesFromJLinksForOutputResolutions.Contains(outputResolution))
if (!string.IsNullOrEmpty(a2PeopleContentDirectory) && _Configuration.JLinks.Where(l => !string.IsNullOrEmpty(l)).Any() && _Configuration.SaveFilteredOriginalImagesFromJLinksForOutputResolutions.Contains(outputResolution))
mapLogic.SaveFilteredOriginalImagesFromJLinks(_Configuration.JLinks, personContainers, a2PeopleContentDirectory, personKeyToIds, distinctFilteredMappingCollection, totalNotMapped);
(cResultsFullGroupDirectory, c2ResultsFullGroupDirectory, dResultsFullGroupDirectory, d2ResultsFullGroupDirectory) = GetResultsFullGroupDirectories(outputResolution);
if (_ArgZeroIsConfigurationRootDirectory
@ -1277,7 +1211,7 @@ public partial class DlibDotNet
&& _Configuration.LoadOrCreateThenSaveDistanceResultsForOutputResolutions.Contains(outputResolution)
&& _Exceptions.Count == 0)
MapLogic(ticks, containers, a2PeopleSingletonDirectory, dResultsFullGroupDirectory, d2ResultsFullGroupDirectory, fPhotoPrismContentDirectory, mapLogic, outputResolution, personKeyToIds, distinctFilteredFaces, distinctFilteredMappingCollection, totalNotMapped);
if (_Configuration.SaveRandomForOutputResolutions.Contains(outputResolution) && personKeyToIds.Any() && distinctFilteredMappingCollection.Any())
if (_Configuration.SaveRandomForOutputResolutions.Contains(outputResolution) && personKeyToIds.Count > 0 && distinctFilteredMappingCollection.Length > 0)
_Random.Random(_Configuration.PropertyConfiguration, outputResolution, personKeyToIds, distinctFilteredMappingCollection);
if (_IsEnvironment.Development)
continue;

View File

@ -84,6 +84,7 @@ public class Configuration
[Display(Name = "Save Sorting Without Person"), Required] public bool? SaveSortingWithoutPerson { get; set; }
[Display(Name = "Skip Not Skip Directories"), Required] public string[] SkipNotSkipDirectories { get; set; }
[Display(Name = "Skip Older Than Days"), Required] public int? SkipOlderThanDays { get; set; }
[Display(Name = "Skip Person With More Then"), Required] public int? SkipPersonWithMoreThen { get; set; }
[Display(Name = "Skip Search"), Required] public bool? SkipSearch { get; set; }
[Display(Name = "SortingMaximumPerFaceShould be High"), Required] public int? SortingMaximumPerFaceShouldBeHigh { get; set; }
[Display(Name = "Sorting Maximum Per Key"), Required] public int? SortingMaximumPerKey { get; set; }
@ -314,6 +315,7 @@ public class Configuration
configuration.SaveSortingWithoutPerson.Value,
configuration.SkipNotSkipDirectories,
configuration.SkipOlderThanDays,
configuration.SkipPersonWithMoreThen,
configuration.SkipSearch.Value,
configuration.SortingMaximumPerFaceShouldBeHigh.Value,
configuration.SortingMaximumPerKey.Value,

View File

@ -14,15 +14,14 @@ public class Configuration
public bool CheckJsonForDistanceResults { init; get; }
public string[] CopyFacesAndSaveFaceLandmarkForOutputResolutions { init; get; }
public int CrossDirectoryMaxItemsInDistanceCollection { init; get; }
public bool DeletePossibleDuplicates { get; internal set; }
public int DistanceFactor { init; get; }
public bool DistanceMoveUnableToMatch { init; get; }
public int DistancePixelDistanceTolerance { init; get; }
public bool DistanceRenameToMatch { init; get; }
public int EyeThreshold { init; get; }
public int FaceAreaPermyriad { init; get; }
public int FaceDistanceHiddenImageFactor { init; get; }
public int FaceConfidencePercent { init; get; }
public int FaceDistanceHiddenImageFactor { init; get; }
public int FaceDistancePermyriad { init; get; }
public string FocusDirectory { init; get; }
public string FocusModel { init; get; }
@ -72,22 +71,24 @@ public class Configuration
public string[] SaveFaceDistancesForOutputResolutions { init; get; }
public string[] SaveFaceLandmarkForOutputResolutions { init; get; }
public string[] SaveFilteredOriginalImagesFromJLinksForOutputResolutions { init; get; }
public bool SaveIndividually { init; get; }
public bool SaveFullYearOfRandomFiles { init; get; }
public bool SaveIndividually { init; get; }
public string[] SaveMappedForOutputResolutions { init; get; }
public string[] SaveRandomForOutputResolutions { init; get; }
public bool SaveResizedSubfiles { init; get; }
public string[] SaveShortcutsForOutputResolutions { init; get; }
public bool SaveSortingWithoutPerson { init; get; }
public string[] SkipNotSkipDirectories { init; get; }
public bool SkipSearch { init; get; }
public int? SkipOlderThanDays { init; get; }
public int? SkipPersonWithMoreThen { init; get; }
public bool SkipSearch { init; get; }
public int SortingMaximumPerFaceShouldBeHigh { init; get; }
public int SortingMaximumPerKey { init; get; }
public int SortingMinimumToUseSigma { init; get; }
public bool TestDistanceResults { init; get; }
public int UseFilterTries { init; get; }
public string[] ValidResolutions { init; get; }
public bool DeletePossibleDuplicates { get; internal set; }
[JsonConstructor]
public Configuration(Property.Models.Configuration propertyConfiguration,
@ -162,6 +163,7 @@ public class Configuration
bool saveSortingWithoutPerson,
string[] skipNotSkipDirectories,
int? skipOlderThanDays,
int? skipPersonWithMoreThen,
bool skipSearch,
int sortingMaximumPerFaceShouldBeHigh,
int sortingMaximumPerKey,
@ -182,8 +184,8 @@ public class Configuration
DistanceRenameToMatch = distanceRenameToMatch;
EyeThreshold = eyeThreshold;
FaceAreaPermyriad = faceAreaPermyriad;
FaceDistanceHiddenImageFactor = faceDistanceHiddenImageFactor;
FaceConfidencePercent = faceConfidencePercent;
FaceDistanceHiddenImageFactor = faceDistanceHiddenImageFactor;
FaceDistancePermyriad = faceDistancePermyriad;
FocusDirectory = focusDirectory;
FocusModel = focusModel;
@ -233,8 +235,8 @@ public class Configuration
SaveFaceDistancesForOutputResolutions = saveFaceDistancesForOutputResolutions;
SaveFaceLandmarkForOutputResolutions = saveFaceLandmarkForOutputResolutions;
SaveFilteredOriginalImagesFromJLinksForOutputResolutions = saveFilteredOriginalImagesFromJLinksForOutputResolutions;
SaveIndividually = saveIndividually;
SaveFullYearOfRandomFiles = saveFullYearOfRandomFiles;
SaveIndividually = saveIndividually;
SaveMappedForOutputResolutions = saveMappedForOutputResolutions;
SaveRandomForOutputResolutions = saveRandomForOutputResolutions;
SaveResizedSubfiles = saveResizedSubfiles;
@ -242,6 +244,7 @@ public class Configuration
SaveSortingWithoutPerson = saveSortingWithoutPerson;
SkipNotSkipDirectories = skipNotSkipDirectories;
SkipOlderThanDays = skipOlderThanDays;
SkipPersonWithMoreThen = skipPersonWithMoreThen;
SkipSearch = skipSearch;
SortingMaximumPerFaceShouldBeHigh = sortingMaximumPerFaceShouldBeHigh;
SortingMaximumPerKey = sortingMaximumPerKey;

View File

@ -85,7 +85,7 @@ internal class F_Random
relativePaths.Add(mapping.MappingFromItem.RelativePath);
distinctCollection.Add(mapping.MappingFromItem.Id);
}
if (relativePaths.Any())
if (relativePaths.Count > 0)
{
for (int i = 0; i < 366; i++)
{

View File

@ -13,18 +13,18 @@ namespace View_by_Distance.Map.Models;
public class MapLogic : Shared.Models.Methods.IMapLogic
{
protected readonly List<PersonContainer> _NotMappedPersonContainers;
protected readonly ReadOnlyDictionary<int, List<int>> _SkipCollection;
protected readonly ReadOnlyDictionary<int, List<int>> _SkipNotSkipCollection;
protected readonly ReadOnlyDictionary<long, PersonContainer> _PersonKeyToPersonContainer;
protected readonly List<LocationContainer<MetadataExtractor.Directory>> _LocationContainers;
protected readonly ReadOnlyDictionary<int, Dictionary<int, PersonContainer[]>> _IdThenWholePercentagesToPersonContainers;
private readonly long _Ticks;
private readonly Serilog.ILogger? _Log;
private readonly Configuration? _Configuration;
private readonly string _EDistanceContentTicksDirectory;
private readonly ReadOnlyDictionary<long, int> _PersonKeyToCount;
private readonly List<PersonContainer> _NotMappedPersonContainers;
private readonly ReadOnlyDictionary<int, List<int>> _SkipCollection;
private readonly ReadOnlyDictionary<int, List<int>> _SkipNotSkipCollection;
private readonly ReadOnlyDictionary<long, PersonContainer> _PersonKeyToPersonContainer;
private readonly Shared.Models.Properties.IPropertyConfiguration _PropertyConfiguration;
private readonly ReadOnlyDictionary<int, List<LocationContainer<MetadataExtractor.Directory>>> _IdToLocationContainers;
private readonly ReadOnlyDictionary<int, ReadOnlyDictionary<int, ReadOnlyCollection<PersonContainer>>> _IdThenWholePercentagesToPersonContainers;
public MapLogic(int maxDegreeOfParallelism, Shared.Models.Properties.IPropertyConfiguration propertyConfiguration, Configuration? configuration, ReadOnlyCollection<PersonContainer> personContainers, long ticks, string a2PeopleSingletonDirectory, string eDistanceContentDirectory)
{
@ -34,56 +34,83 @@ public class MapLogic : Shared.Models.Methods.IMapLogic
_PropertyConfiguration = propertyConfiguration;
if (_Log is null)
{ }
string json;
string fullPath;
List<KeyValuePair<int, int[]>>? collection;
Dictionary<int, List<int>> skipCollection = new();
ReadOnlyDictionary<long, int> readOnlyPersonKeyToCount;
List<PersonContainer> notMappedPersonContainers = new();
Dictionary<int, List<int>> skipNotSkipCollection = new();
Dictionary<int, List<(string, int)>> skipCollection = new();
Dictionary<int, List<(string, int)>> skipNotSkipCollection = new();
Dictionary<long, PersonContainer> personKeyToPersonContainer = new();
List<LocationContainer<MetadataExtractor.Directory>> locationContainers = new();
string? rootDirectoryParent = Path.GetDirectoryName(propertyConfiguration.RootDirectory);
string eDistanceContentTicksDirectory = Path.Combine(eDistanceContentDirectory, $"({ticks})");
Dictionary<int, Dictionary<int, PersonContainer[]>> idThenWholePercentagesToPersonContainers = new();
Dictionary<int, List<LocationContainer<MetadataExtractor.Directory>>> idToLocationContainers = new();
ReadOnlyDictionary<int, ReadOnlyDictionary<int, ReadOnlyCollection<PersonContainer>>> idThenWholePercentagesToPersonContainers;
if (string.IsNullOrEmpty(rootDirectoryParent))
throw new NullReferenceException(nameof(rootDirectoryParent));
if (!Directory.Exists(eDistanceContentDirectory))
_ = Directory.CreateDirectory(eDistanceContentDirectory);
if (configuration is not null)
if (configuration is null)
{
Stateless.MapLogic.Set(maxDegreeOfParallelism,
configuration,
readOnlyPersonKeyToCount = new(new Dictionary<long, int>());
idThenWholePercentagesToPersonContainers = new(new Dictionary<int, ReadOnlyDictionary<int, ReadOnlyCollection<PersonContainer>>>());
}
else
{
ReadOnlyDictionary<string, PersonContainer> readOnlyPersonKeyFormattedToPersonContainer;
ReadOnlyDictionary<long, List<PersonContainer>> readOnlyPersonKeyToPersonContainerCollection;
Stateless.MapLogic.SetSkipCollections(configuration, personContainers, a2PeopleSingletonDirectory, skipCollection, skipNotSkipCollection);
List<Stateless.MapLogic.Record> records = Stateless.MapLogic.SetPersonCollectionsAndGetRecords(configuration, ticks, personContainers, eDistanceContentDirectory);
locationContainers.AddRange(Stateless.MapLogic.GetLocationContainers(maxDegreeOfParallelism, configuration, ticks, personContainers, eDistanceContentDirectory, skipCollection, records));
int lossCount = records.Count - locationContainers.Count;
ReadOnlyCollection<Stateless.MapLogic.PersonKeyFormattedIdThenWholePercentages> personKeyFormattedIdThenWholePercentagesCollection = Stateless.MapLogic.GetPersonKeyFormattedIdThenWholePercentages(configuration, ticks, records);
int unableToMatchCount = records.Count - personKeyFormattedIdThenWholePercentagesCollection.Count;
if (lossCount != 0 || unableToMatchCount != 0)
{
if (lossCount != 0 || unableToMatchCount != 0)
{ }
}
//
{
Dictionary<long, int> personKeyToCount = new();
Dictionary<string, PersonContainer> personKeyFormattedToPersonContainer = new();
Dictionary<long, List<PersonContainer>> personKeyToPersonContainerCollection = new();
List<(Stateless.MapLogic.PersonKeyFormattedIdThenWholePercentages, PersonContainer)> possiblyNewPersonDisplayDirectoryNamesAndPersonContainer = new();
Stateless.MapLogic.SetKeyValuePairsAndAddToCollections(configuration,
personContainers,
personKeyToPersonContainer,
personKeyFormattedIdThenWholePercentagesCollection,
personKeyToCount,
personKeyFormattedToPersonContainer,
personKeyToPersonContainerCollection,
possiblyNewPersonDisplayDirectoryNamesAndPersonContainer);
readOnlyPersonKeyToCount = new(personKeyToCount);
readOnlyPersonKeyFormattedToPersonContainer = new(personKeyFormattedToPersonContainer);
readOnlyPersonKeyToPersonContainerCollection = new(personKeyToPersonContainerCollection);
if (possiblyNewPersonDisplayDirectoryNamesAndPersonContainer.Count > 0)
Stateless.MapLogic.PossiblyRebuildPersonContainers(configuration,
a2PeopleSingletonDirectory,
possiblyNewPersonDisplayDirectoryNamesAndPersonContainer);
}
Stateless.MapLogic.SetPersonKeyToPersonContainer(configuration,
personContainers,
readOnlyPersonKeyToCount,
personKeyToPersonContainer,
readOnlyPersonKeyToPersonContainerCollection);
idThenWholePercentagesToPersonContainers = Stateless.MapLogic.GetIdThenWholePercentagesToPersonContainers(configuration,
readOnlyPersonKeyFormattedToPersonContainer,
personKeyFormattedIdThenWholePercentagesCollection);
notMappedPersonContainers.AddRange(Stateless.MapLogic.GetNotMappedPersonContainers(configuration,
ticks,
personContainers,
a2PeopleSingletonDirectory,
eDistanceContentDirectory,
personKeyToPersonContainer,
notMappedPersonContainers,
skipCollection,
skipNotSkipCollection,
locationContainers,
idThenWholePercentagesToPersonContainers);
readOnlyPersonKeyToCount));
}
foreach (string propertyContentCollectionFile in propertyConfiguration.PropertyContentCollectionFiles)
{
fullPath = Path.GetFullPath(string.Concat(rootDirectoryParent, propertyContentCollectionFile));
if (fullPath.Contains(propertyConfiguration.RootDirectory))
continue;
if (!File.Exists(fullPath))
continue;
json = File.ReadAllText(fullPath);
collection = JsonSerializer.Deserialize<List<KeyValuePair<int, int[]>>>(json);
if (collection is null)
throw new NullReferenceException(nameof(collection));
}
_SkipCollection = new(skipCollection);
_LocationContainers = locationContainers;
_SkipNotSkipCollection = new(skipNotSkipCollection);
_PersonKeyToCount = readOnlyPersonKeyToCount;
_PersonKeyToPersonContainer = new(personKeyToPersonContainer);
_EDistanceContentTicksDirectory = eDistanceContentTicksDirectory;
_NotMappedPersonContainers = notMappedPersonContainers.OrderByDescending(l => l.Key).ToList();
_IdThenWholePercentagesToPersonContainers = new(idThenWholePercentagesToPersonContainers);
_SkipCollection = Stateless.MapLogic.ConvertSkip(skipCollection);
Stateless.MapLogic.CheckCollection(propertyConfiguration, rootDirectoryParent);
_IdThenWholePercentagesToPersonContainers = idThenWholePercentagesToPersonContainers;
_SkipNotSkipCollection = Stateless.MapLogic.ConvertSkipNotSkip(skipNotSkipCollection);
_IdToLocationContainers = Stateless.MapLogic.ConvertLocationContainers(locationContainers);
_NotMappedPersonContainers = new(notMappedPersonContainers.OrderByDescending(l => l.Key).ToArray());
}
public override string ToString()
@ -92,16 +119,19 @@ public class MapLogic : Shared.Models.Methods.IMapLogic
return result;
}
public ReadOnlyDictionary<int, List<LocationContainer<MetadataExtractor.Directory>>> GetIdToLocationContainers()
public ReadOnlyCollection<LocationContainer<MetadataExtractor.Directory>> GetLocationContainers(Item item)
{
Dictionary<int, List<LocationContainer<MetadataExtractor.Directory>>> results = new();
foreach (LocationContainer<MetadataExtractor.Directory> locationContainer in _LocationContainers)
LocationContainer<MetadataExtractor.Directory>[] results;
if (item.Property?.Id is null)
results = Array.Empty<LocationContainer<MetadataExtractor.Directory>>();
else
{
if (!results.ContainsKey(locationContainer.Id))
results.Add(locationContainer.Id, new());
results[locationContainer.Id].Add(locationContainer);
List<LocationContainer<MetadataExtractor.Directory>>? locationContainers;
if (_IdToLocationContainers.TryGetValue(item.Property.Id.Value, out locationContainers))
results = locationContainers.ToArray();
else
results = Array.Empty<LocationContainer<MetadataExtractor.Directory>>();
}
_LocationContainers.Clear();
return new(results);
}
@ -113,9 +143,9 @@ public class MapLogic : Shared.Models.Methods.IMapLogic
List<int>? collection;
PersonBirthday personBirthday;
List<string> shouldMove = new();
foreach (KeyValuePair<int, Dictionary<int, PersonContainer[]>> idToCollection in _IdThenWholePercentagesToPersonContainers)
foreach (KeyValuePair<int, ReadOnlyDictionary<int, ReadOnlyCollection<PersonContainer>>> idToCollection in _IdThenWholePercentagesToPersonContainers)
{
foreach (KeyValuePair<int, PersonContainer[]> wholePercentagesToPersonContainers in idToCollection.Value)
foreach (KeyValuePair<int, ReadOnlyCollection<PersonContainer>> wholePercentagesToPersonContainers in idToCollection.Value)
{
foreach (PersonContainer personContainer in wholePercentagesToPersonContainers.Value)
{
@ -137,28 +167,26 @@ public class MapLogic : Shared.Models.Methods.IMapLogic
}
}
}
if (shouldMove.Any())
if (shouldMove.Count > 0)
throw new Exception(string.Join(Environment.NewLine, shouldMove));
return results;
}
(bool, Dictionary<int, PersonContainer[]>?) Shared.Models.Methods.IMapLogic.GetWholePercentagesToPersonContainers(int id)
(bool, ReadOnlyDictionary<int, ReadOnlyCollection<PersonContainer>>?) Shared.Models.Methods.IMapLogic.GetWholePercentagesToPersonContainers(int id)
{
bool result = _IdThenWholePercentagesToPersonContainers.TryGetValue(id, out Dictionary<int, PersonContainer[]>? wholePercentagesToPersonContainers);
bool result = _IdThenWholePercentagesToPersonContainers.TryGetValue(id, out ReadOnlyDictionary<int, ReadOnlyCollection<PersonContainer>>? wholePercentagesToPersonContainers);
return new(result, wholePercentagesToPersonContainers);
}
public int UpdateMappingFromPerson(Mapping mapping)
public int UpdateMappingFromPerson(ReadOnlyCollection<string>? locationContainersFiles, Mapping mapping)
{
if (_Configuration is null)
throw new NullReferenceException(nameof(_Configuration));
int result = 0;
long personKey;
const int zero = 0;
string mappingSegmentB;
PersonBirthday personBirthday;
PersonContainer[]? personContainers;
Dictionary<int, PersonContainer[]>? wholePercentagesToPersonContainers;
ReadOnlyCollection<PersonContainer>? personContainers;
ReadOnlyDictionary<int, ReadOnlyCollection<PersonContainer>>? wholePercentagesToPersonContainers;
for (int i = 1; i < 2; i++)
{
if (mapping.MappingFromLocation is null)
@ -184,20 +212,31 @@ public class MapLogic : Shared.Models.Methods.IMapLogic
personBirthday = personContainer.Birthdays[zero];
personKey = personBirthday.Value.Ticks;
mappingSegmentB = Stateless.MapLogic.GetMappingSegmentB(_Ticks, personBirthday, personContainer.ApproximateYears, mapping.MappingFromItem);
mapping.UpdateMappingFromPerson(personContainer.ApproximateYears, personContainer.DisplayDirectoryName, personBirthday, mappingSegmentB);
if (locationContainersFiles is null)
{
if (mapping.MappingFromPerson is null || mapping.MappingFromPerson.LocationContainersFiles.Count == 0)
locationContainersFiles = new(Array.Empty<string>());
else
locationContainersFiles = mapping.MappingFromPerson.LocationContainersFiles;
}
mapping.UpdateMappingFromPerson(locationContainersFiles, personContainer.ApproximateYears, personContainer.DisplayDirectoryName, personBirthday, mappingSegmentB);
}
}
return result;
}
public int UpdateMappingFromPerson(Mapping[] mappingCollection)
public int UpdateMappingFromPerson(Property.Models.Configuration propertyConfiguration, Mapping[] mappingCollection)
{
int result = 0;
ReadOnlyCollection<string>? locationContainersFiles = null;
foreach (Mapping mapping in mappingCollection)
{
if (mapping.MappingFromLocation is null)
continue;
result += UpdateMappingFromPerson(mapping);
result += UpdateMappingFromPerson(locationContainersFiles, mapping);
if (mapping.MappingFromPerson is null || mapping.MappingFromPerson.LocationContainersFiles.Count == 0)
continue;
Stateless.MapLogic.MoveToDecade(propertyConfiguration, mapping.MappingFromItem, mapping.MappingFromPerson);
}
return result;
}
@ -564,8 +603,8 @@ public class MapLogic : Shared.Models.Methods.IMapLogic
Sorting sorting;
FaceDistance faceDistanceLength;
List<int>? wholePercentagesCollection;
bool skipNotSkipCollectionAny = _SkipNotSkipCollection.Any();
Dictionary<int, PersonContainer[]>? wholePercentagesToPersonContainers;
bool skipNotSkipCollectionAny = _SkipNotSkipCollection.Count > 0;
ReadOnlyDictionary<int, ReadOnlyCollection<PersonContainer>>? wholePercentagesToPersonContainers;
for (int j = 0; j < faceDistanceLengths.Count; j++)
{
if (faceDistanceEncoding.WholePercentages is null)
@ -615,14 +654,14 @@ public class MapLogic : Shared.Models.Methods.IMapLogic
string mappingSegmentB;
string personKeyFormatted;
PersonBirthday personBirthday;
PersonContainer[]? personContainers;
List<int> wholePercentagesCollectionForA;
List<int> wholePercentagesCollectionForB;
Dictionary<string, int> keyToCount = new();
Dictionary<string, string> keyToSegmentC = new();
ReadOnlyCollection<PersonContainer>? personContainers;
Dictionary<int, List<int>> idToWholePercentagesCollectionForA = new();
Dictionary<int, List<int>> idToWholePercentagesCollectionForB = new();
Dictionary<int, PersonContainer[]>? wholePercentagesToPersonContainers;
ReadOnlyDictionary<int, ReadOnlyCollection<PersonContainer>>? wholePercentagesToPersonContainers;
int totalSeconds = (int)Math.Floor(new TimeSpan(DateTime.Now.Ticks - _Ticks).TotalSeconds);
string message = $") {sortingContainers.Length:000} Update From Sorting Container(s) - {totalSeconds} total second(s)";
ProgressBarOptions options = new() { ProgressCharacter = '─', ProgressBarOnBottom = true, DisableBottomPercentage = true };
@ -707,11 +746,11 @@ public class MapLogic : Shared.Models.Methods.IMapLogic
WindowsShortcut windowsShortcut;
Dictionary<int, Mapping>? wholePercentagesToMapping;
string by = nameof(Shared.Models.Stateless.IMapLogic.ManualCopy);
Dictionary<int, PersonContainer[]>? wholePercentagesToPeronContainerCollection;
ReadOnlyDictionary<int, ReadOnlyCollection<PersonContainer>>? wholePercentagesToPeronContainerCollection;
string successful = $"_ {nameof(Shared.Models.Stateless.IMapLogic.ManualCopy).Humanize(LetterCasing.Title)} Successful";
foreach (KeyValuePair<long, PersonContainer> personKeyToPersonContainer in _PersonKeyToPersonContainer)
{
if (personKeyToPersonContainer.Value.Key is null || personKeyToPersonContainer.Value.Birthdays is null || !personKeyToPersonContainer.Value.Birthdays.Any() || personKeyToPersonContainer.Value.PersonDirectory is null)
if (personKeyToPersonContainer.Value.Key is null || personKeyToPersonContainer.Value.Birthdays is null || personKeyToPersonContainer.Value.Birthdays.Length == 0 || personKeyToPersonContainer.Value.PersonDirectory is null)
continue;
personBirthday = personKeyToPersonContainer.Value.Birthdays[zero];
foreach (string personDisplayDirectoryAllFile in personKeyToPersonContainer.Value.DisplayDirectoryAllFiles)
@ -786,13 +825,11 @@ public class MapLogic : Shared.Models.Methods.IMapLogic
if (_Configuration is null)
throw new NullReferenceException(nameof(_Configuration));
List<string> results = new();
int count;
long personKey;
string directory;
string? directoryName;
PersonContainer? personContainer;
Dictionary<long, int> personKeyToCount = new();
for (int i = 1; i < 3; i++)
{
foreach (Mapping mapping in mappingCollection)
{
if (mapping.MappingFromLocation is null || mapping.MappingFromPerson is null)
@ -809,27 +846,17 @@ public class MapLogic : Shared.Models.Methods.IMapLogic
directoryName = Path.GetDirectoryName(mapping.MappingFromItem.RelativePath);
if (directoryName is null)
throw new NotSupportedException();
if (!_PersonKeyToCount.TryGetValue(personKey, out count))
continue;
if (!_PersonKeyToPersonContainer.TryGetValue(personKey, out personContainer))
continue;
if (personContainer.PersonDirectory is null || !_Configuration.PersonCharacters.Contains(personContainer.PersonDirectory.Char))
continue;
if (i == 1)
{
if (!personKeyToCount.ContainsKey(personKey))
personKeyToCount.Add(personKey, 0);
personKeyToCount[personKey]++;
}
else if (i == 2)
{
directory = Path.Combine(a2PeopleSingletonDirectory, personContainer.PersonDirectory.Char.ToString(), personContainer.PersonDirectory.Group, personContainer.DisplayDirectoryName, personKeyToCount[personKey].ToString("0000"));
directory = Path.Combine(a2PeopleSingletonDirectory, personContainer.PersonDirectory.Char.ToString(), personContainer.PersonDirectory.Group, personContainer.DisplayDirectoryName, count.ToString("0000"));
if (results.Contains(directory))
continue;
results.Add(directory);
}
else
throw new NotSupportedException();
}
}
return results;
}
@ -1008,7 +1035,7 @@ public class MapLogic : Shared.Models.Methods.IMapLogic
foreach ((long personKey, string displayDirectoryName) in collection)
{
matches = (from l in personContainers where l.Key == personKey && l.ApproximateYears.HasValue select l).ToArray();
if (!matches.Any())
if (matches.Length == 0)
continue;
personKeyFormatted = IPersonBirthday.GetFormatted(_Configuration.PersonBirthdayFormat, personKey);
if (!displayDirectoryName.Contains(personKeyFormatted))
@ -1230,7 +1257,7 @@ public class MapLogic : Shared.Models.Methods.IMapLogic
personDirectory = Path.Combine(directory, "No Faces");
fileName = Path.Combine(personDirectory, $"{item.ResizedFileHolder.Name}.lnk");
collection.Add(new(item.ResizedFileHolder.FullName, personDirectory, item.ImageFileHolder.LastWriteTime.Value, fileName, face.Mapping.MappingFromItem.Id.ToString(), MakeAllHidden: false));
if (face.Mapping.MappingFromItem.ContainerDateTimes.Any() && !distinct.Contains(item.ResizedFileHolder.DirectoryName))
if (face.Mapping.MappingFromItem.ContainerDateTimes.Length > 0 && !distinct.Contains(item.ResizedFileHolder.DirectoryName))
{
distinct.Add(item.ResizedFileHolder.DirectoryName);
directoriesAndDateTimes.Add(new(item.ResizedFileHolder.DirectoryName, face.Mapping.MappingFromItem.ContainerDateTimes));
@ -1246,7 +1273,7 @@ public class MapLogic : Shared.Models.Methods.IMapLogic
continue;
if (mapping.By is null or Shared.Models.Stateless.IMapLogic.Sorting || mapping.MappingFromPerson?.ApproximateYears is null)
{
if (mapping.MappingFromItem.ContainerDateTimes.Any() && !distinct.Contains(mapping.MappingFromItem.ResizedFileHolder.DirectoryName))
if (mapping.MappingFromItem.ContainerDateTimes.Length > 0 && !distinct.Contains(mapping.MappingFromItem.ResizedFileHolder.DirectoryName))
{
distinct.Add(mapping.MappingFromItem.ResizedFileHolder.DirectoryName);
directoriesAndDateTimes.Add(new(mapping.MappingFromItem.ResizedFileHolder.DirectoryName, mapping.MappingFromItem.ContainerDateTimes));
@ -1270,7 +1297,7 @@ public class MapLogic : Shared.Models.Methods.IMapLogic
throw new NotSupportedException();
personKeyFormatted = IPersonBirthday.GetFormatted(_Configuration.PersonBirthdayFormat, mapping.MappingFromPerson.PersonBirthday);
personKey = mapping.MappingFromPerson.PersonBirthday.Value.Ticks;
if (mapping.MappingFromItem.ContainerDateTimes.Any() && !distinct.Contains(mapping.MappingFromItem.ResizedFileHolder.DirectoryName))
if (mapping.MappingFromItem.ContainerDateTimes.Length > 0 && !distinct.Contains(mapping.MappingFromItem.ResizedFileHolder.DirectoryName))
{
distinct.Add(mapping.MappingFromItem.ResizedFileHolder.DirectoryName);
directoriesAndDateTimes.Add(new(mapping.MappingFromItem.ResizedFileHolder.DirectoryName, mapping.MappingFromItem.ContainerDateTimes));
@ -1322,17 +1349,17 @@ public class MapLogic : Shared.Models.Methods.IMapLogic
}
foreach ((string directory, DateTime[] dateTimes) in directoriesAndDateTimes)
{
if (!dateTimes.Any())
if (dateTimes.Length == 0)
continue;
Directory.SetCreationTime(directory, dateTimes[0]);
Directory.SetLastWriteTime(directory, dateTimes[1]);
}
}
public Dictionary<int, Dictionary<int, PersonContainer[]>> GetMissing(Dictionary<int, Dictionary<int, Mapping>> idToWholePercentagesToMapping)
public Dictionary<int, ReadOnlyDictionary<int, ReadOnlyCollection<PersonContainer>>> GetMissing(Dictionary<int, Dictionary<int, Mapping>> idToWholePercentagesToMapping)
{
Dictionary<int, Dictionary<int, PersonContainer[]>> results = new();
foreach (KeyValuePair<int, Dictionary<int, PersonContainer[]>> idToCollection in _IdThenWholePercentagesToPersonContainers)
Dictionary<int, ReadOnlyDictionary<int, ReadOnlyCollection<PersonContainer>>> results = new();
foreach (KeyValuePair<int, ReadOnlyDictionary<int, ReadOnlyCollection<PersonContainer>>> idToCollection in _IdThenWholePercentagesToPersonContainers)
{
if (idToWholePercentagesToMapping.ContainsKey(idToCollection.Key))
continue;
@ -1344,9 +1371,9 @@ public class MapLogic : Shared.Models.Methods.IMapLogic
public bool IsUsed(bool ignoreXMatches, int id, MappingFromLocation mappingFromLocation)
{
bool result;
PersonContainer[]? personContainers;
ReadOnlyCollection<PersonContainer>? personContainers;
List<int>? wholePercentagesCollection;
Dictionary<int, PersonContainer[]>? wholePercentagesToPersonContainers;
ReadOnlyDictionary<int, ReadOnlyCollection<PersonContainer>>? wholePercentagesToPersonContainers;
result = _SkipCollection.TryGetValue(id, out wholePercentagesCollection) && wholePercentagesCollection.Contains(mappingFromLocation.WholePercentages);
if (!result && _IdThenWholePercentagesToPersonContainers.TryGetValue(id, out wholePercentagesToPersonContainers))
{
@ -1360,19 +1387,15 @@ public class MapLogic : Shared.Models.Methods.IMapLogic
return result;
}
public bool InSkipCollection(int id, MappingFromLocation mappingFromLocation)
{
bool result;
result = _SkipCollection.TryGetValue(id, out List<int>? wholePercentagesCollection) && wholePercentagesCollection.Contains(mappingFromLocation.WholePercentages);
return result;
}
public bool InSkipCollection(int id, MappingFromLocation mappingFromLocation) =>
_SkipCollection.TryGetValue(id, out List<int>? wholePercentagesCollection) && wholePercentagesCollection.Contains(mappingFromLocation.WholePercentages);
public bool? IsFocusPerson(List<(string Directory, long PersonKey)> jLinkResolvedDirectories, int id, MappingFromLocation mappingFromLocation)
public bool? IsFocusPerson(int? skipPersonWithMoreThen, List<(string Directory, long PersonKey)> jLinkResolvedDirectories, int id, MappingFromLocation mappingFromLocation)
{
bool? result;
PersonContainer[]? personContainers;
Dictionary<int, PersonContainer[]>? wholePercentagesToPersonContainers;
if (jLinkResolvedDirectories.Count == 0)
ReadOnlyCollection<PersonContainer>? personContainers;
ReadOnlyDictionary<int, ReadOnlyCollection<PersonContainer>>? wholePercentagesToPersonContainers;
if (skipPersonWithMoreThen is null && jLinkResolvedDirectories.Count == 0)
result = null;
else if (!_IdThenWholePercentagesToPersonContainers.TryGetValue(id, out wholePercentagesToPersonContainers))
result = null;
@ -1383,7 +1406,14 @@ public class MapLogic : Shared.Models.Methods.IMapLogic
result = false;
foreach (PersonContainer personContainer in personContainers)
{
if (jLinkResolvedDirectories.Any(l => personContainer.Key == l.PersonKey))
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;
@ -1393,4 +1423,55 @@ public class MapLogic : Shared.Models.Methods.IMapLogic
return result;
}
private void LookForAbandoned(Property.Models.Configuration propertyConfiguration, List<int> distinctFilteredIds)
{
List<string> renameCollection = new();
foreach (KeyValuePair<int, List<LocationContainer<MetadataExtractor.Directory>>> keyValuePair in _IdToLocationContainers)
{
if (distinctFilteredIds.Contains(keyValuePair.Key))
continue;
foreach (LocationContainer<MetadataExtractor.Directory> locationContainer in keyValuePair.Value)
{
if (locationContainer.File.Contains('!'))
continue;
renameCollection.Add(locationContainer.File);
}
}
if (renameCollection.Count > 0)
IDirectory.MoveFiles(renameCollection, propertyConfiguration.ResultContent, "(abd)");
}
public void LookForAbandoned(Property.Models.Configuration propertyConfiguration, string bResultsFullGroupDirectory, Container[] containers, string cResultsFullGroupDirectory, string dResultsFullGroupDirectory, string d2ResultsFullGroupDirectory)
{
string[] directories;
string? directoryName;
List<int> distinctFilteredIds = IContainer.GetFilteredDistinctIds(propertyConfiguration, containers);
LookForAbandoned(propertyConfiguration, distinctFilteredIds);
Stateless.MapLogic.LookForAbandoned(bResultsFullGroupDirectory, distinctFilteredIds);
directories = Directory.GetDirectories(cResultsFullGroupDirectory, "*", SearchOption.TopDirectoryOnly);
foreach (string directory in directories)
{
directoryName = Path.GetFileName(directory);
if (string.IsNullOrEmpty(directoryName) || (directoryName.Length != 2 && directoryName.Length != 4))
continue;
Stateless.MapLogic.LookForAbandoned(distinctFilteredIds, directory, directoryName);
}
directories = Directory.GetDirectories(dResultsFullGroupDirectory, "*", SearchOption.TopDirectoryOnly);
foreach (string directory in directories)
{
directoryName = Path.GetFileName(directory);
if (string.IsNullOrEmpty(directoryName) || (directoryName.Length != 2 && directoryName.Length != 4))
continue;
Stateless.MapLogic.LookForAbandoned(distinctFilteredIds, directory, directoryName);
}
directories = Directory.GetDirectories(d2ResultsFullGroupDirectory, "*", SearchOption.TopDirectoryOnly);
foreach (string directory in directories)
{
directoryName = Path.GetFileName(directory);
if (string.IsNullOrEmpty(directoryName) || (directoryName.Length != 2 && directoryName.Length != 4))
continue;
Stateless.MapLogic.LookForAbandoned(distinctFilteredIds, directory, directoryName);
}
}
}

View File

@ -4,6 +4,7 @@ using System.Collections.ObjectModel;
using System.Diagnostics;
using System.Drawing;
using System.Globalization;
using System.Text.Json;
using View_by_Distance.Shared.Models;
using View_by_Distance.Shared.Models.Stateless.Methods;
using WindowsShortcutFactory;
@ -13,53 +14,77 @@ namespace View_by_Distance.Map.Models.Stateless;
internal abstract class MapLogic
{
private record Record(string PersonKeyFormatted,
internal record Record(string PersonKeyFormatted,
string[] PersonDisplayDirectoryNames,
bool IsDefault,
string MappedFaceFile);
private record TicksDirectory(string Directory,
internal record TicksDirectory(string Directory,
string DirectoryName,
long DirectoryTicks,
DateTime DirectoryDateTime,
DateTime AlternateDirectoryDateTime,
float? TotalDays);
private record PersonKeyFormattedIdThenWholePercentages(string PersonKeyFormatted,
internal record PersonKeyFormattedIdThenWholePercentages(string PersonKeyFormatted,
string[] PersonDisplayDirectoryNames,
bool IsDefault,
string MappedFaceFile,
int Id,
int WholePercentages);
private static void SetPersonCollections(Configuration configuration, ReadOnlyCollection<PersonContainer> personContainers, string? a2PeopleSingletonDirectory, Dictionary<string, string> personKeyFormattedToNewestPersonKeyFormatted, List<string> personKeyFormattedCollection, Dictionary<int, List<int>> skipCollection, Dictionary<int, List<int>> skipNotSkipCollection)
internal static void SetSkipCollections(Configuration configuration, ReadOnlyCollection<PersonContainer> personContainers, string? a2PeopleSingletonDirectory, Dictionary<int, List<(string, int)>> skipCollection, Dictionary<int, List<(string, int)>> skipNotSkipCollection)
{
int? id;
string fileName;
int? wholePercentages;
string personKeyFormatted;
string newestPersonKeyFormatted;
bool skipNotSkipDirectoriesAny = configuration.SkipNotSkipDirectories.Any();
string[] checkDirectories = (from l in configuration.SkipNotSkipDirectories select Path.GetFullPath(string.Concat(a2PeopleSingletonDirectory, l))).ToArray();
List<string> distinctFiles = new();
List<string> distinctFileName = new();
bool skipNotSkipDirectoriesAny = configuration.SkipNotSkipDirectories.Length > 0;
string[] checkDirectories = (from l in configuration.SkipNotSkipDirectories select Path.GetFullPath($"{a2PeopleSingletonDirectory}{l}")).ToArray();
foreach (PersonContainer personContainer in personContainers)
{
foreach (string personDisplayDirectoryAllFile in personContainer.DisplayDirectoryAllFiles)
{
if (!personDisplayDirectoryAllFile.EndsWith(configuration.FacesFileNameExtension))
continue;
(id, wholePercentages) = IMapping.GetConverted(configuration.FacesFileNameExtension, personDisplayDirectoryAllFile);
if (distinctFiles.Contains(personDisplayDirectoryAllFile))
continue;
distinctFiles.Add(personDisplayDirectoryAllFile);
}
}
foreach (string distinctFile in distinctFiles)
{
fileName = Path.GetFileName(distinctFile);
if (distinctFileName.Contains(fileName))
{
if (!distinctFile.EndsWith(".dup") && !File.Exists($"{distinctFile}.dup"))
File.Move(distinctFile, $"{distinctFile}.dup");
continue;
}
(id, wholePercentages) = IMapping.GetConverted(configuration.FacesFileNameExtension, distinctFile);
if (id is null || wholePercentages is null)
continue;
if (!skipNotSkipDirectoriesAny || !checkDirectories.Any(l => personDisplayDirectoryAllFile.StartsWith(l)))
if (!skipNotSkipDirectoriesAny || !checkDirectories.Any(l => distinctFile.StartsWith(l)))
{
if (!skipCollection.ContainsKey(id.Value))
skipCollection.Add(id.Value, new());
skipCollection[id.Value].Add(wholePercentages.Value);
skipCollection[id.Value].Add((distinctFile, wholePercentages.Value));
}
else
{
if (!skipNotSkipCollection.ContainsKey(id.Value))
skipNotSkipCollection.Add(id.Value, new());
skipNotSkipCollection[id.Value].Add(wholePercentages.Value);
skipNotSkipCollection[id.Value].Add((distinctFile, wholePercentages.Value));
}
}
}
private static void SetPersonCollections(Configuration configuration, ReadOnlyCollection<PersonContainer> personContainers, Dictionary<string, string> personKeyFormattedToNewestPersonKeyFormatted, List<string> personKeyFormattedCollection)
{
string personKeyFormatted;
string newestPersonKeyFormatted;
foreach (PersonContainer personContainer in personContainers)
{
if (personContainer.Key is null || personContainer.Birthdays is null || personContainer.Birthdays.Length == 0)
continue;
foreach (PersonBirthday personBirthday in personContainer.Birthdays)
@ -220,56 +245,71 @@ internal abstract class MapLogic
}
}
private static List<Record> DeleteEmptyDirectoriesAndGetCollection(Configuration configuration, Dictionary<string, string> personKeyFormattedToNewestPersonKeyFormatted, List<string> personKeyFormattedCollection, List<TicksDirectory> ticksDirectories, string message)
private static List<Record> DeleteEmptyDirectoriesAndGetCollection(Configuration configuration, long ticks, string eDistanceContentDirectory, ReadOnlyDictionary<string, string> personKeyFormattedToNewestPersonKeyFormatted, ReadOnlyCollection<string> personKeyFormattedCollection)
{
List<Record> results = new();
int? id;
bool check;
bool isDefault;
string message;
string[] files;
string fileName;
int totalSeconds;
DateTime dateTime;
TimeSpan timeSpan;
bool check = false;
int? wholePercentages;
string checkDirectory;
string? checkDirectory;
ProgressBar progressBar;
string[] yearDirectories;
string personKeyFormatted;
string? personFirstInitial;
bool isReservedDirectoryName;
List<string> distinct = new();
string[] personKeyDirectories;
string[] personNameDirectories;
string? newestPersonKeyFormatted;
string[] personNameLinkDirectories;
string? personFirstInitialDirectory;
string[] personDisplayDirectoryNames;
List<TicksDirectory> ticksDirectories;
string[] personKeyFormattedDirectories;
string manualCopyHumanized = nameof(Shared.Models.Stateless.IMapLogic.ManualCopy).Humanize(LetterCasing.Title);
string forceSingleImageHumanized = nameof(Shared.Models.Stateless.IMapLogic.ForceSingleImage).Humanize(LetterCasing.Title);
ProgressBarOptions options = new() { ProgressCharacter = '─', ProgressBarOnBottom = true, DisableBottomPercentage = true };
using ProgressBar progressBar = new(ticksDirectories.Count, message, options);
for (int i = 1; i < 3; i++)
{
check = false;
results.Clear();
distinct.Clear();
ticksDirectories = UpdateDateVerifyAndGetTicksDirectories(eDistanceContentDirectory);
totalSeconds = (int)Math.Floor(new TimeSpan(DateTime.Now.Ticks - ticks).TotalSeconds);
message = $"{i}) {ticksDirectories.Count:000} compile from and clean ticks Director(ies) - B - {totalSeconds} total second(s)";
progressBar = new(ticksDirectories.Count, message, options);
foreach (TicksDirectory ticksDirectory in ticksDirectories)
{
if (i == 1)
progressBar.Tick();
personKeyDirectories = Directory.GetDirectories(ticksDirectory.Directory, "*", SearchOption.TopDirectoryOnly);
foreach (string personKeyDirectory in personKeyDirectories)
personKeyFormattedDirectories = Directory.GetDirectories(ticksDirectory.Directory, "*", SearchOption.TopDirectoryOnly);
foreach (string personKeyFormattedDirectory in personKeyFormattedDirectories)
{
personKeyFormatted = Path.GetFileName(personKeyDirectory);
personKeyFormatted = Path.GetFileName(personKeyFormattedDirectory);
isReservedDirectoryName = personKeyFormatted.StartsWith(nameof(Shared.Models.Stateless.IMapLogic.Sorting)) || personKeyFormatted.StartsWith(nameof(Shared.Models.Stateless.IMapLogic.Mapping)) || personKeyFormatted.StartsWith(nameof(Shared.Models.Stateless.IMapLogic.ManualCopy));
if (!isReservedDirectoryName && personKeyFormatted.StartsWith(nameof(Shared.Models.Stateless.IMapLogic.Individually)))
{
Individually(configuration, ticksDirectory, personKeyDirectory);
Individually(configuration, ticksDirectory, personKeyFormattedDirectory);
throw new Exception($"B) Move personKey directories up one from {nameof(Shared.Models.Stateless.IMapLogic.Sorting)} and delete {nameof(Shared.Models.Stateless.IMapLogic.Sorting)} directory!");
}
_ = personKeyFormattedToNewestPersonKeyFormatted.TryGetValue(personKeyFormatted, out newestPersonKeyFormatted);
if (personKeyFormattedToNewestPersonKeyFormatted.Count > 0 && newestPersonKeyFormatted is null)
{
timeSpan = new TimeSpan(DateTime.Now.Ticks - ticksDirectory.DirectoryTicks);
if (timeSpan.TotalDays > 7)
timeSpan = new TimeSpan(DateTime.Now.Ticks - ticksDirectory.DirectoryDateTime.Ticks);
if (timeSpan.TotalDays > 6)
throw new Exception($"{configuration.MappingDefaultName} are only allowed within x days!");
}
yearDirectories = Directory.GetDirectories(personKeyDirectory, "*", SearchOption.TopDirectoryOnly);
yearDirectories = Directory.GetDirectories(personKeyFormattedDirectory, "*", SearchOption.TopDirectoryOnly);
foreach (string yearDirectory in yearDirectories)
{
if (check && !Directory.Exists(yearDirectory))
continue;
files = Directory.GetFiles(yearDirectory, "*", SearchOption.TopDirectoryOnly);
personNameDirectories = Directory.GetDirectories(yearDirectory, "*", SearchOption.TopDirectoryOnly);
foreach (string file in files)
@ -295,12 +335,29 @@ internal abstract class MapLogic
check = true;
continue;
}
if (isDefault && (ticksDirectory.DirectoryDateTime.Hour != 0 || ticksDirectory.DirectoryDateTime.Minute != 0 || ticksDirectory.DirectoryDateTime.Second != 0))
{
checkDirectory = Path.GetDirectoryName(ticksDirectory.Directory);
if (checkDirectory is null)
continue;
checkDirectory = Path.Combine(checkDirectory, $"({ticksDirectory.AlternateDirectoryDateTime.Ticks})");
if (!Directory.Exists(checkDirectory))
_ = Directory.CreateDirectory(checkDirectory);
checkDirectory = Path.Combine(checkDirectory, personKeyFormatted);
if (!Directory.Exists(checkDirectory))
{
Directory.Move(personKeyFormattedDirectory, checkDirectory);
if (!check)
check = true;
break;
}
}
files = Directory.GetFiles(personNameDirectory, "*", SearchOption.TopDirectoryOnly);
if (isReservedDirectoryName && files.Any())
if (isReservedDirectoryName && files.Length > 0)
throw new Exception($"Move personKey directories up one from {nameof(Shared.Models.Stateless.IMapLogic.Sorting)} and delete {nameof(Shared.Models.Stateless.IMapLogic.Sorting)} directory!");
if (personKeyFormatted == manualCopyHumanized && files.Any())
if (personKeyFormatted == manualCopyHumanized && files.Length > 0)
throw new Exception($"Move personKey directories up one from {manualCopyHumanized} and delete {manualCopyHumanized} directory!");
if (personKeyFormatted == forceSingleImageHumanized && files.Any())
if (personKeyFormatted == forceSingleImageHumanized && files.Length > 0)
throw new Exception($"Move personKey directories up one from {forceSingleImageHumanized} and delete {forceSingleImageHumanized} directory!");
if (!isDefault)
{
@ -310,7 +367,7 @@ internal abstract class MapLogic
{
if (!check)
check = true;
MovedToNewestPersonKeyFormatted(personKeyFormatted, newestPersonKeyFormatted, ticksDirectory, personKeyDirectory);
MovedToNewestPersonKeyFormatted(personKeyFormatted, newestPersonKeyFormatted, ticksDirectory, personKeyFormattedDirectory);
continue;
}
}
@ -347,7 +404,7 @@ internal abstract class MapLogic
fileName = Path.GetFileName(mappedFaceFile);
if (distinct.Contains(fileName))
{
if (!File.Exists($"{mappedFaceFile}.dup"))
if (!mappedFaceFile.EndsWith(".dup") && !File.Exists($"{mappedFaceFile}.dup"))
File.Move(mappedFaceFile, $"{mappedFaceFile}.dup");
continue;
}
@ -370,51 +427,40 @@ internal abstract class MapLogic
}
_ = IPath.DeleteEmptyDirectories(yearDirectory);
}
_ = IPath.DeleteEmptyDirectories(personKeyDirectory);
_ = IPath.DeleteEmptyDirectories(personKeyFormattedDirectory);
}
_ = IPath.DeleteEmptyDirectories(ticksDirectory.Directory);
_ = IPath.DeleteEmptyDirectories(ticksDirectory.Directory);
}
progressBar.Dispose();
if (check)
throw new Exception("PersonKey director(ies) where renamed. Please restart!");
continue;
break;
}
return results;
}
private static PersonContainer[] GetDistinctPersonContainers(List<PersonContainer> personContainers)
{
List<PersonContainer> results = new();
List<long> distinctCheck = new();
foreach (PersonContainer personContainer in personContainers)
{
if (personContainer.Key is null || distinctCheck.Contains(personContainer.Key.Value))
continue;
results.Add(personContainer);
}
return results.ToArray();
}
private static void SetKeyValuePairsAndAddToCollections(Configuration configuration, ReadOnlyCollection<PersonContainer> personContainers, Dictionary<long, List<PersonContainer>> personKeyToPersonContainerCollection, Dictionary<string, PersonContainer> personKeyFormattedToPersonContainer, List<PersonKeyFormattedIdThenWholePercentages> personKeyFormattedIdThenWholePercentagesCollection, Dictionary<long, PersonContainer> personKeyToPersonContainer, Dictionary<int, Dictionary<int, PersonContainer[]>> idThenWholePercentagesToPersonContainers, List<(PersonKeyFormattedIdThenWholePercentages, PersonContainer)> possiblyNewPersonDisplayDirectoryNamesAndPersonContainer)
internal static void SetKeyValuePairsAndAddToCollections(Configuration configuration, ReadOnlyCollection<PersonContainer> personContainers, Dictionary<long, PersonContainer> personKeyToPersonContainer, ReadOnlyCollection<PersonKeyFormattedIdThenWholePercentages> personKeyFormattedIdThenWholePercentagesCollection, Dictionary<long, int> personKeyToCount, Dictionary<string, PersonContainer> personKeyFormattedToPersonContainer, Dictionary<long, List<PersonContainer>> personKeyToPersonContainerCollection, List<(PersonKeyFormattedIdThenWholePercentages, PersonContainer)> possiblyNewPersonDisplayDirectoryNamesAndPersonContainer)
{
PersonBirthday? personBirthday;
PersonContainer[] distinctPersonContainers;
Dictionary<int, Dictionary<int, List<PersonContainer>>> idThenWholePercentagesToPersonContainers = new();
(long, PersonContainer)[] collection = GetDistinctCollection(configuration, personContainers, personKeyToPersonContainerCollection, personKeyFormattedToPersonContainer);
foreach ((long personKey, PersonContainer personContainer) in collection)
personKeyToPersonContainer.Add(personKey, personContainer);
Dictionary<int, Dictionary<int, List<PersonContainer>>> idThenWholePercentagesToPersonContainerCollection = new();
if (personKeyFormattedIdThenWholePercentagesCollection.Any())
if (personKeyFormattedIdThenWholePercentagesCollection.Count > 0)
{
string group;
char[] matches;
char status, sex, first;
PersonContainer personContainer;
PersonDirectory personDirectory;
PersonContainer? personContainer;
string personDisplayDirectoryName;
foreach (PersonKeyFormattedIdThenWholePercentages personKeyFormattedIdThenWholePercentages in personKeyFormattedIdThenWholePercentagesCollection)
{
personBirthday = IPersonBirthday.GetPersonBirthday(configuration.PersonBirthdayFormat, personKeyFormattedIdThenWholePercentages.PersonKeyFormatted);
if (personBirthday is null)
continue;
if (!personKeyFormattedToPersonContainer.ContainsKey(personKeyFormattedIdThenWholePercentages.PersonKeyFormatted))
throw new Exception();
if (!personKeyFormattedToPersonContainer.TryGetValue(personKeyFormattedIdThenWholePercentages.PersonKeyFormatted, out personContainer))
{
personDisplayDirectoryName = personKeyFormattedIdThenWholePercentages.PersonDisplayDirectoryNames[^1];
matches = configuration.PersonCharacters.Where(l => personDisplayDirectoryName.Contains(l)).ToArray();
@ -426,23 +472,85 @@ internal abstract class MapLogic
personContainer = new(configuration.PersonCharacters.ToArray(), personBirthday, personDisplayDirectoryName, personDirectory);
personKeyFormattedToPersonContainer.Add(personKeyFormattedIdThenWholePercentages.PersonKeyFormatted, personContainer);
}
if (!idThenWholePercentagesToPersonContainerCollection.ContainsKey(personKeyFormattedIdThenWholePercentages.Id))
idThenWholePercentagesToPersonContainerCollection.Add(personKeyFormattedIdThenWholePercentages.Id, new());
if (!idThenWholePercentagesToPersonContainerCollection[personKeyFormattedIdThenWholePercentages.Id].ContainsKey(personKeyFormattedIdThenWholePercentages.WholePercentages))
idThenWholePercentagesToPersonContainerCollection[personKeyFormattedIdThenWholePercentages.Id].Add(personKeyFormattedIdThenWholePercentages.WholePercentages, new());
idThenWholePercentagesToPersonContainerCollection[personKeyFormattedIdThenWholePercentages.Id][personKeyFormattedIdThenWholePercentages.WholePercentages].Add(personKeyFormattedToPersonContainer[personKeyFormattedIdThenWholePercentages.PersonKeyFormatted]);
possiblyNewPersonDisplayDirectoryNamesAndPersonContainer.Add(new(personKeyFormattedIdThenWholePercentages, personKeyFormattedToPersonContainer[personKeyFormattedIdThenWholePercentages.PersonKeyFormatted]));
if (personContainer.Key is null)
throw new Exception();
if (!personKeyToCount.ContainsKey(personContainer.Key.Value))
personKeyToCount.Add(personContainer.Key.Value, 0);
personKeyToCount[personContainer.Key.Value]++;
possiblyNewPersonDisplayDirectoryNamesAndPersonContainer.Add(new(personKeyFormattedIdThenWholePercentages, personContainer));
}
}
foreach (KeyValuePair<int, Dictionary<int, List<PersonContainer>>> keyValuePair in idThenWholePercentagesToPersonContainerCollection)
}
private static Dictionary<int, Dictionary<int, List<PersonContainer>>> GetAll(Configuration configuration, ReadOnlyDictionary<string, PersonContainer> personKeyFormattedToPersonContainer, ReadOnlyCollection<PersonKeyFormattedIdThenWholePercentages> personKeyFormattedIdThenWholePercentagesCollection)
{
idThenWholePercentagesToPersonContainers.Add(keyValuePair.Key, new());
foreach (KeyValuePair<int, List<PersonContainer>> innerKeyValuePair in keyValuePair.Value)
Dictionary<int, Dictionary<int, List<PersonContainer>>> results = new();
PersonBirthday? personBirthday;
PersonContainer? personContainer;
List<PersonContainer>? personContainers;
Dictionary<int, List<PersonContainer>>? idTo;
if (personKeyFormattedIdThenWholePercentagesCollection.Count > 0)
{
distinctPersonContainers = GetDistinctPersonContainers(innerKeyValuePair.Value);
idThenWholePercentagesToPersonContainers[keyValuePair.Key].Add(innerKeyValuePair.Key, distinctPersonContainers);
foreach (PersonKeyFormattedIdThenWholePercentages personKeyFormattedIdThenWholePercentages in personKeyFormattedIdThenWholePercentagesCollection)
{
personBirthday = IPersonBirthday.GetPersonBirthday(configuration.PersonBirthdayFormat, personKeyFormattedIdThenWholePercentages.PersonKeyFormatted);
if (personBirthday is null)
throw new Exception();
if (!personKeyFormattedToPersonContainer.TryGetValue(personKeyFormattedIdThenWholePercentages.PersonKeyFormatted, out personContainer))
throw new Exception();
if (!results.TryGetValue(personKeyFormattedIdThenWholePercentages.Id, out idTo))
{
results.Add(personKeyFormattedIdThenWholePercentages.Id, new());
if (!results.TryGetValue(personKeyFormattedIdThenWholePercentages.Id, out idTo))
throw new Exception();
}
};
if (!idTo.TryGetValue(personKeyFormattedIdThenWholePercentages.WholePercentages, out personContainers))
{
idTo.Add(personKeyFormattedIdThenWholePercentages.WholePercentages, new());
if (!idTo.TryGetValue(personKeyFormattedIdThenWholePercentages.WholePercentages, out personContainers))
throw new Exception();
}
personContainers.Add(personContainer);
}
}
return results;
}
private static ReadOnlyDictionary<int, ReadOnlyDictionary<int, ReadOnlyCollection<PersonContainer>>> GetReadOnly(Dictionary<int, Dictionary<int, List<PersonContainer>>> idThenWholePercentagesToPersonContainerCollection)
{
Dictionary<int, ReadOnlyDictionary<int, ReadOnlyCollection<PersonContainer>>> results = new();
List<long> distinct = new();
List<PersonContainer> personContainers;
Dictionary<int, ReadOnlyCollection<PersonContainer>> keyValuePairs;
foreach (KeyValuePair<int, Dictionary<int, List<PersonContainer>>> idTo in idThenWholePercentagesToPersonContainerCollection)
{
keyValuePairs = new();
foreach (KeyValuePair<int, List<PersonContainer>> wholePercentagesTo in idThenWholePercentagesToPersonContainerCollection[idTo.Key])
{
distinct.Clear();
personContainers = new();
foreach (PersonContainer personContainer in wholePercentagesTo.Value)
{
if (personContainer.Key is null)
throw new Exception();
if (distinct.Contains(personContainer.Key.Value))
continue;
personContainers.Add(personContainer);
}
keyValuePairs.Add(wholePercentagesTo.Key, new(personContainers));
}
results.Add(idTo.Key, new(keyValuePairs));
}
return new(results);
}
internal static ReadOnlyDictionary<int, ReadOnlyDictionary<int, ReadOnlyCollection<PersonContainer>>> GetIdThenWholePercentagesToPersonContainers(Configuration configuration, ReadOnlyDictionary<string, PersonContainer> personKeyFormattedToPersonContainer, ReadOnlyCollection<PersonKeyFormattedIdThenWholePercentages> personKeyFormattedIdThenWholePercentagesCollection)
{
ReadOnlyDictionary<int, ReadOnlyDictionary<int, ReadOnlyCollection<PersonContainer>>> results;
Dictionary<int, Dictionary<int, List<PersonContainer>>> idThenWholePercentagesToPersonContainerCollection;
idThenWholePercentagesToPersonContainerCollection = GetAll(configuration, personKeyFormattedToPersonContainer, personKeyFormattedIdThenWholePercentagesCollection);
results = GetReadOnly(idThenWholePercentagesToPersonContainerCollection);
return results;
}
private static (long, PersonContainer)[] GetDistinctCollection(Configuration configuration, IEnumerable<PersonContainer> personContainers, Dictionary<long, List<PersonContainer>> personKeyToPersonContainerCollection, Dictionary<string, PersonContainer> personKeyFormattedToPersonContainer)
@ -469,15 +577,15 @@ internal abstract class MapLogic
errors.Add(keyValuePair.Value[zero].DisplayDirectoryName);
collection.Add(new(keyValuePair.Key, keyValuePair.Value[zero]));
}
if (errors.Any())
if (errors.Count > 0)
throw new Exception(string.Join(Environment.NewLine, errors));
results = (from l in collection orderby l.PersonKey descending select (l.PersonKey, l.PersonContainer)).ToArray();
return results;
}
private static int SetCollectionsAndGetUnableToConvertCount(Configuration configuration, long ticks, List<PersonKeyFormattedIdThenWholePercentages> personKeyFormattedIdThenWholePercentagesCollection, List<Record> collection)
internal static ReadOnlyCollection<PersonKeyFormattedIdThenWholePercentages> GetPersonKeyFormattedIdThenWholePercentages(Configuration configuration, long ticks, List<Record> collection)
{
int result = 0;
List<PersonKeyFormattedIdThenWholePercentages> results = new();
int? id;
int? wholePercentages;
string personDisplayDirectoryName;
@ -492,10 +600,7 @@ internal abstract class MapLogic
progressBar.Tick();
(id, wholePercentages) = IMapping.GetConverted(configuration.FacesFileNameExtension, record.MappedFaceFile);
if (id is null || wholePercentages is null)
{
result++;
continue;
}
if (!idToWholePercentagesCollection.ContainsKey(id.Value))
idToWholePercentagesCollection.Add(id.Value, new());
wholePercentagesCollection = idToWholePercentagesCollection[id.Value];
@ -504,12 +609,12 @@ internal abstract class MapLogic
personDisplayDirectoryName = record.PersonDisplayDirectoryNames[^1];
if (string.IsNullOrEmpty(personDisplayDirectoryName))
continue;
personKeyFormattedIdThenWholePercentagesCollection.Add(new(record.PersonKeyFormatted, record.PersonDisplayDirectoryNames, record.IsDefault, record.MappedFaceFile, id.Value, wholePercentages.Value));
results.Add(new(record.PersonKeyFormatted, record.PersonDisplayDirectoryNames, record.IsDefault, record.MappedFaceFile, id.Value, wholePercentages.Value));
}
return result;
return new(results);
}
private static List<PersonContainer> GetNonSpecificPeopleCollection(Configuration configuration, long ticks, List<long> personKeys)
private static List<PersonContainer> GetNonSpecificPeopleCollection(Configuration configuration, long ticks, List<long> personKeys, ReadOnlyDictionary<long, int> personKeyToCount)
{
List<PersonContainer> results = new();
bool check;
@ -529,6 +634,8 @@ internal abstract class MapLogic
break;
if (personKeys.Contains(personKey))
continue;
if (personKeyToCount.ContainsKey(personKey))
continue;
for (int j = 1; j < 24; j++)
{
if (personKeys.Contains(personKey + (oneHour * j)))
@ -536,6 +643,11 @@ internal abstract class MapLogic
check = true;
break;
}
if (personKeyToCount.ContainsKey(personKey + (oneHour * j)))
{
check = true;
break;
}
}
if (check)
continue;
@ -548,7 +660,7 @@ internal abstract class MapLogic
return results;
}
private static List<PersonContainer> GetNotMappedPersonContainers(Configuration configuration, long ticks, ReadOnlyCollection<PersonContainer> personContainers, long[] personKeyCollection)
internal static List<PersonContainer> GetNotMappedPersonContainers(Configuration configuration, long ticks, ReadOnlyCollection<PersonContainer> personContainers, ReadOnlyDictionary<long, int> personKeyToCount)
{
List<PersonContainer> results = new();
List<PersonContainer> notMappedAndNotNamedPersonKeys = new();
@ -560,7 +672,7 @@ internal abstract class MapLogic
continue;
if (personKeys.Contains(personContainer.Key.Value))
continue;
if (personKeyCollection.Contains(personContainer.Key.Value))
if (personKeyToCount.ContainsKey(personContainer.Key.Value))
continue;
if (string.IsNullOrEmpty(personContainer.DisplayDirectoryName) || personContainer.DisplayDirectoryName == configuration.MappingDefaultName)
notMappedAndNotNamedPersonKeys.Add(personContainer);
@ -569,7 +681,7 @@ internal abstract class MapLogic
}
results.AddRange(notMappedAndNotNamedPersonKeys);
if (results.Count == 0)
results.AddRange(GetNonSpecificPeopleCollection(configuration, ticks, personKeys));
results.AddRange(GetNonSpecificPeopleCollection(configuration, ticks, personKeys, personKeyToCount));
return results;
}
@ -585,40 +697,40 @@ internal abstract class MapLogic
return result;
}
private static void SetPersonKeyToPersonContainer(Configuration configuration, ReadOnlyCollection<PersonContainer> personContainers, long[] personKeyCollection, Dictionary<long, PersonContainer> personKeyToPersonContainer, Dictionary<long, List<PersonContainer>> personKeyToPersonContainerCollection)
internal static void SetPersonKeyToPersonContainer(Configuration configuration, ReadOnlyCollection<PersonContainer> personContainers, ReadOnlyDictionary<long, int> personKeyToCount, Dictionary<long, PersonContainer> personKeyToPersonContainer, ReadOnlyDictionary<long, List<PersonContainer>> personKeyToPersonContainerCollection)
{
string? displayDirectoryName;
foreach (PersonContainer personContainer in personContainers)
{
if (personContainer.Key is null || !personKeyCollection.Contains(personContainer.Key.Value))
if (personContainer.Key is null || !personKeyToCount.ContainsKey(personContainer.Key.Value))
continue;
displayDirectoryName = GetDisplayDirectoryName(personKeyToPersonContainer, personContainer.Key.Value);
if (displayDirectoryName is not null && (displayDirectoryName == personContainer.DisplayDirectoryName || (displayDirectoryName[0] == personContainer.DisplayDirectoryName[0] && (displayDirectoryName.Length == 1 || personContainer.DisplayDirectoryName.Length == 1))))
continue;
personKeyToPersonContainer.Add(personContainer.Key.Value, personContainer);
}
if (personKeyCollection.Any())
if (personKeyToCount.Count > 0)
{
const int zero = 0;
int? approximateYears = null;
PersonBirthday? personBirthday;
PersonContainer personContainer;
displayDirectoryName = configuration.MappingDefaultName;
foreach (long personKey in personKeyCollection)
foreach (KeyValuePair<long, int> keyValuePair in personKeyToCount)
{
if (personKeyToPersonContainer.ContainsKey(personKey))
if (personKeyToPersonContainer.ContainsKey(keyValuePair.Key))
continue;
personBirthday = IPersonBirthday.GetPersonBirthday(personKey);
if (!personKeyToPersonContainerCollection.ContainsKey(personKey))
personContainer = new(approximateYears, personBirthday, displayDirectoryName, personKey);
personBirthday = IPersonBirthday.GetPersonBirthday(keyValuePair.Key);
if (!personKeyToPersonContainerCollection.ContainsKey(keyValuePair.Key))
personContainer = new(approximateYears, personBirthday, displayDirectoryName, keyValuePair.Key);
else
personContainer = new(approximateYears, personBirthday, personKeyToPersonContainerCollection[personKey][zero].PersonDirectory, displayDirectoryName, personKey);
personKeyToPersonContainer.Add(personKey, personContainer);
personContainer = new(approximateYears, personBirthday, personKeyToPersonContainerCollection[keyValuePair.Key][zero].PersonDirectory, displayDirectoryName, keyValuePair.Key);
personKeyToPersonContainer.Add(keyValuePair.Key, personContainer);
}
}
}
static void PossiblyRebuildPersonContainers(Configuration configuration, string? a2PeopleSingletonDirectory, Dictionary<string, string> personKeyFormattedToNewestPersonKeyFormatted, List<(PersonKeyFormattedIdThenWholePercentages, PersonContainer)> possiblyNewPersonDisplayDirectoryNamesAndPersonContainer)
internal static void PossiblyRebuildPersonContainers(Configuration configuration, string? a2PeopleSingletonDirectory, List<(PersonKeyFormattedIdThenWholePercentages, PersonContainer)> possiblyNewPersonDisplayDirectoryNamesAndPersonContainer)
{
bool[] matches;
string fileName;
@ -648,7 +760,7 @@ internal abstract class MapLogic
personDisplayDirectory = Path.Combine(a2PeopleSingletonDirectory, personContainer.PersonDirectory.Char.ToString(), personContainer.PersonDirectory.Group, personContainer.DisplayDirectoryName);
personKeyFormattedDirectory = Path.GetFullPath(Path.Combine(personDisplayDirectory, personKeyFormatted));
deleteCollection = (from l in personContainer.DisplayDirectoryAllFiles where l.StartsWith(personKeyFormattedDirectory) select l).ToArray();
if (personKeyFormattedToNewestPersonKeyFormatted.Count > 0 && personContainer.DisplayDirectoryAllFiles.Length != 0 && deleteCollection.Length == 0)
if (personContainer.DisplayDirectoryAllFiles.Length != 0 && deleteCollection.Length == 0)
throw new NotSupportedException();
if (!Directory.Exists(personKeyFormattedDirectory))
_ = Directory.CreateDirectory(personKeyFormattedDirectory);
@ -676,6 +788,7 @@ internal abstract class MapLogic
List<TicksDirectory> results = new();
float? totalDays;
string ticksDirectoryName;
DateTime directoryDateTime;
DirectoryInfo directoryInfo;
long? lastDirectoryTicks = null;
DateTime dateTime = DateTime.Now;
@ -693,16 +806,17 @@ internal abstract class MapLogic
throw new NotSupportedException();
}
directoryInfo = new(ticksDirectory);
directoryDateTime = new DateTime(directoryTicks);
if (directoryInfo.CreationTime.Ticks != directoryTicks)
Directory.SetCreationTime(ticksDirectory, new DateTime(directoryTicks));
if (directoryInfo.LastWriteTime.Ticks != directoryTicks)
Directory.SetLastWriteTime(ticksDirectory, new DateTime(directoryTicks));
totalDays = lastDirectoryTicks is null || new TimeSpan(dateTime.Ticks - directoryTicks).TotalDays < 1 ? null : (float)new TimeSpan(directoryTicks - lastDirectoryTicks.Value).TotalDays;
results.Add(new(ticksDirectory, ticksDirectoryName, directoryTicks, totalDays));
results.Add(new(ticksDirectory, ticksDirectoryName, new(directoryTicks), new DateTime(directoryDateTime.Year, directoryDateTime.Month, directoryDateTime.Day + 1), totalDays));
lastDirectoryTicks = directoryTicks;
}
string[] compare = (from l in results where l.TotalDays is not null and < 3.95f select l.Directory).ToArray();
if (compare.Any())
if (compare.Length > 0)
throw new Exception($"Please Consolidate <{string.Join(Environment.NewLine, compare)}>");
return results;
}
@ -769,11 +883,13 @@ internal abstract class MapLogic
return results;
}
private static void ParallelFor(Configuration configuration, string eDistanceContentDirectory, List<LocationContainer<MetadataExtractor.Directory>> locationContainers, long personKey, string file)
private static void ParallelFor(Configuration configuration, string eDistanceContentDirectory, Dictionary<int, List<(string, int)>> skipCollection, List<LocationContainer<MetadataExtractor.Directory>> locationContainers, long personKey, string file)
{
string[] fileMatches;
const string lnk = ".lnk";
int? id, wholePercentages;
IReadOnlyList<MetadataExtractor.Directory> directories;
List<(string File, int WholePercentages)>? wholePercentagesCollection;
bool fromDistanceContent = !file.EndsWith(lnk) && file.Contains(eDistanceContentDirectory);
if (!file.EndsWith(lnk))
(id, wholePercentages) = IMapping.GetConverted(configuration.FacesFileNameExtension, file);
@ -781,6 +897,15 @@ internal abstract class MapLogic
(id, wholePercentages) = IMapping.GetConverted(configuration.FacesFileNameExtension, file[..^4]);
if (id is null || wholePercentages is null)
return;
if (skipCollection.TryGetValue(id.Value, out wholePercentagesCollection))
{
fileMatches = (from l in wholePercentagesCollection where l.WholePercentages == wholePercentages select l.File).ToArray();
foreach (string fileMatch in fileMatches)
{
if (!fileMatch.EndsWith(".dup") && !File.Exists($"{fileMatch}.dup"))
File.Move(fileMatch, $"{fileMatch}.dup");
}
}
if (file.EndsWith(lnk) || (!configuration.DistanceMoveUnableToMatch && !configuration.DistanceRenameToMatch) || !File.Exists(file))
directories = new List<MetadataExtractor.Directory>();
else
@ -816,7 +941,7 @@ internal abstract class MapLogic
}
}
private static void LookForPossibleDuplicates(Configuration configuration, List<LocationContainer<MetadataExtractor.Directory>> locationContainers)
private static void LookForPossibleDuplicates(Configuration configuration, ReadOnlyCollection<LocationContainer<MetadataExtractor.Directory>> locationContainers)
{
string key;
float? percent;
@ -848,7 +973,7 @@ internal abstract class MapLogic
}
distinct.Add(key, new(locationContainer.File, locationContainer.WholePercentages));
}
if (!configuration.DeletePossibleDuplicates && duplicates.Any())
if (!configuration.DeletePossibleDuplicates && duplicates.Count > 0)
OpenPossibleDuplicates(configuration, duplicates);
else
{
@ -862,11 +987,11 @@ internal abstract class MapLogic
}
}
private static List<LocationContainer<MetadataExtractor.Directory>> GetLocationContainers(int maxDegreeOfParallelism, Configuration configuration, long ticks, ReadOnlyCollection<PersonContainer> personContainers, string eDistanceContentDirectory, List<Record> records)
internal static List<LocationContainer<MetadataExtractor.Directory>> GetLocationContainers(int maxDegreeOfParallelism, Configuration configuration, long ticks, ReadOnlyCollection<PersonContainer> personContainers, string eDistanceContentDirectory, Dictionary<int, List<(string, int)>> skipCollection, List<Record> records)
{
List<LocationContainer<MetadataExtractor.Directory>> results = new();
List<(long PersonKey, string File)> collection = GetCollection(configuration, personContainers, records);
if (collection.Any() && (configuration.DistanceMoveUnableToMatch || configuration.DistanceRenameToMatch))
if (collection.Count > 0 && (configuration.DistanceMoveUnableToMatch || configuration.DistanceRenameToMatch))
{
int totalSeconds = (int)Math.Floor(new TimeSpan(DateTime.Now.Ticks - ticks).TotalSeconds);
string message = $") Building Mapped Face Files Collection - {totalSeconds} total second(s)";
@ -876,48 +1001,21 @@ internal abstract class MapLogic
_ = Parallel.For(0, collection.Count, parallelOptions, (i, state) =>
{
progressBar.Tick();
ParallelFor(configuration, eDistanceContentDirectory, results, collection[i].PersonKey, collection[i].File);
ParallelFor(configuration, eDistanceContentDirectory, skipCollection, results, collection[i].PersonKey, collection[i].File);
});
}
LookForPossibleDuplicates(configuration, results);
LookForPossibleDuplicates(configuration, new(results));
return results;
}
internal static void Set(int maxDegreeOfParallelism, Configuration configuration, long ticks, ReadOnlyCollection<PersonContainer> personContainers, string? a2PeopleSingletonDirectory, string eDistanceContentDirectory, Dictionary<long, PersonContainer> personKeyToPersonContainer, List<PersonContainer> notMappedPersonContainers, Dictionary<int, List<int>> skipCollection, Dictionary<int, List<int>> skipNotSkipCollection, List<LocationContainer<MetadataExtractor.Directory>> locationContainers, Dictionary<int, Dictionary<int, PersonContainer[]>> idThenWholePercentagesToPersonContainers)
internal static List<Record> SetPersonCollectionsAndGetRecords(Configuration configuration, long ticks, ReadOnlyCollection<PersonContainer> personContainers, string eDistanceContentDirectory)
{
string message;
int totalSeconds;
List<long?> nullablePersonKeyCollection = new();
List<Record> results;
List<string> personKeyFormattedCollection = new();
Dictionary<string, string> personKeyFormattedToNewestPersonKeyFormatted = new();
Dictionary<string, PersonContainer> personKeyFormattedToPersonContainer = new();
Dictionary<long, List<PersonContainer>> personKeyToPersonContainerCollection = new();
List<TicksDirectory> ticksDirectories = UpdateDateVerifyAndGetTicksDirectories(eDistanceContentDirectory);
List<PersonKeyFormattedIdThenWholePercentages> personKeyFormattedIdThenWholePercentagesCollection = new();
List<(PersonKeyFormattedIdThenWholePercentages, PersonContainer)> possiblyNewPersonDisplayDirectoryNamesAndPersonContainer = new();
SetPersonCollections(configuration, personContainers, a2PeopleSingletonDirectory, personKeyFormattedToNewestPersonKeyFormatted, personKeyFormattedCollection, skipCollection, skipNotSkipCollection);
totalSeconds = (int)Math.Floor(new TimeSpan(DateTime.Now.Ticks - ticks).TotalSeconds);
message = $") {ticksDirectories.Count:000} compile from and clean ticks Director(ies) - B - {totalSeconds} total second(s)";
List<Record> records = DeleteEmptyDirectoriesAndGetCollection(configuration, personKeyFormattedToNewestPersonKeyFormatted, personKeyFormattedCollection, ticksDirectories, message);
locationContainers.AddRange(GetLocationContainers(maxDegreeOfParallelism, configuration, ticks, personContainers, eDistanceContentDirectory, records));
int unableToMatchCount = SetCollectionsAndGetUnableToConvertCount(configuration, ticks, personKeyFormattedIdThenWholePercentagesCollection, records);
SetKeyValuePairsAndAddToCollections(configuration, personContainers, personKeyToPersonContainerCollection, personKeyFormattedToPersonContainer, personKeyFormattedIdThenWholePercentagesCollection, personKeyToPersonContainer, idThenWholePercentagesToPersonContainers, possiblyNewPersonDisplayDirectoryNamesAndPersonContainer);
totalSeconds = (int)Math.Floor(new TimeSpan(DateTime.Now.Ticks - ticks).TotalSeconds);
message = $") {records.Count:000} message from ticks Director(ies) - D - {unableToMatchCount} Unable To Match Count / {records.Count} Collection - {totalSeconds} total second(s)";
ProgressBarOptions options = new() { ProgressCharacter = '─', ProgressBarOnBottom = true, DisableBottomPercentage = true };
using (ProgressBar progressBar = new(records.Count, message, options))
{
foreach (KeyValuePair<int, Dictionary<int, PersonContainer[]>> keyValuePair in idThenWholePercentagesToPersonContainers)
{
progressBar.Tick();
foreach (KeyValuePair<int, PersonContainer[]> keyValue in keyValuePair.Value)
nullablePersonKeyCollection.AddRange(from l in keyValue.Value select l.Key);
}
}
long[] personKeyCollection = (from l in nullablePersonKeyCollection where l is not null select l.Value).Distinct().ToArray();
PossiblyRebuildPersonContainers(configuration, a2PeopleSingletonDirectory, personKeyFormattedToNewestPersonKeyFormatted, possiblyNewPersonDisplayDirectoryNamesAndPersonContainer);
SetPersonKeyToPersonContainer(configuration, personContainers, personKeyCollection, personKeyToPersonContainer, personKeyToPersonContainerCollection);
notMappedPersonContainers.AddRange(GetNotMappedPersonContainers(configuration, ticks, personContainers, personKeyCollection));
SetPersonCollections(configuration, personContainers, personKeyFormattedToNewestPersonKeyFormatted, personKeyFormattedCollection);
results = DeleteEmptyDirectoriesAndGetCollection(configuration, ticks, eDistanceContentDirectory, new(personKeyFormattedToNewestPersonKeyFormatted), new(personKeyFormattedCollection));
return results;
}
private static string GetMappingSegmentB(long ticks, PersonBirthday personBirthday, int? approximateYears, long dateTimeOriginalThenMinimumDateTimeTicks, bool? isWrongYear)
@ -1365,4 +1463,169 @@ internal abstract class MapLogic
return new(by, isByMapping, isBySorting);
}
internal static void CheckCollection(Shared.Models.Properties.IPropertyConfiguration propertyConfiguration, string? rootDirectoryParent)
{
string json;
string fullPath;
List<KeyValuePair<int, int[]>>? collection;
foreach (string propertyContentCollectionFile in propertyConfiguration.PropertyContentCollectionFiles)
{
fullPath = Path.GetFullPath(string.Concat(rootDirectoryParent, propertyContentCollectionFile));
if (fullPath.Contains(propertyConfiguration.RootDirectory))
continue;
if (!File.Exists(fullPath))
continue;
json = File.ReadAllText(fullPath);
collection = JsonSerializer.Deserialize<List<KeyValuePair<int, int[]>>>(json);
if (collection is null)
throw new NullReferenceException(nameof(collection));
}
}
internal static void LookForAbandoned(List<int> distinctFilteredIds, string directory, string directoryName)
{
string fileNameWithoutExtension;
bool nameWithoutExtensionIsIdFormat;
List<string> renameCollection = new();
bool nameWithoutExtensionIsPaddedIdFormat;
int sortOrderOnlyLengthIndex = IDirectory.GetSortOrderOnlyLengthIndex();
string[] distinctFilteredIdsValues = distinctFilteredIds.Select(l => l.ToString()).ToArray();
string[] files = Directory.GetFiles(directory, "*", SearchOption.AllDirectories);
foreach (string file in files)
{
fileNameWithoutExtension = Path.GetFileNameWithoutExtension(Path.GetFileNameWithoutExtension(Path.GetFileNameWithoutExtension(file)));
nameWithoutExtensionIsIdFormat = IProperty.NameWithoutExtensionIsIdFormat(fileNameWithoutExtension);
nameWithoutExtensionIsPaddedIdFormat = IDirectory.NameWithoutExtensionIsPaddedIdFormat(fileNameWithoutExtension, sortOrderOnlyLengthIndex);
if (!nameWithoutExtensionIsIdFormat && !nameWithoutExtensionIsPaddedIdFormat)
continue;
if (distinctFilteredIdsValues.Contains(fileNameWithoutExtension))
continue;
renameCollection.Add(file);
}
if (renameCollection.Count > 0)
{
if (directoryName.Length == 2)
IDirectory.MoveFiles(renameCollection, directoryName, $"{directoryName[0]}abd{directoryName[^1]}");
else if (directoryName.Length == 4)
IDirectory.MoveFiles(renameCollection, directoryName, $"{directoryName[..2]}abd{directoryName[^2..]}");
else
throw new NotSupportedException();
}
}
internal static void LookForAbandoned(string bResultsFullGroupDirectory, List<int> distinctFilteredIds)
{
string[] directories = Directory.GetDirectories(bResultsFullGroupDirectory, "*", SearchOption.TopDirectoryOnly);
foreach (string directory in directories)
{
string? directoryName = Path.GetFileName(directory);
if (string.IsNullOrEmpty(directoryName) || (directoryName.Length != 2 && directoryName.Length != 4))
continue;
LookForAbandoned(distinctFilteredIds, directory, directoryName);
}
}
internal static ReadOnlyDictionary<int, List<int>> ConvertSkip(Dictionary<int, List<(string, int)>> skipCollection)
{
Dictionary<int, List<int>> results = new();
List<int>? wholePercentagesCollection;
foreach (KeyValuePair<int, List<(string, int)>> keyValuePair in skipCollection)
{
if (!results.TryGetValue(keyValuePair.Key, out wholePercentagesCollection))
{
results.Add(keyValuePair.Key, new());
if (!results.TryGetValue(keyValuePair.Key, out wholePercentagesCollection))
throw new Exception();
}
foreach ((string _, int wholePercentage) in keyValuePair.Value)
wholePercentagesCollection.Add(wholePercentage);
}
return new(results);
}
internal static ReadOnlyDictionary<int, List<int>> ConvertSkipNotSkip(Dictionary<int, List<(string, int)>> skipNotSkipCollection)
{
Dictionary<int, List<int>> results = new();
List<int>? wholePercentagesCollection;
foreach (KeyValuePair<int, List<(string, int)>> keyValuePair in skipNotSkipCollection)
{
if (!results.TryGetValue(keyValuePair.Key, out wholePercentagesCollection))
{
results.Add(keyValuePair.Key, new());
if (!results.TryGetValue(keyValuePair.Key, out wholePercentagesCollection))
throw new Exception();
}
foreach ((string _, int wholePercentage) in keyValuePair.Value)
wholePercentagesCollection.Add(wholePercentage);
}
return new(results);
}
internal static ReadOnlyDictionary<int, List<LocationContainer<MetadataExtractor.Directory>>> ConvertLocationContainers(List<LocationContainer<MetadataExtractor.Directory>> locationContainers)
{
Dictionary<int, List<LocationContainer<MetadataExtractor.Directory>>> results = new();
foreach (LocationContainer<MetadataExtractor.Directory> locationContainer in locationContainers)
{
if (!results.ContainsKey(locationContainer.Id))
results.Add(locationContainer.Id, new());
results[locationContainer.Id].Add(locationContainer);
}
return new(results);
}
internal static void MoveToDecade(Property.Models.Configuration propertyConfiguration, MappingFromItem mappingFromItem, MappingFromPerson mappingFromPerson)
{
string year;
DateTime dateTime;
FileInfo fileInfo;
string halfDecade;
string checkDirectory;
string? yearDirectory;
string yearDirectoryName;
string? personNameDirectory;
string personNameDirectoryName;
string? personKeyFormattedDirectory;
string? personKeyFormattedDirectoryName;
foreach (string locationContainersFile in mappingFromPerson.LocationContainersFiles)
{
fileInfo = new(locationContainersFile);
if (!fileInfo.Exists)
continue;
personNameDirectory = Path.GetDirectoryName(locationContainersFile);
if (string.IsNullOrEmpty(personNameDirectory))
continue;
personNameDirectoryName = Path.GetFileName(personNameDirectory);
yearDirectory = Path.GetDirectoryName(personNameDirectory);
if (string.IsNullOrEmpty(yearDirectory))
continue;
yearDirectoryName = Path.GetFileName(yearDirectory);
personKeyFormattedDirectory = Path.GetDirectoryName(yearDirectory);
if (string.IsNullOrEmpty(personKeyFormattedDirectory))
continue;
personKeyFormattedDirectoryName = Path.GetFileName(personKeyFormattedDirectory);
if (personKeyFormattedDirectoryName.Length != propertyConfiguration.PersonBirthdayFormat.Length)
break;
if (mappingFromItem.DateTimeOriginal is null)
{
dateTime = mappingFromItem.MinimumDateTime;
year = mappingFromItem.MinimumDateTime.Year.ToString();
halfDecade = year[3] > '4' ? $"#{year[..3]}+" : $"#{year[..3]}-";
}
else
{
dateTime = mappingFromItem.DateTimeOriginal.Value;
year = mappingFromItem.DateTimeOriginal.Value.Year.ToString();
halfDecade = year[3] > '4' ? $"^{year[..3]}+" : $"^{year[..3]}-";
}
if (fileInfo.CreationTime != dateTime)
File.SetCreationTime(locationContainersFile, dateTime);
if (halfDecade == yearDirectoryName)
continue;
checkDirectory = Path.Combine(personKeyFormattedDirectory, halfDecade, personNameDirectoryName);
if (!Directory.Exists(checkDirectory))
_ = Directory.CreateDirectory(checkDirectory);
File.Move(locationContainersFile, Path.Combine(checkDirectory, Path.Combine(checkDirectory, Path.GetFileName(locationContainersFile))));
}
}
}

View File

@ -1,3 +1,4 @@
using System.Collections.ObjectModel;
using System.Drawing;
using System.Text;
using System.Text.Json;
@ -18,7 +19,7 @@ public class F_PhotoPrism
{
string json = File.ReadAllText(fileName);
JsonElement[]? jsonElements = JsonSerializer.Deserialize<JsonElement[]>(json);
if (jsonElements is null || !jsonElements.Any())
if (jsonElements is null || jsonElements.Length == 0)
results = Array.Empty<JsonProperty>();
else
{
@ -37,7 +38,7 @@ public class F_PhotoPrism
Marker[]? results;
string file = Path.Combine(fPhotoPrismSingletonDirectory, "markers.json");
JsonProperty[] jsonProperties = GetJsonProperty(file);
if (!jsonProperties.Any())
if (jsonProperties.Length == 0)
results = null;
else
results = JsonSerializer.Deserialize<Marker[]>(jsonProperties.Last().Value);
@ -79,7 +80,7 @@ public class F_PhotoPrism
List<Shared.Models.DatabaseFile>? results;
string file = Path.Combine(fPhotoPrismSingletonDirectory, "files.json");
JsonProperty[] jsonProperties = GetJsonProperty(file);
if (!jsonProperties.Any())
if (jsonProperties.Length == 0)
results = null;
else
{
@ -140,7 +141,7 @@ public class F_PhotoPrism
return results;
}
private static void PopulateSubjects(string mappingDefaultName, string personBirthdayFormat, List<string> subjects, StringBuilder stringBuilder, PersonContainer[] personContainers, (MappingFromPhotoPrism MappingFromPhotoPrism, Shared.Models.Marker Marker, float Percent)[] sortedCollection)
private static void PopulateSubjects(string mappingDefaultName, string personBirthdayFormat, List<string> subjects, StringBuilder stringBuilder, ReadOnlyCollection<PersonContainer> personContainers, (MappingFromPhotoPrism MappingFromPhotoPrism, Shared.Models.Marker Marker, float Percent)[] sortedCollection)
{
long? personKey;
const int zero = 0;
@ -150,7 +151,7 @@ public class F_PhotoPrism
{
foreach (PersonContainer personContainer in personContainers)
{
if (personContainer.Key is null || personContainer.Birthdays is null || !personContainer.Birthdays.Any())
if (personContainer.Key is null || personContainer.Birthdays is null || personContainer.Birthdays.Length == 0)
continue;
if (IPerson.IsDefaultName(mappingDefaultName, personContainer.DisplayDirectoryName))
continue;
@ -181,11 +182,11 @@ public class F_PhotoPrism
List<string> subjects = new();
DateTime dateTime = new(ticks);
int dlibLocationWholePercentages;
PersonContainer[]? personContainers;
StringBuilder stringBuilder = new();
RectangleF? dlibPercentagesRectangle;
ReadOnlyCollection<PersonContainer>? personContainers;
float rectangleIntersectMinimum = rectangleIntersectMinimums.Min();
Dictionary<int, PersonContainer[]>? wholePercentagesToPersonContainers;
ReadOnlyDictionary<int, ReadOnlyCollection<PersonContainer>>? wholePercentagesToPersonContainers;
(MappingFromPhotoPrism MappingFromPhotoPrism, Shared.Models.Marker Marker, float Percent)[] sortedCollection;
List<(MappingFromPhotoPrism MappingFromPhotoPrism, Shared.Models.Marker Marker, float Percent)> collection = new();
foreach (Face face in distinctFilteredFaces)
@ -220,12 +221,12 @@ public class F_PhotoPrism
collection.Add(new(mappingFromPhotoPrism, marker, percent.Value));
}
}
if (!collection.Any())
if (collection.Count == 0)
continue;
sortedCollection = collection.OrderByDescending(l => l.Percent).ToArray();
PopulateSubjects(mappingDefaultName, personBirthdayFormat, subjects, stringBuilder, personContainers, sortedCollection);
}
if (subjects.Any())
if (subjects.Count > 0)
{
directory = Path.Combine(fPhotoPrismContentDirectory, dateTime.ToString("yyyy-MM-dd"));
if (!Directory.Exists(directory))

View File

@ -97,11 +97,11 @@ public class Configuration : Shared.Models.Properties.IPropertyConfiguration
{
if (propertyConfiguration is null)
throw new NullReferenceException(nameof(propertyConfiguration));
if (propertyConfiguration.IgnoreExtensions is null || !propertyConfiguration.IgnoreExtensions.Any())
if (propertyConfiguration.IgnoreExtensions is null || propertyConfiguration.IgnoreExtensions.Length == 0)
throw new NullReferenceException(nameof(propertyConfiguration.IgnoreExtensions));
if (propertyConfiguration.PropertyContentCollectionFiles is null)
throw new NullReferenceException(nameof(propertyConfiguration.PropertyContentCollectionFiles));
if (propertyConfiguration.ValidImageFormatExtensions is null || !propertyConfiguration.ValidImageFormatExtensions.Any())
if (propertyConfiguration.ValidImageFormatExtensions is null || propertyConfiguration.ValidImageFormatExtensions.Length == 0)
throw new NullReferenceException(nameof(propertyConfiguration.ValidImageFormatExtensions));
if (propertyConfiguration is null)
throw new NullReferenceException(nameof(propertyConfiguration));

View File

@ -45,7 +45,7 @@ public class SetCreatedDate
Verify();
List<string> lines = SetCreatedDateFilesInDirectories(log);
File.WriteAllLines($"D:/Tmp/Phares/{DateTime.Now.Ticks}.tsv", lines);
if (!lines.Any())
if (lines.Count == 0)
_ = Shared.Models.Stateless.Methods.IPath.DeleteEmptyDirectories(propertyConfiguration.RootDirectory);
}

View File

@ -1,10 +1,11 @@
---
created: "2023-07-21T18:26:38.899Z"
updated: "2023-07-21T18:26:38.900Z"
created: 2023-07-21T18:26:38.899Z
updated: 2023-07-21T18:26:38.900Z
assigned: ""
progress: 0
type: "kanbn"
completed: "2023-07-21T04:34:47.650Z"
type: kanbn
completed: 2023-07-21T04:34:47.650Z
column: Done
---
# Family Tree as Markdown Files

View File

@ -0,0 +1,15 @@
---
created: 2023-07-21T18:26:38.916Z
updated: 2023-07-21T18:26:38.917Z
assigned: ""
progress: 0
status: 4-Done
type: kanbn
column: Done
---
# Run Scan Originals
## Sub-tasks
- [x] run-scan-originals

View File

@ -32,20 +32,21 @@ taskTemplate: '^+^_${overdue ? ''^R'' : ''''}${name}^: ${relations ? (''\n^-^/^g
- [nef-support](tasks/nef-support.md)
- [set-date-taken-when-missing](tasks/set-date-taken-when-missing.md)
- [set-focus-person-based-on-number-of-matched](tasks/set-focus-person-based-on-number-of-matched.md)
- [move-images-in-distance-directories-to-decade-match-minimum-decade-match-maximum-decade-match-none](tasks/move-images-in-distance-directories-to-decade-match-minimum-decade-match-maximum-decade-match-none.md)
## In Progress
- [merge-kristy-files](tasks/merge-kristy-files.md)
- [look-for-family-from-jlink-in-x-mapped](tasks/look-for-family-from-jlink-in-x-mapped.md)
- [review-what-system-does-when-duplicate-matched-with-x-and-non-x](tasks/review-what-system-does-when-duplicate-matched-with-x-and-non-x.md)
- [move-over-2023-california-pictures](tasks/move-over-2023-california-pictures.md)
## Done
- [eof-error](tasks/eof-error.md)
- [run-scan-originals](tasks/run-scan-originals.md)
- [shrink-percent](tasks/shrink-percent.md)
- [merge-kristy-files](tasks/merge-kristy-files.md)
- [family-tree-as-markdown-files](tasks/family-tree-as-markdown-files.md)
- [move-over-2023-california-pictures](tasks/move-over-2023-california-pictures.md)
- [verify-person-key-collection-fixed-x-issue](tasks/verify-person-key-collection-fixed-x-issue.md)
- [genealogical-data-communication-as-golden](tasks/genealogical-data-communication-as-golden.md)
- [review-what-system-does-when-duplicate-matched-with-x-and-non-x](tasks/review-what-system-does-when-duplicate-matched-with-x-and-non-x.md)
- [add-facebook-and-linked-in-txt-to-ged](tasks/add-facebook-and-linked-in-txt-to-ged.md)
- [setup-photo-prism-again-in-wsl-docker](tasks/setup-photo-prism-again-in-wsl-docker.md)
- [rename-files-to-padded-number-string](tasks/rename-files-to-padded-number-string.md)

View File

@ -0,0 +1,11 @@
---
created: 2023-08-05T17:50:34.233Z
updated: 2023-08-05T23:12:26.511Z
assigned: ""
progress: 0
tags: []
started: 2023-08-05T17:50:34.233Z
completed: 2023-08-05T23:12:26.511Z
---
# Add Facebook and LinkedIn *.txt to *.ged

View File

@ -1,6 +1,6 @@
---
created: 2023-07-31T19:08:57.684Z
updated: 2023-08-01T06:13:54.468Z
updated: 2023-08-06T03:40:58.576Z
assigned: ""
progress: 0
tags: []

View File

@ -1,12 +1,11 @@
---
created: 2023-07-21T18:26:38.910Z
updated: 2023-08-05T08:33:35.448Z
updated: 2023-08-05T17:43:51.430Z
assigned: ""
progress: 0
status: 2-Todo
type: kanbn
started: 2023-07-08T21:44:14.665Z
completed: 2023-08-05T08:33:35.448Z
progress: 0.5
tags: []
started: 2023-07-06T00:00:00.000Z
completed: 2023-08-03T00:00:00.000Z
---
# Merge Kristy Files
@ -26,3 +25,4 @@ return new(result, (from l in results orderby l.FileHolder.DirectoryName?.EndsWi
- [x] Set created date
- [x] Verify
- [x] Move to production ...
- [ ] Cleanup D:/7-Question/- Scans.*

View File

@ -0,0 +1,9 @@
---
created: 2023-08-06T00:25:42.224Z
updated: 2023-08-06T00:25:42.220Z
assigned: ""
progress: 0
tags: []
---
# Move images in Distance directories to {Decade}MatchMinimum {Decade}MatchMaximum {Decade}MatchNone

View File

@ -1,10 +1,11 @@
---
created: 2023-08-05T08:33:59.693Z
updated: 2023-08-05T08:33:59.689Z
updated: 2023-08-05T17:38:11.824Z
assigned: ""
progress: 0
tags: []
started: 2023-08-05T08:33:59.693Z
completed: 2023-08-05T17:38:11.824Z
---
# Move over 2023 California Pictures

View File

@ -9,13 +9,14 @@ type: "kanbn"
# Rename Files to Padded Number String
- [?] ~~Go Back to Index for Sort~~
- [?] ~~New file for index to to id~~
- [?] ~~Count backwards~~
- [?] ~~Maybe skip some for scan images~~
- [?] [Set Date Taken When Missing](set-date-taken-when-missing.md)
## Sub-tasks
- [ ] ~~Go Back to Index for Sort~~
- [ ] ~~New file for index to to id~~
- [ ] ~~Count backwards~~
- [ ] ~~Maybe skip some for scan images~~
- [Set Date Taken When Missing](set-date-taken-when-missing.md)
- [x] Rename production with padding names starting with one directory
- [x] Need equivalent to NameWithoutExtensionIsIdFormat method
- [x] Verify nothing broke (run from resize original now ... ?)

View File

@ -1,10 +1,13 @@
---
created: 2023-08-05T08:33:05.117Z
updated: 2023-08-05T08:33:22.874Z
updated: 2023-08-06T05:44:59.047Z
assigned: ""
progress: 0
tags: []
started: 2023-08-05T00:00:00.000Z
started: 2023-08-04T00:00:00.000Z
completed: 2023-08-06T05:44:59.047Z
---
# Review what system does when duplicate matched with X] and non X]
AlternateDirectoryDateTime helps but not full proof

View File

@ -1,14 +0,0 @@
---
created: "2023-07-21T18:26:38.916Z"
updated: "2023-07-21T18:26:38.917Z"
assigned: ""
progress: 0
status: "4-Done"
type: "kanbn"
---
# Run Scan Originals
## Sub-tasks
- [x] run-scan-originals

View File

@ -0,0 +1,11 @@
---
created: 2023-08-06T01:04:57.884Z
updated: 2023-08-06T06:55:09.617Z
assigned: ""
progress: 0
tags: []
started: 2023-08-06T01:04:57.884Z
completed: 2023-08-06T06:55:09.617Z
---
# Verify personKeyCollection fixed X] issue

View File

@ -1,3 +1,4 @@
using System.Collections.ObjectModel;
using System.Text.Json;
using System.Text.Json.Serialization;
@ -49,11 +50,11 @@ public class Mapping : Properties.IMapping
_SegmentC = !saveIndividually ? null : sortingContainer.Sorting.DistancePermyriad.ToString();
}
public void UpdateMappingFromPerson(int? approximateYears, string displayDirectoryName, PersonBirthday personBirthday, string segmentB)
public void UpdateMappingFromPerson(ReadOnlyCollection<string> locationContainersFiles, int? approximateYears, string displayDirectoryName, PersonBirthday personBirthday, string segmentB)
{
_SortingContainer = null;
_By = Stateless.IMapLogic.Mapping;
_MappingFromPerson = new(approximateYears, displayDirectoryName, personBirthday, segmentB);
_MappingFromPerson = new(approximateYears, displayDirectoryName, locationContainersFiles, personBirthday, segmentB);
}
public void UpdateMappingFromPerson(int? approximateYears, string displayDirectoryName, PersonBirthday personBirthday, string segmentB, string segmentC, SortingContainer sortingContainer)
@ -61,7 +62,8 @@ public class Mapping : Properties.IMapping
_SegmentC = segmentC;
_By = Stateless.IMapLogic.Sorting;
_SortingContainer = sortingContainer;
_MappingFromPerson = new(approximateYears, displayDirectoryName, personBirthday, segmentB);
ReadOnlyCollection<string> locationContainersFiles = new(Array.Empty<string>());
_MappingFromPerson = new(approximateYears, displayDirectoryName, locationContainersFiles, personBirthday, segmentB);
}
}

View File

@ -1,3 +1,4 @@
using System.Collections.ObjectModel;
using System.Text.Json;
using System.Text.Json.Serialization;
@ -8,14 +9,16 @@ public class MappingFromPerson : Properties.IMappingFromPerson
public int? ApproximateYears { init; get; }
public string DisplayDirectoryName { init; get; }
public ReadOnlyCollection<string> LocationContainersFiles { init; get; }
public PersonBirthday PersonBirthday { init; get; }
public string SegmentB { init; get; }
[JsonConstructor]
public MappingFromPerson(int? approximateYears, string displayDirectoryName, PersonBirthday personBirthday, string segmentB)
public MappingFromPerson(int? approximateYears, string displayDirectoryName, ReadOnlyCollection<string> locationContainersFiles, PersonBirthday personBirthday, string segmentB)
{
ApproximateYears = approximateYears;
DisplayDirectoryName = displayDirectoryName;
LocationContainersFiles = locationContainersFiles;
PersonBirthday = personBirthday;
SegmentB = segmentB;
}

View File

@ -1,8 +1,10 @@
using System.Collections.ObjectModel;
namespace View_by_Distance.Shared.Models.Methods;
public interface IMapLogic
{
(bool, Dictionary<int, PersonContainer[]>?) GetWholePercentagesToPersonContainers(int id);
(bool, ReadOnlyDictionary<int, ReadOnlyCollection<PersonContainer>>?) GetWholePercentagesToPersonContainers(int id);
}

View File

@ -1,3 +1,5 @@
using System.Collections.ObjectModel;
namespace View_by_Distance.Shared.Models.Properties;
public interface IMapping

View File

@ -1,3 +1,5 @@
using System.Collections.ObjectModel;
namespace View_by_Distance.Shared.Models.Properties;
public interface IMappingFromPerson
@ -5,6 +7,7 @@ public interface IMappingFromPerson
public int? ApproximateYears { init; get; }
public string DisplayDirectoryName { init; get; }
public ReadOnlyCollection<string> LocationContainersFiles { init; get; }
public PersonBirthday PersonBirthday { init; get; }
public string SegmentB { init; get; }

View File

@ -63,7 +63,7 @@ internal abstract class Container
{
foreach (Models.Container container in containers)
{
if (!container.Items.Any())
if (container.Items.Count == 0)
continue;
if (!argZeroIsConfigurationRootDirectory && !container.SourceDirectory.StartsWith(argZero))
continue;
@ -169,7 +169,7 @@ internal abstract class Container
Dictionary<string, List<Models.Item>> directoryToItems = new();
foreach (string[] files in filesCollection)
{
if (!files.Any())
if (files.Length == 0)
continue;
directory = Path.GetDirectoryName(files.First());
if (directory is null)
@ -199,7 +199,7 @@ internal abstract class Container
}
foreach (KeyValuePair<string, List<Models.Item>> keyValuePair in directoryToItems)
{
if (!keyValuePair.Value.Any())
if (keyValuePair.Value.Count == 0)
continue;
container = new(keyValuePair.Key, keyValuePair.Value);
results.Add(container);
@ -233,10 +233,10 @@ internal abstract class Container
Models.Item[] filteredItems;
foreach (Models.Container container in containers)
{
if (!container.Items.Any())
if (container.Items.Count == 0)
continue;
filteredItems = GetFilterItems(propertyConfiguration, container);
if (!filteredItems.Any())
if (filteredItems.Length == 0)
continue;
foreach (Models.Item item in filteredItems)
{
@ -257,7 +257,7 @@ internal abstract class Container
IEnumerable<Models.Item> filteredItems;
foreach (Models.Container container in containers)
{
if (!container.Items.Any())
if (container.Items.Count == 0)
continue;
if (!filterItems)
filteredItems = container.Items;

View File

@ -56,7 +56,7 @@ internal abstract class Face
{
Models.Face? result;
List<Models.Face> results = GetFaces(jsonFileFullName, maximum: 1);
if (!results.Any())
if (results.Count == 0)
throw new Exception();
result = results[0];
return result;

View File

@ -17,7 +17,7 @@ internal abstract class FaceFileSystem
else
{
string[] files = Directory.GetFiles(parentDirectoryName, Path.GetFileName(fullFileName), SearchOption.AllDirectories);
if (!files.Any())
if (files.Length == 0)
throw new Exception($"File [{fileInfo.Name}] <{fullFileName}> doesn't exist (deep search)!");
else
{

View File

@ -30,7 +30,7 @@ internal abstract class FileHolder
next = Directory.GetFiles(path, searchPattern);
}
catch { }
if (next is not null && next.Any())
if (next is not null && next.Length > 0)
yield return new(path, next);
try
{

View File

@ -37,9 +37,9 @@ public interface IPerson
hour == 17 ? "Dead-Male-No" :
throw new NotImplementedException(personDisplayDirectoryName);
bool TestStatic_IsDefaultName(string mappingDefaultName, string value) =>
IsDefaultName(mappingDefaultName, value);
static bool IsDefaultName(string mappingDefaultName, string value) =>
value == mappingDefaultName || (value.Length > 1 && value[0] == 'X' && value[1] == ']');
bool TestStatic_IsDefaultName(string mappingDefaultName, string personDisplayDirectoryName) =>
IsDefaultName(mappingDefaultName, personDisplayDirectoryName);
static bool IsDefaultName(string mappingDefaultName, string personDisplayDirectoryName) =>
personDisplayDirectoryName == mappingDefaultName || (personDisplayDirectoryName.Length > 1 && personDisplayDirectoryName[0] == 'X' && personDisplayDirectoryName[1] == ']');
}

View File

@ -103,7 +103,7 @@ internal abstract class PersonContainer
foreach ((string personKeyFormatted, Models.PersonBirthday personBirthday) in collection)
{
orderedPersonBirthdays = (from l in collection where !l.PersonKeyFormatted.Contains(numberSign) orderby l.PersonBirthday.Value.Ticks descending select l.PersonBirthday).ToArray();
if (!orderedPersonBirthdays.Any())
if (orderedPersonBirthdays.Length == 0)
personKey = collection[zero].PersonBirthday.Value.Ticks;
else
{
@ -113,7 +113,7 @@ internal abstract class PersonContainer
}
personKeyDirectory = Path.Combine(personDisplayDirectory, personKeyFormatted);
files = Directory.GetFiles(personKeyDirectory, "*", SearchOption.AllDirectories);
if (!files.Any())
if (files.Length == 0)
continue;
personDisplayDirectoryAllFiles.AddRange(files.Where(l => l.EndsWith(".rel")));
personContainer = new(approximateYears, orderedPersonBirthdays, personDisplayDirectoryAllFiles.ToArray(), personDisplayDirectoryName, personKey, personDirectory);
@ -127,7 +127,7 @@ internal abstract class PersonContainer
string? result;
if (approximateYears is null)
throw new NotSupportedException();
if (!collection.Any())
if (collection.Count == 0)
throw new NotSupportedException();
const int zero = 0;
int? updateApproximateYears;
@ -225,7 +225,7 @@ internal abstract class PersonContainer
{
innerGroupDirectoryName = Path.GetFileName(innerGroupDirectory);
segments = innerGroupDirectoryName.Split('-');
if (!segments.Any())
if (segments.Length == 0)
throw new NotSupportedException("Misplaced directory!");
if (segments.Length != 3)
continue;
@ -285,7 +285,7 @@ internal abstract class PersonContainer
_ = Directory.CreateDirectory(a2PeopleSingletonDirectoryChar);
}
string[] groupDirectories = Directory.GetDirectories(a2PeopleSingletonDirectory, "*", SearchOption.TopDirectoryOnly);
if (!groupDirectories.Any())
if (groupDirectories.Length == 0)
results = new();
else
results = GetPersonContainersGroups(personBirthdayFormat, facesFileNameExtension, personCharacters, groupDirectories);

View File

@ -40,10 +40,10 @@ internal abstract class Property
|| (l.Length == 7 && l.Substring(1, 4) == year && l[5] == '.')
select l
).ToArray();
if (!results.Any())
if (results.Length == 0)
result = null;
else
result = !matches.Any();
result = matches.Length == 0;
return new(result, results);
}
@ -203,7 +203,7 @@ internal abstract class Property
}
long threeStandardDeviationHigh;
long min;
if (!ticksCollection.Any())
if (ticksCollection.Count == 0)
min = 0;
else
min = ticksCollection.Min();
@ -263,7 +263,7 @@ internal abstract class Property
bool result = false;
foreach (Models.Container container in containers)
{
if (!container.Items.Any())
if (container.Items.Count == 0)
continue;
if ((from l in container.Items where l.Any() select true).Any())
{

View File

@ -97,7 +97,7 @@ internal abstract partial class XDirectory
}
}
}
if (renameCollection.Any())
if (renameCollection.Count > 0)
IDirectory.MoveFiles(renameCollection, "{}", "{abd}");
return renameCollection.Count;
}
@ -139,7 +139,7 @@ internal abstract partial class XDirectory
continue;
matches.Add(possible);
}
if (matches.Count == 1 || (matches.Any() && lengths.Distinct().Count() == 1 && creationTimes.Distinct().Count() == 1))
if (matches.Count == 1 || (matches.Count > 0 && lengths.Distinct().Count() == 1 && creationTimes.Distinct().Count() == 1))
result = matches.First();
return result;
}
@ -167,7 +167,7 @@ internal abstract partial class XDirectory
results.Add(new(file, uniqueFileName, isNotUniqueAndNeedsReview, new(), null));
else
{
if (!collection.Any())
if (collection.Count == 0)
results.Add(new(file, uniqueFileName, isNotUniqueAndNeedsReview, collection, null));
else if (uniqueFileName && collection.Count == 1)
results.Add(new(file, uniqueFileName, isNotUniqueAndNeedsReview, collection, collection.First()));

View File

@ -32,7 +32,7 @@ internal abstract class XPath
bool result;
List<string> results = new();
DeleteEmptyDirectories(rootDirectory, results);
result = results.Any();
result = results.Count > 0;
return result;
}
@ -64,7 +64,7 @@ internal abstract class XPath
{
DeleteEmptyDirectories(directory, check);
deletedDirectories.AddRange(check);
if (check.Any())
if (check.Count > 0)
DeleteEmptyDirectories(directory, deletedDirectories);
}
}