SaveShortcutsForOutputResolutions

This commit is contained in:
Mike Phares 2023-01-02 20:22:27 -07:00
parent d0cd52807d
commit 92288c9381
7 changed files with 252 additions and 143 deletions

View File

@ -40,7 +40,6 @@ public partial class DlibDotNet
private readonly Models.Configuration _Configuration; private readonly Models.Configuration _Configuration;
private readonly bool _ArgZeroIsConfigurationRootDirectory; private readonly bool _ArgZeroIsConfigurationRootDirectory;
private readonly Map.Models.Configuration _MapConfiguration; private readonly Map.Models.Configuration _MapConfiguration;
private readonly Dictionary<string, List<MappingFromPhotoPrism>> _FileNameToCollection;
public DlibDotNet( public DlibDotNet(
List<string> args, List<string> args,
@ -54,7 +53,6 @@ public partial class DlibDotNet
string message; string message;
_Console = console; _Console = console;
_AppSettings = appSettings; _AppSettings = appSettings;
_FileNameToCollection = new();
_IsEnvironment = isEnvironment; _IsEnvironment = isEnvironment;
long ticks = DateTime.Now.Ticks; long ticks = DateTime.Now.Ticks;
_Exceptions = new List<string>(); _Exceptions = new List<string>();
@ -209,7 +207,7 @@ public partial class DlibDotNet
private void Verify(Models.Configuration configuration) private void Verify(Models.Configuration configuration)
{ {
if (!configuration.OutputResolutions.Any() || string.IsNullOrEmpty(configuration.OutputResolutions[0]) || !configuration.ValidResolutions.Contains(configuration.OutputResolutions[0])) if (!configuration.OutputResolutions.Any() || string.IsNullOrEmpty(configuration.OutputResolutions[0]) || !configuration.ValidResolutions.Contains(configuration.OutputResolutions[0]))
throw new NullReferenceException($"{nameof(configuration.OutputResolutions)} must be _FileNameToCollection valid outputResolution!"); 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()) 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!"); throw new Exception($"One or more {nameof(configuration.OutputResolutions)} are not in the ValidResolutions list!");
if ((from l in configuration.LoadOrCreateThenSaveDistanceResultsForOutputResolutions where !configuration.ValidResolutions.Contains(l) select false).Any()) if ((from l in configuration.LoadOrCreateThenSaveDistanceResultsForOutputResolutions where !configuration.ValidResolutions.Contains(l) select false).Any())
@ -253,13 +251,13 @@ public partial class DlibDotNet
string[] segments = sourceDirectoryNames[0].Split(' '); string[] segments = sourceDirectoryNames[0].Split(' ');
century = segments[^1].Length == 4 ? segments[^1][..2] : null; century = segments[^1].Length == 4 ? segments[^1][..2] : null;
if (segments.Length < 2 || century is null || (century != "18" && century != "19" && century != "20")) if (segments.Length < 2 || century is null || (century != "18" && century != "19" && century != "20"))
throw new Exception("root subdirectory must have _FileNameToCollection year at the end or directory name needs to be added to the exclude list!"); throw new Exception("root subdirectory must have fileNameToCollection year at the end or directory name needs to be added to the exclude list!");
} }
} }
} }
string[] resizeMatch = (from l in sourceDirectoryNames where configuration.ValidResolutions.Contains(l) select l).ToArray(); string[] resizeMatch = (from l in sourceDirectoryNames where configuration.ValidResolutions.Contains(l) select l).ToArray();
if (resizeMatch.Any()) if (resizeMatch.Any())
throw new Exception("Input directory should be the source and not _FileNameToCollection resized directory!"); throw new Exception("Input directory should be the source and not fileNameToCollection resized directory!");
if (configuration.LocationDigits != Shared.Models.Stateless.ILocation.Digits) if (configuration.LocationDigits != Shared.Models.Stateless.ILocation.Digits)
throw new Exception("Configuration has to match interface!"); throw new Exception("Configuration has to match interface!");
if (configuration.LocationFactor != Shared.Models.Stateless.ILocation.Factor) if (configuration.LocationFactor != Shared.Models.Stateless.ILocation.Factor)
@ -287,7 +285,26 @@ public partial class DlibDotNet
return result; return result;
} }
private void FullParallelForWork(A_Property propertyLogic, Dictionary<int, List<LocationContainer<MetadataExtractor.Directory>>> idToMappedFaceFilesWithCollection, string outputResolution, string bResultsFullGroupDirectory, string cResultsFullGroupDirectory, string dResultsDateGroupDirectory, string dResultsFullGroupDirectory, string eDistanceContentDirectory, List<Tuple<string, DateTime>> sourceDirectoryChanges, List<FileHolder?> propertyFileHolderCollection, List<Shared.Models.Property?> propertyCollection, List<List<KeyValuePair<string, string>>> metadataCollections, List<Dictionary<string, int[]>> resizeKeyValuePairs, List<List<Shared.Models.Face>> imageFaceCollections, Container container, int index, Item item, DateTime[] containerDateTimes) private void FullParallelForWork(
A_Property propertyLogic,
Dictionary<int, List<LocationContainer<MetadataExtractor.Directory>>> idToMappedFaceFilesWithCollection,
string outputResolution,
string bResultsFullGroupDirectory,
string cResultsFullGroupDirectory,
string dResultsDateGroupDirectory,
string dResultsFullGroupDirectory,
string eDistanceContentDirectory,
List<Tuple<string, DateTime>> sourceDirectoryChanges,
List<FileHolder?> propertyFileHolderCollection,
List<Shared.Models.Property?> propertyCollection,
List<List<KeyValuePair<string, string>>> metadataCollections,
List<Dictionary<string, int[]>> resizeKeyValuePairs,
Dictionary<string, List<MappingFromPhotoPrism>> fileNameToCollection,
List<List<Shared.Models.Face>> imageFaceCollections,
Container container,
int index,
Item item,
DateTime[] containerDateTimes)
{ {
if (_Log is null) if (_Log is null)
throw new NullReferenceException(nameof(_Log)); throw new NullReferenceException(nameof(_Log));
@ -364,7 +381,7 @@ public partial class DlibDotNet
collection = null; collection = null;
else else
_ = idToMappedFaceFilesWithCollection.TryGetValue(item.Property.Id.Value, out collection); _ = idToMappedFaceFilesWithCollection.TryGetValue(item.Property.Id.Value, out collection);
if (!_FileNameToCollection.TryGetValue(mappingFromItem.RelativePath[1..], out mappingFromPhotoPrismCollection)) if (!fileNameToCollection.TryGetValue(mappingFromItem.RelativePath[1..], out mappingFromPhotoPrismCollection))
mappingFromPhotoPrismCollection = null; mappingFromPhotoPrismCollection = null;
faces = _Faces.GetFaces(outputResolution, dResultsFullGroupDirectory, subFileTuples, parseExceptions, property, mappingFromItem, outputResolutionToResize, collection, mappingFromPhotoPrismCollection); faces = _Faces.GetFaces(outputResolution, dResultsFullGroupDirectory, subFileTuples, parseExceptions, property, mappingFromItem, outputResolutionToResize, collection, mappingFromPhotoPrismCollection);
if (_AppSettings.MaxDegreeOfParallelism < 2) if (_AppSettings.MaxDegreeOfParallelism < 2)
@ -410,6 +427,7 @@ public partial class DlibDotNet
List<Shared.Models.Property?> propertyCollection, List<Shared.Models.Property?> propertyCollection,
List<List<KeyValuePair<string, string>>> metadataCollection, List<List<KeyValuePair<string, string>>> metadataCollection,
List<Dictionary<string, int[]>> resizeKeyValuePairs, List<Dictionary<string, int[]>> resizeKeyValuePairs,
Dictionary<string, List<MappingFromPhotoPrism>> fileNameToCollection,
List<List<Shared.Models.Face>> imageFaceCollections, List<List<Shared.Models.Face>> imageFaceCollections,
Container container, Container container,
Item[] filteredItems, Item[] filteredItems,
@ -453,6 +471,7 @@ public partial class DlibDotNet
propertyCollection, propertyCollection,
metadataCollection, metadataCollection,
resizeKeyValuePairs, resizeKeyValuePairs,
fileNameToCollection,
imageFaceCollections, imageFaceCollections,
container, container,
index: i, index: i,
@ -627,7 +646,7 @@ public partial class DlibDotNet
_Metadata.SetAngleBracketCollection(_Configuration.PropertyConfiguration, bResultsFullGroupDirectory, container.SourceDirectory); _Metadata.SetAngleBracketCollection(_Configuration.PropertyConfiguration, bResultsFullGroupDirectory, container.SourceDirectory);
} }
private void FullDoWork(string argZero, string propertyRoot, long ticks, A_Property propertyLogic, int t, Container[] containers, string? a2PeopleContentDirectory, string eDistanceContentDirectory) private void FullDoWork(string argZero, string propertyRoot, long ticks, A_Property propertyLogic, int t, Container[] containers, string eDistanceContentDirectory, Dictionary<string, List<MappingFromPhotoPrism>> fileNameToCollection, Dictionary<int, List<LocationContainer<MetadataExtractor.Directory>>> idToMappedFaceFilesWithCollection)
{ {
if (_Log is null) if (_Log is null)
throw new NullReferenceException(nameof(_Log)); throw new NullReferenceException(nameof(_Log));
@ -651,7 +670,6 @@ public partial class DlibDotNet
int maxDegreeOfParallelism = _AppSettings.MaxDegreeOfParallelism; int maxDegreeOfParallelism = _AppSettings.MaxDegreeOfParallelism;
List<Shared.Models.Property?> nullablePropertyCollection = new(); List<Shared.Models.Property?> nullablePropertyCollection = new();
List<List<KeyValuePair<string, string>>> metadataCollection = new(); List<List<KeyValuePair<string, string>>> metadataCollection = new();
Dictionary<int, List<LocationContainer<MetadataExtractor.Directory>>> idToMappedFaceFilesWithCollection = GetDictionary(ticks, a2PeopleContentDirectory, eDistanceContentDirectory);
string dResultsDateGroupDirectory = Property.Models.Stateless.IResult.GetResultsDateGroupDirectory(_Configuration.PropertyConfiguration, nameof(D_Face)); string dResultsDateGroupDirectory = Property.Models.Stateless.IResult.GetResultsDateGroupDirectory(_Configuration.PropertyConfiguration, nameof(D_Face));
foreach (string outputResolution in _Configuration.OutputResolutions) foreach (string outputResolution in _Configuration.OutputResolutions)
{ {
@ -696,6 +714,7 @@ public partial class DlibDotNet
nullablePropertyCollection, nullablePropertyCollection,
metadataCollection, metadataCollection,
resizeKeyValuePairs, resizeKeyValuePairs,
fileNameToCollection,
imageFaceCollections, imageFaceCollections,
container, container,
filteredItems, filteredItems,
@ -801,8 +820,16 @@ public partial class DlibDotNet
} }
if (renameCollection.Any()) if (renameCollection.Any())
{ {
foreach (string rename in renameCollection) string checkFile;
File.Move(rename, $"{rename}.abd"); foreach (string file in renameCollection)
{
if (!File.Exists(file))
continue;
checkFile = $"{file}.abd";
if (File.Exists(checkFile))
continue;
File.Move(file, checkFile);
}
throw new Exception($"Renamed {renameCollection.Count}(s) files!"); throw new Exception($"Renamed {renameCollection.Count}(s) files!");
} }
} }
@ -824,18 +851,26 @@ public partial class DlibDotNet
} }
if (renameCollection.Any()) if (renameCollection.Any())
{ {
foreach (string rename in renameCollection) string checkFile;
File.Move(rename, $"{rename}.mvd"); foreach (string file in renameCollection)
{
if (!File.Exists(file))
continue;
checkFile = $"{file}.mvd";
if (File.Exists(checkFile))
continue;
File.Move(file, checkFile);
}
throw new Exception($"Renamed {renameCollection.Count}(s) files!"); throw new Exception($"Renamed {renameCollection.Count}(s) files!");
} }
} }
private List<Shared.Models.Face> GetFilteredDistinctFaces(string argZero, Container[] containers) private (List<int>, List<Shared.Models.Face>) GetFilteredDistinct(string argZero, Container[] containers)
{ {
List<Shared.Models.Face> results = new(); List<int> resultIds = new();
List<Shared.Models.Face> resultFaces = new();
Item[] filteredItems; Item[] filteredItems;
bool isIgnoreRelativePath; bool isIgnoreRelativePath;
List<int> distinct = new();
foreach (Container container in containers) foreach (Container container in containers)
{ {
if (!container.Items.Any()) if (!container.Items.Any())
@ -850,20 +885,20 @@ public partial class DlibDotNet
{ {
if (item.Property?.Id is null || item.ResizedFileHolder is null) if (item.Property?.Id is null || item.ResizedFileHolder is null)
continue; continue;
if (distinct.Contains(item.Property.Id.Value)) if (resultIds.Contains(item.Property.Id.Value))
continue; continue;
distinct.Add(item.Property.Id.Value); resultIds.Add(item.Property.Id.Value);
if (isIgnoreRelativePath) if (isIgnoreRelativePath)
continue; continue;
foreach (Shared.Models.Face face in item.Faces) foreach (Shared.Models.Face face in item.Faces)
{ {
if (face.FaceEncoding is null || face.Location is null || face.OutputResolution is null) if (face.FaceEncoding is null || face.Location is null || face.OutputResolution is null)
continue; continue;
results.Add(face); resultFaces.Add(face);
} }
} }
} }
return results; return new(resultIds, resultFaces);
} }
private List<Item> GetItems(string argZero, Container[] containers) private List<Item> GetItems(string argZero, Container[] containers)
@ -892,7 +927,7 @@ public partial class DlibDotNet
return items; return items;
} }
private void MapLogic(string argZero, long ticks, Container[] containers, string a2PeopleSingletonDirectory, string dResultsFullGroupDirectory, string d2ResultsFullGroupDirectory, string fPhotoPrismContentDirectory, MapLogicSupport mapLogicSupport, MapLogic mapLogic, string outputResolution, List<Shared.Models.Face> distinctFilteredFaces, Mapping[] mappingCollection, int totalNotMapped, Dictionary<long, int> personKeyToCount) private void MapLogic(string argZero, long ticks, Container[] containers, string a2PeopleSingletonDirectory, string dResultsFullGroupDirectory, string d2ResultsFullGroupDirectory, string fPhotoPrismContentDirectory, MapLogicSupport mapLogicSupport, MapLogic mapLogic, string outputResolution, Dictionary<long, List<int>> personKeyToIds, List<Shared.Models.Face> distinctFilteredFaces, Mapping[] mappingCollection, int totalNotMapped)
{ {
int? useFiltersCounter = null; int? useFiltersCounter = null;
SortingContainer[] sortingContainers; SortingContainer[] sortingContainers;
@ -905,13 +940,13 @@ public partial class DlibDotNet
if (_Configuration.SaveShortcutsForOutputResolutions.Contains(outputResolution)) if (_Configuration.SaveShortcutsForOutputResolutions.Contains(outputResolution))
{ {
List<Item> filteredItems = GetItems(argZero, containers); List<Item> filteredItems = GetItems(argZero, containers);
mapLogic.SaveShortcutsForOutputResolutions(filteredItems, mappingCollection, personKeyToCount); mapLogic.SaveShortcutsForOutputResolutions(personKeyToIds, filteredItems, mappingCollection);
} }
if (_Configuration.PersonCharactersCopyCount > 0 && !string.IsNullOrEmpty(_Configuration.PersonCharacters)) if (_Configuration.PersonCharactersCopyCount > 0 && !string.IsNullOrEmpty(_Configuration.PersonCharacters))
mapLogic.CopyAtLeastOneMappedFiles(dFacesContentDirectory, a2PeopleSingletonDirectory, mappingCollection); mapLogic.CopyAtLeastOneMappedFiles(dFacesContentDirectory, a2PeopleSingletonDirectory, mappingCollection);
mapLogic.CopyManualFiles(dFacesContentDirectory, idToNormalizedRectangleToMapping); mapLogic.CopyManualFiles(dFacesContentDirectory, idToNormalizedRectangleToMapping);
if (_Configuration.SaveMappedForOutputResolutions.Contains(outputResolution)) if (_Configuration.SaveMappedForOutputResolutions.Contains(outputResolution))
mapLogic.SaveMapped(dFacesContentDirectory, d2FacePartsContentDirectory, mappingCollection, idToNormalizedRectangleToMapping, personKeyToCount, totalNotMapped); mapLogic.SaveMapped(dFacesContentDirectory, d2FacePartsContentDirectory, personKeyToIds, mappingCollection, idToNormalizedRectangleToMapping, totalNotMapped);
if (_Configuration.SaveFaceDistancesForOutputResolutions.Contains(outputResolution)) if (_Configuration.SaveFaceDistancesForOutputResolutions.Contains(outputResolution))
{ {
MapLogicSupport.SetFaceDistances(_AppSettings.MaxDegreeOfParallelism, ticks, distinctFilteredFaces); MapLogicSupport.SetFaceDistances(_AppSettings.MaxDegreeOfParallelism, ticks, distinctFilteredFaces);
@ -984,7 +1019,7 @@ public partial class DlibDotNet
bool isValidImageFormatExtension; bool isValidImageFormatExtension;
for (int y = 0; y < int.MaxValue; y++) for (int y = 0; y < int.MaxValue; y++)
{ {
_Log.Information("Enter _FileNameToCollection url for _FileNameToCollection image"); _Log.Information("Enter fileNameToCollection url for fileNameToCollection image");
line = _Console.ReadLine(); line = _Console.ReadLine();
if (string.IsNullOrEmpty(line)) if (string.IsNullOrEmpty(line))
break; break;
@ -1154,6 +1189,36 @@ public partial class DlibDotNet
return results; return results;
} }
private static void LookForAbandoned(Dictionary<int, List<LocationContainer<MetadataExtractor.Directory>>> idToMappedFaceFilesWithCollection, List<int> distinctFilteredIds)
{
List<string> renameCollection = new();
foreach (KeyValuePair<int, List<LocationContainer<MetadataExtractor.Directory>>> idToCollection in idToMappedFaceFilesWithCollection)
{
if (distinctFilteredIds.Contains(idToCollection.Key))
continue;
foreach (LocationContainer<MetadataExtractor.Directory> locationContainer in idToCollection.Value)
{
if (locationContainer.File.Contains('!'))
continue;
renameCollection.Add(locationContainer.File);
}
}
if (renameCollection.Any())
{
string checkFile;
foreach (string file in renameCollection)
{
if (!File.Exists(file))
continue;
checkFile = $"{file}.abd";
if (File.Exists(checkFile))
continue;
File.Move(file, checkFile);
}
throw new Exception($"Renamed {renameCollection.Count}(s) files!");
}
}
private void Search(long ticks, string argZero, string propertyRoot) private void Search(long ticks, string argZero, string propertyRoot)
{ {
int f; int f;
@ -1169,6 +1234,8 @@ public partial class DlibDotNet
string d2ResultsFullGroupDirectory; string d2ResultsFullGroupDirectory;
string fPhotoPrismContentDirectory; string fPhotoPrismContentDirectory;
string fPhotoPrismSingletonDirectory; string fPhotoPrismSingletonDirectory;
Dictionary<long, List<int>> personKeyToIds;
Dictionary<string, List<MappingFromPhotoPrism>> fileNameToCollection;
string a2PeopleSingletonDirectory = Property.Models.Stateless.IResult.GetResultsDateGroupDirectory(_Configuration.PropertyConfiguration, nameof(A2_People), "{}"); string a2PeopleSingletonDirectory = Property.Models.Stateless.IResult.GetResultsDateGroupDirectory(_Configuration.PropertyConfiguration, nameof(A2_People), "{}");
int totalSeconds = (int)Math.Floor(new TimeSpan(DateTime.Now.Ticks - ticks).TotalSeconds); int totalSeconds = (int)Math.Floor(new TimeSpan(DateTime.Now.Ticks - ticks).TotalSeconds);
string message = $") Building Container(s) - {totalSeconds} total second(s)"; string message = $") Building Container(s) - {totalSeconds} total second(s)";
@ -1210,19 +1277,18 @@ public partial class DlibDotNet
containers = Shared.Models.Stateless.Methods.IContainer.SortContainers(_Configuration.PropertyConfiguration, _Configuration.IgnoreRelativePaths, _ArgZeroIsConfigurationRootDirectory, argZero, containers); containers = Shared.Models.Stateless.Methods.IContainer.SortContainers(_Configuration.PropertyConfiguration, _Configuration.IgnoreRelativePaths, _ArgZeroIsConfigurationRootDirectory, argZero, containers);
MapLogicSupport mapLogicSupport = new(_Configuration.FaceConfidencePercent, _Configuration.FaceDistancePermyriad, _Configuration.RangeDaysDeltaTolerance, _Configuration.RangeFaceAreaPermilleTolerance, _Configuration.SortingMaximumPerFaceShouldBeHigh); MapLogicSupport mapLogicSupport = new(_Configuration.FaceConfidencePercent, _Configuration.FaceDistancePermyriad, _Configuration.RangeDaysDeltaTolerance, _Configuration.RangeFaceAreaPermilleTolerance, _Configuration.SortingMaximumPerFaceShouldBeHigh);
MapLogic? mapLogic = _Configuration.DistanceMoveUnableToMatch ? null : new(_AppSettings.MaxDegreeOfParallelism, _Configuration.PropertyConfiguration, _MapConfiguration, ticks, _PersonContainers, a2PeopleSingletonDirectory, eDistanceContentDirectory, mapLogicSupport); MapLogic? mapLogic = _Configuration.DistanceMoveUnableToMatch ? null : new(_AppSettings.MaxDegreeOfParallelism, _Configuration.PropertyConfiguration, _MapConfiguration, ticks, _PersonContainers, a2PeopleSingletonDirectory, eDistanceContentDirectory, mapLogicSupport);
if (Directory.Exists(fPhotoPrismSingletonDirectory)) personKeyToIds = mapLogic is null ? new() : mapLogic.GetPersonKeyToIds();
{ fileNameToCollection = !Directory.Exists(fPhotoPrismSingletonDirectory) ? fileNameToCollection = new() : F_PhotoPrism.GetFileNameToCollection(fPhotoPrismSingletonDirectory);
Dictionary<string, List<MappingFromPhotoPrism>> fileNameToCollection = F_PhotoPrism.GetFileNameToCollection(fPhotoPrismSingletonDirectory); Dictionary<int, List<LocationContainer<MetadataExtractor.Directory>>> idToMappedFaceFilesWithCollection = GetDictionary(ticks, a2PeopleContentDirectory, eDistanceContentDirectory);
foreach (KeyValuePair<string, List<MappingFromPhotoPrism>> keyValuePair in fileNameToCollection) FullDoWork(argZero, propertyRoot, ticks, propertyLogic, t, containers, eDistanceContentDirectory, fileNameToCollection, idToMappedFaceFilesWithCollection);
_FileNameToCollection.Add(keyValuePair.Key, keyValuePair.Value);
}
FullDoWork(argZero, propertyRoot, ticks, propertyLogic, t, containers, a2PeopleContentDirectory, eDistanceContentDirectory);
_Distance.Clear(); _Distance.Clear();
mapLogic ??= new(_AppSettings.MaxDegreeOfParallelism, _Configuration.PropertyConfiguration, _MapConfiguration, ticks, _PersonContainers, a2PeopleSingletonDirectory, eDistanceContentDirectory, mapLogicSupport); mapLogic ??= new(_AppSettings.MaxDegreeOfParallelism, _Configuration.PropertyConfiguration, _MapConfiguration, ticks, _PersonContainers, a2PeopleSingletonDirectory, eDistanceContentDirectory, mapLogicSupport);
SetMapping(_FileNameToCollection, argZero, containers); SetMapping(fileNameToCollection, argZero, containers);
List<Shared.Models.Face> distinctFilteredFaces = GetFilteredDistinctFaces(argZero, containers); if (!personKeyToIds.Any())
personKeyToIds = mapLogic.GetPersonKeyToIds();
(List<int> distinctFilteredIds, List<Shared.Models.Face> distinctFilteredFaces) = GetFilteredDistinct(argZero, containers);
LookForAbandoned(idToMappedFaceFilesWithCollection, distinctFilteredIds);
Mapping[] mappingCollection = MapLogicSupport.GetSelectedMappingCollection(distinctFilteredFaces); Mapping[] mappingCollection = MapLogicSupport.GetSelectedMappingCollection(distinctFilteredFaces);
Dictionary<long, int> personKeyToCount = mapLogic.GetPersonKeyToCount(mappingCollection);
int totalNotMapped = mapLogic.UpdateMappingFromPerson(mappingCollection); int totalNotMapped = mapLogic.UpdateMappingFromPerson(mappingCollection);
if (a2PeopleContentDirectory is not null && false) if (a2PeopleContentDirectory is not null && false)
mapLogic.CreateTree(ticks, a2PeopleContentDirectory); mapLogic.CreateTree(ticks, a2PeopleContentDirectory);
@ -1230,17 +1296,19 @@ public partial class DlibDotNet
{ {
if (_PropertyRootExistedBefore || container is not null) if (_PropertyRootExistedBefore || container is not null)
break; break;
(aResultsFullGroupDirectory, bResultsFullGroupDirectory, cResultsFullGroupDirectory, dResultsFullGroupDirectory, d2ResultsFullGroupDirectory) = GetResultsFullGroupDirectories(outputResolution); if (!string.IsNullOrEmpty(a2PeopleContentDirectory) && _Configuration.SaveShortcutsForOutputResolutions.Contains(outputResolution))
mapLogic.SaveShortcutsForOutputResolutions(a2PeopleContentDirectory, personKeyToIds, mappingCollection, totalNotMapped);
if (!string.IsNullOrEmpty(a2PeopleContentDirectory) && _Configuration.SaveFilteredOriginalImagesFromJLinksForOutputResolutions.Contains(outputResolution)) if (!string.IsNullOrEmpty(a2PeopleContentDirectory) && _Configuration.SaveFilteredOriginalImagesFromJLinksForOutputResolutions.Contains(outputResolution))
mapLogic.SaveFilteredOriginalImagesFromJLinks(_Configuration.JLinks, _PersonContainers, a2PeopleContentDirectory, mappingCollection, personKeyToCount, totalNotMapped); mapLogic.SaveFilteredOriginalImagesFromJLinks(_Configuration.JLinks, _PersonContainers, a2PeopleContentDirectory, personKeyToIds, mappingCollection, totalNotMapped);
(aResultsFullGroupDirectory, bResultsFullGroupDirectory, cResultsFullGroupDirectory, dResultsFullGroupDirectory, d2ResultsFullGroupDirectory) = GetResultsFullGroupDirectories(outputResolution);
if (_ArgZeroIsConfigurationRootDirectory if (_ArgZeroIsConfigurationRootDirectory
&& _Configuration.SaveResizedSubfiles && _Configuration.SaveResizedSubfiles
&& outputResolution == _Configuration.OutputResolutions[0] && outputResolution == _Configuration.OutputResolutions[0]
&& _Configuration.LoadOrCreateThenSaveDistanceResultsForOutputResolutions.Contains(outputResolution) && _Configuration.LoadOrCreateThenSaveDistanceResultsForOutputResolutions.Contains(outputResolution)
&& _Exceptions.Count == 0) && _Exceptions.Count == 0)
MapLogic(argZero, ticks, containers, a2PeopleSingletonDirectory, dResultsFullGroupDirectory, d2ResultsFullGroupDirectory, fPhotoPrismContentDirectory, mapLogicSupport, mapLogic, outputResolution, distinctFilteredFaces, mappingCollection, totalNotMapped, personKeyToCount); MapLogic(argZero, ticks, containers, a2PeopleSingletonDirectory, dResultsFullGroupDirectory, d2ResultsFullGroupDirectory, fPhotoPrismContentDirectory, mapLogicSupport, mapLogic, outputResolution, personKeyToIds, distinctFilteredFaces, mappingCollection, totalNotMapped);
if (_Configuration.SaveRandomForOutputResolutions.Contains(outputResolution)) if (_Configuration.SaveRandomForOutputResolutions.Contains(outputResolution))
_Random.Random(_Configuration.PropertyConfiguration, mapLogic, outputResolution, mappingCollection); _Random.Random(_Configuration.PropertyConfiguration, outputResolution, personKeyToIds, mappingCollection);
if (_IsEnvironment.Development) if (_IsEnvironment.Development)
continue; continue;
G2_Identify identify = new(_Configuration); G2_Identify identify = new(_Configuration);

View File

@ -43,14 +43,15 @@ internal class F_Random
return result; return result;
} }
private static Dictionary<string, List<string>> Get(Map.Models.MapLogic mapLogic, Shared.Models.Mapping[] mappingCollection, string dateFormat) private static Dictionary<string, List<string>> Get(Dictionary<long, List<int>> personKeyToIds, Shared.Models.Mapping[] mappingCollection, string dateFormat)
{ {
Dictionary<string, List<string>> results = new(); Dictionary<string, List<string>> results = new();
string key; string key;
long personKey;
DateTime dateTime; DateTime dateTime;
List<long>? personKeys; List<long>? personKeys;
List<string>? relativePaths; List<string>? relativePaths;
Dictionary<int, List<long>> idToPersonKeys = mapLogic.GetIdToPeronKeys(); Dictionary<int, List<long>> idToPersonKeys = Map.Models.Stateless.Methods.IMapLogic.GetIdToPersonKeys(personKeyToIds);
foreach (Shared.Models.Mapping mapping in mappingCollection) foreach (Shared.Models.Mapping mapping in mappingCollection)
{ {
if (mapping.MappingFromItem.ImageFileHolder.DirectoryName is null || mapping.MappingFromPerson is null) if (mapping.MappingFromItem.ImageFileHolder.DirectoryName is null || mapping.MappingFromPerson is null)
@ -59,7 +60,8 @@ internal class F_Random
continue; continue;
if (!personKeys.Contains(mapping.MappingFromPerson.PersonBirthday.Value.Ticks)) if (!personKeys.Contains(mapping.MappingFromPerson.PersonBirthday.Value.Ticks))
continue; continue;
dateTime = new(mapping.MappingFromPerson.PersonBirthday.Value.Ticks); personKey = mapping.MappingFromPerson.PersonBirthday.Value.Ticks;
dateTime = new(personKey);
key = dateTime.ToString(dateFormat); key = dateTime.ToString(dateFormat);
if (!results.TryGetValue(key, out relativePaths)) if (!results.TryGetValue(key, out relativePaths))
{ {
@ -72,7 +74,7 @@ internal class F_Random
return results; return results;
} }
internal void Random(Property.Models.Configuration configuration, Map.Models.MapLogic mapLogic, string outputResolution, Shared.Models.Mapping[] mappingCollection) internal void Random(Property.Models.Configuration configuration, string outputResolution, Dictionary<long, List<int>> personKeyToIds, Shared.Models.Mapping[] mappingCollection)
{ {
string key; string key;
string json; string json;
@ -82,7 +84,7 @@ internal class F_Random
string dateFormat = "MM-dd"; string dateFormat = "MM-dd";
List<string> relativePaths = new(); List<string> relativePaths = new();
DateTime dateTime = new(2024, 1, 1); //Leap year DateTime dateTime = new(2024, 1, 1); //Leap year
Dictionary<string, List<string>> dayToRelativePaths = Get(mapLogic, mappingCollection, dateFormat); Dictionary<string, List<string>> dayToRelativePaths = Get(personKeyToIds, mappingCollection, dateFormat);
string fRandomCollectionDirectory = Property.Models.Stateless.IResult.GetResultsDateGroupDirectory(configuration, nameof(F_Random), "[]"); string fRandomCollectionDirectory = Property.Models.Stateless.IResult.GetResultsDateGroupDirectory(configuration, nameof(F_Random), "[]");
string[] files = Directory.GetFiles(fRandomCollectionDirectory, "*", SearchOption.TopDirectoryOnly); string[] files = Directory.GetFiles(fRandomCollectionDirectory, "*", SearchOption.TopDirectoryOnly);
foreach (string file in files) foreach (string file in files)

View File

@ -1,5 +1,6 @@
using Humanizer; using Humanizer;
using ShellProgressBar; using ShellProgressBar;
using System.Collections.ObjectModel;
using System.Text.Json; using System.Text.Json;
using View_by_Distance.Shared.Models; using View_by_Distance.Shared.Models;
using View_by_Distance.Shared.Models.Stateless.Methods; using View_by_Distance.Shared.Models.Stateless.Methods;
@ -10,10 +11,10 @@ namespace View_by_Distance.Map.Models;
public class MapLogic : Shared.Models.Methods.IMapLogic public class MapLogic : Shared.Models.Methods.IMapLogic
{ {
protected readonly Dictionary<int, List<int>> _SkipCollection;
protected readonly List<PersonContainer> _NotMappedPersonContainers; protected readonly List<PersonContainer> _NotMappedPersonContainers;
protected readonly Dictionary<long, PersonContainer> _PersonKeyToPersonContainer; protected readonly ReadOnlyDictionary<int, List<int>> _SkipCollection;
protected readonly Dictionary<int, Dictionary<int, PersonContainer[]>> _IdThenNormalizedRectangleToPersonContainers; protected readonly ReadOnlyDictionary<long, PersonContainer> _PersonKeyToPersonContainer;
protected readonly ReadOnlyDictionary<int, Dictionary<int, PersonContainer[]>> _IdThenNormalizedRectangleToPersonContainers;
public Dictionary<int, int[]> KeyValuePairs => throw new NotImplementedException(); public Dictionary<int, int[]> KeyValuePairs => throw new NotImplementedException();
public Dictionary<int, int[]> IndicesFromNew => throw new NotImplementedException(); public Dictionary<int, int[]> IndicesFromNew => throw new NotImplementedException();
@ -87,11 +88,11 @@ public class MapLogic : Shared.Models.Methods.IMapLogic
if (collection is null) if (collection is null)
throw new NullReferenceException(nameof(collection)); throw new NullReferenceException(nameof(collection));
} }
_SkipCollection = skipCollection; _SkipCollection = new(skipCollection);
_PersonKeyToPersonContainer = personKeyToPersonContainer; _PersonKeyToPersonContainer = new(personKeyToPersonContainer);
_EDistanceContentTicksDirectory = eDistanceContentTicksDirectory; _EDistanceContentTicksDirectory = eDistanceContentTicksDirectory;
_IdThenNormalizedRectangleToPersonContainers = idThenNormalizedRectangleToPersonContainers;
_NotMappedPersonContainers = notMappedPersonContainers.OrderByDescending(l => l.Key).ToList(); _NotMappedPersonContainers = notMappedPersonContainers.OrderByDescending(l => l.Key).ToList();
_IdThenNormalizedRectangleToPersonContainers = new(idThenNormalizedRectangleToPersonContainers);
} }
public override string ToString() public override string ToString()
@ -131,36 +132,13 @@ public class MapLogic : Shared.Models.Methods.IMapLogic
} }
} }
private static Dictionary<int, List<long>> GetIdToPersonKeys(Dictionary<long, List<int>> keyValuePairs) public Dictionary<long, List<int>> GetPersonKeyToIds()
{ {
Dictionary<int, List<long>> results = new(); Dictionary<long, List<int>> results = new();
List<long>? collection; long personKey;
foreach (KeyValuePair<long, List<int>> keyValuePair in keyValuePairs)
{
foreach (int id in keyValuePair.Value)
{
if (!results.TryGetValue(id, out collection))
{
results.Add(id, new());
if (!results.TryGetValue(id, out collection))
throw new Exception();
}
if (collection.Contains(keyValuePair.Key))
continue;
collection.Add(keyValuePair.Key);
}
}
return results;
}
public Dictionary<int, List<long>> GetIdToPeronKeys()
{
Dictionary<int, List<long>> results;
long key;
const int zero = 0; const int zero = 0;
List<int>? collection; List<int>? collection;
PersonBirthday personBirthday; PersonBirthday personBirthday;
Dictionary<long, List<int>> keyValuePairs = new();
foreach (KeyValuePair<int, Dictionary<int, PersonContainer[]>> idToCollection in _IdThenNormalizedRectangleToPersonContainers) foreach (KeyValuePair<int, Dictionary<int, PersonContainer[]>> idToCollection in _IdThenNormalizedRectangleToPersonContainers)
{ {
foreach (KeyValuePair<int, PersonContainer[]> normalizedRectangleToPersonContainers in idToCollection.Value) foreach (KeyValuePair<int, PersonContainer[]> normalizedRectangleToPersonContainers in idToCollection.Value)
@ -172,11 +150,11 @@ public class MapLogic : Shared.Models.Methods.IMapLogic
personBirthday = personContainer.Birthdays[zero]; personBirthday = personContainer.Birthdays[zero];
if (IPersonBirthday.IsCounterPersonBirthday(personBirthday)) if (IPersonBirthday.IsCounterPersonBirthday(personBirthday))
continue; continue;
key = personBirthday.Value.Ticks; personKey = personBirthday.Value.Ticks;
if (!keyValuePairs.TryGetValue(key, out collection)) if (!results.TryGetValue(personKey, out collection))
{ {
keyValuePairs.Add(key, new()); results.Add(personKey, new());
if (!keyValuePairs.TryGetValue(key, out collection)) if (!results.TryGetValue(personKey, out collection))
throw new Exception(); throw new Exception();
} }
if (collection.Contains(idToCollection.Key)) if (collection.Contains(idToCollection.Key))
@ -185,7 +163,6 @@ public class MapLogic : Shared.Models.Methods.IMapLogic
} }
} }
} }
results = GetIdToPersonKeys(keyValuePairs);
return results; return results;
} }
@ -236,36 +213,6 @@ public class MapLogic : Shared.Models.Methods.IMapLogic
return result; return result;
} }
public Dictionary<long, int> GetPersonKeyToCount(Mapping[] mappingCollection)
{
if (_Configuration is null)
throw new NullReferenceException(nameof(_Configuration));
Dictionary<long, int> results = new();
long personKey;
const int zero = 0;
PersonBirthday personBirthday;
PersonContainer[]? personContainers;
Dictionary<int, PersonContainer[]>? normalizedRectangleToPersonContainers;
foreach (Mapping mapping in mappingCollection)
{
if (!_IdThenNormalizedRectangleToPersonContainers.TryGetValue(mapping.MappingFromItem.Id, out normalizedRectangleToPersonContainers))
continue;
if (!normalizedRectangleToPersonContainers.TryGetValue(mapping.MappingFromLocation.NormalizedRectangle, out personContainers))
continue;
foreach (PersonContainer personContainer in personContainers)
{
if (personContainer.Key is null || personContainer.Birthdays is null || !personContainer.Birthdays.Any())
continue;
personBirthday = personContainer.Birthdays[zero];
personKey = personBirthday.Value.Ticks;
if (!results.ContainsKey(personKey))
results.Add(personKey, 0);
results[personKey] += 1;
}
}
return results;
}
public void SaveContainers(int totalNotMapped, int? updated, List<SaveContainer> saveContainers) public void SaveContainers(int totalNotMapped, int? updated, List<SaveContainer> saveContainers)
{ {
if (_Configuration is null) if (_Configuration is null)
@ -472,12 +419,13 @@ public class MapLogic : Shared.Models.Methods.IMapLogic
return result; return result;
} }
private List<SaveContainer> GetSaveContainers(string dFacesContentDirectory, string d2FacePartsContentDirectory, Mapping[] mappingCollection, Dictionary<int, Dictionary<int, Mapping>> idToNormalizedRectangleToMapping, Dictionary<long, int> personKeyToCount, int? useFiltersCounter, bool saveMapped, bool sortingContainersAny) private List<SaveContainer> GetSaveContainers(string dFacesContentDirectory, string d2FacePartsContentDirectory, Mapping[] mappingCollection, Dictionary<int, Dictionary<int, Mapping>> idToNormalizedRectangleToMapping, Dictionary<long, List<int>> personKeyToIds, int? useFiltersCounter, bool saveMapped, bool sortingContainersAny)
{ {
if (_Configuration is null) if (_Configuration is null)
throw new NullReferenceException(nameof(_Configuration)); throw new NullReferenceException(nameof(_Configuration));
List<SaveContainer> results = new(); List<SaveContainer> results = new();
string by; string by;
List<int>? ids;
long personKey; long personKey;
bool isByMapping; bool isByMapping;
bool isBySorting; bool isBySorting;
@ -546,9 +494,9 @@ public class MapLogic : Shared.Models.Methods.IMapLogic
personDirectory = Path.Combine(directory, mapping.MappingFromPerson.DisplayDirectoryName, "lnk"); personDirectory = Path.Combine(directory, mapping.MappingFromPerson.DisplayDirectoryName, "lnk");
else else
personDirectory = Path.Combine(directory, mapping.MappingFromPerson.DisplayDirectoryName[..1], "lnk"); personDirectory = Path.Combine(directory, mapping.MappingFromPerson.DisplayDirectoryName[..1], "lnk");
if (isByMapping && personKeyToCount.TryGetValue(personKey, out int count)) if (isByMapping && personKeyToIds.TryGetValue(personKey, out ids))
{ {
saveContainer = new(Path.Combine(directory, mapping.MappingFromPerson.DisplayDirectoryName, $"{count} Face(s)")); saveContainer = new(Path.Combine(directory, mapping.MappingFromPerson.DisplayDirectoryName, $"{ids.Count} Face(s)"));
results.Add(saveContainer); results.Add(saveContainer);
} }
} }
@ -604,12 +552,12 @@ public class MapLogic : Shared.Models.Methods.IMapLogic
throw new NullReferenceException(nameof(_Configuration)); throw new NullReferenceException(nameof(_Configuration));
List<SaveContainer> results; List<SaveContainer> results;
bool saveMapped = false; bool saveMapped = false;
Dictionary<long, int> personKeyToCount = new(); Dictionary<long, List<int>> personKeyToIds = new();
results = GetSaveContainers(dFacesContentDirectory, d2FacePartsContentDirectory, mappingCollection, idToNormalizedRectangleToMapping, personKeyToCount, useFiltersCounter, saveMapped, sortingContainersAny); results = GetSaveContainers(dFacesContentDirectory, d2FacePartsContentDirectory, mappingCollection, idToNormalizedRectangleToMapping, personKeyToIds, useFiltersCounter, saveMapped, sortingContainersAny);
return results; return results;
} }
public void SaveMapped(string dFacesContentDirectory, string d2FacePartsContentDirectory, Mapping[] mappingCollection, Dictionary<int, Dictionary<int, Mapping>> idToNormalizedRectangleToMapping, Dictionary<long, int> personKeyToCount, int totalNotMapped) public void SaveMapped(string dFacesContentDirectory, string d2FacePartsContentDirectory, Dictionary<long, List<int>> personKeyToIds, Mapping[] mappingCollection, Dictionary<int, Dictionary<int, Mapping>> idToNormalizedRectangleToMapping, int totalNotMapped)
{ {
if (_Configuration is null) if (_Configuration is null)
throw new NullReferenceException(nameof(_Configuration)); throw new NullReferenceException(nameof(_Configuration));
@ -617,7 +565,7 @@ public class MapLogic : Shared.Models.Methods.IMapLogic
bool saveMapped = true; bool saveMapped = true;
int? useFiltersCounter = null; int? useFiltersCounter = null;
string mappingDirectory = Path.Combine(_EDistanceContentTicksDirectory, nameof(Shared.Models.Stateless.IMapLogic.Mapping)); string mappingDirectory = Path.Combine(_EDistanceContentTicksDirectory, nameof(Shared.Models.Stateless.IMapLogic.Mapping));
List<SaveContainer> saveContainers = GetSaveContainers(dFacesContentDirectory, d2FacePartsContentDirectory, mappingCollection, idToNormalizedRectangleToMapping, personKeyToCount, useFiltersCounter, saveMapped, sortingContainersAny: true); List<SaveContainer> saveContainers = GetSaveContainers(dFacesContentDirectory, d2FacePartsContentDirectory, mappingCollection, idToNormalizedRectangleToMapping, personKeyToIds, useFiltersCounter, saveMapped, sortingContainersAny: true);
SaveContainers(totalNotMapped, updated, saveContainers); SaveContainers(totalNotMapped, updated, saveContainers);
if (!string.IsNullOrEmpty(_EDistanceContentTicksDirectory) && Directory.Exists(mappingDirectory)) if (!string.IsNullOrEmpty(_EDistanceContentTicksDirectory) && Directory.Exists(mappingDirectory))
Stateless.MapLogic.SaveMappingShortcuts(mappingDirectory); Stateless.MapLogic.SaveMappingShortcuts(mappingDirectory);
@ -952,7 +900,7 @@ public class MapLogic : Shared.Models.Methods.IMapLogic
return new(personKeyFormatted, personBirthday); return new(personKeyFormatted, personBirthday);
} }
private List<string> GetPersonKeyFormattedCollection(string[] jLinks, string a2PeopleContentDirectory, PersonContainer[] personContainers, Dictionary<long, int> personKeyToCount) private List<string> GetPersonKeyFormattedCollection(string[] jLinks, string a2PeopleContentDirectory, PersonContainer[] personContainers, Dictionary<long, List<int>> personKeyToIds)
{ {
if (_Configuration is null) if (_Configuration is null)
throw new NullReferenceException(nameof(_Configuration)); throw new NullReferenceException(nameof(_Configuration));
@ -991,10 +939,10 @@ public class MapLogic : Shared.Models.Methods.IMapLogic
(personKeyFormatted, personBirthday) = GetPersonBirthday(windowsShortcut.Path); (personKeyFormatted, personBirthday) = GetPersonBirthday(windowsShortcut.Path);
if (personBirthday is null) if (personBirthday is null)
throw new NotSupportedException(fileNameWithoutExtension); throw new NotSupportedException(fileNameWithoutExtension);
if (!personKeyToCount.ContainsKey(personBirthday.Value.Ticks)) if (!personKeyToIds.ContainsKey(personBirthday.Value.Ticks))
collection.Add(new(personBirthday.Value.Ticks, Path.Combine(checkDirectory, personKeyFormatted, fileNameWithoutExtension))); collection.Add(new(personBirthday.Value.Ticks, Path.Combine(checkDirectory, personKeyFormatted, fileNameWithoutExtension)));
else else
collection.Add(new(personBirthday.Value.Ticks, Path.Combine(checkDirectory, personKeyFormatted, fileNameWithoutExtension, $"{personKeyToCount[personBirthday.Value.Ticks]} Face(s)"))); collection.Add(new(personBirthday.Value.Ticks, Path.Combine(checkDirectory, personKeyFormatted, fileNameWithoutExtension, $"{personKeyToIds[personBirthday.Value.Ticks].Count} Face(s)")));
foreach ((long personKey, string displayDirectoryName) in collection) foreach ((long personKey, string displayDirectoryName) in collection)
{ {
matches = (from l in personContainers where l.Key == personKey && l.ApproximateYears.HasValue select l).ToArray(); matches = (from l in personContainers where l.Key == personKey && l.ApproximateYears.HasValue select l).ToArray();
@ -1012,7 +960,7 @@ public class MapLogic : Shared.Models.Methods.IMapLogic
return results; return results;
} }
private (int, FileHolder, int, string, string, string, string)[] GetCollectionForSaveFilteredOriginalImagesFromJLinks(string[] jLinks, string a2PeopleContentDirectory, PersonContainer[] personContainers, Mapping[] mappingCollection, Dictionary<long, int> personKeyToCount) private (int, FileHolder, int, string, string, string, string)[] GetCollectionForSaveFilteredOriginalImagesFromJLinks(string[] jLinks, string a2PeopleContentDirectory, PersonContainer[] personContainers, Mapping[] mappingCollection, Dictionary<long, List<int>> personKeyToIds)
{ {
if (_Configuration is null) if (_Configuration is null)
throw new NullReferenceException(nameof(_Configuration)); throw new NullReferenceException(nameof(_Configuration));
@ -1023,7 +971,7 @@ public class MapLogic : Shared.Models.Methods.IMapLogic
string personDirectory; string personDirectory;
string personKeyFormatted; string personKeyFormatted;
bool usePersonKeyAndDeterministicHashCodeKey = false; bool usePersonKeyAndDeterministicHashCodeKey = false;
List<string> personKeyFormattedCollection = GetPersonKeyFormattedCollection(jLinks, a2PeopleContentDirectory, personContainers, personKeyToCount); List<string> personKeyFormattedCollection = GetPersonKeyFormattedCollection(jLinks, a2PeopleContentDirectory, personContainers, personKeyToIds);
List<(int Id, FileHolder ImageFileHolder, int ApproximateYears, string PersonKeyFormatted, string CheckFile, string Directory, string PersonDirectory)> collection = new(); List<(int Id, FileHolder ImageFileHolder, int ApproximateYears, string PersonKeyFormatted, string CheckFile, string Directory, string PersonDirectory)> collection = new();
foreach (Mapping mapping in mappingCollection) foreach (Mapping mapping in mappingCollection)
{ {
@ -1112,7 +1060,7 @@ public class MapLogic : Shared.Models.Methods.IMapLogic
} }
} }
public void SaveFilteredOriginalImagesFromJLinks(string[] jLinks, PersonContainer[] personContainers, string a2PeopleContentDirectory, Mapping[] mappingCollection, Dictionary<long, int> personKeyToCount, int totalNotMapped) public void SaveFilteredOriginalImagesFromJLinks(string[] jLinks, PersonContainer[] personContainers, string a2PeopleContentDirectory, Dictionary<long, List<int>> personKeyToIds, Mapping[] mappingCollection, int totalNotMapped)
{ {
if (_Configuration is null) if (_Configuration is null)
throw new NullReferenceException(nameof(_Configuration)); throw new NullReferenceException(nameof(_Configuration));
@ -1120,7 +1068,7 @@ public class MapLogic : Shared.Models.Methods.IMapLogic
List<int> distinctCollection = new(); List<int> distinctCollection = new();
List<SaveContainer> saveContainers = new(); List<SaveContainer> saveContainers = new();
BeforeSaveFilteredOriginalImagesFromJLinks(jLinks, a2PeopleContentDirectory); BeforeSaveFilteredOriginalImagesFromJLinks(jLinks, a2PeopleContentDirectory);
(int, FileHolder, int, string, string, string, string)[] collection = GetCollectionForSaveFilteredOriginalImagesFromJLinks(jLinks, a2PeopleContentDirectory, personContainers, mappingCollection, personKeyToCount); (int, FileHolder, int, string, string, string, string)[] collection = GetCollectionForSaveFilteredOriginalImagesFromJLinks(jLinks, a2PeopleContentDirectory, personContainers, mappingCollection, personKeyToIds);
foreach ((int id, FileHolder imageFileHolder, int approximateYears, string personKeyFormatted, string directory, string personDirectory, string checkFile) in collection) foreach ((int id, FileHolder imageFileHolder, int approximateYears, string personKeyFormatted, string directory, string personDirectory, string checkFile) in collection)
{ {
if (distinctCollection.Contains(id)) if (distinctCollection.Contains(id))
@ -1134,7 +1082,64 @@ public class MapLogic : Shared.Models.Methods.IMapLogic
SaveContainers(totalNotMapped, null, saveContainers); SaveContainers(totalNotMapped, null, saveContainers);
} }
private (List<(string, DateTime[])>, List<(string, string, string, string)>) GetCollectionForSaveShortcutsForOutputResolutions(List<Item> filteredItems, Mapping[] mappingCollection, Dictionary<long, int> personKeyToCount) public void SaveShortcutsForOutputResolutions(string a2PeopleContentDirectory, Dictionary<long, List<int>> personKeyToIds, Mapping[] mappingCollection, int totalNotMapped)
{
if (_Configuration is null)
throw new NullReferenceException(nameof(_Configuration));
long personKey;
string fileName;
string directory;
string hiddenFile;
string personDirectory;
List<long>? personKeys;
string personKeyFormatted;
WindowsShortcut windowsShortcut;
List<SaveShortcutsForOutputResolutions> collection = new();
Dictionary<int, List<long>> idToPersonKeys = Stateless.Methods.IMapLogic.GetIdToPersonKeys(personKeyToIds);
foreach (Mapping mapping in mappingCollection)
{
if (mapping.MappingFromItem.ImageFileHolder.DirectoryName is null || mapping.MappingFromPerson is null)
continue;
if (!idToPersonKeys.TryGetValue(mapping.MappingFromItem.Id, out personKeys))
continue;
personKey = mapping.MappingFromPerson.PersonBirthday.Value.Ticks;
if (!personKeys.Contains(mapping.MappingFromPerson.PersonBirthday.Value.Ticks))
continue;
personKeyFormatted = IPersonBirthday.GetFormatted(_Configuration.PersonBirthdayFormat, mapping.MappingFromPerson.PersonBirthday);
directory = Path.Combine(a2PeopleContentDirectory, $"{_PropertyConfiguration.ResultAllInOne}Shortcuts", personKeyFormatted);
personDirectory = Path.Combine(directory, mapping.MappingFromPerson.DisplayDirectoryName[..1], Path.GetFileName(mapping.MappingFromItem.ImageFileHolder.DirectoryName));
fileName = Path.Combine(personDirectory, $"{mapping.MappingFromItem.ResizedFileHolder.Name}.lnk");
collection.Add(new(mapping.MappingFromItem.ResizedFileHolder.FullName, personDirectory, mapping.MappingFromItem.MinimumDateTime, fileName, mapping.MappingFromLocation.DeterministicHashCodeKey));
}
string[] directories = (from l in collection select l.Directory).Distinct().ToArray();
foreach (string d in directories)
{
if (string.IsNullOrEmpty(d))
continue;
if (!Directory.Exists(d))
_ = Directory.CreateDirectory(d);
}
foreach (SaveShortcutsForOutputResolutions s in collection)
{
hiddenFile = $"{s.FileName}.lvs";
File.WriteAllLines(hiddenFile, new string[] { s.FullName, s.Description });
File.SetAttributes(hiddenFile, FileAttributes.Hidden);
File.SetLastWriteTime(hiddenFile, s.DateTime);
if (File.Exists(s.FileName))
continue;
try
{
windowsShortcut = new() { Path = s.FullName, Description = s.Description };
windowsShortcut.Save(s.FileName);
windowsShortcut.Dispose();
File.SetLastWriteTime(s.FileName, s.DateTime);
}
catch (Exception)
{ }
}
}
private (List<(string, DateTime[])>, List<SaveShortcutsForOutputResolutions>) GetCollectionForSaveShortcutsForOutputResolutions(Dictionary<long, List<int>> personKeyToIds, List<Item> filteredItems, Mapping[] mappingCollection)
{ {
if (_Configuration is null) if (_Configuration is null)
throw new NullReferenceException(nameof(_Configuration)); throw new NullReferenceException(nameof(_Configuration));
@ -1145,7 +1150,7 @@ public class MapLogic : Shared.Models.Methods.IMapLogic
string personDirectory; string personDirectory;
string personKeyFormatted; string personKeyFormatted;
List<string> distinct = new(); List<string> distinct = new();
List<(string, string, string, string)> collection = new(); List<SaveShortcutsForOutputResolutions> collection = new();
List<(string, DateTime[])> directoriesAndDateTimes = new(); List<(string, DateTime[])> directoriesAndDateTimes = new();
foreach (Item item in filteredItems) foreach (Item item in filteredItems)
{ {
@ -1158,12 +1163,12 @@ public class MapLogic : Shared.Models.Methods.IMapLogic
directoryName = Path.GetDirectoryName(face.Mapping.MappingFromItem.RelativePath); directoryName = Path.GetDirectoryName(face.Mapping.MappingFromItem.RelativePath);
if (directoryName is null) if (directoryName is null)
throw new NotSupportedException(); throw new NotSupportedException();
if (item.ResizedFileHolder?.DirectoryName is null || !item.ResizedFileHolder.Exists) if (item.ResizedFileHolder?.DirectoryName is null || !item.ResizedFileHolder.Exists || item.ImageFileHolder.LastWriteTime is null)
continue; continue;
directory = Path.Combine(item.ResizedFileHolder.DirectoryName, $"{_PropertyConfiguration.ResultAllInOne}Shortcuts", _PropertyConfiguration.ResultAllInOne); directory = Path.Combine(item.ResizedFileHolder.DirectoryName, $"{_PropertyConfiguration.ResultAllInOne}Shortcuts", _PropertyConfiguration.ResultAllInOne);
personDirectory = Path.Combine(directory, "No Faces"); personDirectory = Path.Combine(directory, "No Faces");
fileName = Path.Combine(personDirectory, $"{item.ResizedFileHolder.Name}.lnk"); fileName = Path.Combine(personDirectory, $"{item.ResizedFileHolder.Name}.lnk");
collection.Add(new(item.ResizedFileHolder.FullName, personDirectory, fileName, face.Mapping.MappingFromItem.Id.ToString())); collection.Add(new(item.ResizedFileHolder.FullName, personDirectory, item.ImageFileHolder.LastWriteTime.Value, fileName, face.Mapping.MappingFromItem.Id.ToString()));
if (face.Mapping.MappingFromItem.ContainerDateTimes.Any() && !distinct.Contains(item.ResizedFileHolder.DirectoryName)) if (face.Mapping.MappingFromItem.ContainerDateTimes.Any() && !distinct.Contains(item.ResizedFileHolder.DirectoryName))
{ {
distinct.Add(item.ResizedFileHolder.DirectoryName); distinct.Add(item.ResizedFileHolder.DirectoryName);
@ -1188,7 +1193,7 @@ public class MapLogic : Shared.Models.Methods.IMapLogic
directory = Path.Combine(mapping.MappingFromItem.ResizedFileHolder.DirectoryName, $"{_PropertyConfiguration.ResultAllInOne}Shortcuts", _PropertyConfiguration.ResultAllInOne); directory = Path.Combine(mapping.MappingFromItem.ResizedFileHolder.DirectoryName, $"{_PropertyConfiguration.ResultAllInOne}Shortcuts", _PropertyConfiguration.ResultAllInOne);
personDirectory = Path.Combine(directory, "Unknown"); personDirectory = Path.Combine(directory, "Unknown");
fileName = Path.Combine(personDirectory, $"{mapping.MappingFromItem.ResizedFileHolder.Name}.lnk"); fileName = Path.Combine(personDirectory, $"{mapping.MappingFromItem.ResizedFileHolder.Name}.lnk");
collection.Add(new(mapping.MappingFromItem.ResizedFileHolder.FullName, personDirectory, fileName, mapping.MappingFromLocation.DeterministicHashCodeKey)); collection.Add(new(mapping.MappingFromItem.ResizedFileHolder.FullName, personDirectory, mapping.MappingFromItem.MinimumDateTime, fileName, mapping.MappingFromLocation.DeterministicHashCodeKey));
} }
else else
{ {
@ -1204,25 +1209,25 @@ public class MapLogic : Shared.Models.Methods.IMapLogic
directoriesAndDateTimes.Add(new(mapping.MappingFromItem.ResizedFileHolder.DirectoryName, mapping.MappingFromItem.ContainerDateTimes)); directoriesAndDateTimes.Add(new(mapping.MappingFromItem.ResizedFileHolder.DirectoryName, mapping.MappingFromItem.ContainerDateTimes));
} }
directory = Path.Combine(mapping.MappingFromItem.ResizedFileHolder.DirectoryName, $"{_PropertyConfiguration.ResultAllInOne}Shortcuts", personKeyFormatted); directory = Path.Combine(mapping.MappingFromItem.ResizedFileHolder.DirectoryName, $"{_PropertyConfiguration.ResultAllInOne}Shortcuts", personKeyFormatted);
if (!personKeyToCount.ContainsKey(personKey)) if (!personKeyToIds.ContainsKey(personKey))
personDirectory = Path.Combine(directory, mapping.MappingFromPerson.DisplayDirectoryName); personDirectory = Path.Combine(directory, mapping.MappingFromPerson.DisplayDirectoryName);
else else
personDirectory = Path.Combine(directory, mapping.MappingFromPerson.DisplayDirectoryName, $"{personKeyToCount[personKey]} Face(s)"); personDirectory = Path.Combine(directory, mapping.MappingFromPerson.DisplayDirectoryName, $"{personKeyToIds[personKey].Count} Face(s)");
fileName = Path.Combine(directory, $"{mapping.MappingFromItem.ResizedFileHolder.Name}.lnk"); fileName = Path.Combine(directory, $"{mapping.MappingFromItem.ResizedFileHolder.Name}.lnk");
collection.Add(new(mapping.MappingFromItem.ResizedFileHolder.FullName, personDirectory, fileName, mapping.MappingFromLocation.DeterministicHashCodeKey)); collection.Add(new(mapping.MappingFromItem.ResizedFileHolder.FullName, personDirectory, mapping.MappingFromItem.MinimumDateTime, fileName, mapping.MappingFromLocation.DeterministicHashCodeKey));
} }
} }
return new(directoriesAndDateTimes, collection); return new(directoriesAndDateTimes, collection);
} }
public void SaveShortcutsForOutputResolutions(List<Item> filteredItems, Mapping[] mappingCollection, Dictionary<long, int> personKeyToCount) public void SaveShortcutsForOutputResolutions(Dictionary<long, List<int>> personKeyToIds, List<Item> filteredItems, Mapping[] mappingCollection)
{ {
if (_Configuration is null) if (_Configuration is null)
throw new NullReferenceException(nameof(_Configuration)); throw new NullReferenceException(nameof(_Configuration));
WindowsShortcut windowsShortcut; WindowsShortcut windowsShortcut;
List<(string, DateTime[])> directoriesAndDateTimes; List<(string, DateTime[])> directoriesAndDateTimes;
List<(string, string Directory, string, string)> collection; List<SaveShortcutsForOutputResolutions> collection;
(directoriesAndDateTimes, collection) = GetCollectionForSaveShortcutsForOutputResolutions(filteredItems, mappingCollection, personKeyToCount); (directoriesAndDateTimes, collection) = GetCollectionForSaveShortcutsForOutputResolutions(personKeyToIds, filteredItems, mappingCollection);
string[] directories = (from l in collection select l.Directory).Distinct().ToArray(); string[] directories = (from l in collection select l.Directory).Distinct().ToArray();
foreach (string directory in directories) foreach (string directory in directories)
{ {
@ -1231,14 +1236,14 @@ public class MapLogic : Shared.Models.Methods.IMapLogic
if (!Directory.Exists(directory)) if (!Directory.Exists(directory))
_ = Directory.CreateDirectory(directory); _ = Directory.CreateDirectory(directory);
} }
foreach ((string fullName, string directory, string fileName, string description) in collection) foreach (SaveShortcutsForOutputResolutions saveShortcutsForOutputResolutions in collection)
{ {
if (File.Exists(fileName)) if (File.Exists(saveShortcutsForOutputResolutions.FileName))
continue; continue;
try try
{ {
windowsShortcut = new() { Path = fullName, Description = description }; windowsShortcut = new() { Path = saveShortcutsForOutputResolutions.FullName, Description = saveShortcutsForOutputResolutions.Description };
windowsShortcut.Save(fileName); windowsShortcut.Save(saveShortcutsForOutputResolutions.FileName);
windowsShortcut.Dispose(); windowsShortcut.Dispose();
} }
catch (Exception) catch (Exception)

View File

@ -680,4 +680,26 @@ internal abstract class MapLogic
return results; return results;
} }
internal static Dictionary<int, List<long>> GetIdToPersonKeys(Dictionary<long, List<int>> personKeyToIds)
{
Dictionary<int, List<long>> results = new();
List<long>? collection;
foreach (KeyValuePair<long, List<int>> keyValuePair in personKeyToIds)
{
foreach (int id in keyValuePair.Value)
{
if (!results.TryGetValue(id, out collection))
{
results.Add(id, new());
if (!results.TryGetValue(id, out collection))
throw new Exception();
}
if (collection.Contains(keyValuePair.Key))
continue;
collection.Add(keyValuePair.Key);
}
}
return results;
}
} }

View File

@ -1,7 +1,12 @@
namespace View_by_Distance.Map.Models.Stateless.Methods; namespace View_by_Distance.Map.Models.Stateless.Methods;
public interface IMapLogic public interface IMapLogic
{ // ... {
Dictionary<int, List<long>> TestStatic_GetIdToPersonKeys(Dictionary<long, List<int>> personKeyToIds) =>
GetIdToPersonKeys(personKeyToIds);
static Dictionary<int, List<long>> GetIdToPersonKeys(Dictionary<long, List<int>> personKeyToIds) =>
MapLogic.GetIdToPersonKeys(personKeyToIds);
List<(long, string)> TestStatic_GetDisplayDirectoryAllFiles(Shared.Models.PersonContainer[] personContainers) => List<(long, string)> TestStatic_GetDisplayDirectoryAllFiles(Shared.Models.PersonContainer[] personContainers) =>
GetDisplayDirectoryAllFiles(personContainers); GetDisplayDirectoryAllFiles(personContainers);

View File

@ -244,14 +244,16 @@ public class Rename
{ {
List<string> results = new(); List<string> results = new();
string[] files; string[] files;
string message;
int distinctCount; int distinctCount;
string message = "Renaming files"; ProgressBar progressBar;
List<(FileHolder, string)> renameCollection; List<(FileHolder, string)> renameCollection;
List<string> allFiles = GetAllFiles(matchNginxCollection); List<string> allFiles = GetAllFiles(matchNginxCollection);
using ProgressBar progressBar = new(matchNginxCollection.Length * 2, message, options);
for (int i = 1; i < 3; i++) for (int i = 1; i < 3; i++)
{ {
message = $"{i}) Renaming files";
files = i == 2 ? allFiles.ToArray() : (from l in allFiles where l.Contains("Rename") select l).ToArray(); files = i == 2 ? allFiles.ToArray() : (from l in allFiles where l.Contains("Rename") select l).ToArray();
progressBar = new(files.Length, message, options);
(renameCollection, distinctCount) = RenameFilesInDirectory(progressBar, files); (renameCollection, distinctCount) = RenameFilesInDirectory(progressBar, files);
foreach ((FileHolder fileHolder, string to) in renameCollection) foreach ((FileHolder fileHolder, string to) in renameCollection)
{ {
@ -263,6 +265,7 @@ public class Rename
File.Move(fileHolder.FullName, to); File.Move(fileHolder.FullName, to);
File.WriteAllText($"{to}.id", $"{to}{Environment.NewLine}{fileHolder.FullName}"); File.WriteAllText($"{to}.id", $"{to}{Environment.NewLine}{fileHolder.FullName}");
} }
progressBar.Dispose();
} }
return results; return results;
} }

View File

@ -0,0 +1,4 @@
namespace View_by_Distance.Shared.Models;
public record SaveShortcutsForOutputResolutions(string FullName, string Directory, DateTime DateTime, string FileName, string Description)
{ }