Changed GetDimensions to handle a stream at the end and one exit Switched to using Action? over IDlibDotNet for Tick method Switched to using AsReadOnly over new() Moved Meta Base to Shared
1541 lines
94 KiB
C#
1541 lines
94 KiB
C#
using Humanizer;
|
|
using ShellProgressBar;
|
|
using System.Buffers;
|
|
using System.Collections.ObjectModel;
|
|
using System.Globalization;
|
|
using System.Text.Json;
|
|
using System.Text.RegularExpressions;
|
|
using View_by_Distance.Map.Models.Stateless.Methods;
|
|
using View_by_Distance.Shared.Models;
|
|
using View_by_Distance.Shared.Models.Stateless.Methods;
|
|
using WindowsShortcutFactory;
|
|
|
|
namespace View_by_Distance.Map.Models;
|
|
|
|
public partial class MapLogic : Shared.Models.Methods.IMapLogic
|
|
{
|
|
|
|
internal record Record(string? DebugDirectory,
|
|
string? Directory,
|
|
long? Ticks,
|
|
string? PersonDirectory);
|
|
|
|
internal record FilteredOriginalImage(int Id,
|
|
FilePath FilePath,
|
|
int ApproximateYears,
|
|
string PersonKeyFormatted,
|
|
string Directory,
|
|
string PersonDirectory,
|
|
string CheckFile);
|
|
|
|
private readonly long _Ticks;
|
|
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 Shared.Models.Properties.IPropertyConfiguration _PropertyConfiguration;
|
|
private readonly ReadOnlyDictionary<int, List<LocationContainer>> _IdToLocationContainers;
|
|
private readonly ReadOnlyDictionary<int, ReadOnlyDictionary<int, ReadOnlyCollection<PersonContainer>>> _IdThenWholePercentagesToPersonContainers;
|
|
|
|
(bool, ReadOnlyDictionary<int, ReadOnlyCollection<PersonContainer>>?) Shared.Models.Methods.IMapLogic.GetWholePercentagesToPersonContainers(int id)
|
|
{
|
|
bool result = _IdThenWholePercentagesToPersonContainers.TryGetValue(id, out ReadOnlyDictionary<int, ReadOnlyCollection<PersonContainer>>? wholePercentagesToPersonContainers);
|
|
return new(result, wholePercentagesToPersonContainers);
|
|
}
|
|
|
|
public MapLogic(int maxDegreeOfParallelism, Shared.Models.Properties.IPropertyConfiguration propertyConfiguration, Configuration? configuration, Shared.Models.Methods.IDistance distance, ReadOnlyCollection<PersonContainer> personContainers, long ticks, string? a2PeopleContentDirectory, string a2PeopleSingletonDirectory, string eDistanceContentDirectory)
|
|
{
|
|
_Ticks = ticks;
|
|
_Configuration = configuration;
|
|
_PropertyConfiguration = propertyConfiguration;
|
|
List<LocationContainer> locationContainers = [];
|
|
List<PersonContainer> notMappedPersonContainers = [];
|
|
ReadOnlyDictionary<long, int> readOnlyPersonKeyToCount;
|
|
Dictionary<int, List<(string, int)>> skipCollection = [];
|
|
Dictionary<int, List<(string, int)>> skipNotSkipCollection = [];
|
|
ReadOnlyDictionary<int, List<(string, int)>> readOnlySkipCollection;
|
|
string? rootDirectoryParent = Path.GetDirectoryName(propertyConfiguration.RootDirectory);
|
|
string eDistanceContentTicksDirectory = Path.Combine(eDistanceContentDirectory, ticks.ToString());
|
|
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 null)
|
|
{
|
|
readOnlyPersonKeyToCount = new(new Dictionary<long, int>());
|
|
idThenWholePercentagesToPersonContainers = new(new Dictionary<int, ReadOnlyDictionary<int, ReadOnlyCollection<PersonContainer>>>());
|
|
}
|
|
else
|
|
{
|
|
ReadOnlyCollection<string> readOnlyPersonKeyFormattedCollection;
|
|
ReadOnlyDictionary<string, string> readOnlyPersonKeyFormattedToNewestPersonKeyFormatted;
|
|
ReadOnlyDictionary<string, PersonContainer> readOnlyPersonKeyFormattedToPersonContainer;
|
|
ReadOnlyDictionary<long, List<PersonContainer>> readOnlyPersonKeyToPersonContainerCollection;
|
|
int copied = Stateless.MapLogic.CopyManualFiles(configuration, ticks, personContainers, eDistanceContentTicksDirectory);
|
|
if (copied > 0)
|
|
throw new Exception("Confirm Manual files and then restart!");
|
|
Stateless.MapLogic.SetSkipCollections(configuration, personContainers, a2PeopleSingletonDirectory, skipCollection, skipNotSkipCollection);
|
|
{
|
|
List<string> personKeyFormattedCollection = [];
|
|
Dictionary<string, string> personKeyFormattedToNewestPersonKeyFormatted = [];
|
|
Stateless.MapLogic.SetPersonCollectionsAfterSetSkipCollections(configuration, personContainers, personKeyFormattedToNewestPersonKeyFormatted, personKeyFormattedCollection);
|
|
readOnlyPersonKeyFormattedCollection = personKeyFormattedCollection.AsReadOnly();
|
|
readOnlyPersonKeyFormattedToNewestPersonKeyFormatted = personKeyFormattedToNewestPersonKeyFormatted.AsReadOnly();
|
|
}
|
|
List<Stateless.Record> records = Stateless.DistanceLogic.DeleteEmptyDirectoriesAndGetCollection(propertyConfiguration, configuration, ticks, eDistanceContentDirectory, readOnlyPersonKeyFormattedToNewestPersonKeyFormatted, readOnlyPersonKeyFormattedCollection);
|
|
ReadOnlyCollection<(Stateless.MapLogic.PersonKeyFormattedIdThenWholePercentages, PersonContainer)> readOnlyPossiblyNewPersonDisplayDirectoryNamesAndPersonContainer;
|
|
ReadOnlyCollection<Stateless.MapLogic.PersonKeyFormattedIdThenWholePercentages> personKeyFormattedIdThenWholePercentagesCollection = Stateless.MapLogic.GetPersonKeyFormattedIdThenWholePercentages(configuration, ticks, records);
|
|
//
|
|
{
|
|
Dictionary<long, int> personKeyToCount = [];
|
|
Dictionary<long, PersonContainer> personKeyToPersonContainer = [];
|
|
Dictionary<string, PersonContainer> personKeyFormattedToPersonContainer = [];
|
|
Dictionary<long, List<PersonContainer>> personKeyToPersonContainerCollection = [];
|
|
List<(Stateless.MapLogic.PersonKeyFormattedIdThenWholePercentages, PersonContainer)> possiblyNewPersonDisplayDirectoryNamesAndPersonContainer = [];
|
|
Stateless.MapLogic.SetKeyValuePairsAndAddToCollections(configuration,
|
|
personContainers,
|
|
personKeyToPersonContainer,
|
|
personKeyFormattedIdThenWholePercentagesCollection,
|
|
personKeyToCount,
|
|
personKeyFormattedToPersonContainer,
|
|
personKeyToPersonContainerCollection,
|
|
possiblyNewPersonDisplayDirectoryNamesAndPersonContainer);
|
|
readOnlyPersonKeyToCount = personKeyToCount.AsReadOnly();
|
|
readOnlyPersonKeyFormattedToPersonContainer = personKeyFormattedToPersonContainer.AsReadOnly();
|
|
readOnlyPersonKeyToPersonContainerCollection = personKeyToPersonContainerCollection.AsReadOnly();
|
|
readOnlyPossiblyNewPersonDisplayDirectoryNamesAndPersonContainer = possiblyNewPersonDisplayDirectoryNamesAndPersonContainer.AsReadOnly();
|
|
Stateless.MapLogic.SetPersonKeyToPersonContainer(configuration,
|
|
personContainers,
|
|
readOnlyPersonKeyToCount,
|
|
personKeyToPersonContainer,
|
|
readOnlyPersonKeyToPersonContainerCollection);
|
|
}
|
|
Stateless.MapLogic.PossiblyRebuildPersonContainers(configuration,
|
|
ticks,
|
|
a2PeopleSingletonDirectory,
|
|
readOnlyPersonKeyToCount,
|
|
readOnlyPossiblyNewPersonDisplayDirectoryNamesAndPersonContainer);
|
|
idThenWholePercentagesToPersonContainers = Stateless.MapLogic.GetIdThenWholePercentagesToPersonContainers(configuration,
|
|
skipCollection,
|
|
readOnlyPersonKeyFormattedToPersonContainer,
|
|
personKeyFormattedIdThenWholePercentagesCollection);
|
|
readOnlySkipCollection = new(skipCollection);
|
|
notMappedPersonContainers.AddRange(Stateless.MapLogic.GetNotMappedPersonContainers(configuration,
|
|
ticks,
|
|
personContainers,
|
|
readOnlyPersonKeyToCount));
|
|
locationContainers.AddRange(Stateless.MapLogic.GetLocationContainers(maxDegreeOfParallelism,
|
|
propertyConfiguration,
|
|
configuration,
|
|
ticks,
|
|
personContainers,
|
|
readOnlySkipCollection,
|
|
records));
|
|
int lossCount = records.Count - locationContainers.Count;
|
|
int unableToMatchCount = records.Count - personKeyFormattedIdThenWholePercentagesCollection.Count;
|
|
if (lossCount != 0 || unableToMatchCount != 0)
|
|
if (lossCount != 0 || unableToMatchCount != 0)
|
|
{ }
|
|
if (!string.IsNullOrEmpty(a2PeopleContentDirectory) && configuration.LocationContainerDistanceTolerance is not null)
|
|
Stateless.RelationLogic.SaveMappedRelations(configuration, distance, a2PeopleContentDirectory, eDistanceContentDirectory, ticks, locationContainers, readOnlyPersonKeyFormattedToPersonContainer, readOnlyPersonKeyToPersonContainerCollection);
|
|
if (!string.IsNullOrEmpty(configuration.LocationContainerDebugDirectory))
|
|
throw new Exception($"{nameof(configuration.LocationContainerDebugDirectory)} is not IsNullOrEmpty!");
|
|
}
|
|
_PersonKeyToCount = readOnlyPersonKeyToCount;
|
|
_EDistanceContentTicksDirectory = eDistanceContentTicksDirectory;
|
|
_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 bool InSkipCollection(int id, int wholePercentages) =>
|
|
_SkipCollection.TryGetValue(id, out List<int>? wholePercentagesCollection) && wholePercentagesCollection.Contains(wholePercentages);
|
|
|
|
public bool InSkipCollection(int id, MappingFromLocation mappingFromLocation) =>
|
|
InSkipCollection(id, mappingFromLocation.WholePercentages);
|
|
|
|
public void SaveContainers(int? updated, List<SaveContainer> saveContainers)
|
|
{
|
|
if (_Configuration is null)
|
|
throw new NullReferenceException(nameof(_Configuration));
|
|
string fileName;
|
|
string checkFile;
|
|
string sourceFile;
|
|
List<string> distinct = [];
|
|
WindowsShortcut windowsShortcut;
|
|
string[] directories = (from l in saveContainers select l.Directory).Distinct().ToArray();
|
|
int totalSeconds = (int)Math.Floor(new TimeSpan(DateTime.Now.Ticks - _Ticks).TotalSeconds);
|
|
string message;
|
|
if (updated is null)
|
|
message = $") {saveContainers.Count:000} save(s) - {totalSeconds} total second(s)";
|
|
else
|
|
message = $") {saveContainers.Count:000} save(s) - {updated} Updated - {totalSeconds} total second(s)";
|
|
ProgressBarOptions options = new() { ProgressCharacter = '─', ProgressBarOnBottom = true, DisableBottomPercentage = true };
|
|
foreach (string directory in directories)
|
|
{
|
|
if (string.IsNullOrEmpty(directory))
|
|
continue;
|
|
if (!Directory.Exists(directory))
|
|
_ = Directory.CreateDirectory(directory);
|
|
}
|
|
using ProgressBar progressBar = new(saveContainers.Count, message, options);
|
|
foreach (SaveContainer saveContainer in saveContainers)
|
|
{
|
|
progressBar.Tick();
|
|
if (string.IsNullOrEmpty(saveContainer.Directory) || string.IsNullOrEmpty(saveContainer.CheckFile) || saveContainer.FaceFileHolder is null)
|
|
continue;
|
|
if (saveContainer.FacePartsFileHolder is null && saveContainer.HiddenFaceFileHolder is null && saveContainer.ResizedFileHolder is null)
|
|
{
|
|
checkFile = saveContainer.CheckFile;
|
|
sourceFile = saveContainer.FaceFileHolder.FullName;
|
|
}
|
|
else if (!saveContainer.FaceFileHolder.Exists && saveContainer.ResizedFileHolder is not null && saveContainer.ResizedFileHolder.Exists)
|
|
{
|
|
checkFile = saveContainer.CheckFile;
|
|
sourceFile = saveContainer.ResizedFileHolder.FullName;
|
|
}
|
|
else if (saveContainer.FaceFileHolder.Exists)
|
|
{
|
|
sourceFile = saveContainer.FaceFileHolder.FullName;
|
|
checkFile = $"{saveContainer.CheckFile}{_Configuration.FacesFileNameExtension}";
|
|
}
|
|
else
|
|
continue;
|
|
if (_Configuration.SaveIndividually)
|
|
{
|
|
fileName = Path.GetFileName(checkFile);
|
|
if (distinct.Contains(fileName))
|
|
continue;
|
|
distinct.Add(fileName);
|
|
}
|
|
if (File.Exists(checkFile))
|
|
continue;
|
|
File.Copy(sourceFile, checkFile);
|
|
if (_Configuration.SaveIndividually)
|
|
continue;
|
|
if (saveContainer.MakeAllHidden)
|
|
File.SetAttributes(checkFile, FileAttributes.Hidden);
|
|
if (saveContainer.HiddenFaceFileHolder is not null && saveContainer.HiddenFaceFileHolder.Exists)
|
|
{
|
|
sourceFile = saveContainer.HiddenFaceFileHolder.FullName;
|
|
checkFile = $"{saveContainer.CheckFile}{_Configuration.FacesHiddenFileNameExtension}";
|
|
}
|
|
else if (saveContainer.FacePartsFileHolder is not null && saveContainer.FacePartsFileHolder.Exists)
|
|
{
|
|
sourceFile = saveContainer.FacePartsFileHolder.FullName;
|
|
checkFile = $"{saveContainer.CheckFile}{_Configuration.FacePartsFileNameExtension}";
|
|
}
|
|
if (File.Exists(checkFile))
|
|
continue;
|
|
File.Copy(sourceFile, checkFile);
|
|
if (saveContainer.MakeAllHidden)
|
|
File.SetAttributes(checkFile, FileAttributes.Hidden);
|
|
}
|
|
if (updated is null)
|
|
{
|
|
foreach (SaveContainer saveContainer in saveContainers)
|
|
{
|
|
if (string.IsNullOrEmpty(saveContainer.Directory) || string.IsNullOrEmpty(saveContainer.CheckFile) || saveContainer.ResizedFileHolder is null || !saveContainer.ResizedFileHolder.Exists)
|
|
continue;
|
|
checkFile = saveContainer.CheckFile;
|
|
sourceFile = saveContainer.ResizedFileHolder.FullName;
|
|
if (File.Exists(checkFile))
|
|
continue;
|
|
File.Copy(sourceFile, checkFile);
|
|
if (saveContainer.MakeAllHidden)
|
|
File.SetAttributes(checkFile, FileAttributes.Hidden);
|
|
}
|
|
}
|
|
foreach (SaveContainer saveContainer in saveContainers)
|
|
{
|
|
if (string.IsNullOrEmpty(saveContainer.Directory) || string.IsNullOrEmpty(saveContainer.ShortcutFile) || saveContainer.ResizedFileHolder is null || !saveContainer.ResizedFileHolder.Exists)
|
|
continue;
|
|
try
|
|
{
|
|
string description;
|
|
if (saveContainer.FaceFileHolder is not null && saveContainer.FaceFileHolder.Name.StartsWith(saveContainer.ResizedFileHolder.Name))
|
|
description = saveContainer.FaceFileHolder.Name;
|
|
else
|
|
description = saveContainer.ResizedFileHolder.Name;
|
|
windowsShortcut = new() { Path = saveContainer.ResizedFileHolder.FullName, Description = description };
|
|
windowsShortcut.Save(saveContainer.ShortcutFile);
|
|
windowsShortcut.Dispose();
|
|
if (saveContainer.MakeAllHidden)
|
|
File.SetAttributes(saveContainer.ShortcutFile, FileAttributes.Hidden);
|
|
}
|
|
catch (Exception)
|
|
{ }
|
|
}
|
|
}
|
|
|
|
public override string ToString()
|
|
{
|
|
string result = JsonSerializer.Serialize(this, new JsonSerializerOptions() { WriteIndented = true });
|
|
return result;
|
|
}
|
|
|
|
public ReadOnlyDictionary<long, List<int>> GetPersonKeyToIds()
|
|
{
|
|
Dictionary<long, List<int>> results = [];
|
|
long personKey;
|
|
const int zero = 0;
|
|
List<int>? collection;
|
|
PersonBirthday personBirthday;
|
|
List<string> shouldMove = [];
|
|
foreach (KeyValuePair<int, ReadOnlyDictionary<int, ReadOnlyCollection<PersonContainer>>> idToCollection in _IdThenWholePercentagesToPersonContainers)
|
|
{
|
|
foreach (KeyValuePair<int, ReadOnlyCollection<PersonContainer>> wholePercentagesToPersonContainers in idToCollection.Value)
|
|
{
|
|
foreach (PersonContainer personContainer in wholePercentagesToPersonContainers.Value)
|
|
{
|
|
if (personContainer.Key is null || personContainer.Birthdays is null || personContainer.Birthdays.Length == 0)
|
|
continue;
|
|
if (personContainer.DisplayDirectoryName.Contains(@"{}\~\"))
|
|
shouldMove.Add(personContainer.DisplayDirectoryName);
|
|
personBirthday = personContainer.Birthdays[zero];
|
|
personKey = personBirthday.Value.Ticks;
|
|
if (!results.TryGetValue(personKey, out collection))
|
|
{
|
|
results.Add(personKey, []);
|
|
if (!results.TryGetValue(personKey, out collection))
|
|
throw new Exception();
|
|
}
|
|
if (collection.Contains(idToCollection.Key))
|
|
continue;
|
|
collection.Add(idToCollection.Key);
|
|
}
|
|
}
|
|
}
|
|
if (shouldMove.Count > 0)
|
|
throw new Exception(string.Join(Environment.NewLine, shouldMove));
|
|
return results.AsReadOnly();
|
|
}
|
|
|
|
public ReadOnlyCollection<LocationContainer> GetLocationContainers(Item item)
|
|
{
|
|
LocationContainer[] results;
|
|
if (item.ExifDirectory?.FilePath?.Id is null)
|
|
results = [];
|
|
else
|
|
{
|
|
List<LocationContainer>? locationContainers;
|
|
if (_IdToLocationContainers.TryGetValue(item.ExifDirectory.FilePath.Id.Value, out locationContainers))
|
|
results = locationContainers.ToArray();
|
|
else
|
|
results = [];
|
|
}
|
|
return results.AsReadOnly();
|
|
}
|
|
|
|
public ReadOnlyDictionary<int, ReadOnlyCollection<PersonContainer>>? GetWholePercentagesToPersonContainers(int? id)
|
|
{
|
|
ReadOnlyDictionary<int, ReadOnlyCollection<PersonContainer>>? result;
|
|
if (id is null)
|
|
result = null;
|
|
else
|
|
_ = _IdThenWholePercentagesToPersonContainers.TryGetValue(id.Value, out result);
|
|
return result;
|
|
}
|
|
|
|
public List<Sorting> GetSortingCollection(int i, Face face, FaceDistance faceDistanceEncoding, List<FaceDistance> faceDistanceLengths)
|
|
{
|
|
if (_Configuration is null)
|
|
throw new NullReferenceException(nameof(_Configuration));
|
|
List<Sorting> results = [];
|
|
Sorting sorting;
|
|
FaceDistance faceDistanceLength;
|
|
for (int j = 0; j < faceDistanceLengths.Count; j++)
|
|
{
|
|
if (faceDistanceEncoding.WholePercentages is null)
|
|
throw new NotSupportedException();
|
|
if (face.Mapping?.MappingFromFilterPost is null)
|
|
throw new NotSupportedException();
|
|
if (j == i)
|
|
continue;
|
|
if (face.Mapping.MappingFromFilterPre.InSkipCollection is not null && face.Mapping.MappingFromFilterPre.InSkipCollection.Value)
|
|
throw new NotSupportedException(nameof(Shared.Models.Methods.IDistance));
|
|
if (face.Mapping.MappingFromFilterPre.IsFocusModel is not null && !face.Mapping.MappingFromFilterPre.IsFocusModel.Value)
|
|
throw new NotSupportedException(nameof(Shared.Models.Methods.IDistance));
|
|
if (face.Mapping.MappingFromFilterPre.IsFocusRelativePath is not null && !face.Mapping.MappingFromFilterPre.IsFocusRelativePath.Value)
|
|
throw new NotSupportedException(nameof(Shared.Models.Methods.IDistance));
|
|
if (face.Mapping.MappingFromFilterPost.InSkipCollection is not null && face.Mapping.MappingFromFilterPost.InSkipCollection.Value)
|
|
throw new NotSupportedException(nameof(Shared.Models.Methods.IDistance));
|
|
if (face.Mapping.MappingFromFilterPost.IsFocusPerson is not null && !face.Mapping.MappingFromFilterPost.IsFocusPerson.Value)
|
|
throw new NotSupportedException(nameof(Shared.Models.Methods.IDistance));
|
|
if (face.Mapping.MappingFromFilterPost.InSkipCollection is not null && face.Mapping.MappingFromFilterPost.InSkipCollection.Value)
|
|
throw new NotSupportedException(nameof(Shared.Models.Methods.IDistance));
|
|
faceDistanceLength = faceDistanceLengths[j];
|
|
if (faceDistanceLength.WholePercentages is null || faceDistanceLength.Length is null)
|
|
throw new NotSupportedException();
|
|
if (faceDistanceLength.Length == 0)
|
|
continue;
|
|
if (faceDistanceLength.Id == faceDistanceEncoding.Id)
|
|
continue;
|
|
if (faceDistanceLength.MappingFromFilterPost is null)
|
|
throw new NotSupportedException();
|
|
if (faceDistanceLength.MappingFromFilterPost.CanReMap is not null && !_Configuration.ReMap)
|
|
continue;
|
|
if (faceDistanceLength.MappingFromFilterPost.CanReMap is not null && !faceDistanceLength.MappingFromFilterPost.CanReMap.Value)
|
|
continue;
|
|
if (faceDistanceLength.MappingFromFilterPost.InSkipCollection is not null && faceDistanceLength.MappingFromFilterPost.InSkipCollection.Value)
|
|
continue;
|
|
if (faceDistanceLength.MappingFromFilterPost.IsFocusPerson is not null && !faceDistanceLength.MappingFromFilterPost.IsFocusPerson.Value)
|
|
continue;
|
|
sorting = ISorting.Get(_Configuration.FaceDistancePermyriad, faceDistanceEncoding, faceDistanceLength);
|
|
if (sorting.DistancePermyriad == 0)
|
|
continue;
|
|
if (sorting.Id == faceDistanceEncoding.Id)
|
|
{
|
|
if (sorting.WholePercentages == faceDistanceEncoding.WholePercentages.Value)
|
|
continue;
|
|
continue;
|
|
}
|
|
results.Add(sorting);
|
|
}
|
|
return results;
|
|
}
|
|
|
|
public int UpdateMappingFromPerson(ReadOnlyDictionary<int, ReadOnlyCollection<PersonContainer>>? wholePercentagesToPersonContainers, Mapping mapping)
|
|
{
|
|
int result = 0;
|
|
if (mapping.MappingFromLocation is not null)
|
|
{
|
|
if (wholePercentagesToPersonContainers is null)
|
|
result += 1;
|
|
else
|
|
{
|
|
ReadOnlyCollection<PersonContainer>? personContainers;
|
|
if (!wholePercentagesToPersonContainers.TryGetValue(mapping.MappingFromLocation.WholePercentages, out personContainers))
|
|
result += 1;
|
|
else
|
|
{
|
|
const int zero = 0;
|
|
string mappingSegmentB;
|
|
PersonBirthday personBirthday;
|
|
foreach (PersonContainer personContainer in personContainers)
|
|
{
|
|
if (personContainer.Key is null || personContainer.Birthdays is null || personContainer.Birthdays.Length == 0)
|
|
continue;
|
|
personBirthday = personContainer.Birthdays[zero];
|
|
mappingSegmentB = Stateless.MapLogic.GetMappingSegmentB(_Ticks, personBirthday, personContainer.ApproximateYears, mapping.MappingFromItem);
|
|
mapping.UpdateMappingFromPerson(personContainer.ApproximateYears, personContainer.DisplayDirectoryName, personContainer.Key.Value, mappingSegmentB);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
|
|
public bool? IsFocusPerson(int? skipPersonWithMoreThen, long[] jLinkResolvedPersonKeys, ReadOnlyDictionary<int, ReadOnlyCollection<PersonContainer>>? wholePercentagesToPersonContainers, int wholePercentages)
|
|
{
|
|
bool? result;
|
|
ReadOnlyCollection<PersonContainer>? personContainers;
|
|
if (skipPersonWithMoreThen is null && jLinkResolvedPersonKeys.Length == 0)
|
|
result = null;
|
|
else if (wholePercentagesToPersonContainers is null)
|
|
result = null;
|
|
else if (!wholePercentagesToPersonContainers.TryGetValue(wholePercentages, out personContainers))
|
|
result = null;
|
|
else
|
|
{
|
|
result = false;
|
|
foreach (PersonContainer personContainer in personContainers)
|
|
{
|
|
if (personContainer.Key is null)
|
|
continue;
|
|
if (skipPersonWithMoreThen is not null && _PersonKeyToCount.TryGetValue(personContainer.Key.Value, out int count) && count > 2 && count < skipPersonWithMoreThen.Value)
|
|
{
|
|
result = true;
|
|
break;
|
|
}
|
|
if (jLinkResolvedPersonKeys.Contains(personContainer.Key.Value))
|
|
{
|
|
result = true;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
|
|
public void SaveShortcutsForOutputResolutionsPreMapLogic(string eDistanceContentDirectory, ReadOnlyDictionary<long, List<int>> personKeyToIds, ReadOnlyCollection<Mapping> distinctValidImageMappingCollection)
|
|
{
|
|
string hiddenFile;
|
|
WindowsShortcut windowsShortcut;
|
|
List<SaveShortcutsForOutputResolutions> collection = [];
|
|
collection = GetCollectionForSaveShortcutsForOutputResolutionsPreMapLogic(eDistanceContentDirectory, personKeyToIds, distinctValidImageMappingCollection);
|
|
string[] distinctDirectories = (from l in collection select l.Directory).Distinct().ToArray();
|
|
foreach (string directory in distinctDirectories)
|
|
{
|
|
if (string.IsNullOrEmpty(directory))
|
|
continue;
|
|
if (!Directory.Exists(directory))
|
|
_ = Directory.CreateDirectory(directory);
|
|
}
|
|
foreach (SaveShortcutsForOutputResolutions s in collection)
|
|
{
|
|
hiddenFile = $"{s.FileName}.lvs";
|
|
if (File.Exists(hiddenFile))
|
|
continue;
|
|
if (s.Description is not null)
|
|
{
|
|
File.WriteAllLines(hiddenFile, [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<SaveShortcutsForOutputResolutions> GetCollectionForSaveShortcutsForOutputResolutionsPreMapLogic(string eDistanceContentDirectory, ReadOnlyDictionary<long, List<int>> personKeyToIds, ReadOnlyCollection<Mapping> distinctValidImageMappingCollection)
|
|
{
|
|
List<SaveShortcutsForOutputResolutions> results = [];
|
|
if (_Configuration is null)
|
|
throw new NullReferenceException(nameof(_Configuration));
|
|
int season;
|
|
string fileName;
|
|
string directory;
|
|
string weekOfYear;
|
|
DateTime dateTime;
|
|
string description;
|
|
string directoryName;
|
|
List<long>? personKeys;
|
|
string personKeyFormatted;
|
|
Calendar calendar = new CultureInfo("en-US").Calendar;
|
|
ReadOnlyDictionary<int, List<long>> idToPersonKeys = IMapLogic.GetIdToPersonKeys(personKeyToIds);
|
|
foreach (Mapping mapping in distinctValidImageMappingCollection)
|
|
{
|
|
dateTime = mapping.MappingFromItem.GetDateTimeOriginalThenMinimumDateTime();
|
|
description = mapping.MappingFromLocation is null ? mapping.MappingFromItem.Id.ToString() : mapping.MappingFromLocation.DeterministicHashCodeKey;
|
|
(season, _) = IProperty.GetSeason(dateTime.DayOfYear);
|
|
weekOfYear = calendar.GetWeekOfYear(dateTime, CalendarWeekRule.FirstDay, DayOfWeek.Sunday).ToString("00");
|
|
directory = Path.Combine($"{eDistanceContentDirectory}---", "Date Shortcuts", $"{dateTime.Year}.{season}-MM{dateTime.Month:00}-WW{weekOfYear}");
|
|
fileName = Path.Combine(directory, $"{mapping.MappingFromItem.FilePath.Name}.lnk");
|
|
results.Add(new(mapping.MappingFromItem.FilePath.FullName, directory, dateTime, fileName, description, MakeAllHidden: false));
|
|
if (mapping.MappingFromItem.FilePath.DirectoryFullPath is null)
|
|
continue;
|
|
directoryName = Path.GetFileName(mapping.MappingFromItem.FilePath.DirectoryFullPath);
|
|
if (!string.IsNullOrEmpty(mapping.MappingFromItem.Model) && !string.IsNullOrEmpty(mapping.MappingFromItem.Model.Trim()))
|
|
{
|
|
// Remove-Item -LiteralPath "\\?\D:\Tmp\a\EX-Z70 "
|
|
directory = Path.Combine($"{eDistanceContentDirectory}---", "Model Shortcuts", FileSystemSafe().Replace(mapping.MappingFromItem.Model.Trim(), "_"), directoryName);
|
|
fileName = Path.Combine(directory, $"{mapping.MappingFromItem.FilePath.Name}.lnk");
|
|
results.Add(new(mapping.MappingFromItem.FilePath.FullName, directory, dateTime, fileName, description, MakeAllHidden: false));
|
|
}
|
|
if (mapping.MappingFromPerson is null)
|
|
continue;
|
|
if (!idToPersonKeys.TryGetValue(mapping.MappingFromItem.Id, out personKeys))
|
|
continue;
|
|
if (!personKeys.Contains(mapping.MappingFromPerson.PersonKey))
|
|
continue;
|
|
personKeyFormatted = IPersonBirthday.GetFormatted(_Configuration.PersonBirthdayFormat, mapping.MappingFromPerson.PersonKey);
|
|
directory = Path.Combine($"{eDistanceContentDirectory}---", "Person Key Shortcuts", personKeyFormatted, directoryName);
|
|
fileName = Path.Combine(directory, $"{mapping.MappingFromItem.FilePath.Name}.lnk");
|
|
results.Add(new(mapping.MappingFromItem.FilePath.FullName, directory, dateTime, fileName, description, MakeAllHidden: false));
|
|
if (IPerson.IsDefaultName(mapping.MappingFromPerson))
|
|
continue;
|
|
directory = Path.Combine($"{eDistanceContentDirectory}---", "Name Shortcuts", mapping.MappingFromPerson.DisplayDirectoryName, directoryName);
|
|
fileName = Path.Combine(directory, $"{mapping.MappingFromItem.FilePath.Name}.lnk");
|
|
results.Add(new(mapping.MappingFromItem.FilePath.FullName, directory, dateTime, fileName, description, MakeAllHidden: false));
|
|
}
|
|
return results;
|
|
}
|
|
|
|
[GeneratedRegex("[\\\\,\\/,\\:,\\*,\\?,\\\",\\<,\\>,\\|]")]
|
|
private static partial Regex FileSystemSafe();
|
|
|
|
public bool? IsFocusPerson(int? skipPersonWithMoreThen, long[] jLinkResolvedPersonKeys, ReadOnlyDictionary<int, ReadOnlyCollection<PersonContainer>>? wholePercentagesToPersonContainers, MappingFromLocation mappingFromLocation) =>
|
|
IsFocusPerson(skipPersonWithMoreThen, jLinkResolvedPersonKeys, wholePercentagesToPersonContainers, mappingFromLocation.WholePercentages);
|
|
|
|
public void SaveShortcutsForOutputResolutionsDuringMapLogic(ReadOnlyCollection<Container.Models.Container> containers, ReadOnlyDictionary<long, List<int>> personKeyToIds, string dFacesContentDirectory, ReadOnlyCollection<Mapping> distinctValidImageMappingCollection)
|
|
{
|
|
if (_Configuration is null)
|
|
throw new NullReferenceException(nameof(_Configuration));
|
|
WindowsShortcut windowsShortcut;
|
|
List<(string, DateTime[])> directoriesAndDateTimes;
|
|
List<SaveShortcutsForOutputResolutions> collection;
|
|
ReadOnlyCollection<Item> validImageItems = Container.Models.Stateless.Methods.IContainer.GetValidImageItems(_PropertyConfiguration, containers, distinctItems: true, filterItems: true);
|
|
(directoriesAndDateTimes, collection) = GetCollectionForSaveShortcutsForOutputResolutionsDuringMapLogic(personKeyToIds, dFacesContentDirectory, validImageItems, distinctValidImageMappingCollection);
|
|
string[] directories = (from l in collection select l.Directory).Distinct().ToArray();
|
|
foreach (string directory in directories)
|
|
{
|
|
if (string.IsNullOrEmpty(directory))
|
|
continue;
|
|
if (!Directory.Exists(directory))
|
|
_ = Directory.CreateDirectory(directory);
|
|
}
|
|
foreach (SaveShortcutsForOutputResolutions s in collection)
|
|
{
|
|
if (File.Exists(s.FileName))
|
|
continue;
|
|
try
|
|
{
|
|
windowsShortcut = new() { Path = s.FullName, Description = s.Description };
|
|
windowsShortcut.Save(s.FileName);
|
|
windowsShortcut.Dispose();
|
|
if (s.MakeAllHidden)
|
|
File.SetAttributes(s.FileName, FileAttributes.Hidden);
|
|
File.SetLastWriteTime(s.FileName, s.DateTime);
|
|
}
|
|
catch (Exception)
|
|
{ }
|
|
}
|
|
foreach ((string directory, DateTime[] dateTimes) in directoriesAndDateTimes)
|
|
{
|
|
if (dateTimes.Length == 0)
|
|
continue;
|
|
Directory.SetCreationTime(directory, dateTimes[0]);
|
|
Directory.SetLastWriteTime(directory, dateTimes[1]);
|
|
}
|
|
}
|
|
|
|
private (List<(string, DateTime[])>, List<SaveShortcutsForOutputResolutions>) GetCollectionForSaveShortcutsForOutputResolutionsDuringMapLogic(ReadOnlyDictionary<long, List<int>> personKeyToIds, string dFacesContentDirectory, ReadOnlyCollection<Item> validImageItems, ReadOnlyCollection<Mapping> distinctValidImageMappingCollection)
|
|
{
|
|
if (_Configuration is null)
|
|
throw new NullReferenceException(nameof(_Configuration));
|
|
List<int>? ids;
|
|
string fileName;
|
|
string fullName;
|
|
string directory;
|
|
DateTime dateTime;
|
|
string facesDirectory;
|
|
string? directoryName;
|
|
string personDirectory;
|
|
string personKeyFormatted;
|
|
List<string> distinct = [];
|
|
List<SaveShortcutsForOutputResolutions> collection = [];
|
|
List<(string, DateTime[])> directoriesAndDateTimes = [];
|
|
foreach (Item item in validImageItems)
|
|
{
|
|
if (item.ResizedFileHolder is null)
|
|
continue;
|
|
if (item.Faces.Any(l => l.FaceEncoding is not null))
|
|
continue;
|
|
foreach (Face face in item.Faces)
|
|
{
|
|
if (face.Mapping is null)
|
|
continue;
|
|
directoryName = Path.GetDirectoryName(face.Mapping.MappingFromItem.RelativePath);
|
|
if (directoryName is null)
|
|
throw new NotSupportedException();
|
|
if (item.ResizedFileHolder?.DirectoryFullPath is null || !item.ResizedFileHolder.Exists)
|
|
continue;
|
|
directory = Path.Combine(item.ResizedFileHolder.DirectoryFullPath, $"{_PropertyConfiguration.ResultAllInOne}Shortcuts", _PropertyConfiguration.ResultAllInOne);
|
|
personDirectory = Path.Combine(directory, "No Faces");
|
|
fileName = Path.Combine(personDirectory, $"{item.ResizedFileHolder.Name}.lnk");
|
|
collection.Add(new(item.ResizedFileHolder.FullName, personDirectory, new(item.FilePath.LastWriteTicks), fileName, face.Mapping.MappingFromItem.Id.ToString(), MakeAllHidden: false));
|
|
if (face.Mapping.MappingFromItem.ContainerDateTimes.Length > 0 && !distinct.Contains(item.ResizedFileHolder.DirectoryFullPath))
|
|
{
|
|
distinct.Add(item.ResizedFileHolder.DirectoryFullPath);
|
|
directoriesAndDateTimes.Add(new(item.ResizedFileHolder.DirectoryFullPath, face.Mapping.MappingFromItem.ContainerDateTimes));
|
|
}
|
|
}
|
|
}
|
|
foreach (Mapping mapping in distinctValidImageMappingCollection)
|
|
{
|
|
directoryName = Path.GetDirectoryName(mapping.MappingFromItem.RelativePath);
|
|
if (directoryName is null)
|
|
throw new NotSupportedException();
|
|
if (mapping.MappingFromItem.ResizedFileHolder.DirectoryFullPath is null || !mapping.MappingFromItem.ResizedFileHolder.Exists)
|
|
continue;
|
|
dateTime = mapping.MappingFromItem.GetDateTimeOriginalThenMinimumDateTime();
|
|
if (mapping.By is null or Shared.Models.Stateless.IMapLogic.Sorting || mapping.MappingFromPerson?.ApproximateYears is null)
|
|
{
|
|
if (mapping.MappingFromItem.ContainerDateTimes.Length > 0 && !distinct.Contains(mapping.MappingFromItem.ResizedFileHolder.DirectoryFullPath))
|
|
{
|
|
distinct.Add(mapping.MappingFromItem.ResizedFileHolder.DirectoryFullPath);
|
|
directoriesAndDateTimes.Add(new(mapping.MappingFromItem.ResizedFileHolder.DirectoryFullPath, mapping.MappingFromItem.ContainerDateTimes));
|
|
}
|
|
directory = Path.Combine(mapping.MappingFromItem.ResizedFileHolder.DirectoryFullPath, $"{_PropertyConfiguration.ResultAllInOne}Shortcuts", _PropertyConfiguration.ResultAllInOne);
|
|
personDirectory = Path.Combine(directory, "Unknown");
|
|
fileName = Path.Combine(personDirectory, $"{mapping.MappingFromItem.ResizedFileHolder.Name}.lnk");
|
|
collection.Add(new(mapping.MappingFromItem.ResizedFileHolder.FullName, personDirectory, dateTime, fileName, mapping.MappingFromLocation?.DeterministicHashCodeKey, MakeAllHidden: false));
|
|
facesDirectory = Stateless.MapLogic.GetFacesDirectory(_PropertyConfiguration, dFacesContentDirectory, mapping.FilePath, mapping.MappingFromItem);
|
|
if (mapping.MappingFromLocation is null)
|
|
continue;
|
|
fullName = Path.Combine(facesDirectory, $"{mapping.MappingFromLocation.DeterministicHashCodeKey}{mapping.MappingFromItem.FilePath.ExtensionLowered}{_Configuration.FacesFileNameExtension}");
|
|
fileName = Path.Combine(personDirectory, $"{mapping.MappingFromLocation.DeterministicHashCodeKey}{mapping.MappingFromItem.ResizedFileHolder.ExtensionLowered}{_Configuration.FacesFileNameExtension}.lnk");
|
|
collection.Add(new(fullName, personDirectory, dateTime, fileName, mapping.MappingFromLocation.DeterministicHashCodeKey, MakeAllHidden: true));
|
|
}
|
|
else
|
|
{
|
|
if (string.IsNullOrEmpty(mapping.MappingFromPerson.SegmentB))
|
|
throw new NotSupportedException();
|
|
if (string.IsNullOrEmpty(mapping.MappingFromPerson.DisplayDirectoryName))
|
|
throw new NotSupportedException();
|
|
personKeyFormatted = IPersonBirthday.GetFormatted(_Configuration.PersonBirthdayFormat, mapping.MappingFromPerson.PersonKey);
|
|
if (mapping.MappingFromItem.ContainerDateTimes.Length > 0 && !distinct.Contains(mapping.MappingFromItem.ResizedFileHolder.DirectoryFullPath))
|
|
{
|
|
distinct.Add(mapping.MappingFromItem.ResizedFileHolder.DirectoryFullPath);
|
|
directoriesAndDateTimes.Add(new(mapping.MappingFromItem.ResizedFileHolder.DirectoryFullPath, mapping.MappingFromItem.ContainerDateTimes));
|
|
}
|
|
directory = Path.Combine(mapping.MappingFromItem.ResizedFileHolder.DirectoryFullPath, $"{_PropertyConfiguration.ResultAllInOne}Shortcuts", personKeyFormatted);
|
|
if (!personKeyToIds.TryGetValue(mapping.MappingFromPerson.PersonKey, out ids))
|
|
personDirectory = Path.Combine(directory, mapping.MappingFromPerson.DisplayDirectoryName);
|
|
else
|
|
personDirectory = Path.Combine(directory, mapping.MappingFromPerson.DisplayDirectoryName, $"{ids.Count} Face(s)");
|
|
fileName = Path.Combine(directory, $"{mapping.MappingFromItem.ResizedFileHolder.Name}.lnk");
|
|
collection.Add(new(mapping.MappingFromItem.ResizedFileHolder.FullName, personDirectory, dateTime, fileName, mapping.MappingFromLocation?.DeterministicHashCodeKey, MakeAllHidden: false));
|
|
}
|
|
}
|
|
return new(directoriesAndDateTimes, collection);
|
|
}
|
|
|
|
public void SaveFilteredOriginalImagesFromJLinks(string[] jLinks, ReadOnlyCollection<PersonContainer> personContainers, string a2PeopleContentDirectory, ReadOnlyDictionary<long, List<int>> personKeyToIds, ReadOnlyCollection<Mapping> distinctValidImageMappingCollection)
|
|
{
|
|
if (_Configuration is null)
|
|
throw new NullReferenceException(nameof(_Configuration));
|
|
int? updated = null;
|
|
FileHolder fileHolder;
|
|
SaveContainer? saveContainer;
|
|
List<SaveContainer> saveContainers = [];
|
|
FilteredOriginalImage[] filteredOriginalImages = GetCollectionForSaveFilteredOriginalImagesFromJLinks(jLinks, a2PeopleContentDirectory, personContainers, distinctValidImageMappingCollection, personKeyToIds);
|
|
foreach (FilteredOriginalImage filteredOriginalImage in filteredOriginalImages)
|
|
{
|
|
fileHolder = FileHolder.Get(filteredOriginalImage.FilePath);
|
|
saveContainer = new(filteredOriginalImage.PersonDirectory);
|
|
saveContainers.Add(saveContainer);
|
|
saveContainer = new(fileHolder, filteredOriginalImage.CheckFile, filteredOriginalImage.Directory);
|
|
saveContainers.Add(saveContainer);
|
|
}
|
|
SaveContainers(updated, saveContainers);
|
|
}
|
|
|
|
private FilteredOriginalImage[] GetCollectionForSaveFilteredOriginalImagesFromJLinks(string[] jLinks, string a2PeopleContentDirectory, ReadOnlyCollection<PersonContainer> personContainers, ReadOnlyCollection<Mapping> distinctValidImageMappingCollection, ReadOnlyDictionary<long, List<int>> personKeyToIds)
|
|
{
|
|
if (_Configuration is null)
|
|
throw new NullReferenceException(nameof(_Configuration));
|
|
FilteredOriginalImage[] results;
|
|
int count = 0;
|
|
int group = 65;
|
|
string checkFile;
|
|
string directory;
|
|
string? directoryName;
|
|
string personDirectory;
|
|
string personKeyFormatted;
|
|
List<int> distinctCollection = [];
|
|
bool usePersonKeyAndDeterministicHashCodeKey = false;
|
|
List<FilteredOriginalImage> filteredOriginalImages = [];
|
|
List<string> personKeyFormattedCollection = GetPersonKeyFormattedCollection(jLinks, a2PeopleContentDirectory, personContainers, personKeyToIds);
|
|
foreach (Mapping mapping in distinctValidImageMappingCollection)
|
|
{
|
|
if (distinctCollection.Contains(mapping.MappingFromItem.Id))
|
|
continue;
|
|
directoryName = Path.GetDirectoryName(mapping.MappingFromItem.RelativePath);
|
|
if (directoryName is null)
|
|
throw new NotSupportedException();
|
|
if (mapping.By is null or Shared.Models.Stateless.IMapLogic.Sorting)
|
|
continue;
|
|
if (mapping.MappingFromPerson is null || mapping.MappingFromLocation is null)
|
|
continue;
|
|
if (string.IsNullOrEmpty(mapping.MappingFromPerson.SegmentB))
|
|
throw new NotSupportedException();
|
|
if (string.IsNullOrEmpty(mapping.MappingFromPerson.DisplayDirectoryName))
|
|
throw new NotSupportedException();
|
|
personKeyFormatted = IPersonBirthday.GetFormatted(_Configuration.PersonBirthdayFormat, mapping.MappingFromPerson.PersonKey);
|
|
if (personKeyFormatted == "1501-04-10_00")
|
|
continue;
|
|
if (!personKeyFormattedCollection.Contains(personKeyFormatted))
|
|
continue;
|
|
if (!usePersonKeyAndDeterministicHashCodeKey)
|
|
{
|
|
if (count > 499)
|
|
{
|
|
count = 0;
|
|
group += 1;
|
|
}
|
|
directory = Path.Combine(_EDistanceContentTicksDirectory, ((char)group).ToString());
|
|
personDirectory = Path.Combine(directory, mapping.MappingFromPerson.DisplayDirectoryName);
|
|
checkFile = Path.Combine(directory, $"{mapping.MappingFromItem.Id}{mapping.MappingFromItem.FilePath.ExtensionLowered}");
|
|
}
|
|
else
|
|
{
|
|
directory = Path.Combine(_EDistanceContentTicksDirectory, "Images", personKeyFormatted);
|
|
personDirectory = Path.Combine(directory, mapping.MappingFromPerson.DisplayDirectoryName);
|
|
checkFile = Path.Combine(directory, $"{mapping.MappingFromLocation.DeterministicHashCodeKey}{mapping.MappingFromItem.FilePath.ExtensionLowered}");
|
|
}
|
|
if (mapping is null)
|
|
continue;
|
|
if (mapping.MappingFromPerson.ApproximateYears is null)
|
|
filteredOriginalImages.Add(new(mapping.MappingFromItem.Id, mapping.MappingFromItem.FilePath, -1, personKeyFormatted, directory, personDirectory, checkFile));
|
|
else
|
|
filteredOriginalImages.Add(new(mapping.MappingFromItem.Id, mapping.MappingFromItem.FilePath, mapping.MappingFromPerson.ApproximateYears.Value, personKeyFormatted, directory, personDirectory, checkFile));
|
|
distinctCollection.Add(mapping.MappingFromItem.Id);
|
|
count += 1;
|
|
}
|
|
results = (from l in filteredOriginalImages orderby l.ApproximateYears descending, l.PersonKeyFormatted descending select l).ToArray();
|
|
return results;
|
|
}
|
|
|
|
private List<string> GetPersonKeyFormattedCollection(string[] jLinks, string a2PeopleContentDirectory, ReadOnlyCollection<PersonContainer> personContainers, ReadOnlyDictionary<long, List<int>> personKeyToIds)
|
|
{
|
|
if (_Configuration is null)
|
|
throw new NullReferenceException(nameof(_Configuration));
|
|
List<string> results = [];
|
|
string[] files;
|
|
List<int>? ids;
|
|
string checkDirectory;
|
|
string[] checkDirectories;
|
|
string personKeyFormatted;
|
|
PersonContainer[] matches;
|
|
PersonBirthday? personBirthday;
|
|
string fileNameWithoutExtension;
|
|
WindowsShortcut windowsShortcut;
|
|
List<(long, string)> collection = [];
|
|
foreach (string directoryName in jLinks)
|
|
{
|
|
checkDirectory = Path.Combine(a2PeopleContentDirectory, directoryName);
|
|
if (!Directory.Exists(checkDirectory))
|
|
continue;
|
|
checkDirectories = Directory.GetDirectories(checkDirectory, "*", SearchOption.TopDirectoryOnly);
|
|
files = Directory.GetFiles(checkDirectory, "*.lnk", SearchOption.TopDirectoryOnly);
|
|
foreach (string file in files)
|
|
{
|
|
collection.Clear();
|
|
windowsShortcut = WindowsShortcut.Load(file);
|
|
fileNameWithoutExtension = Path.GetFileNameWithoutExtension(file);
|
|
if (string.IsNullOrEmpty(windowsShortcut.Path))
|
|
continue;
|
|
if (!Directory.Exists(windowsShortcut.Path))
|
|
{
|
|
if (files.Length != checkDirectories.Length)
|
|
throw new NotSupportedException(fileNameWithoutExtension);
|
|
continue;
|
|
}
|
|
(personKeyFormatted, personBirthday) = GetPersonBirthday(windowsShortcut.Path);
|
|
if (personBirthday is null)
|
|
throw new NotSupportedException(fileNameWithoutExtension);
|
|
if (!personKeyToIds.TryGetValue(personBirthday.Value.Ticks, out ids))
|
|
collection.Add(new(personBirthday.Value.Ticks, Path.Combine(checkDirectory, personKeyFormatted, fileNameWithoutExtension)));
|
|
else
|
|
collection.Add(new(personBirthday.Value.Ticks, Path.Combine(checkDirectory, personKeyFormatted, fileNameWithoutExtension, $"{ids.Count} Face(s)")));
|
|
foreach ((long personKey, string displayDirectoryName) in collection)
|
|
{
|
|
matches = (from l in personContainers where l.Key == personKey select l).ToArray();
|
|
if (matches.Length == 0)
|
|
continue;
|
|
personKeyFormatted = IPersonBirthday.GetFormatted(_Configuration.PersonBirthdayFormat, personKey);
|
|
if (!displayDirectoryName.Contains(personKeyFormatted))
|
|
continue;
|
|
if (!Directory.Exists(displayDirectoryName))
|
|
_ = Directory.CreateDirectory(displayDirectoryName);
|
|
results.Add(personKeyFormatted);
|
|
}
|
|
}
|
|
}
|
|
return results;
|
|
}
|
|
|
|
private (string, PersonBirthday?) GetPersonBirthday(string[] directoryNames)
|
|
{
|
|
if (_Configuration is null)
|
|
throw new NullReferenceException(nameof(_Configuration));
|
|
PersonBirthday? personBirthday = null;
|
|
string personKeyFormatted = string.Empty;
|
|
foreach (string directoryName in directoryNames)
|
|
{
|
|
personBirthday = IPersonBirthday.GetPersonBirthday(_Configuration.PersonBirthdayFormat, directoryName);
|
|
if (personBirthday is not null)
|
|
{
|
|
personKeyFormatted = directoryName;
|
|
break;
|
|
}
|
|
}
|
|
return new(personKeyFormatted, personBirthday);
|
|
}
|
|
|
|
private (string, PersonBirthday?) GetPersonBirthday(string windowsShortcutPath)
|
|
{
|
|
if (_Configuration is null)
|
|
throw new NullReferenceException(nameof(_Configuration));
|
|
string[] directoryNames = IPath.GetDirectoryNames(windowsShortcutPath);
|
|
(string personKeyFormatted, PersonBirthday? personBirthday) = GetPersonBirthday(directoryNames);
|
|
if (personBirthday is null)
|
|
{
|
|
string[] directories = Directory.GetDirectories(windowsShortcutPath, "*", SearchOption.TopDirectoryOnly);
|
|
foreach (string directory in directories)
|
|
{
|
|
directoryNames = IPath.GetDirectoryNames(directory);
|
|
(personKeyFormatted, personBirthday) = GetPersonBirthday(directoryNames);
|
|
if (personBirthday is not null)
|
|
break;
|
|
}
|
|
}
|
|
return new(personKeyFormatted, personBirthday);
|
|
}
|
|
|
|
public int UpdateFromSortingContainers(string dFacesContentDirectory, string d2FacePartsContentDirectory, string d2FacePartsContentCollectionDirectory, ReadOnlyDictionary<int, ReadOnlyDictionary<int, Mapping>> idToWholePercentagesToMapping, ReadOnlyCollection<SortingContainer> sortingContainers)
|
|
{
|
|
if (_Configuration is null)
|
|
throw new NullReferenceException(nameof(_Configuration));
|
|
int result = 0;
|
|
string key;
|
|
string segmentB;
|
|
string? segmentC;
|
|
string personKeyFormatted;
|
|
MappingFromPerson mappingFromPerson;
|
|
Dictionary<string, int> keyToCount = [];
|
|
foreach (SortingContainer sortingContainer in sortingContainers)
|
|
{
|
|
if (sortingContainer.Question is null)
|
|
continue;
|
|
if (sortingContainer.Source.MappingFromPerson is null)
|
|
{
|
|
sortingContainer.Question.UpdateMappingFromUnknownPerson(_Configuration.SaveIndividually, sortingContainer);
|
|
result += 1;
|
|
}
|
|
else
|
|
{
|
|
mappingFromPerson = sortingContainer.Source.MappingFromPerson;
|
|
personKeyFormatted = IPersonBirthday.GetFormatted(_Configuration.PersonBirthdayFormat, mappingFromPerson.PersonKey);
|
|
segmentB = IMapLogic.GetDecade(sortingContainer.Question.MappingFromItem);
|
|
key = string.Concat(personKeyFormatted, '\t', segmentB);
|
|
if (!keyToCount.ContainsKey(key))
|
|
keyToCount.Add(key, new());
|
|
_ = keyToCount.TryAdd(key, 0);
|
|
keyToCount[key]++;
|
|
if (!_Configuration.SaveIndividually && keyToCount[key] <= _Configuration.SortingMaximumPerKey)
|
|
segmentC = null;
|
|
else
|
|
segmentC = sortingContainer.Sorting.DistancePermyriad.ToString();
|
|
sortingContainer.Question.UpdateMappingFromPerson(mappingFromPerson.ApproximateYears, mappingFromPerson.DisplayDirectoryName, mappingFromPerson.PersonKey, segmentB, segmentC, sortingContainer);
|
|
result += 1;
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
|
|
public void LookForAbandoned(Property.Models.Configuration propertyConfiguration, string bResultsFullGroupDirectory, ReadOnlyCollection<Container.Models.Container> readOnlyContainers, string cResultsFullGroupDirectory, string dResultsFullGroupDirectory, string d2ResultsFullGroupDirectory, Action? tick)
|
|
{
|
|
string[] directories;
|
|
string? directoryName;
|
|
List<int> distinctFilteredIds = Container.Models.Stateless.Methods.IContainer.GetFilteredDistinctIds(propertyConfiguration, readOnlyContainers);
|
|
LookForAbandoned(propertyConfiguration, distinctFilteredIds);
|
|
tick?.Invoke();
|
|
List<string> distinctFilteredFileNameFirstSegments = Container.Models.Stateless.Methods.IContainer.GetFilteredDistinctFileNameFirstSegments(propertyConfiguration, readOnlyContainers);
|
|
Stateless.LookForAbandonedLogic.LookForAbandoned(propertyConfiguration, bResultsFullGroupDirectory, distinctFilteredFileNameFirstSegments);
|
|
tick?.Invoke();
|
|
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.LookForAbandonedLogic.LookForAbandoned(propertyConfiguration, distinctFilteredFileNameFirstSegments, directory, directoryName);
|
|
}
|
|
tick?.Invoke();
|
|
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.LookForAbandonedLogic.LookForAbandoned(propertyConfiguration, distinctFilteredFileNameFirstSegments, directory, directoryName);
|
|
}
|
|
tick?.Invoke();
|
|
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.LookForAbandonedLogic.LookForAbandoned(propertyConfiguration, distinctFilteredFileNameFirstSegments, directory, directoryName);
|
|
}
|
|
tick?.Invoke();
|
|
}
|
|
|
|
private void LookForAbandoned(Property.Models.Configuration propertyConfiguration, List<int> distinctFilteredIds)
|
|
{
|
|
List<string> renameCollection = [];
|
|
foreach (KeyValuePair<int, List<LocationContainer>> keyValuePair in _IdToLocationContainers)
|
|
{
|
|
if (distinctFilteredIds.Contains(keyValuePair.Key))
|
|
continue;
|
|
foreach (LocationContainer locationContainer in keyValuePair.Value)
|
|
{
|
|
if (locationContainer.FilePath.FullName.Contains('!'))
|
|
continue;
|
|
renameCollection.Add(locationContainer.FilePath.FullName);
|
|
}
|
|
}
|
|
if (renameCollection.Count > 0)
|
|
IDirectory.MoveFiles(renameCollection, propertyConfiguration.ResultContent, "(abd)");
|
|
}
|
|
|
|
public List<SaveContainer> GetSaveContainers(string cResultsFullGroupDirectory, string dResultsFullGroupDirectory, string d2ResultsFullGroupDirectory, Shared.Models.Methods.IDistanceLimits distanceLimits, ReadOnlyDictionary<string, LocationContainer> onlyOne, ReadOnlyDictionary<long, PersonContainer> personKeyToPersonContainer)
|
|
{
|
|
if (_Configuration is null)
|
|
throw new NullReferenceException(nameof(_Configuration));
|
|
List<SaveContainer> results = [];
|
|
string by;
|
|
Record record;
|
|
string segmentB;
|
|
bool isBySorting;
|
|
string checkFile;
|
|
string? directory;
|
|
string shortcutFile;
|
|
string facesDirectory;
|
|
bool isCounterPersonYear;
|
|
string facePartsDirectory;
|
|
FileHolder? faceFileHolder;
|
|
SaveContainer? saveContainer;
|
|
string? displayDirectoryName;
|
|
FileHolder? resizedFileHolder;
|
|
int? useFiltersCounter = null;
|
|
string resizeContentDirectory;
|
|
FileHolder? facePartsFileHolder;
|
|
FileHolder? hiddenFaceFileHolder;
|
|
LocationContainer locationContainer;
|
|
bool sortingContainersAny = onlyOne.Count > 0;
|
|
string cContentDirectory = Path.Combine(cResultsFullGroupDirectory, _Configuration.PropertyConfiguration.ResultContent);
|
|
string forceSingleImageHumanized = nameof(Shared.Models.Stateless.IMapLogic.ForceSingleImage).Humanize(LetterCasing.Title);
|
|
string d2FacePartsContentDirectory = Path.Combine(d2ResultsFullGroupDirectory, _Configuration.PropertyConfiguration.ResultContent);
|
|
foreach (KeyValuePair<string, LocationContainer> keyValuePair in onlyOne)
|
|
{
|
|
if (_Configuration.SaveIndividually)
|
|
break;
|
|
locationContainer = keyValuePair.Value;
|
|
if (locationContainer.LengthPermyriad is null || locationContainer.LengthSource is null)
|
|
continue;
|
|
segmentB = locationContainer.LengthPermyriad.Value.ToString().PadLeft(2, '0')[..2];
|
|
displayDirectoryName = GetDisplayDirectoryName(locationContainer.DisplayDirectoryName, locationContainer, personKeyToPersonContainer);
|
|
isCounterPersonYear = locationContainer.PersonKey is not null && IPersonBirthday.IsCounterPersonYear(locationContainer.PersonKey.Value);
|
|
(by, _, isBySorting) = Stateless.MapLogic.Get(useFiltersCounter, _Configuration.SaveIndividually, sortingContainersAny, forceSingleImageHumanized, locationContainer.LengthPermyriad, locationContainer.PersonKey, displayDirectoryName);
|
|
record = Get(_Configuration, by, locationContainer, displayDirectoryName, segmentB);
|
|
if (string.IsNullOrEmpty(record.Directory) || string.IsNullOrEmpty(record.PersonDirectory))
|
|
continue;
|
|
directory = record.Directory;
|
|
if (!string.IsNullOrEmpty(record.DebugDirectory))
|
|
results.Add(new(record.DebugDirectory));
|
|
if (locationContainer.PersonKey is null)
|
|
{
|
|
if (!_Configuration.SaveSortingWithoutPerson)
|
|
throw new NotSupportedException();
|
|
if (record.Ticks is null)
|
|
continue;
|
|
}
|
|
results.Add(new(record.PersonDirectory));
|
|
facesDirectory = locationContainer.LengthSource.DirectoryFullPath;
|
|
faceFileHolder = IFileHolder.Get(locationContainer.LengthSource.FullName);
|
|
checkFile = Path.Combine(directory, $"{locationContainer.LengthSource.Name}");
|
|
shortcutFile = Path.Combine(record.PersonDirectory, $"{locationContainer.LengthSource.Name}.lnk");
|
|
resizeContentDirectory = Stateless.MapLogic.GetResizeContentDirectory(_PropertyConfiguration, cContentDirectory, locationContainer.LengthSource);
|
|
facePartsDirectory = Stateless.MapLogic.GetFacePartsDirectoryX(_PropertyConfiguration, d2FacePartsContentDirectory, locationContainer.LengthSource);
|
|
hiddenFaceFileHolder = IFileHolder.Get(Path.Combine(facesDirectory, $"{locationContainer.LengthSource.NameWithoutExtension}{_Configuration.FacesHiddenFileNameExtension}"));
|
|
facePartsFileHolder = IFileHolder.Get(Path.Combine(facePartsDirectory, $"{locationContainer.LengthSource.NameWithoutExtension}{_Configuration.FacePartsFileNameExtension}"));
|
|
resizedFileHolder = IFileHolder.Get(Path.Combine(resizeContentDirectory, $"{locationContainer.LengthSource.FileNameFirstSegment}{Path.GetExtension(locationContainer.LengthSource.NameWithoutExtension)}"));
|
|
saveContainer = new(checkFile, directory, faceFileHolder, hiddenFaceFileHolder, facePartsFileHolder, resizedFileHolder, shortcutFile);
|
|
results.Add(saveContainer);
|
|
}
|
|
return results;
|
|
}
|
|
|
|
private string? GetDisplayDirectoryName(string? displayDirectoryName, LocationContainer locationContainer, ReadOnlyDictionary<long, PersonContainer> personKeyToPersonContainer)
|
|
{
|
|
string? result = displayDirectoryName;
|
|
if (personKeyToPersonContainer.Count != 0)
|
|
{
|
|
ReadOnlyDictionary<int, ReadOnlyCollection<PersonContainer>>? wholePercentagesToPersonContainers = GetWholePercentagesToPersonContainers(locationContainer.Id);
|
|
if (wholePercentagesToPersonContainers is not null)
|
|
{
|
|
foreach (KeyValuePair<int, ReadOnlyCollection<PersonContainer>> keyValuePair in wholePercentagesToPersonContainers)
|
|
{
|
|
if (keyValuePair.Key != locationContainer.WholePercentages)
|
|
continue;
|
|
if (keyValuePair.Value.Count != 1)
|
|
continue;
|
|
result = keyValuePair.Value[0].DisplayDirectoryName;
|
|
}
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
|
|
private Record Get(Configuration configuration, bool saveIndividually, int padLeft, string by, Mapping question)
|
|
{
|
|
long? ticks;
|
|
string? directory;
|
|
string? debugDirectory;
|
|
string? personDirectory;
|
|
if (question.MappingFromPerson is null)
|
|
{
|
|
debugDirectory = null;
|
|
(ticks, directory) = GetDirectory(configuration, saveIndividually, padLeft, question.SegmentC, by, question.MappingFromItem);
|
|
personDirectory = directory is null ? null : Path.Combine(directory, $"X+{ticks}");
|
|
}
|
|
else
|
|
{
|
|
ticks = null;
|
|
string personKeyFormatted = IPersonBirthday.GetFormatted(configuration.PersonBirthdayFormat, question.MappingFromPerson.PersonKey);
|
|
debugDirectory = Path.Combine(_EDistanceContentTicksDirectory, by, personKeyFormatted, question.MappingFromPerson.DisplayDirectoryName);
|
|
if (string.IsNullOrEmpty(question.SegmentC))
|
|
directory = Path.Combine(_EDistanceContentTicksDirectory, by, personKeyFormatted, question.MappingFromPerson.SegmentB);
|
|
else if (!saveIndividually)
|
|
directory = Path.Combine(_EDistanceContentTicksDirectory, by, personKeyFormatted, $"Z-{question.MappingFromPerson.SegmentB}-{question.SegmentC}");
|
|
else
|
|
directory = Path.Combine(_EDistanceContentTicksDirectory, by, question.SegmentC.PadLeft(padLeft, '0'), personKeyFormatted, question.MappingFromPerson.SegmentB);
|
|
personDirectory = Path.Combine(directory, question.MappingFromPerson.DisplayDirectoryName, "lnk");
|
|
}
|
|
return new(debugDirectory, directory, ticks, personDirectory);
|
|
}
|
|
|
|
private Record Get(Configuration configuration, string by, LocationContainer locationContainer, string? displayDirectoryName, string segmentB)
|
|
{
|
|
long? ticks;
|
|
string? directory;
|
|
string? debugDirectory;
|
|
string? personDirectory;
|
|
if (locationContainer.PersonKey is null || string.IsNullOrEmpty(displayDirectoryName))
|
|
{
|
|
debugDirectory = null;
|
|
(ticks, directory) = GetDirectory(configuration, by, locationContainer, segmentB);
|
|
personDirectory = directory is null ? null : Path.Combine(directory, $"X+{ticks}");
|
|
}
|
|
else
|
|
{
|
|
ticks = null;
|
|
string personKeyFormatted = IPersonBirthday.GetFormatted(configuration.PersonBirthdayFormat, locationContainer.PersonKey.Value);
|
|
debugDirectory = Path.Combine(_EDistanceContentTicksDirectory, by, personKeyFormatted, displayDirectoryName);
|
|
directory = Path.Combine(_EDistanceContentTicksDirectory, by, personKeyFormatted, segmentB);
|
|
personDirectory = Path.Combine(directory, displayDirectoryName, "lnk");
|
|
}
|
|
return new(debugDirectory, directory, ticks, personDirectory);
|
|
}
|
|
|
|
private (long?, string?) GetDirectory(Configuration configuration, string by, LocationContainer _, string segmentB)
|
|
{
|
|
long? ticks = null;
|
|
const int zero = 0;
|
|
string? directory = null;
|
|
string personKeyFormatted;
|
|
PersonBirthday personBirthday;
|
|
PersonContainer personContainer;
|
|
for (int i = _NotMappedPersonContainers.Count - 1; i > 0; i--)
|
|
{
|
|
if (configuration.SaveIndividually)
|
|
break;
|
|
personContainer = _NotMappedPersonContainers[i];
|
|
if (personContainer.Key is null || personContainer.Birthdays is null || personContainer.Birthdays.Length == 0)
|
|
continue;
|
|
personBirthday = personContainer.Birthdays[zero];
|
|
ticks = personBirthday.Value.Ticks;
|
|
personKeyFormatted = IPersonBirthday.GetFormatted(configuration.PersonBirthdayFormat, personBirthday);
|
|
directory = Path.Combine(_EDistanceContentTicksDirectory, by, personKeyFormatted, segmentB);
|
|
_NotMappedPersonContainers.RemoveAt(i);
|
|
break;
|
|
}
|
|
return (ticks, directory);
|
|
}
|
|
|
|
private (long?, string?) GetDirectory(Configuration configuration, bool saveIndividually, int padLeft, string? segmentC, string by, MappingFromItem mappingFromItem)
|
|
{
|
|
long? ticks = null;
|
|
const int zero = 0;
|
|
string mappingSegmentB;
|
|
string? directory = null;
|
|
string personKeyFormatted;
|
|
PersonBirthday personBirthday;
|
|
PersonContainer personContainer;
|
|
for (int i = _NotMappedPersonContainers.Count - 1; i > 0; i--)
|
|
{
|
|
personContainer = _NotMappedPersonContainers[i];
|
|
if (personContainer.Key is null || personContainer.Birthdays is null || personContainer.Birthdays.Length == 0)
|
|
continue;
|
|
personBirthday = personContainer.Birthdays[zero];
|
|
ticks = personBirthday.Value.Ticks;
|
|
mappingSegmentB = Stateless.MapLogic.GetMappingSegmentB(_Ticks, personBirthday, personContainer.ApproximateYears, mappingFromItem);
|
|
personKeyFormatted = IPersonBirthday.GetFormatted(configuration.PersonBirthdayFormat, personBirthday);
|
|
if (!saveIndividually || segmentC is null)
|
|
directory = Path.Combine(_EDistanceContentTicksDirectory, by, personKeyFormatted, mappingSegmentB);
|
|
else
|
|
directory = Path.Combine(_EDistanceContentTicksDirectory, by, segmentC.PadLeft(padLeft, '0'), personKeyFormatted, mappingSegmentB);
|
|
_NotMappedPersonContainers.RemoveAt(i);
|
|
break;
|
|
}
|
|
return (ticks, directory);
|
|
}
|
|
|
|
public void SaveMapped(string dFacesContentDirectory, string d2FacePartsContentDirectory, string d2FacePartsContentCollectionDirectory, ReadOnlyDictionary<long, List<int>> personKeyToIds, ReadOnlyCollection<Mapping> distinctValidImageMappingCollection, ReadOnlyDictionary<int, ReadOnlyDictionary<int, Mapping>> idToWholePercentagesToMapping)
|
|
{
|
|
if (_Configuration is null)
|
|
throw new NullReferenceException(nameof(_Configuration));
|
|
int? updated = null;
|
|
bool saveMapped = true;
|
|
int? useFiltersCounter = null;
|
|
string mappingDirectory = Path.Combine(_EDistanceContentTicksDirectory, nameof(Shared.Models.Stateless.IMapLogic.Mapping));
|
|
List<SaveContainer> saveContainers = GetSaveContainers(dFacesContentDirectory, d2FacePartsContentDirectory, distinctValidImageMappingCollection, idToWholePercentagesToMapping, personKeyToIds, useFiltersCounter, saveMapped, sortingContainersAny: true, saveIndividually: false);
|
|
SaveContainers(updated, saveContainers);
|
|
if (!string.IsNullOrEmpty(_EDistanceContentTicksDirectory) && Directory.Exists(mappingDirectory))
|
|
Stateless.MapLogic.SaveMappingShortcuts(mappingDirectory);
|
|
}
|
|
|
|
private List<SaveContainer> GetSaveContainers(string dFacesContentDirectory, string d2FacePartsContentDirectory, ReadOnlyCollection<Mapping> distinctValidImageMappingCollection, ReadOnlyDictionary<int, ReadOnlyDictionary<int, Mapping>> idToWholePercentagesToMapping, ReadOnlyDictionary<long, List<int>> personKeyToIds, int? useFiltersCounter, bool saveMapped, bool saveIndividually, bool sortingContainersAny)
|
|
{
|
|
if (_Configuration is null)
|
|
throw new NullReferenceException(nameof(_Configuration));
|
|
List<SaveContainer> results = [];
|
|
string by;
|
|
Record record;
|
|
List<int>? ids;
|
|
bool isByMapping;
|
|
bool isBySorting;
|
|
Sorting? sorting;
|
|
string checkFile;
|
|
Mapping? question;
|
|
string? directory;
|
|
string shortcutFile;
|
|
string facesDirectory;
|
|
FileHolder faceFileHolder;
|
|
string facePartsDirectory;
|
|
SaveContainer? saveContainer;
|
|
int? distancePermyriad = null;
|
|
FileHolder facePartsFileHolder;
|
|
FileHolder hiddenFaceFileHolder;
|
|
ReadOnlyDictionary<int, Mapping>? wholePercentagesToMapping;
|
|
int padLeft = _Configuration.FaceDistancePermyriad.ToString().Length;
|
|
string forceSingleImageHumanized = nameof(Shared.Models.Stateless.IMapLogic.ForceSingleImage).Humanize(LetterCasing.Title);
|
|
foreach (Mapping mapping in distinctValidImageMappingCollection)
|
|
{
|
|
if (mapping.MappingFromLocation is null)
|
|
continue;
|
|
if (mapping.MappingFromFilterPre.InSkipCollection is not null && mapping.MappingFromFilterPre.InSkipCollection.Value)
|
|
continue;
|
|
if (mapping.MappingFromFilterPre.IsFocusModel is not null && !mapping.MappingFromFilterPre.IsFocusModel.Value)
|
|
continue;
|
|
if (mapping.MappingFromFilterPre.IsFocusRelativePath is not null && !mapping.MappingFromFilterPre.IsFocusRelativePath.Value)
|
|
continue;
|
|
if (mapping.MappingFromFilterPost.InSkipCollection is not null && mapping.MappingFromFilterPost.InSkipCollection.Value)
|
|
continue;
|
|
if (mapping.MappingFromFilterPost.IsFocusPerson is not null && !mapping.MappingFromFilterPost.IsFocusPerson.Value)
|
|
continue;
|
|
(by, isByMapping, isBySorting) = Stateless.MapLogic.Get(useFiltersCounter, saveIndividually, sortingContainersAny, forceSingleImageHumanized, distancePermyriad, mapping);
|
|
if (isByMapping && !saveMapped)
|
|
continue;
|
|
if (!isBySorting || mapping.SortingContainer is null)
|
|
(sorting, question) = (null, null);
|
|
else
|
|
{
|
|
sorting = mapping.SortingContainer.Sorting;
|
|
if (!idToWholePercentagesToMapping.TryGetValue(sorting.Id, out wholePercentagesToMapping))
|
|
throw new NotSupportedException();
|
|
if (!wholePercentagesToMapping.TryGetValue(sorting.WholePercentages, out question))
|
|
throw new NotSupportedException();
|
|
if (!PreAndPostContinue(_Configuration, mapping, question))
|
|
continue;
|
|
}
|
|
record = Get(_Configuration, saveIndividually, padLeft, by, mapping);
|
|
if (string.IsNullOrEmpty(record.Directory) || string.IsNullOrEmpty(record.PersonDirectory))
|
|
continue;
|
|
directory = record.Directory;
|
|
if (mapping.MappingFromPerson is not null)
|
|
{
|
|
if (saveIndividually)
|
|
{
|
|
directory = Path.Combine(directory, mapping.MappingFromItem.Id.ToString());
|
|
results.Add(new(Path.Combine(directory, mapping.MappingFromPerson.DisplayDirectoryName)));
|
|
}
|
|
if (isByMapping && personKeyToIds.TryGetValue(mapping.MappingFromPerson.PersonKey, out ids))
|
|
results.Add(new(Path.Combine(directory, mapping.MappingFromPerson.DisplayDirectoryName, $"{ids.Count} Face(s)")));
|
|
}
|
|
else
|
|
{
|
|
if (!_Configuration.SaveSortingWithoutPerson)
|
|
continue;
|
|
if (record.Ticks is null)
|
|
continue;
|
|
if (saveIndividually)
|
|
{
|
|
directory = Path.Combine(directory, mapping.MappingFromItem.Id.ToString());
|
|
results.Add(new(Path.Combine(directory, $"X+{record.Ticks}")));
|
|
}
|
|
}
|
|
results.Add(new(record.PersonDirectory));
|
|
if (question is not null)
|
|
{
|
|
if (question.MappingFromLocation is null)
|
|
continue;
|
|
if (saveIndividually && question.MappingFromLocation.WholePercentages == mapping.MappingFromLocation.WholePercentages)
|
|
results.Add(new(Path.Combine(directory, "Maybe")));
|
|
}
|
|
facesDirectory = Stateless.MapLogic.GetFacesDirectory(_PropertyConfiguration, dFacesContentDirectory, mapping.FilePath, mapping.MappingFromItem);
|
|
faceFileHolder = IFileHolder.Get(Path.Combine(facesDirectory, $"{mapping.MappingFromLocation.DeterministicHashCodeKey}{mapping.MappingFromItem.FilePath.ExtensionLowered}{_Configuration.FacesFileNameExtension}"));
|
|
if (!faceFileHolder.Exists)
|
|
continue;
|
|
if (isByMapping)
|
|
{
|
|
checkFile = Path.Combine(record.PersonDirectory, $"{mapping.MappingFromLocation.DeterministicHashCodeKey}{mapping.MappingFromItem.FilePath.ExtensionLowered}");
|
|
saveContainer = new(checkFile, directory, faceFileHolder);
|
|
}
|
|
else if (saveIndividually)
|
|
{
|
|
facePartsDirectory = Stateless.MapLogic.GetFacePartsDirectory(_PropertyConfiguration, d2FacePartsContentDirectory, mapping.FilePath, mapping.MappingFromItem);
|
|
facePartsFileHolder = IFileHolder.Get(Path.Combine(facePartsDirectory, $"{mapping.MappingFromLocation.DeterministicHashCodeKey}{mapping.MappingFromItem.FilePath.ExtensionLowered}{_Configuration.FacePartsFileNameExtension}"));
|
|
(saveContainer, SaveContainer? extraSaveContainer) = Stateless.MapLogic.GetContainers(_Configuration.FacesFileNameExtension, _Configuration.FacePartsFileNameExtension, directory, faceFileHolder, facePartsFileHolder, mapping);
|
|
if (extraSaveContainer is not null)
|
|
results.Add(extraSaveContainer);
|
|
}
|
|
else
|
|
{
|
|
facePartsDirectory = Stateless.MapLogic.GetFacePartsDirectory(_PropertyConfiguration, d2FacePartsContentDirectory, mapping.FilePath, mapping.MappingFromItem);
|
|
shortcutFile = Path.Combine(record.PersonDirectory, $"{mapping.MappingFromLocation.DeterministicHashCodeKey}{mapping.MappingFromItem.FilePath.ExtensionLowered}.lnk");
|
|
checkFile = Path.Combine(directory, $"{mapping.MappingFromLocation.DeterministicHashCodeKey}{mapping.MappingFromItem.FilePath.ExtensionLowered}");
|
|
hiddenFaceFileHolder = IFileHolder.Get(Path.Combine(facesDirectory, $"{mapping.MappingFromLocation.DeterministicHashCodeKey}{mapping.MappingFromItem.FilePath.ExtensionLowered}{_Configuration.FacesHiddenFileNameExtension}"));
|
|
facePartsFileHolder = IFileHolder.Get(Path.Combine(facePartsDirectory, $"{mapping.MappingFromLocation.DeterministicHashCodeKey}{mapping.MappingFromItem.FilePath.ExtensionLowered}{_Configuration.FacePartsFileNameExtension}"));
|
|
saveContainer = new(checkFile, directory, faceFileHolder, hiddenFaceFileHolder, facePartsFileHolder, mapping.MappingFromItem.ResizedFileHolder, shortcutFile);
|
|
}
|
|
results.Add(saveContainer);
|
|
}
|
|
return results;
|
|
}
|
|
|
|
private static bool PreAndPostContinue(Configuration configuration, Mapping mapping, Mapping keyMapping)
|
|
{
|
|
bool result = true;
|
|
if (result && mapping.MappingFromFilterPre.InSkipCollection is not null && mapping.MappingFromFilterPre.InSkipCollection.Value)
|
|
result = false;
|
|
if (result && mapping.MappingFromFilterPre.IsFocusModel is not null && !mapping.MappingFromFilterPre.IsFocusModel.Value)
|
|
result = false;
|
|
if (result && mapping.MappingFromFilterPre.IsFocusRelativePath is not null && !mapping.MappingFromFilterPre.IsFocusRelativePath.Value)
|
|
result = false;
|
|
if (result && mapping.MappingFromFilterPost.InSkipCollection is not null && mapping.MappingFromFilterPost.InSkipCollection.Value)
|
|
result = false;
|
|
if (result && mapping.MappingFromFilterPost.IsFocusPerson is not null && !mapping.MappingFromFilterPost.IsFocusPerson.Value)
|
|
result = false;
|
|
if (result && keyMapping.MappingFromFilterPost.CanReMap is not null && !configuration.ReMap)
|
|
result = false;
|
|
if (result && keyMapping.MappingFromFilterPost.CanReMap is not null && (!keyMapping.MappingFromFilterPost.CanReMap.Value || (mapping.MappingFromPerson is not null && IPerson.IsDefaultName(mapping.MappingFromPerson.DisplayDirectoryName))))
|
|
result = false;
|
|
if (result && keyMapping.MappingFromFilterPost.InSkipCollection is not null && keyMapping.MappingFromFilterPost.InSkipCollection.Value)
|
|
result = false;
|
|
if (result && keyMapping.MappingFromFilterPost.IsFocusPerson is not null && keyMapping.MappingFromFilterPost.IsFocusPerson.Value)
|
|
result = false;
|
|
return result;
|
|
}
|
|
|
|
public List<SaveContainer> GetSaveContainers(string dFacesContentDirectory, string d2FacePartsContentDirectory, string d2FacePartsContentCollectionDirectory, ReadOnlyDictionary<int, ReadOnlyDictionary<int, Mapping>> idToWholePercentagesToMapping, Shared.Models.Methods.IDistanceLimits distanceLimits, int? useFiltersCounter, ReadOnlyCollection<SortingContainer> sortingContainers)
|
|
{
|
|
if (_Configuration is null)
|
|
throw new NullReferenceException(nameof(_Configuration));
|
|
if (distanceLimits is not null)
|
|
{
|
|
string counts = distanceLimits.GetCounts();
|
|
_ = Directory.CreateDirectory(Path.Combine(_EDistanceContentTicksDirectory, counts));
|
|
}
|
|
List<SaveContainer> results = [];
|
|
string by;
|
|
Record record;
|
|
bool isBySorting;
|
|
string checkFile;
|
|
Mapping? question;
|
|
string? directory;
|
|
string shortcutFile;
|
|
string facesDirectory;
|
|
bool isCounterPersonYear;
|
|
string facePartsDirectory;
|
|
FileHolder? faceFileHolder;
|
|
SaveContainer? saveContainer;
|
|
FileHolder? facePartsFileHolder;
|
|
FileHolder? hiddenFaceFileHolder;
|
|
bool sortingContainersAny = sortingContainers.Count > 0;
|
|
int padLeft = _Configuration.FaceDistancePermyriad.ToString().Length;
|
|
string forceSingleImageHumanized = nameof(Shared.Models.Stateless.IMapLogic.ForceSingleImage).Humanize(LetterCasing.Title);
|
|
foreach (SortingContainer sortingContainer in sortingContainers)
|
|
{
|
|
if (sortingContainer.Question is null)
|
|
throw new NotSupportedException();
|
|
isCounterPersonYear = sortingContainer.Source.MappingFromPerson is not null && IPersonBirthday.IsCounterPersonYear(sortingContainer.Source.MappingFromPerson.PersonKey);
|
|
(by, _, isBySorting) = Stateless.MapLogic.Get(useFiltersCounter, _Configuration.SaveIndividually, sortingContainersAny, forceSingleImageHumanized, sortingContainer.Sorting.DistancePermyriad, sortingContainer.Question);
|
|
question = sortingContainer.Question.MappingFromPerson is null ? sortingContainer.Source : sortingContainer.Question;
|
|
if (question is null)
|
|
throw new NotSupportedException();
|
|
if (question.MappingFromLocation is null)
|
|
continue;
|
|
record = Get(_Configuration, _Configuration.SaveIndividually, padLeft, by, question);
|
|
if (string.IsNullOrEmpty(record.Directory) || string.IsNullOrEmpty(record.PersonDirectory))
|
|
continue;
|
|
directory = record.Directory;
|
|
if (!string.IsNullOrEmpty(record.DebugDirectory))
|
|
results.Add(new(record.DebugDirectory));
|
|
if (question.MappingFromPerson is not null)
|
|
{
|
|
if (_Configuration.SaveIndividually)
|
|
{
|
|
directory = Path.Combine(directory, question.MappingFromItem.Id.ToString());
|
|
results.Add(new(Path.Combine(directory, question.MappingFromPerson.DisplayDirectoryName)));
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (!_Configuration.SaveSortingWithoutPerson)
|
|
throw new NotSupportedException();
|
|
if (record.Ticks is null)
|
|
continue;
|
|
if (_Configuration.SaveIndividually)
|
|
{
|
|
directory = Path.Combine(directory, question.MappingFromItem.Id.ToString());
|
|
results.Add(new(Path.Combine(directory, $"X+{record.Ticks}")));
|
|
}
|
|
}
|
|
results.Add(new(record.PersonDirectory));
|
|
if (_Configuration.SaveIndividually && question.MappingFromLocation.WholePercentages == question.MappingFromLocation.WholePercentages)
|
|
results.Add(new(Path.Combine(directory, "Maybe")));
|
|
facesDirectory = Stateless.MapLogic.GetFacesDirectory(_PropertyConfiguration, dFacesContentDirectory, question.FilePath, question.MappingFromItem);
|
|
faceFileHolder = IFileHolder.Get(Path.Combine(facesDirectory, $"{question.MappingFromLocation.DeterministicHashCodeKey}{question.MappingFromItem.FilePath.ExtensionLowered}{_Configuration.FacesFileNameExtension}"));
|
|
facePartsDirectory = Stateless.MapLogic.GetFacePartsDirectory(_PropertyConfiguration, d2FacePartsContentDirectory, question.FilePath, question.MappingFromItem);
|
|
shortcutFile = Path.Combine(record.PersonDirectory, $"{question.MappingFromLocation.DeterministicHashCodeKey}{question.MappingFromItem.FilePath.ExtensionLowered}.lnk");
|
|
checkFile = Path.Combine(directory, $"{question.MappingFromLocation.DeterministicHashCodeKey}{question.MappingFromItem.FilePath.ExtensionLowered}");
|
|
hiddenFaceFileHolder = IFileHolder.Get(Path.Combine(facesDirectory, $"{question.MappingFromLocation.DeterministicHashCodeKey}{question.MappingFromItem.FilePath.ExtensionLowered}{_Configuration.FacesHiddenFileNameExtension}"));
|
|
facePartsFileHolder = IFileHolder.Get(Path.Combine(facePartsDirectory, $"{question.MappingFromLocation.DeterministicHashCodeKey}{question.MappingFromItem.FilePath.ExtensionLowered}{_Configuration.FacePartsFileNameExtension}"));
|
|
saveContainer = new(checkFile, directory, faceFileHolder, hiddenFaceFileHolder, facePartsFileHolder, question.MappingFromItem.ResizedFileHolder, shortcutFile);
|
|
results.Add(saveContainer);
|
|
if (!_Configuration.SaveIndividually && isBySorting && question.MappingFromPerson is null)
|
|
{
|
|
saveContainer = GetMatchSaveContainer(dFacesContentDirectory, d2FacePartsContentDirectory, directory, question);
|
|
if (saveContainer is not null)
|
|
results.Add(saveContainer);
|
|
}
|
|
if (!_Configuration.SaveIndividually)
|
|
saveContainer = Stateless.MapLogic.GetDebugSaveContainer(sortingContainer, directory, question);
|
|
else
|
|
{
|
|
(saveContainer, SaveContainer? extraSaveContainer) = Stateless.MapLogic.GetContainers(_Configuration.FacesFileNameExtension, _Configuration.FacePartsFileNameExtension, _PropertyConfiguration, dFacesContentDirectory, d2FacePartsContentCollectionDirectory, directory, question);
|
|
if (saveContainer is null || extraSaveContainer is null)
|
|
continue;
|
|
results.Add(extraSaveContainer);
|
|
}
|
|
results.Add(saveContainer);
|
|
}
|
|
return results;
|
|
}
|
|
|
|
private SaveContainer? GetMatchSaveContainer(string dFacesContentDirectory, string d2FacePartsContentDirectory, string directory, Mapping mapping)
|
|
{
|
|
if (_Configuration is null)
|
|
throw new NullReferenceException(nameof(_Configuration));
|
|
SaveContainer? result;
|
|
if (mapping.MappingFromLocation is null)
|
|
result = null;
|
|
else
|
|
{
|
|
string checkFile;
|
|
string facesDirectory = Stateless.MapLogic.GetFacesDirectory(_PropertyConfiguration, dFacesContentDirectory, mapping.FilePath, mapping.MappingFromItem);
|
|
FileHolder faceFileHolder = IFileHolder.Get(Path.Combine(facesDirectory, $"{mapping.MappingFromLocation.DeterministicHashCodeKey}{mapping.MappingFromItem.FilePath.ExtensionLowered}{_Configuration.FacesFileNameExtension}"));
|
|
if (!faceFileHolder.Exists)
|
|
result = null;
|
|
else
|
|
{
|
|
string shortcutFile = string.Empty;
|
|
string facePartsDirectory = Stateless.MapLogic.GetFacePartsDirectory(_PropertyConfiguration, d2FacePartsContentDirectory, mapping.FilePath, mapping.MappingFromItem);
|
|
checkFile = Path.Combine(directory, $"{mapping.MappingFromLocation.DeterministicHashCodeKey}{mapping.MappingFromItem.FilePath.ExtensionLowered}");
|
|
FileHolder hiddenFaceFileHolder = IFileHolder.Get(Path.Combine(facesDirectory, $"{mapping.MappingFromLocation.DeterministicHashCodeKey}{mapping.MappingFromItem.FilePath.ExtensionLowered}{_Configuration.FacesHiddenFileNameExtension}"));
|
|
FileHolder facePartsFileHolder = IFileHolder.Get(Path.Combine(facePartsDirectory, $"{mapping.MappingFromLocation.DeterministicHashCodeKey}{mapping.MappingFromItem.FilePath.ExtensionLowered}{_Configuration.FacePartsFileNameExtension}"));
|
|
result = new(checkFile, directory, faceFileHolder, hiddenFaceFileHolder, facePartsFileHolder, mapping.MappingFromItem.ResizedFileHolder, shortcutFile);
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
|
|
public ReadOnlyCollection<SortingContainer> GetFilterSortingContainers(string dFacesContentDirectory, string d2FacePartsContentDirectory, string d2FacePartsContentCollectionDirectory, ReadOnlyDictionary<int, ReadOnlyDictionary<int, Mapping>> idToWholePercentagesToMapping, Shared.Models.Methods.IDistanceLimits distanceLimits, ReadOnlyCollection<SortingContainer> sortingContainers)
|
|
{
|
|
if (_Configuration is null)
|
|
throw new NullReferenceException(nameof(_Configuration));
|
|
if (distanceLimits is not null)
|
|
{
|
|
string counts = distanceLimits.GetCounts();
|
|
_ = Directory.CreateDirectory(Path.Combine(_EDistanceContentTicksDirectory, counts));
|
|
}
|
|
List<SortingContainer> results = [];
|
|
Sorting sorting;
|
|
Mapping? keyMapping;
|
|
List<int>? wholePercentagesCollection;
|
|
MappingFromFilterPre mappingFromFilterPre;
|
|
Dictionary<string, int> keyToCount = [];
|
|
MappingFromFilterPost mappingFromFilterPost;
|
|
ReadOnlyCollection<PersonContainer>? personContainers;
|
|
ReadOnlyDictionary<int, Mapping>? wholePercentagesToMapping;
|
|
Dictionary<int, List<int>> idToWholePercentagesCollection = [];
|
|
int totalSeconds = (int)Math.Floor(new TimeSpan(DateTime.Now.Ticks - _Ticks).TotalSeconds);
|
|
ReadOnlyDictionary<int, ReadOnlyCollection<PersonContainer>>? wholePercentagesToPersonContainers;
|
|
string message = $") {sortingContainers.Count:000} Filter Sorting Container(s) - {totalSeconds} total second(s)";
|
|
ProgressBarOptions options = new() { ProgressCharacter = '─', ProgressBarOnBottom = true, DisableBottomPercentage = true };
|
|
using ProgressBar progressBar = new(sortingContainers.Count, message, options);
|
|
foreach (SortingContainer sortingContainer in sortingContainers)
|
|
{
|
|
progressBar.Tick();
|
|
if (sortingContainer.Source?.MappingFromLocation is null)
|
|
throw new NotSupportedException();
|
|
mappingFromFilterPre = sortingContainer.Source.MappingFromFilterPre;
|
|
mappingFromFilterPost = sortingContainer.Source.MappingFromFilterPost;
|
|
if (sortingContainer.Source.MappingFromFilterPre.InSkipCollection is not null && sortingContainer.Source.MappingFromFilterPre.InSkipCollection.Value)
|
|
throw new NotSupportedException(nameof(GetSortingCollection));
|
|
if (sortingContainer.Source.MappingFromFilterPre.IsFocusModel is not null && !sortingContainer.Source.MappingFromFilterPre.IsFocusModel.Value)
|
|
throw new NotSupportedException(nameof(GetSortingCollection));
|
|
if (sortingContainer.Source.MappingFromFilterPre.IsFocusRelativePath is not null && !sortingContainer.Source.MappingFromFilterPre.IsFocusRelativePath.Value)
|
|
throw new NotSupportedException(nameof(GetSortingCollection));
|
|
if (sortingContainer.Source.MappingFromFilterPost.InSkipCollection is not null && sortingContainer.Source.MappingFromFilterPost.InSkipCollection.Value)
|
|
throw new NotSupportedException(nameof(GetSortingCollection));
|
|
if (sortingContainer.Source.MappingFromFilterPost.InSkipCollection is not null && sortingContainer.Source.MappingFromFilterPost.InSkipCollection.Value)
|
|
throw new NotSupportedException(nameof(GetSortingCollection));
|
|
if (sortingContainer.Source.MappingFromFilterPost.IsFocusPerson is not null && !sortingContainer.Source.MappingFromFilterPost.IsFocusPerson.Value)
|
|
throw new NotSupportedException(nameof(GetSortingCollection));
|
|
sorting = sortingContainer.Sorting;
|
|
if (!idToWholePercentagesToMapping.TryGetValue(sorting.Id, out wholePercentagesToMapping))
|
|
throw new NotSupportedException();
|
|
if (!wholePercentagesToMapping.TryGetValue(sorting.WholePercentages, out keyMapping))
|
|
throw new NotSupportedException();
|
|
if (sortingContainer.Source.MappingFromItem.Id == keyMapping.MappingFromItem.Id)
|
|
throw new NotSupportedException(nameof(GetSortingCollection));
|
|
if (keyMapping.MappingFromFilterPost.CanReMap is not null && !_Configuration.ReMap)
|
|
throw new NotSupportedException(nameof(GetSortingCollection));
|
|
if (keyMapping.MappingFromFilterPost.CanReMap is not null && !keyMapping.MappingFromFilterPost.CanReMap.Value)
|
|
throw new NotSupportedException(nameof(GetSortingCollection));
|
|
if (!PreAndPostContinue(_Configuration, sortingContainer.Source, keyMapping))
|
|
continue;
|
|
if (!idToWholePercentagesCollection.TryGetValue(sorting.Id, out wholePercentagesCollection))
|
|
{
|
|
idToWholePercentagesCollection.Add(sorting.Id, []);
|
|
if (!idToWholePercentagesCollection.TryGetValue(sorting.Id, out wholePercentagesCollection))
|
|
throw new Exception();
|
|
}
|
|
if (sortingContainer.Source.MappingFromPerson is null)
|
|
{
|
|
if (!_Configuration.SaveSortingWithoutPerson)
|
|
continue;
|
|
if (wholePercentagesCollection.Contains(sorting.WholePercentages))
|
|
continue;
|
|
keyMapping.UpdateMappingFromUnknownPerson(_Configuration.SaveIndividually, sortingContainer);
|
|
wholePercentagesCollection.Add(sorting.WholePercentages);
|
|
results.Add(new(keyMapping, sortingContainer.Sorting, sortingContainer.Source));
|
|
}
|
|
else
|
|
{
|
|
if (wholePercentagesCollection.Contains(sorting.WholePercentages))
|
|
continue;
|
|
if (keyMapping.MappingFromFilterPost.CanReMap is not null && (IPerson.IsDefaultName(sortingContainer.Source.MappingFromPerson.DisplayDirectoryName) || _IdThenWholePercentagesToPersonContainers.TryGetValue(sorting.Id, out wholePercentagesToPersonContainers) && wholePercentagesToPersonContainers.TryGetValue(sorting.WholePercentages, out personContainers) && personContainers.Any(l => l.Key == sortingContainer.Source.MappingFromPerson.PersonKey)))
|
|
continue;
|
|
if (sortingContainer.Source.MappingFromPerson is null)
|
|
throw new NotSupportedException();
|
|
wholePercentagesCollection.Add(sorting.WholePercentages);
|
|
results.Add(new(keyMapping, sortingContainer.Sorting, sortingContainer.Source));
|
|
}
|
|
}
|
|
return results.AsReadOnly();
|
|
}
|
|
|
|
} |