SaveMappedForOutputResolutions
This commit is contained in:
parent
a9d0f67227
commit
600f6e7e2b
@ -3,6 +3,7 @@ using System.Collections.ObjectModel;
|
|||||||
using System.Text.Json;
|
using System.Text.Json;
|
||||||
using View_by_Distance.Distance.Models.Stateless;
|
using View_by_Distance.Distance.Models.Stateless;
|
||||||
using View_by_Distance.FaceRecognitionDotNet;
|
using View_by_Distance.FaceRecognitionDotNet;
|
||||||
|
using View_by_Distance.Property.Models.Stateless;
|
||||||
using View_by_Distance.Shared.Models;
|
using View_by_Distance.Shared.Models;
|
||||||
using View_by_Distance.Shared.Models.Methods;
|
using View_by_Distance.Shared.Models.Methods;
|
||||||
|
|
||||||
@ -11,6 +12,14 @@ namespace View_by_Distance.Distance.Models;
|
|||||||
public partial class E_Distance : IDistance<MetadataExtractor.Directory>
|
public partial class E_Distance : IDistance<MetadataExtractor.Directory>
|
||||||
{
|
{
|
||||||
|
|
||||||
|
internal record Mapped(string File,
|
||||||
|
double? Length,
|
||||||
|
string Link,
|
||||||
|
string Image);
|
||||||
|
|
||||||
|
internal record Record(string File,
|
||||||
|
FaceRecognitionDotNet.FaceEncoding FaceRecognitionDotNetFaceEncoding);
|
||||||
|
|
||||||
private readonly List<string> _Moved;
|
private readonly List<string> _Moved;
|
||||||
private readonly List<double?> _Debug;
|
private readonly List<double?> _Debug;
|
||||||
private readonly List<string> _Renamed;
|
private readonly List<string> _Renamed;
|
||||||
@ -213,7 +222,7 @@ public partial class E_Distance : IDistance<MetadataExtractor.Directory>
|
|||||||
Face[] filteredFaces = (from l in faces where l.FaceEncoding is not null && l.Location is not null && l.OutputResolution is not null select l).ToArray();
|
Face[] filteredFaces = (from l in faces where l.FaceEncoding is not null && l.Location is not null && l.OutputResolution is not null select l).ToArray();
|
||||||
if (filteredFaces.Length != faces.Count)
|
if (filteredFaces.Length != faces.Count)
|
||||||
checkFaces.Clear();
|
checkFaces.Clear();
|
||||||
foreach (LocationContainer<MetadataExtractor.Directory>? locationContainer in locationContainers)
|
foreach (LocationContainer<MetadataExtractor.Directory> locationContainer in locationContainers)
|
||||||
{
|
{
|
||||||
if (_Renamed.Contains(locationContainer.File))
|
if (_Renamed.Contains(locationContainer.File))
|
||||||
continue;
|
continue;
|
||||||
@ -317,7 +326,7 @@ public partial class E_Distance : IDistance<MetadataExtractor.Directory>
|
|||||||
|
|
||||||
public static void SaveFaceDistances(Property.Models.Configuration configuration, SortingContainer[] sortingContainers)
|
public static void SaveFaceDistances(Property.Models.Configuration configuration, SortingContainer[] sortingContainers)
|
||||||
{
|
{
|
||||||
string eDistanceContentCollectionDirectory = Property.Models.Stateless.IResult.GetResultsDateGroupDirectory(configuration, nameof(E_Distance), "([])");
|
string eDistanceContentCollectionDirectory = IResult.GetResultsDateGroupDirectory(configuration, nameof(E_Distance), "([])");
|
||||||
if (!Directory.Exists(eDistanceContentCollectionDirectory))
|
if (!Directory.Exists(eDistanceContentCollectionDirectory))
|
||||||
_ = Directory.CreateDirectory(eDistanceContentCollectionDirectory);
|
_ = Directory.CreateDirectory(eDistanceContentCollectionDirectory);
|
||||||
#pragma warning disable
|
#pragma warning disable
|
||||||
@ -480,7 +489,7 @@ public partial class E_Distance : IDistance<MetadataExtractor.Directory>
|
|||||||
return results;
|
return results;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void ReviewLocationContainerDistanceTolerance(float locationContainerDistanceTolerance, DateTime dateTime, DateTime yesterday, List<(string File, FaceRecognitionDotNet.FaceEncoding FaceRecognitionDotNetFaceEncoding)> collection)
|
private static void ReviewLocationContainerDistanceTolerance(float locationContainerDistanceTolerance, DateTime dateTime, DateTime yesterday, List<Record> records)
|
||||||
{
|
{
|
||||||
FileInfo fileInfo;
|
FileInfo fileInfo;
|
||||||
List<string> files = new();
|
List<string> files = new();
|
||||||
@ -488,14 +497,14 @@ public partial class E_Distance : IDistance<MetadataExtractor.Directory>
|
|||||||
List<FaceDistance> faceDistanceLengths;
|
List<FaceDistance> faceDistanceLengths;
|
||||||
List<string> firstPassFailures = new();
|
List<string> firstPassFailures = new();
|
||||||
List<FaceDistance> faceDistanceEncodings = new();
|
List<FaceDistance> faceDistanceEncodings = new();
|
||||||
faceDistanceEncoding = new(collection[0].FaceRecognitionDotNetFaceEncoding);
|
faceDistanceEncoding = new(records[0].FaceRecognitionDotNetFaceEncoding);
|
||||||
foreach ((string file, FaceRecognitionDotNet.FaceEncoding faceRecognitionDotNetFaceEncoding) in collection)
|
foreach (Record record in records)
|
||||||
{
|
{
|
||||||
files.Add(file);
|
files.Add(record.File);
|
||||||
faceDistanceEncodings.Add(new(faceRecognitionDotNetFaceEncoding));
|
faceDistanceEncodings.Add(new(record.FaceRecognitionDotNetFaceEncoding));
|
||||||
}
|
}
|
||||||
if (faceDistanceEncoding is null)
|
if (faceDistanceEncoding is null)
|
||||||
throw new Exception();
|
throw new NullReferenceException(nameof(faceDistanceEncoding));
|
||||||
faceDistanceLengths = FaceRecognition.FaceDistances(new(faceDistanceEncodings), faceDistanceEncoding);
|
faceDistanceLengths = FaceRecognition.FaceDistances(new(faceDistanceEncodings), faceDistanceEncoding);
|
||||||
if (faceDistanceLengths.Count != files.Count)
|
if (faceDistanceLengths.Count != files.Count)
|
||||||
throw new Exception();
|
throw new Exception();
|
||||||
@ -505,14 +514,14 @@ public partial class E_Distance : IDistance<MetadataExtractor.Directory>
|
|||||||
continue;
|
continue;
|
||||||
firstPassFailures.Add(files[i]);
|
firstPassFailures.Add(files[i]);
|
||||||
}
|
}
|
||||||
faceDistanceEncoding = new(collection[^1].FaceRecognitionDotNetFaceEncoding);
|
faceDistanceEncoding = new(records[^1].FaceRecognitionDotNetFaceEncoding);
|
||||||
foreach ((string file, FaceRecognitionDotNet.FaceEncoding faceRecognitionDotNetFaceEncoding) in collection)
|
foreach (Record record in records)
|
||||||
{
|
{
|
||||||
files.Add(file);
|
files.Add(record.File);
|
||||||
faceDistanceEncodings.Add(new(faceRecognitionDotNetFaceEncoding));
|
faceDistanceEncodings.Add(new(record.FaceRecognitionDotNetFaceEncoding));
|
||||||
}
|
}
|
||||||
if (faceDistanceEncoding is null)
|
if (faceDistanceEncoding is null)
|
||||||
throw new Exception();
|
throw new NullReferenceException(nameof(faceDistanceEncoding));
|
||||||
faceDistanceLengths = FaceRecognition.FaceDistances(new(faceDistanceEncodings), faceDistanceEncoding);
|
faceDistanceLengths = FaceRecognition.FaceDistances(new(faceDistanceEncodings), faceDistanceEncoding);
|
||||||
if (faceDistanceLengths.Count != files.Count)
|
if (faceDistanceLengths.Count != files.Count)
|
||||||
throw new Exception();
|
throw new Exception();
|
||||||
@ -534,21 +543,21 @@ public partial class E_Distance : IDistance<MetadataExtractor.Directory>
|
|||||||
void IDistance<MetadataExtractor.Directory>.ReviewLocationContainerDistanceTolerance(float locationContainerDistanceTolerance, ReadOnlyCollection<LocationContainer<MetadataExtractor.Directory>> locationContainers)
|
void IDistance<MetadataExtractor.Directory>.ReviewLocationContainerDistanceTolerance(float locationContainerDistanceTolerance, ReadOnlyCollection<LocationContainer<MetadataExtractor.Directory>> locationContainers)
|
||||||
{
|
{
|
||||||
string? json;
|
string? json;
|
||||||
|
List<Record> records = new();
|
||||||
int? lastDirectoryNumber = null;
|
int? lastDirectoryNumber = null;
|
||||||
DateTime dateTime = DateTime.Now;
|
DateTime dateTime = DateTime.Now;
|
||||||
DateTime yesterday = DateTime.Now.AddDays(-1);
|
DateTime yesterday = DateTime.Now.AddDays(-1);
|
||||||
Shared.Models.FaceEncoding? modelsFaceEncoding;
|
Shared.Models.FaceEncoding? modelsFaceEncoding;
|
||||||
FaceRecognitionDotNet.FaceEncoding faceRecognitionDotNetFaceEncoding;
|
FaceRecognitionDotNet.FaceEncoding faceRecognitionDotNetFaceEncoding;
|
||||||
List<(string, FaceRecognitionDotNet.FaceEncoding)> collection = new();
|
foreach (LocationContainer<MetadataExtractor.Directory> locationContainer in locationContainers)
|
||||||
foreach (LocationContainer<MetadataExtractor.Directory>? locationContainer in locationContainers)
|
|
||||||
{
|
{
|
||||||
if (locationContainer.DirectoryNumber is null)
|
if (locationContainer.DirectoryNumber is null)
|
||||||
continue;
|
continue;
|
||||||
if (lastDirectoryNumber is not null && locationContainer.DirectoryNumber.Value != lastDirectoryNumber.Value)
|
if (lastDirectoryNumber is not null && locationContainer.DirectoryNumber.Value != lastDirectoryNumber.Value)
|
||||||
{
|
{
|
||||||
if (collection.Count > 2)
|
if (records.Count > 2)
|
||||||
ReviewLocationContainerDistanceTolerance(locationContainerDistanceTolerance, dateTime, yesterday, collection);
|
ReviewLocationContainerDistanceTolerance(locationContainerDistanceTolerance, dateTime, yesterday, records);
|
||||||
collection.Clear();
|
records.Clear();
|
||||||
}
|
}
|
||||||
json = Metadata.Models.Stateless.Methods.IMetadata.GetFaceEncoding(locationContainer.Directories);
|
json = Metadata.Models.Stateless.Methods.IMetadata.GetFaceEncoding(locationContainer.Directories);
|
||||||
if (json is null)
|
if (json is null)
|
||||||
@ -557,11 +566,176 @@ public partial class E_Distance : IDistance<MetadataExtractor.Directory>
|
|||||||
if (modelsFaceEncoding is null)
|
if (modelsFaceEncoding is null)
|
||||||
throw new NotSupportedException();
|
throw new NotSupportedException();
|
||||||
faceRecognitionDotNetFaceEncoding = FaceRecognition.LoadFaceEncoding(modelsFaceEncoding.RawEncoding);
|
faceRecognitionDotNetFaceEncoding = FaceRecognition.LoadFaceEncoding(modelsFaceEncoding.RawEncoding);
|
||||||
collection.Add((locationContainer.File, faceRecognitionDotNetFaceEncoding));
|
records.Add(new(locationContainer.File, faceRecognitionDotNetFaceEncoding));
|
||||||
lastDirectoryNumber = locationContainer.DirectoryNumber.Value;
|
lastDirectoryNumber = locationContainer.DirectoryNumber.Value;
|
||||||
}
|
}
|
||||||
if (collection.Count > 2)
|
if (records.Count > 2)
|
||||||
ReviewLocationContainerDistanceTolerance(locationContainerDistanceTolerance, dateTime, yesterday, collection);
|
ReviewLocationContainerDistanceTolerance(locationContainerDistanceTolerance, dateTime, yesterday, records);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void WriteVsCodeFiles(string eDistanceContentDirectory, string? displayDirectoryName, string directory)
|
||||||
|
{
|
||||||
|
string json;
|
||||||
|
string vsCodeDirectory = Path.Combine(directory, ".vscode");
|
||||||
|
if (!Directory.Exists(vsCodeDirectory))
|
||||||
|
_ = Directory.CreateDirectory(vsCodeDirectory);
|
||||||
|
if (displayDirectoryName is not null)
|
||||||
|
File.WriteAllText(Path.Combine(directory, $"_ {displayDirectoryName}.txt"), string.Empty);
|
||||||
|
json = "{ \"[markdown]\": { \"editor.wordWrap\": \"off\" }, \"foam.links.hover.enable\": false, \"foam.graph.style\": { \"background\": \"#202020\", \"node\": { \"note\": \"#f2cb1d\", \"distance\": \"green\", \"image\": \"orange\", \"placeholder\": \"white\", } } }";
|
||||||
|
_ = Shared.Models.Stateless.Methods.IPath.WriteAllText(Path.Combine(vsCodeDirectory, "settings.json"), json, updateDateWhenMatches: false, compareBeforeWrite: true, updateToWhenMatches: null);
|
||||||
|
json = string.Concat("{ \"version\": \"2.0.0\", \"tasks\": [ { \"label\": \"MKLink\", \"type\": \"shell\", \"command\": \"New-Item\", \"args\": [ \"-ItemType\", \"Junction\", \"-Path\", \"'", directory.Replace('\\', '/'), "/()'\", \"-Target\", \"'", eDistanceContentDirectory.Replace('\\', '/'), "'\" ], \"problemMatcher\": [] } ] }");
|
||||||
|
_ = Shared.Models.Stateless.Methods.IPath.WriteAllText(Path.Combine(vsCodeDirectory, "tasks.json"), json, updateDateWhenMatches: false, compareBeforeWrite: true, updateToWhenMatches: null);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void MoveFiles(Dictionary<string, int> keyValuePairs, List<string> linkedOnce, List<string> linkedTwice, List<string> linkedThrice)
|
||||||
|
{
|
||||||
|
string checkFile;
|
||||||
|
string checkDirectory;
|
||||||
|
string? yearDirectory;
|
||||||
|
string? personNameDirectory;
|
||||||
|
string? personNameDirectoryName;
|
||||||
|
string? personKeyFormattedDirectory;
|
||||||
|
foreach (string file in linkedOnce)
|
||||||
|
keyValuePairs[file] += 1;
|
||||||
|
foreach (string file in linkedTwice)
|
||||||
|
keyValuePairs[file] += 1;
|
||||||
|
foreach (string file in linkedThrice)
|
||||||
|
keyValuePairs[file] += 1;
|
||||||
|
foreach (KeyValuePair<string, int> keyValuePair in keyValuePairs)
|
||||||
|
{
|
||||||
|
personNameDirectory = Path.GetDirectoryName(keyValuePair.Key);
|
||||||
|
yearDirectory = Path.GetDirectoryName(personNameDirectory);
|
||||||
|
personNameDirectoryName = Path.GetFileName(personNameDirectory);
|
||||||
|
personKeyFormattedDirectory = Path.GetDirectoryName(yearDirectory);
|
||||||
|
if (string.IsNullOrEmpty(personNameDirectory) || string.IsNullOrEmpty(yearDirectory) || string.IsNullOrEmpty(personKeyFormattedDirectory) || string.IsNullOrEmpty(personNameDirectoryName))
|
||||||
|
continue;
|
||||||
|
checkDirectory = Path.Combine(personKeyFormattedDirectory, $"{keyValuePair.Value}{new string(Convert.ToChar(65 + keyValuePair.Value), 7)}");
|
||||||
|
if (checkDirectory == yearDirectory)
|
||||||
|
continue;
|
||||||
|
checkDirectory = Path.Combine(checkDirectory, personNameDirectoryName);
|
||||||
|
if (!Directory.Exists(checkDirectory))
|
||||||
|
_ = Directory.CreateDirectory(checkDirectory);
|
||||||
|
checkFile = Path.Combine(checkDirectory, Path.GetFileName(keyValuePair.Key));
|
||||||
|
if (File.Exists(checkFile))
|
||||||
|
continue;
|
||||||
|
File.Move(keyValuePair.Key, checkFile);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void SaveMappedForOutputResolutions(string eDistanceContentDirectory, float distanceTolerance, string personKeyFormatted, string? displayDirectoryName, List<Record> records, string directory)
|
||||||
|
{
|
||||||
|
string text;
|
||||||
|
string fileName;
|
||||||
|
FileInfo fileInfo;
|
||||||
|
List<string> files = new();
|
||||||
|
List<string> lines = new();
|
||||||
|
List<string> linkedOnce = new();
|
||||||
|
string fileNameWithoutExtension;
|
||||||
|
List<string> linkedTwice = new();
|
||||||
|
List<string> linkedThrice = new();
|
||||||
|
FaceDistance? faceDistanceEncoding;
|
||||||
|
List<string> relativePaths = new();
|
||||||
|
List<FaceDistance> faceDistanceLengths;
|
||||||
|
Uri uri = new(eDistanceContentDirectory);
|
||||||
|
Dictionary<string, int> keyValuePairs = new();
|
||||||
|
List<FaceDistance> faceDistanceEncodings = new();
|
||||||
|
List<Mapped> results = new();
|
||||||
|
foreach (Record record in records)
|
||||||
|
{
|
||||||
|
files.Add(record.File);
|
||||||
|
relativePaths.Add(uri.MakeRelativeUri(new(record.File)).OriginalString);
|
||||||
|
faceDistanceEncodings.Add(new(record.FaceRecognitionDotNetFaceEncoding));
|
||||||
|
}
|
||||||
|
foreach (Record record in records)
|
||||||
|
{
|
||||||
|
lines.Clear();
|
||||||
|
results.Clear();
|
||||||
|
fileInfo = new(record.File);
|
||||||
|
if (files.Count > 1)
|
||||||
|
{
|
||||||
|
faceDistanceEncoding = new(record.FaceRecognitionDotNetFaceEncoding);
|
||||||
|
if (faceDistanceEncoding is null)
|
||||||
|
throw new NullReferenceException(nameof(faceDistanceEncoding));
|
||||||
|
faceDistanceLengths = FaceRecognition.FaceDistances(new(faceDistanceEncodings), faceDistanceEncoding);
|
||||||
|
for (int i = 0; i < faceDistanceLengths.Count; i++)
|
||||||
|
{
|
||||||
|
fileName = Path.GetFileName(relativePaths[i]);
|
||||||
|
if (fileName == fileInfo.Name)
|
||||||
|
continue;
|
||||||
|
FaceDistance faceDistance = faceDistanceLengths[i];
|
||||||
|
if (faceDistance.Length > distanceTolerance)
|
||||||
|
continue;
|
||||||
|
fileNameWithoutExtension = Path.GetFileNameWithoutExtension(Path.GetFileNameWithoutExtension(fileName));
|
||||||
|
results.Add(new(files[i], faceDistance.Length, $"[[{fileNameWithoutExtension}]]", $""));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
results = (from l in results orderby l.Length select l).Take(3).ToList();
|
||||||
|
keyValuePairs.Add(record.File, results.Count);
|
||||||
|
foreach (Mapped mapped in results)
|
||||||
|
{
|
||||||
|
if (!linkedOnce.Contains(mapped.File))
|
||||||
|
{
|
||||||
|
linkedOnce.Add(mapped.File);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (!linkedTwice.Contains(mapped.File))
|
||||||
|
{
|
||||||
|
linkedTwice.Add(mapped.File);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (!linkedThrice.Contains(mapped.File))
|
||||||
|
{
|
||||||
|
linkedThrice.Add(mapped.File);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fileNameWithoutExtension = Path.GetFileNameWithoutExtension(Path.GetFileNameWithoutExtension(fileInfo.Name));
|
||||||
|
lines.Add("---");
|
||||||
|
lines.Add("type: \"distance\"");
|
||||||
|
lines.Add("---");
|
||||||
|
lines.Add(string.Empty);
|
||||||
|
if (displayDirectoryName is null)
|
||||||
|
lines.Add($"## {personKeyFormatted}");
|
||||||
|
else
|
||||||
|
lines.Add($"## {displayDirectoryName}");
|
||||||
|
lines.Add(string.Empty);
|
||||||
|
lines.Add($").OriginalString})");
|
||||||
|
lines.Add($"__{fileNameWithoutExtension}__");
|
||||||
|
lines.Add(string.Empty);
|
||||||
|
lines.AddRange(results.Select(l => $"{l.Image}{Environment.NewLine}{l.Link}{Environment.NewLine}"));
|
||||||
|
text = string.Join(Environment.NewLine, lines);
|
||||||
|
if (!Shared.Models.Stateless.Methods.IPath.WriteAllText(Path.Combine(directory, $"{fileNameWithoutExtension}.md"), text, updateDateWhenMatches: false, compareBeforeWrite: true, updateToWhenMatches: null))
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
MoveFiles(keyValuePairs, linkedOnce, linkedTwice, linkedThrice);
|
||||||
|
}
|
||||||
|
|
||||||
|
void IDistance<MetadataExtractor.Directory>.SaveMappedForOutputResolutions(string a2PeopleContentDirectory, string eDistanceContentDirectory, float[] rangeDistanceTolerance, ReadOnlyCollection<LocationContainer<MetadataExtractor.Directory>> locationContainers, string personKeyFormatted, string? displayDirectoryName)
|
||||||
|
{
|
||||||
|
string? json;
|
||||||
|
List<Record> records = new();
|
||||||
|
Shared.Models.FaceEncoding? modelsFaceEncoding;
|
||||||
|
FaceRecognitionDotNet.FaceEncoding faceRecognitionDotNetFaceEncoding;
|
||||||
|
foreach (LocationContainer<MetadataExtractor.Directory> locationContainer in locationContainers)
|
||||||
|
{
|
||||||
|
json = Metadata.Models.Stateless.Methods.IMetadata.GetFaceEncoding(locationContainer.Directories);
|
||||||
|
if (json is null)
|
||||||
|
continue;
|
||||||
|
modelsFaceEncoding = JsonSerializer.Deserialize<Shared.Models.FaceEncoding>(json);
|
||||||
|
if (modelsFaceEncoding is null)
|
||||||
|
throw new NotSupportedException();
|
||||||
|
faceRecognitionDotNetFaceEncoding = FaceRecognition.LoadFaceEncoding(modelsFaceEncoding.RawEncoding);
|
||||||
|
records.Add(new(locationContainer.File, faceRecognitionDotNetFaceEncoding));
|
||||||
|
}
|
||||||
|
string directory = Path.Combine(a2PeopleContentDirectory, rangeDistanceTolerance[1].ToString(), personKeyFormatted);
|
||||||
|
if (!Directory.Exists(directory))
|
||||||
|
_ = Directory.CreateDirectory(directory);
|
||||||
|
if (records.Count > 0)
|
||||||
|
{
|
||||||
|
WriteVsCodeFiles(eDistanceContentDirectory, displayDirectoryName, directory);
|
||||||
|
SaveMappedForOutputResolutions(eDistanceContentDirectory, rangeDistanceTolerance[1], personKeyFormatted, displayDirectoryName, records, directory);
|
||||||
|
}
|
||||||
|
_ = Shared.Models.Stateless.Methods.IPath.DeleteEmptyDirectories(directory);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -307,7 +307,7 @@ public class D_Face
|
|||||||
if (location is null)
|
if (location is null)
|
||||||
continue;
|
continue;
|
||||||
if (!results.Any(l => l.WholePercentages == locationContainer.WholePercentages))
|
if (!results.Any(l => l.WholePercentages == locationContainer.WholePercentages))
|
||||||
results.Add(new(locationContainer.FromDistanceContent, locationContainer.DirectoryNumber, locationContainer.File, locationContainer.PersonKey, locationContainer.Id, locationContainer.WholePercentages, locationContainer.Directories, rectangle.Value, location));
|
results.Add(new(locationContainer.FromDistanceContent, locationContainer.DirectoryNumber, locationContainer.File, locationContainer.PersonKey, locationContainer.DisplayDirectoryName, locationContainer.Id, locationContainer.WholePercentages, locationContainer.Directories, rectangle.Value, location));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (results.Count > 0)
|
if (results.Count > 0)
|
||||||
|
@ -260,7 +260,7 @@ public partial class DlibDotNet
|
|||||||
if (runToDoCollectionFirst)
|
if (runToDoCollectionFirst)
|
||||||
mapLogic = null;
|
mapLogic = null;
|
||||||
else
|
else
|
||||||
mapLogic = new(_AppSettings.MaxDegreeOfParallelism, _Configuration.PropertyConfiguration, _MapConfiguration, _Distance, personContainers, ticks, a2PeopleSingletonDirectory, eDistanceContentDirectory);
|
mapLogic = new(_AppSettings.MaxDegreeOfParallelism, _Configuration.PropertyConfiguration, _MapConfiguration, _Distance, personContainers, ticks, a2PeopleContentDirectory, a2PeopleSingletonDirectory, eDistanceContentDirectory);
|
||||||
foreach (string outputResolution in _Configuration.OutputResolutions)
|
foreach (string outputResolution in _Configuration.OutputResolutions)
|
||||||
{
|
{
|
||||||
if (outputResolution.Any(l => char.IsNumber(l)))
|
if (outputResolution.Any(l => char.IsNumber(l)))
|
||||||
@ -323,7 +323,7 @@ public partial class DlibDotNet
|
|||||||
}
|
}
|
||||||
fileNameToCollection = !Directory.Exists(fPhotoPrismSingletonDirectory) ? fileNameToCollection = new() : F_PhotoPrism.GetFileNameToCollection(fPhotoPrismSingletonDirectory);
|
fileNameToCollection = !Directory.Exists(fPhotoPrismSingletonDirectory) ? fileNameToCollection = new() : F_PhotoPrism.GetFileNameToCollection(fPhotoPrismSingletonDirectory);
|
||||||
B_Metadata metadata = new(_Configuration.PropertyConfiguration, _Configuration.ForceMetadataLastWriteTimeToCreationTime, _Configuration.PropertiesChangedForMetadata, bResultsFullGroupDirectory);
|
B_Metadata metadata = new(_Configuration.PropertyConfiguration, _Configuration.ForceMetadataLastWriteTimeToCreationTime, _Configuration.PropertiesChangedForMetadata, bResultsFullGroupDirectory);
|
||||||
mapLogic ??= new(_AppSettings.MaxDegreeOfParallelism, _Configuration.PropertyConfiguration, _MapConfiguration, _Distance, personContainers, ticks, a2PeopleSingletonDirectory, eDistanceContentDirectory);
|
mapLogic ??= new(_AppSettings.MaxDegreeOfParallelism, _Configuration.PropertyConfiguration, _MapConfiguration, _Distance, personContainers, ticks, a2PeopleContentDirectory, a2PeopleSingletonDirectory, eDistanceContentDirectory);
|
||||||
FullDoWork(argZero, propertyRoot, ticks, aResultsFullGroupDirectory, bResultsFullGroupDirectory, t, containers, propertyLogic, metadata, fileNameToCollection, mapLogic);
|
FullDoWork(argZero, propertyRoot, ticks, aResultsFullGroupDirectory, bResultsFullGroupDirectory, t, containers, propertyLogic, metadata, fileNameToCollection, mapLogic);
|
||||||
ReadOnlyCollection<Item> distinctFilteredItems = Shared.Models.Stateless.Methods.IContainer.GetItems(_Configuration.PropertyConfiguration, new(containers), distinctItems: true, filterItems: true);
|
ReadOnlyCollection<Item> distinctFilteredItems = Shared.Models.Stateless.Methods.IContainer.GetItems(_Configuration.PropertyConfiguration, new(containers), distinctItems: true, filterItems: true);
|
||||||
if (_Configuration.LookForAbandoned)
|
if (_Configuration.LookForAbandoned)
|
||||||
@ -848,6 +848,7 @@ public partial class DlibDotNet
|
|||||||
configuration.PersonCharacters.ToArray(),
|
configuration.PersonCharacters.ToArray(),
|
||||||
configuration.RangeDaysDeltaTolerance,
|
configuration.RangeDaysDeltaTolerance,
|
||||||
configuration.RangeDistanceTolerance,
|
configuration.RangeDistanceTolerance,
|
||||||
|
configuration.SaveMappedRelations,
|
||||||
configuration.SaveSortingWithoutPerson,
|
configuration.SaveSortingWithoutPerson,
|
||||||
configuration.SkipNotSkipDirectories,
|
configuration.SkipNotSkipDirectories,
|
||||||
configuration.SortingMaximumPerKey,
|
configuration.SortingMaximumPerKey,
|
||||||
|
@ -75,6 +75,8 @@ public class Configuration
|
|||||||
public bool? SaveFullYearOfRandomFiles { get; set; }
|
public bool? SaveFullYearOfRandomFiles { get; set; }
|
||||||
public bool? SaveIndividually { get; set; }
|
public bool? SaveIndividually { get; set; }
|
||||||
public string[]? SaveMappedForOutputResolutions { get; set; }
|
public string[]? SaveMappedForOutputResolutions { get; set; }
|
||||||
|
public bool? SaveMappedRelations { get; set; }
|
||||||
|
public string[]? SaveMappedRelationsForOutputResolutions { get; set; }
|
||||||
public string[]? SavePropertyShortcutsForOutputResolutions { get; set; }
|
public string[]? SavePropertyShortcutsForOutputResolutions { get; set; }
|
||||||
public string[]? SaveRandomForOutputResolutions { get; set; }
|
public string[]? SaveRandomForOutputResolutions { get; set; }
|
||||||
public bool? SaveResizedSubfiles { get; set; }
|
public bool? SaveResizedSubfiles { get; set; }
|
||||||
@ -171,6 +173,7 @@ public class Configuration
|
|||||||
if (configuration?.SaveFullYearOfRandomFiles is null) throw new NullReferenceException(nameof(configuration.SaveFullYearOfRandomFiles));
|
if (configuration?.SaveFullYearOfRandomFiles is null) throw new NullReferenceException(nameof(configuration.SaveFullYearOfRandomFiles));
|
||||||
if (configuration?.SaveIndividually is null) throw new NullReferenceException(nameof(configuration.SaveIndividually));
|
if (configuration?.SaveIndividually is null) throw new NullReferenceException(nameof(configuration.SaveIndividually));
|
||||||
// if (configuration?.SaveMappedForOutputResolutions is null) throw new NullReferenceException(nameof(configuration.SaveMappedForOutputResolutions));
|
// if (configuration?.SaveMappedForOutputResolutions is null) throw new NullReferenceException(nameof(configuration.SaveMappedForOutputResolutions));
|
||||||
|
if (configuration?.SaveMappedRelations is null) throw new NullReferenceException(nameof(configuration.SaveMappedRelations));
|
||||||
// if (configuration?.SavePropertyShortcutsForOutputResolutions is null) throw new NullReferenceException(nameof(configuration.SavePropertyShortcutsForOutputResolutions));
|
// if (configuration?.SavePropertyShortcutsForOutputResolutions is null) throw new NullReferenceException(nameof(configuration.SavePropertyShortcutsForOutputResolutions));
|
||||||
// if (configuration?.SaveRandomForOutputResolutions is null) throw new NullReferenceException(nameof(configuration.SaveRandomForOutputResolutions));
|
// if (configuration?.SaveRandomForOutputResolutions is null) throw new NullReferenceException(nameof(configuration.SaveRandomForOutputResolutions));
|
||||||
if (configuration?.SaveResizedSubfiles is null) throw new NullReferenceException(nameof(configuration.SaveResizedSubfiles));
|
if (configuration?.SaveResizedSubfiles is null) throw new NullReferenceException(nameof(configuration.SaveResizedSubfiles));
|
||||||
@ -251,9 +254,10 @@ public class Configuration
|
|||||||
configuration.SaveFaceDistancesForOutputResolutions ?? Array.Empty<string>(),
|
configuration.SaveFaceDistancesForOutputResolutions ?? Array.Empty<string>(),
|
||||||
configuration.SaveFaceLandmarkForOutputResolutions ?? Array.Empty<string>(),
|
configuration.SaveFaceLandmarkForOutputResolutions ?? Array.Empty<string>(),
|
||||||
configuration.SaveFilteredOriginalImagesFromJLinksForOutputResolutions ?? Array.Empty<string>(),
|
configuration.SaveFilteredOriginalImagesFromJLinksForOutputResolutions ?? Array.Empty<string>(),
|
||||||
configuration.SaveIndividually.Value,
|
|
||||||
configuration.SaveFullYearOfRandomFiles.Value,
|
configuration.SaveFullYearOfRandomFiles.Value,
|
||||||
|
configuration.SaveIndividually.Value,
|
||||||
configuration.SaveMappedForOutputResolutions ?? Array.Empty<string>(),
|
configuration.SaveMappedForOutputResolutions ?? Array.Empty<string>(),
|
||||||
|
configuration.SaveMappedRelations.Value,
|
||||||
configuration.SavePropertyShortcutsForOutputResolutions ?? Array.Empty<string>(),
|
configuration.SavePropertyShortcutsForOutputResolutions ?? Array.Empty<string>(),
|
||||||
configuration.SaveRandomForOutputResolutions ?? Array.Empty<string>(),
|
configuration.SaveRandomForOutputResolutions ?? Array.Empty<string>(),
|
||||||
configuration.SaveResizedSubfiles.Value,
|
configuration.SaveResizedSubfiles.Value,
|
||||||
|
@ -64,9 +64,10 @@ public record Configuration(Property.Models.Configuration PropertyConfiguration,
|
|||||||
string[] SaveFaceDistancesForOutputResolutions,
|
string[] SaveFaceDistancesForOutputResolutions,
|
||||||
string[] SaveFaceLandmarkForOutputResolutions,
|
string[] SaveFaceLandmarkForOutputResolutions,
|
||||||
string[] SaveFilteredOriginalImagesFromJLinksForOutputResolutions,
|
string[] SaveFilteredOriginalImagesFromJLinksForOutputResolutions,
|
||||||
bool SaveIndividually,
|
|
||||||
bool SaveFullYearOfRandomFiles,
|
bool SaveFullYearOfRandomFiles,
|
||||||
|
bool SaveIndividually,
|
||||||
string[] SaveMappedForOutputResolutions,
|
string[] SaveMappedForOutputResolutions,
|
||||||
|
bool SaveMappedRelations,
|
||||||
string[] SavePropertyShortcutsForOutputResolutions,
|
string[] SavePropertyShortcutsForOutputResolutions,
|
||||||
string[] SaveRandomForOutputResolutions,
|
string[] SaveRandomForOutputResolutions,
|
||||||
bool SaveResizedSubfiles,
|
bool SaveResizedSubfiles,
|
||||||
|
@ -1,80 +1,23 @@
|
|||||||
using System.Text.Json;
|
|
||||||
using System.Text.Json.Serialization;
|
|
||||||
|
|
||||||
namespace View_by_Distance.Map.Models;
|
namespace View_by_Distance.Map.Models;
|
||||||
|
|
||||||
public class Configuration
|
public record Configuration(bool DeletePossibleDuplicates,
|
||||||
{
|
bool DistanceMoveUnableToMatch,
|
||||||
|
bool DistanceRenameToMatch,
|
||||||
public bool DeletePossibleDuplicates { get; internal set; }
|
int FaceConfidencePercent,
|
||||||
public bool DistanceMoveUnableToMatch { init; get; }
|
int FaceDistancePermyriad,
|
||||||
public bool DistanceRenameToMatch { init; get; }
|
float? LocationContainerDistanceTolerance,
|
||||||
public int FaceConfidencePercent { init; get; }
|
int LocationDigits,
|
||||||
public int FaceDistancePermyriad { init; get; }
|
string MappingDefaultName,
|
||||||
public string FacePartsFileNameExtension { init; get; }
|
int PersonBirthdayFirstYear,
|
||||||
public string FacesFileNameExtension { init; get; }
|
string PersonBirthdayFormat,
|
||||||
public string FacesHiddenFileNameExtension { init; get; }
|
char[] PersonCharacters,
|
||||||
public float? LocationContainerDistanceTolerance { init; get; }
|
int[] RangeDaysDeltaTolerance,
|
||||||
public int LocationDigits { init; get; }
|
float[] RangeDistanceTolerance,
|
||||||
public string MappingDefaultName { init; get; }
|
bool SaveMappedRelations,
|
||||||
public int PersonBirthdayFirstYear { init; get; }
|
bool SaveSortingWithoutPerson,
|
||||||
public string PersonBirthdayFormat { init; get; }
|
string[] SkipNotSkipDirectories,
|
||||||
public char[] PersonCharacters { init; get; }
|
int SortingMaximumPerKey,
|
||||||
public int RangeDaysDeltaTolerance { init; get; }
|
int SortingMinimumToUseSigma,
|
||||||
public double RangeDistanceTolerance { init; get; }
|
string FacesFileNameExtension,
|
||||||
public bool SaveSortingWithoutPerson { init; get; }
|
string FacesHiddenFileNameExtension,
|
||||||
public string[] SkipNotSkipDirectories { init; get; }
|
string FacePartsFileNameExtension);
|
||||||
public int SortingMaximumPerKey { init; get; }
|
|
||||||
public int SortingMinimumToUseSigma { init; get; }
|
|
||||||
|
|
||||||
[JsonConstructor]
|
|
||||||
public Configuration(bool deletePossibleDuplicates,
|
|
||||||
bool distanceMoveUnableToMatch,
|
|
||||||
bool distanceRenameToMatch,
|
|
||||||
int faceConfidencePercent,
|
|
||||||
int faceDistancePermyriad,
|
|
||||||
float? locationContainerDistanceTolerance,
|
|
||||||
int locationDigits,
|
|
||||||
string mappingDefaultName,
|
|
||||||
int personBirthdayFirstYear,
|
|
||||||
string personBirthdayFormat,
|
|
||||||
char[] personCharacters,
|
|
||||||
int[] rangeDaysDeltaTolerance,
|
|
||||||
float[] rangeDistanceTolerance,
|
|
||||||
bool saveSortingWithoutPerson,
|
|
||||||
string[] skipNotSkipDirectories,
|
|
||||||
int sortingMaximumPerKey,
|
|
||||||
int sortingMinimumToUseSigma,
|
|
||||||
string facesFileNameExtension,
|
|
||||||
string facesHiddenFileNameExtension,
|
|
||||||
string facePartsFileNameExtension)
|
|
||||||
{
|
|
||||||
LocationDigits = locationDigits;
|
|
||||||
PersonCharacters = personCharacters;
|
|
||||||
MappingDefaultName = mappingDefaultName;
|
|
||||||
PersonBirthdayFormat = personBirthdayFormat;
|
|
||||||
SortingMaximumPerKey = sortingMaximumPerKey;
|
|
||||||
DistanceRenameToMatch = distanceRenameToMatch;
|
|
||||||
FaceConfidencePercent = faceConfidencePercent;
|
|
||||||
FaceDistancePermyriad = faceDistancePermyriad;
|
|
||||||
FacesFileNameExtension = facesFileNameExtension;
|
|
||||||
SkipNotSkipDirectories = skipNotSkipDirectories;
|
|
||||||
PersonBirthdayFirstYear = personBirthdayFirstYear;
|
|
||||||
RangeDistanceTolerance = rangeDistanceTolerance[1];
|
|
||||||
DeletePossibleDuplicates = deletePossibleDuplicates;
|
|
||||||
SaveSortingWithoutPerson = saveSortingWithoutPerson;
|
|
||||||
SortingMinimumToUseSigma = sortingMinimumToUseSigma;
|
|
||||||
RangeDaysDeltaTolerance = rangeDaysDeltaTolerance[1];
|
|
||||||
DistanceMoveUnableToMatch = distanceMoveUnableToMatch;
|
|
||||||
FacePartsFileNameExtension = facePartsFileNameExtension;
|
|
||||||
FacesHiddenFileNameExtension = facesHiddenFileNameExtension;
|
|
||||||
LocationContainerDistanceTolerance = locationContainerDistanceTolerance;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override string ToString()
|
|
||||||
{
|
|
||||||
string result = JsonSerializer.Serialize(this, new JsonSerializerOptions() { WriteIndented = true });
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,4 +1,4 @@
|
|||||||
using Humanizer;
|
using Humanizer;
|
||||||
using ShellProgressBar;
|
using ShellProgressBar;
|
||||||
using System.Collections.ObjectModel;
|
using System.Collections.ObjectModel;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
@ -226,7 +226,7 @@ public partial class MapLogic : Shared.Models.Methods.IMapLogic
|
|||||||
private readonly ReadOnlyDictionary<int, List<LocationContainer<MetadataExtractor.Directory>>> _IdToLocationContainers;
|
private readonly ReadOnlyDictionary<int, List<LocationContainer<MetadataExtractor.Directory>>> _IdToLocationContainers;
|
||||||
private readonly ReadOnlyDictionary<int, ReadOnlyDictionary<int, ReadOnlyCollection<PersonContainer>>> _IdThenWholePercentagesToPersonContainers;
|
private readonly ReadOnlyDictionary<int, ReadOnlyDictionary<int, ReadOnlyCollection<PersonContainer>>> _IdThenWholePercentagesToPersonContainers;
|
||||||
|
|
||||||
public MapLogic(int maxDegreeOfParallelism, Shared.Models.Properties.IPropertyConfiguration propertyConfiguration, Configuration? configuration, Shared.Models.Methods.IDistance<MetadataExtractor.Directory> distance, ReadOnlyCollection<PersonContainer> personContainers, long ticks, string a2PeopleSingletonDirectory, string eDistanceContentDirectory)
|
public MapLogic(int maxDegreeOfParallelism, Shared.Models.Properties.IPropertyConfiguration propertyConfiguration, Configuration? configuration, Shared.Models.Methods.IDistance<MetadataExtractor.Directory> distance, ReadOnlyCollection<PersonContainer> personContainers, long ticks, string? a2PeopleContentDirectory, string a2PeopleSingletonDirectory, string eDistanceContentDirectory)
|
||||||
{
|
{
|
||||||
_Ticks = ticks;
|
_Ticks = ticks;
|
||||||
_Configuration = configuration;
|
_Configuration = configuration;
|
||||||
@ -240,7 +240,7 @@ public partial class MapLogic : Shared.Models.Methods.IMapLogic
|
|||||||
Dictionary<int, List<(string, int)>> skipNotSkipCollection = new();
|
Dictionary<int, List<(string, int)>> skipNotSkipCollection = new();
|
||||||
List<LocationContainer<MetadataExtractor.Directory>> locationContainers = new();
|
List<LocationContainer<MetadataExtractor.Directory>> locationContainers = new();
|
||||||
string? rootDirectoryParent = Path.GetDirectoryName(propertyConfiguration.RootDirectory);
|
string? rootDirectoryParent = Path.GetDirectoryName(propertyConfiguration.RootDirectory);
|
||||||
string eDistanceContentTicksDirectory = Path.Combine(eDistanceContentDirectory, $"({ticks})");
|
string eDistanceContentTicksDirectory = Path.Combine(eDistanceContentDirectory, ticks.ToString());
|
||||||
ReadOnlyDictionary<int, ReadOnlyDictionary<int, ReadOnlyCollection<PersonContainer>>> idThenWholePercentagesToPersonContainers;
|
ReadOnlyDictionary<int, ReadOnlyDictionary<int, ReadOnlyCollection<PersonContainer>>> idThenWholePercentagesToPersonContainers;
|
||||||
if (string.IsNullOrEmpty(rootDirectoryParent))
|
if (string.IsNullOrEmpty(rootDirectoryParent))
|
||||||
throw new NullReferenceException(nameof(rootDirectoryParent));
|
throw new NullReferenceException(nameof(rootDirectoryParent));
|
||||||
@ -270,13 +270,7 @@ public partial class MapLogic : Shared.Models.Methods.IMapLogic
|
|||||||
}
|
}
|
||||||
List<Stateless.MapLogic.Record> records = Stateless.MapLogic.DeleteEmptyDirectoriesAndGetCollection(configuration, ticks, eDistanceContentDirectory, readOnlyPersonKeyFormattedToNewestPersonKeyFormatted, readOnlyPersonKeyFormattedCollection);
|
List<Stateless.MapLogic.Record> records = Stateless.MapLogic.DeleteEmptyDirectoriesAndGetCollection(configuration, ticks, eDistanceContentDirectory, readOnlyPersonKeyFormattedToNewestPersonKeyFormatted, readOnlyPersonKeyFormattedCollection);
|
||||||
ReadOnlyCollection<(Stateless.MapLogic.PersonKeyFormattedIdThenWholePercentages, PersonContainer)> readOnlyPossiblyNewPersonDisplayDirectoryNamesAndPersonContainer;
|
ReadOnlyCollection<(Stateless.MapLogic.PersonKeyFormattedIdThenWholePercentages, PersonContainer)> readOnlyPossiblyNewPersonDisplayDirectoryNamesAndPersonContainer;
|
||||||
locationContainers.AddRange(Stateless.MapLogic.GetLocationContainers(distance, maxDegreeOfParallelism, configuration, ticks, personContainers, eDistanceContentDirectory, skipCollection, records));
|
|
||||||
int lossCount = records.Count - locationContainers.Count;
|
|
||||||
ReadOnlyCollection<Stateless.MapLogic.PersonKeyFormattedIdThenWholePercentages> personKeyFormattedIdThenWholePercentagesCollection = Stateless.MapLogic.GetPersonKeyFormattedIdThenWholePercentages(configuration, ticks, records);
|
ReadOnlyCollection<Stateless.MapLogic.PersonKeyFormattedIdThenWholePercentages> personKeyFormattedIdThenWholePercentagesCollection = Stateless.MapLogic.GetPersonKeyFormattedIdThenWholePercentages(configuration, ticks, records);
|
||||||
int unableToMatchCount = records.Count - personKeyFormattedIdThenWholePercentagesCollection.Count;
|
|
||||||
if (lossCount != 0 || unableToMatchCount != 0)
|
|
||||||
if (lossCount != 0 || unableToMatchCount != 0)
|
|
||||||
{ }
|
|
||||||
//
|
//
|
||||||
{
|
{
|
||||||
Dictionary<long, int> personKeyToCount = new();
|
Dictionary<long, int> personKeyToCount = new();
|
||||||
@ -314,6 +308,20 @@ public partial class MapLogic : Shared.Models.Methods.IMapLogic
|
|||||||
ticks,
|
ticks,
|
||||||
personContainers,
|
personContainers,
|
||||||
readOnlyPersonKeyToCount));
|
readOnlyPersonKeyToCount));
|
||||||
|
locationContainers.AddRange(Stateless.MapLogic.GetLocationContainers(distance,
|
||||||
|
maxDegreeOfParallelism,
|
||||||
|
configuration,
|
||||||
|
ticks,
|
||||||
|
personContainers,
|
||||||
|
skipCollection,
|
||||||
|
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.SaveMappedRelations)
|
||||||
|
Stateless.MapLogic.SaveMappedRelations(configuration, distance, a2PeopleContentDirectory, eDistanceContentDirectory, ticks, locationContainers, readOnlyPersonKeyFormattedToPersonContainer, readOnlyPersonKeyToPersonContainerCollection);
|
||||||
}
|
}
|
||||||
_PersonKeyToCount = readOnlyPersonKeyToCount;
|
_PersonKeyToCount = readOnlyPersonKeyToCount;
|
||||||
_EDistanceContentTicksDirectory = eDistanceContentTicksDirectory;
|
_EDistanceContentTicksDirectory = eDistanceContentTicksDirectory;
|
||||||
@ -548,11 +556,11 @@ public partial class MapLogic : Shared.Models.Methods.IMapLogic
|
|||||||
(ticks, directory) = GetDirectory(_Configuration, saveIndividually, padLeft, mapping.SegmentC, by, mapping.MappingFromItem);
|
(ticks, directory) = GetDirectory(_Configuration, saveIndividually, padLeft, mapping.SegmentC, by, mapping.MappingFromItem);
|
||||||
if (ticks is null || string.IsNullOrEmpty(directory))
|
if (ticks is null || string.IsNullOrEmpty(directory))
|
||||||
continue;
|
continue;
|
||||||
personDirectory = Path.Combine(directory, $"X]{ticks}");
|
personDirectory = Path.Combine(directory, $"X+{ticks}");
|
||||||
if (saveIndividually)
|
if (saveIndividually)
|
||||||
{
|
{
|
||||||
directory = Path.Combine(directory, mapping.MappingFromItem.Id.ToString());
|
directory = Path.Combine(directory, mapping.MappingFromItem.Id.ToString());
|
||||||
results.Add(new(Path.Combine(directory, $"X]{ticks}")));
|
results.Add(new(Path.Combine(directory, $"X+{ticks}")));
|
||||||
}
|
}
|
||||||
distinct.Add(mapping.MappingFromItem.Id);
|
distinct.Add(mapping.MappingFromItem.Id);
|
||||||
distinct.Add(mapping.SortingContainer.Sorting.Id);
|
distinct.Add(mapping.SortingContainer.Sorting.Id);
|
||||||
@ -686,6 +694,7 @@ public partial class MapLogic : Shared.Models.Methods.IMapLogic
|
|||||||
FaceDistance faceDistanceLength;
|
FaceDistance faceDistanceLength;
|
||||||
List<int>? wholePercentagesCollection;
|
List<int>? wholePercentagesCollection;
|
||||||
bool skipNotSkipCollectionAny = _SkipNotSkipCollection.Count > 0;
|
bool skipNotSkipCollectionAny = _SkipNotSkipCollection.Count > 0;
|
||||||
|
float distanceTolerance = _Configuration.RangeDistanceTolerance[1];
|
||||||
for (int j = 0; j < faceDistanceLengths.Count; j++)
|
for (int j = 0; j < faceDistanceLengths.Count; j++)
|
||||||
{
|
{
|
||||||
if (faceDistanceEncoding.WholePercentages is null)
|
if (faceDistanceEncoding.WholePercentages is null)
|
||||||
@ -705,7 +714,7 @@ public partial class MapLogic : Shared.Models.Methods.IMapLogic
|
|||||||
throw new NotSupportedException();
|
throw new NotSupportedException();
|
||||||
if (faceDistanceLength.Length == 0)
|
if (faceDistanceLength.Length == 0)
|
||||||
continue;
|
continue;
|
||||||
sorting = ISorting.Get(_Configuration.FaceDistancePermyriad, _Configuration.RangeDistanceTolerance, faceDistanceEncoding, faceDistanceLength);
|
sorting = ISorting.Get(_Configuration.FaceDistancePermyriad, distanceTolerance, faceDistanceEncoding, faceDistanceLength);
|
||||||
if (sorting.DistancePermyriad == 0)
|
if (sorting.DistancePermyriad == 0)
|
||||||
continue;
|
continue;
|
||||||
if (sorting.Id == faceDistanceEncoding.Id)
|
if (sorting.Id == faceDistanceEncoding.Id)
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
using Humanizer;
|
using Humanizer;
|
||||||
using ShellProgressBar;
|
using ShellProgressBar;
|
||||||
using System.Collections.ObjectModel;
|
using System.Collections.ObjectModel;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
@ -20,6 +20,12 @@ internal abstract class MapLogic
|
|||||||
bool IsDefault,
|
bool IsDefault,
|
||||||
string MappedFaceFile);
|
string MappedFaceFile);
|
||||||
|
|
||||||
|
internal record MappedFile(long PersonKey,
|
||||||
|
string PersonKeyFormatted,
|
||||||
|
string PersonDisplayDirectoryName,
|
||||||
|
int? DirectoryNumber,
|
||||||
|
string File);
|
||||||
|
|
||||||
internal record Duplicate(long PersonKey,
|
internal record Duplicate(long PersonKey,
|
||||||
int Id,
|
int Id,
|
||||||
string File,
|
string File,
|
||||||
@ -227,10 +233,11 @@ internal abstract class MapLogic
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static List<(long, int?, string)> GetDisplayDirectoryAllFiles(string fileNameExtension, ReadOnlyCollection<PersonContainer> personContainers)
|
private static List<MappedFile> GetDisplayDirectoryAllFiles(string fileNameExtension, string personBirthdayFormat, ReadOnlyCollection<PersonContainer> personContainers)
|
||||||
{
|
{
|
||||||
List<(long, int?, string)> results = new();
|
List<MappedFile> results = new();
|
||||||
string fileName;
|
string fileName;
|
||||||
|
string personKeyFormatted;
|
||||||
List<string> distinct = new();
|
List<string> distinct = new();
|
||||||
foreach (PersonContainer personContainer in personContainers)
|
foreach (PersonContainer personContainer in personContainers)
|
||||||
{
|
{
|
||||||
@ -244,7 +251,8 @@ internal abstract class MapLogic
|
|||||||
if (distinct.Contains(fileName))
|
if (distinct.Contains(fileName))
|
||||||
continue;
|
continue;
|
||||||
distinct.Add(fileName);
|
distinct.Add(fileName);
|
||||||
results.Add(new(personContainer.Key.Value, null, personContainer.DisplayDirectoryAllFiles[i]));
|
personKeyFormatted = IPersonBirthday.GetFormatted(personBirthdayFormat, personContainer.Key.Value);
|
||||||
|
results.Add(new(personContainer.Key.Value, personKeyFormatted, personContainer.DisplayDirectoryName, null, personContainer.DisplayDirectoryAllFiles[i]));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return results;
|
return results;
|
||||||
@ -280,11 +288,14 @@ internal abstract class MapLogic
|
|||||||
{
|
{
|
||||||
List<TicksDirectory> results = new();
|
List<TicksDirectory> results = new();
|
||||||
float? totalDays;
|
float? totalDays;
|
||||||
|
long? next = null;
|
||||||
|
string? checkDirectory;
|
||||||
string ticksDirectoryName;
|
string ticksDirectoryName;
|
||||||
DateTime directoryDateTime;
|
DateTime directoryDateTime;
|
||||||
DirectoryInfo directoryInfo;
|
DirectoryInfo directoryInfo;
|
||||||
long? lastDirectoryTicks = null;
|
long? lastDirectoryTicks = null;
|
||||||
DateTime dateTime = DateTime.Now;
|
DateTime dateTime = DateTime.Now;
|
||||||
|
long month = dateTime.AddMonths(1).Ticks - dateTime.Ticks;
|
||||||
for (int i = 1; i < 5; i++)
|
for (int i = 1; i < 5; i++)
|
||||||
_ = IPath.DeleteEmptyDirectories(eDistanceContentDirectory);
|
_ = IPath.DeleteEmptyDirectories(eDistanceContentDirectory);
|
||||||
if (!Directory.Exists(eDistanceContentDirectory))
|
if (!Directory.Exists(eDistanceContentDirectory))
|
||||||
@ -293,12 +304,20 @@ internal abstract class MapLogic
|
|||||||
foreach (string ticksDirectory in ticksDirectories)
|
foreach (string ticksDirectory in ticksDirectories)
|
||||||
{
|
{
|
||||||
ticksDirectoryName = Path.GetFileName(ticksDirectory);
|
ticksDirectoryName = Path.GetFileName(ticksDirectory);
|
||||||
if (ticksDirectoryName.Length < 3 || ticksDirectoryName.First() != '(' || ticksDirectoryName[^1] != ')')
|
if (!long.TryParse(ticksDirectoryName, out long directoryTicks))
|
||||||
continue;
|
|
||||||
if (!long.TryParse(ticksDirectoryName[1..^1], out long directoryTicks))
|
|
||||||
{
|
|
||||||
if (!long.TryParse(ticksDirectoryName[1..^4], out directoryTicks))
|
|
||||||
throw new NotSupportedException();
|
throw new NotSupportedException();
|
||||||
|
if (next is null)
|
||||||
|
next = new DateTime(directoryTicks).Ticks;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
next += month;
|
||||||
|
checkDirectory = Path.GetDirectoryName(ticksDirectory);
|
||||||
|
if (string.IsNullOrEmpty(checkDirectory))
|
||||||
|
{
|
||||||
|
if (!string.IsNullOrEmpty(checkDirectory))
|
||||||
|
Directory.Move(ticksDirectory, Path.Combine(checkDirectory, next.Value.ToString()));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
directoryInfo = new(ticksDirectory);
|
directoryInfo = new(ticksDirectory);
|
||||||
directoryDateTime = new DateTime(directoryTicks);
|
directoryDateTime = new DateTime(directoryTicks);
|
||||||
@ -568,15 +587,15 @@ internal abstract class MapLogic
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static List<(long PersonKey, int? DirectoryNumber, string File)> GetCollection(Configuration configuration, ReadOnlyCollection<PersonContainer> personContainers, List<Record> records)
|
private static List<MappedFile> GetMappedFiles(Configuration configuration, ReadOnlyCollection<PersonContainer> personContainers, List<Record> records)
|
||||||
{
|
{
|
||||||
List<(long PersonKey, int? DirectoryNumber, string File)> results = new();
|
List<MappedFile> results = new();
|
||||||
string file;
|
string file;
|
||||||
long personKey;
|
long personKey;
|
||||||
string fileName;
|
string fileName;
|
||||||
List<string> distinct = new();
|
List<string> distinct = new();
|
||||||
PersonBirthday? personBirthday;
|
PersonBirthday? personBirthday;
|
||||||
results.AddRange(GetDisplayDirectoryAllFiles(configuration.FacesFileNameExtension, personContainers));
|
results.AddRange(GetDisplayDirectoryAllFiles(configuration.FacesFileNameExtension, configuration.PersonBirthdayFormat, personContainers));
|
||||||
foreach (Record record in records)
|
foreach (Record record in records)
|
||||||
{
|
{
|
||||||
personBirthday = IPersonBirthday.GetPersonBirthday(configuration.PersonBirthdayFormat, record.PersonKeyFormatted);
|
personBirthday = IPersonBirthday.GetPersonBirthday(configuration.PersonBirthdayFormat, record.PersonKeyFormatted);
|
||||||
@ -587,7 +606,7 @@ internal abstract class MapLogic
|
|||||||
continue;
|
continue;
|
||||||
distinct.Add(fileName);
|
distinct.Add(fileName);
|
||||||
personKey = personBirthday.Value.Ticks;
|
personKey = personBirthday.Value.Ticks;
|
||||||
results.Add(new(personKey, record.DirectoryNumber, record.MappedFaceFile));
|
results.Add(new(personKey, record.PersonKeyFormatted, record.PersonDisplayDirectoryName, record.DirectoryNumber, record.MappedFaceFile));
|
||||||
}
|
}
|
||||||
for (int i = results.Count - 1; i > -1; i--)
|
for (int i = results.Count - 1; i > -1; i--)
|
||||||
{
|
{
|
||||||
@ -602,24 +621,24 @@ internal abstract class MapLogic
|
|||||||
if (!File.Exists(file))
|
if (!File.Exists(file))
|
||||||
continue;
|
continue;
|
||||||
File.Move(file, file[..^4]);
|
File.Move(file, file[..^4]);
|
||||||
results[i] = new(results[i].PersonKey, results[i].DirectoryNumber, file[..^4]);
|
results[i] = new(results[i].PersonKey, results[i].PersonKeyFormatted, results[i].PersonDisplayDirectoryName, results[i].DirectoryNumber, file[..^4]);
|
||||||
}
|
}
|
||||||
return results;
|
return results;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void ParallelFor(Configuration configuration, string eDistanceContentDirectory, Dictionary<int, List<(string, int)>> skipCollection, List<LocationContainer<MetadataExtractor.Directory>> locationContainers, long personKey, int? directoryNumber, string file)
|
private static void ParallelFor(Configuration configuration, Dictionary<int, List<(string, int)>> skipCollection, List<LocationContainer<MetadataExtractor.Directory>> locationContainers, MappedFile mappedFile)
|
||||||
{
|
{
|
||||||
string checkFile;
|
string checkFile;
|
||||||
string[] fileMatches;
|
string[] fileMatches;
|
||||||
const string lnk = ".lnk";
|
const string lnk = ".lnk";
|
||||||
int? id, wholePercentages;
|
int? id, wholePercentages;
|
||||||
|
const bool fromDistanceContent = true;
|
||||||
IReadOnlyList<MetadataExtractor.Directory> directories;
|
IReadOnlyList<MetadataExtractor.Directory> directories;
|
||||||
List<(string File, int WholePercentages)>? wholePercentagesCollection;
|
List<(string File, int WholePercentages)>? wholePercentagesCollection;
|
||||||
bool fromDistanceContent = !file.EndsWith(lnk) && file.Contains(eDistanceContentDirectory);
|
if (!mappedFile.File.EndsWith(lnk))
|
||||||
if (!file.EndsWith(lnk))
|
(id, wholePercentages) = IMapping.GetConverted(configuration.FacesFileNameExtension, mappedFile.File);
|
||||||
(id, wholePercentages) = IMapping.GetConverted(configuration.FacesFileNameExtension, file);
|
|
||||||
else
|
else
|
||||||
(id, wholePercentages) = IMapping.GetConverted(configuration.FacesFileNameExtension, file[..^4]);
|
(id, wholePercentages) = IMapping.GetConverted(configuration.FacesFileNameExtension, mappedFile.File[..^4]);
|
||||||
if (id is null || wholePercentages is null)
|
if (id is null || wholePercentages is null)
|
||||||
return;
|
return;
|
||||||
if (skipCollection.TryGetValue(id.Value, out wholePercentagesCollection))
|
if (skipCollection.TryGetValue(id.Value, out wholePercentagesCollection))
|
||||||
@ -636,13 +655,13 @@ internal abstract class MapLogic
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (file.EndsWith(lnk) || (!configuration.DistanceMoveUnableToMatch && !configuration.DistanceRenameToMatch) || !File.Exists(file))
|
if (mappedFile.File.EndsWith(lnk) || (!configuration.DistanceMoveUnableToMatch && !configuration.DistanceRenameToMatch) || !File.Exists(mappedFile.File))
|
||||||
directories = new List<MetadataExtractor.Directory>();
|
directories = new List<MetadataExtractor.Directory>();
|
||||||
else
|
else
|
||||||
directories = MetadataExtractor.ImageMetadataReader.ReadMetadata(file);
|
directories = MetadataExtractor.ImageMetadataReader.ReadMetadata(mappedFile.File);
|
||||||
RectangleF? rectangle = ILocation.GetPercentagesRectangle(configuration.LocationDigits, wholePercentages.Value);
|
RectangleF? rectangle = ILocation.GetPercentagesRectangle(configuration.LocationDigits, wholePercentages.Value);
|
||||||
lock (locationContainers)
|
lock (locationContainers)
|
||||||
locationContainers.Add(new(fromDistanceContent, directoryNumber, file, personKey, id.Value, wholePercentages.Value, directories, rectangle, null));
|
locationContainers.Add(new(fromDistanceContent, mappedFile.DirectoryNumber, mappedFile.File, mappedFile.PersonKey, mappedFile.PersonDisplayDirectoryName, id.Value, wholePercentages.Value, directories, rectangle, null));
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void LookForPossibleDuplicates(Configuration configuration, ReadOnlyCollection<LocationContainer<MetadataExtractor.Directory>> locationContainers)
|
private static void LookForPossibleDuplicates(Configuration configuration, ReadOnlyCollection<LocationContainer<MetadataExtractor.Directory>> locationContainers)
|
||||||
@ -852,6 +871,7 @@ internal abstract class MapLogic
|
|||||||
int? wholePercentages;
|
int? wholePercentages;
|
||||||
string? checkDirectory;
|
string? checkDirectory;
|
||||||
ProgressBar progressBar;
|
ProgressBar progressBar;
|
||||||
|
string? yearDirectoryName;
|
||||||
string[] yearDirectories;
|
string[] yearDirectories;
|
||||||
string personKeyFormatted;
|
string personKeyFormatted;
|
||||||
string? personFirstInitial;
|
string? personFirstInitial;
|
||||||
@ -896,7 +916,7 @@ internal abstract class MapLogic
|
|||||||
{
|
{
|
||||||
timeSpan = new TimeSpan(DateTime.Now.Ticks - ticksDirectory.DirectoryDateTime.Ticks);
|
timeSpan = new TimeSpan(DateTime.Now.Ticks - ticksDirectory.DirectoryDateTime.Ticks);
|
||||||
if (timeSpan.TotalDays > 6)
|
if (timeSpan.TotalDays > 6)
|
||||||
throw new Exception($"{configuration.MappingDefaultName} are only allowed within x days!");
|
throw new Exception($"{configuration.MappingDefaultName} <{ticksDirectory.DirectoryDateTime}> are only allowed within x days!");
|
||||||
}
|
}
|
||||||
yearDirectories = Directory.GetDirectories(personKeyFormattedDirectory, "*", SearchOption.TopDirectoryOnly);
|
yearDirectories = Directory.GetDirectories(personKeyFormattedDirectory, "*", SearchOption.TopDirectoryOnly);
|
||||||
foreach (string yearDirectory in yearDirectories)
|
foreach (string yearDirectory in yearDirectories)
|
||||||
@ -907,6 +927,22 @@ internal abstract class MapLogic
|
|||||||
personNameDirectories = Directory.GetDirectories(yearDirectory, "*", SearchOption.TopDirectoryOnly);
|
personNameDirectories = Directory.GetDirectories(yearDirectory, "*", SearchOption.TopDirectoryOnly);
|
||||||
foreach (string file in files)
|
foreach (string file in files)
|
||||||
File.Delete(file);
|
File.Delete(file);
|
||||||
|
yearDirectoryName = Path.GetFileName(yearDirectory);
|
||||||
|
if (!string.IsNullOrEmpty(yearDirectoryName) && yearDirectoryName.Length != 8)
|
||||||
|
{
|
||||||
|
checkDirectory = Path.Combine(personKeyFormattedDirectory, "abcdefgh");
|
||||||
|
if (Directory.Exists(checkDirectory))
|
||||||
|
{
|
||||||
|
MoveDirectory(personNameDirectories, checkDirectory);
|
||||||
|
if (!check)
|
||||||
|
check = true;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
Directory.Move(yearDirectory, checkDirectory);
|
||||||
|
if (!check)
|
||||||
|
check = true;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
foreach (string personNameDirectory in personNameDirectories)
|
foreach (string personNameDirectory in personNameDirectories)
|
||||||
{
|
{
|
||||||
directoryNumber++;
|
directoryNumber++;
|
||||||
@ -916,7 +952,7 @@ internal abstract class MapLogic
|
|||||||
{
|
{
|
||||||
if (personKeyFormatted.Length != configuration.PersonBirthdayFormat.Length || !DateTime.TryParseExact(personKeyFormatted, configuration.PersonBirthdayFormat, CultureInfo.InvariantCulture, DateTimeStyles.None, out dateTime))
|
if (personKeyFormatted.Length != configuration.PersonBirthdayFormat.Length || !DateTime.TryParseExact(personKeyFormatted, configuration.PersonBirthdayFormat, CultureInfo.InvariantCulture, DateTimeStyles.None, out dateTime))
|
||||||
continue;
|
continue;
|
||||||
checkDirectory = Path.Combine(yearDirectory, $"X]{dateTime.Ticks}");
|
checkDirectory = Path.Combine(yearDirectory, $"X+{dateTime.Ticks}");
|
||||||
if (Directory.Exists(checkDirectory))
|
if (Directory.Exists(checkDirectory))
|
||||||
{
|
{
|
||||||
Directory.Delete(yearDirectory, recursive: true);
|
Directory.Delete(yearDirectory, recursive: true);
|
||||||
@ -932,7 +968,7 @@ internal abstract class MapLogic
|
|||||||
checkDirectory = Path.GetDirectoryName(ticksDirectory.Directory);
|
checkDirectory = Path.GetDirectoryName(ticksDirectory.Directory);
|
||||||
if (checkDirectory is null)
|
if (checkDirectory is null)
|
||||||
continue;
|
continue;
|
||||||
checkDirectory = Path.Combine(checkDirectory, $"({ticksDirectory.AlternateDirectoryDateTime.Ticks})");
|
checkDirectory = Path.Combine(checkDirectory, ticksDirectory.AlternateDirectoryDateTime.Ticks.ToString());
|
||||||
if (!Directory.Exists(checkDirectory))
|
if (!Directory.Exists(checkDirectory))
|
||||||
_ = Directory.CreateDirectory(checkDirectory);
|
_ = Directory.CreateDirectory(checkDirectory);
|
||||||
checkDirectory = Path.Combine(checkDirectory, personKeyFormatted);
|
checkDirectory = Path.Combine(checkDirectory, personKeyFormatted);
|
||||||
@ -1034,6 +1070,33 @@ internal abstract class MapLogic
|
|||||||
return results;
|
return results;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void MoveDirectory(string[] personNameDirectories, string destination)
|
||||||
|
{
|
||||||
|
string[] files;
|
||||||
|
string checkFile;
|
||||||
|
string checkDirectory;
|
||||||
|
string? personNameDirectoryName;
|
||||||
|
foreach (string personNameDirectory in personNameDirectories)
|
||||||
|
{
|
||||||
|
personNameDirectoryName = Path.GetFileName(personNameDirectory);
|
||||||
|
checkDirectory = Path.Combine(destination, personNameDirectoryName);
|
||||||
|
if (personNameDirectory == checkDirectory)
|
||||||
|
continue;
|
||||||
|
if (!Directory.Exists(checkDirectory))
|
||||||
|
_ = Directory.CreateDirectory(checkDirectory);
|
||||||
|
files = Directory.GetFiles(personNameDirectory, "*", SearchOption.TopDirectoryOnly);
|
||||||
|
foreach (string file in files)
|
||||||
|
{
|
||||||
|
checkFile = Path.Combine(checkDirectory, Path.GetFileName(file));
|
||||||
|
if (checkFile == file)
|
||||||
|
continue;
|
||||||
|
if (File.Exists(checkFile))
|
||||||
|
continue;
|
||||||
|
File.Move(file, checkFile);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
internal static void SetKeyValuePairsAndAddToCollections(Configuration configuration, ReadOnlyCollection<PersonContainer> personContainers, Dictionary<long, PersonContainer> personKeyToPersonContainer, ReadOnlyCollection<PersonKeyFormattedIdThenWholePercentages> personKeyFormattedIdThenWholePercentagesCollection, Dictionary<long, int> personKeyToCount, Dictionary<string, PersonContainer> personKeyFormattedToPersonContainer, Dictionary<long, List<PersonContainer>> personKeyToPersonContainerCollection, List<(PersonKeyFormattedIdThenWholePercentages, PersonContainer)> possiblyNewPersonDisplayDirectoryNamesAndPersonContainer)
|
internal static void SetKeyValuePairsAndAddToCollections(Configuration configuration, ReadOnlyCollection<PersonContainer> personContainers, Dictionary<long, PersonContainer> personKeyToPersonContainer, ReadOnlyCollection<PersonKeyFormattedIdThenWholePercentages> personKeyFormattedIdThenWholePercentagesCollection, Dictionary<long, int> personKeyToCount, Dictionary<string, PersonContainer> personKeyFormattedToPersonContainer, Dictionary<long, List<PersonContainer>> personKeyToPersonContainerCollection, List<(PersonKeyFormattedIdThenWholePercentages, PersonContainer)> possiblyNewPersonDisplayDirectoryNamesAndPersonContainer)
|
||||||
{
|
{
|
||||||
PersonBirthday? personBirthday;
|
PersonBirthday? personBirthday;
|
||||||
@ -1228,21 +1291,21 @@ internal abstract class MapLogic
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static List<LocationContainer<MetadataExtractor.Directory>> GetLocationContainers(Shared.Models.Methods.IDistance<MetadataExtractor.Directory> distance, int maxDegreeOfParallelism, Configuration configuration, long ticks, ReadOnlyCollection<PersonContainer> personContainers, string eDistanceContentDirectory, Dictionary<int, List<(string, int)>> skipCollection, List<Record> records)
|
internal static List<LocationContainer<MetadataExtractor.Directory>> GetLocationContainers(Shared.Models.Methods.IDistance<MetadataExtractor.Directory> distance, int maxDegreeOfParallelism, Configuration configuration, long ticks, ReadOnlyCollection<PersonContainer> personContainers, Dictionary<int, List<(string, int)>> skipCollection, List<Record> records)
|
||||||
{
|
{
|
||||||
List<LocationContainer<MetadataExtractor.Directory>> results = new();
|
List<LocationContainer<MetadataExtractor.Directory>> results = new();
|
||||||
List<(long PersonKey, int? DirectoryNumber, string File)> collection = GetCollection(configuration, personContainers, records);
|
List<MappedFile> mappedFiles = GetMappedFiles(configuration, personContainers, records);
|
||||||
if (collection.Count > 0 && (configuration.DistanceMoveUnableToMatch || configuration.DistanceRenameToMatch))
|
if (mappedFiles.Count > 0 && (configuration.DistanceMoveUnableToMatch || configuration.DistanceRenameToMatch))
|
||||||
{
|
{
|
||||||
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 Mapped Face Files Collection - {totalSeconds} total second(s)";
|
string message = $") Building Mapped Face Files Collection - {totalSeconds} total second(s)";
|
||||||
ParallelOptions parallelOptions = new() { MaxDegreeOfParallelism = maxDegreeOfParallelism };
|
ParallelOptions parallelOptions = new() { MaxDegreeOfParallelism = maxDegreeOfParallelism };
|
||||||
ProgressBarOptions options = new() { ProgressCharacter = '─', ProgressBarOnBottom = true, DisableBottomPercentage = true };
|
ProgressBarOptions options = new() { ProgressCharacter = '─', ProgressBarOnBottom = true, DisableBottomPercentage = true };
|
||||||
using ProgressBar progressBar = new(collection.Count, message, options);
|
using ProgressBar progressBar = new(mappedFiles.Count, message, options);
|
||||||
_ = Parallel.For(0, collection.Count, parallelOptions, (i, state) =>
|
_ = Parallel.For(0, mappedFiles.Count, parallelOptions, (i, state) =>
|
||||||
{
|
{
|
||||||
progressBar.Tick();
|
progressBar.Tick();
|
||||||
ParallelFor(configuration, eDistanceContentDirectory, skipCollection, results, collection[i].PersonKey, collection[i].DirectoryNumber, collection[i].File);
|
ParallelFor(configuration, skipCollection, results, mappedFiles[i]);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
ReadOnlyCollection<LocationContainer<MetadataExtractor.Directory>> locationContainers = new(results.OrderBy(l => l.DirectoryNumber).ToArray());
|
ReadOnlyCollection<LocationContainer<MetadataExtractor.Directory>> locationContainers = new(results.OrderBy(l => l.DirectoryNumber).ToArray());
|
||||||
@ -1702,4 +1765,64 @@ internal abstract class MapLogic
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static ReadOnlyCollection<ReadOnlyCollection<LocationContainer<MetadataExtractor.Directory>>> GetCollections(List<LocationContainer<MetadataExtractor.Directory>> locationContainers)
|
||||||
|
{
|
||||||
|
List<ReadOnlyCollection<LocationContainer<MetadataExtractor.Directory>>> results = new();
|
||||||
|
List<LocationContainer<MetadataExtractor.Directory>>? collection;
|
||||||
|
Dictionary<long, List<LocationContainer<MetadataExtractor.Directory>>> keyValuePairs = new();
|
||||||
|
foreach (LocationContainer<MetadataExtractor.Directory> locationContainer in locationContainers)
|
||||||
|
{
|
||||||
|
if (!locationContainer.FromDistanceContent)
|
||||||
|
continue;
|
||||||
|
if (!keyValuePairs.TryGetValue(locationContainer.PersonKey, out collection))
|
||||||
|
{
|
||||||
|
keyValuePairs.Add(locationContainer.PersonKey, new());
|
||||||
|
if (!keyValuePairs.TryGetValue(locationContainer.PersonKey, out collection))
|
||||||
|
throw new Exception();
|
||||||
|
}
|
||||||
|
collection.Add(locationContainer);
|
||||||
|
}
|
||||||
|
foreach (KeyValuePair<long, List<LocationContainer<MetadataExtractor.Directory>>> keyValuePair in keyValuePairs)
|
||||||
|
results.Add(new(keyValuePair.Value));
|
||||||
|
return new(results);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string? GetDisplayDirectoryName(ReadOnlyDictionary<long, List<PersonContainer>> readOnlyPersonKeyToPersonContainerCollection, ReadOnlyDictionary<string, PersonContainer> readOnlyPersonKeyFormattedToPersonContainer, long personKey, string personKeyFormatted)
|
||||||
|
{
|
||||||
|
string? result;
|
||||||
|
PersonContainer? personContainer;
|
||||||
|
List<PersonContainer>? collection;
|
||||||
|
_ = readOnlyPersonKeyToPersonContainerCollection.TryGetValue(personKey, out collection);
|
||||||
|
if (collection is not null)
|
||||||
|
result = collection[0].DisplayDirectoryName;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (!readOnlyPersonKeyFormattedToPersonContainer.TryGetValue(personKeyFormatted, out personContainer))
|
||||||
|
result = null;
|
||||||
|
else
|
||||||
|
result = personContainer.DisplayDirectoryName;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static void SaveMappedRelations(Configuration configuration, Shared.Models.Methods.IDistance<MetadataExtractor.Directory> distance, string a2PeopleContentDirectory, string eDistanceContentDirectory, long ticks, List<LocationContainer<MetadataExtractor.Directory>> locationContainers, ReadOnlyDictionary<string, PersonContainer> readOnlyPersonKeyFormattedToPersonContainer, ReadOnlyDictionary<long, List<PersonContainer>> readOnlyPersonKeyToPersonContainerCollection)
|
||||||
|
{
|
||||||
|
string personKeyFormatted;
|
||||||
|
string? displayDirectoryName;
|
||||||
|
int totalSeconds = (int)Math.Floor(new TimeSpan(DateTime.Now.Ticks - ticks).TotalSeconds);
|
||||||
|
string message = $") Save Mapped Relations - {totalSeconds} total second(s)";
|
||||||
|
ProgressBarOptions options = new() { ProgressCharacter = '─', ProgressBarOnBottom = true, DisableBottomPercentage = true };
|
||||||
|
ReadOnlyCollection<ReadOnlyCollection<LocationContainer<MetadataExtractor.Directory>>> collections = GetCollections(locationContainers);
|
||||||
|
using ProgressBar progressBar = new(collections.Count, message, options);
|
||||||
|
foreach (ReadOnlyCollection<LocationContainer<MetadataExtractor.Directory>> collection in collections)
|
||||||
|
{
|
||||||
|
progressBar.Tick();
|
||||||
|
if (collection.Count == 0)
|
||||||
|
continue;
|
||||||
|
personKeyFormatted = IPersonBirthday.GetFormatted(configuration.PersonBirthdayFormat, collection[0].PersonKey);
|
||||||
|
displayDirectoryName = GetDisplayDirectoryName(readOnlyPersonKeyToPersonContainerCollection, readOnlyPersonKeyFormattedToPersonContainer, collection[0].PersonKey, personKeyFormatted);
|
||||||
|
distance.SaveMappedForOutputResolutions(a2PeopleContentDirectory, eDistanceContentDirectory, configuration.RangeDistanceTolerance, collection, personKeyFormatted, displayDirectoryName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
10
Shared/.kanbn/tasks/google-api-for-family.md
Normal file
10
Shared/.kanbn/tasks/google-api-for-family.md
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
---
|
||||||
|
created: 2023-08-19T18:52:14.422Z
|
||||||
|
updated: 2023-08-19T18:52:14.418Z
|
||||||
|
assigned: ""
|
||||||
|
progress: 0
|
||||||
|
tags: []
|
||||||
|
started: 2023-08-19T18:52:14.422Z
|
||||||
|
---
|
||||||
|
|
||||||
|
# Google API for family
|
14
Shared/.vscode/tasks.json
vendored
14
Shared/.vscode/tasks.json
vendored
@ -19,12 +19,6 @@
|
|||||||
"command": "& L:/DevOps/Mesa_FI/File-Folder-Helper/bin/Release/net7.0/win-x64/publish/File-Folder-Helper.exe s M .kanbn/tasks",
|
"command": "& L:/DevOps/Mesa_FI/File-Folder-Helper/bin/Release/net7.0/win-x64/publish/File-Folder-Helper.exe s M .kanbn/tasks",
|
||||||
"problemMatcher": []
|
"problemMatcher": []
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"label": "File-Folder-Helper AOT s G 638263275367065735",
|
|
||||||
"type": "shell",
|
|
||||||
"command": "& L:/DevOps/Mesa_FI/File-Folder-Helper/bin/Release/net7.0/win-x64/publish/File-Folder-Helper.exe s G 'D:/1-Images-A/Images-dd514b88-Results/A2) People/dd514b88/{}' -g 'D:/1-Images-A/Images-dd514b88-Results/A2) People/dd514b88/([])/File-Folder-Helper/638263275367065735/638263275367065735.ged' -d 'D:/1-Images-A/Images-dd514b88-Results/A2) People/dd514b88/{2}'",
|
|
||||||
"problemMatcher": []
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"label": "File-Folder-Helper AOT s C Backup",
|
"label": "File-Folder-Helper AOT s C Backup",
|
||||||
"type": "shell",
|
"type": "shell",
|
||||||
@ -34,7 +28,13 @@
|
|||||||
{
|
{
|
||||||
"label": "File-Folder-Helper AOT s G File System to Genealogical Data Communication",
|
"label": "File-Folder-Helper AOT s G File System to Genealogical Data Communication",
|
||||||
"type": "shell",
|
"type": "shell",
|
||||||
"command": "& L:/DevOps/Mesa_FI/File-Folder-Helper/bin/Release/net7.0/win-x64/publish/File-Folder-Helper.exe s G 'D:/1-Images-A/Images-dd514b88-Results/A2) People/dd514b88/([])/File-Folder-Helper/638268289384407819' -d 'D:/1-Images-A/Images-dd514b88-Results/A2) People/dd514b88/{2}'",
|
"command": "& L:/DevOps/Mesa_FI/File-Folder-Helper/bin/Release/net7.0/win-x64/publish/File-Folder-Helper.exe s G 'D:/1-Images-A/Images-dd514b88-Results/A2)People/dd514b88/([])/File-Folder-Helper/638280519245151237' -d 'D:/1-Images-A/Images-dd514b88-Results/A2)People/dd514b88/{2}'",
|
||||||
|
"problemMatcher": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": "File-Folder-Helper AOT s VSCode Possible",
|
||||||
|
"type": "shell",
|
||||||
|
"command": "& L:/DevOps/Mesa_FI/File-Folder-Helper/bin/Release/net7.0/win-x64/publish/File-Folder-Helper.exe s V 'L:/Git/View-by-Distance-MKLink-Console/Instance'",
|
||||||
"problemMatcher": []
|
"problemMatcher": []
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
@ -2,5 +2,13 @@ using System.Drawing;
|
|||||||
|
|
||||||
namespace View_by_Distance.Shared.Models;
|
namespace View_by_Distance.Shared.Models;
|
||||||
|
|
||||||
public record LocationContainer<T>(bool FromDistanceContent, int? DirectoryNumber, string File, long PersonKey, int Id, int WholePercentages, IReadOnlyList<T> Directories, RectangleF? Rectangle, Location? Location)
|
public record LocationContainer<T>(bool FromDistanceContent,
|
||||||
{ }
|
int? DirectoryNumber,
|
||||||
|
string File,
|
||||||
|
long PersonKey,
|
||||||
|
string DisplayDirectoryName,
|
||||||
|
int Id,
|
||||||
|
int WholePercentages,
|
||||||
|
IReadOnlyList<T> Directories,
|
||||||
|
RectangleF? Rectangle,
|
||||||
|
Location? Location);
|
@ -6,5 +6,6 @@ public interface IDistance<T>
|
|||||||
{
|
{
|
||||||
|
|
||||||
void ReviewLocationContainerDistanceTolerance(float locationContainerDistanceTolerance, ReadOnlyCollection<LocationContainer<T>> locationContainers);
|
void ReviewLocationContainerDistanceTolerance(float locationContainerDistanceTolerance, ReadOnlyCollection<LocationContainer<T>> locationContainers);
|
||||||
|
void SaveMappedForOutputResolutions(string a2PeopleContentDirectory, string eDistanceContentDirectory, float[] rangeDistanceTolerance, ReadOnlyCollection<LocationContainer<T>> locationContainers, string personKeyFormatted, string? displayDirectoryName);
|
||||||
|
|
||||||
}
|
}
|
@ -40,7 +40,7 @@ public interface IPerson
|
|||||||
bool TestStatic_IsDefaultName(string personDisplayDirectoryName) =>
|
bool TestStatic_IsDefaultName(string personDisplayDirectoryName) =>
|
||||||
IsDefaultName(personDisplayDirectoryName);
|
IsDefaultName(personDisplayDirectoryName);
|
||||||
static bool IsDefaultName(string personDisplayDirectoryName) =>
|
static bool IsDefaultName(string personDisplayDirectoryName) =>
|
||||||
personDisplayDirectoryName.Length > 1 && personDisplayDirectoryName[0] == 'X' && personDisplayDirectoryName[1] == ']';
|
personDisplayDirectoryName.Length > 1 && personDisplayDirectoryName[0] == 'X' && personDisplayDirectoryName[1] == '+';
|
||||||
|
|
||||||
bool TestStatic_IsDefaultName(Models.PersonContainer personContainer) =>
|
bool TestStatic_IsDefaultName(Models.PersonContainer personContainer) =>
|
||||||
IsDefaultName(personContainer);
|
IsDefaultName(personContainer);
|
||||||
|
@ -8,9 +8,9 @@ public interface ISorting
|
|||||||
static Models.Sorting[] Sort(List<Models.Sorting> collection) =>
|
static Models.Sorting[] Sort(List<Models.Sorting> collection) =>
|
||||||
(from l in collection orderby l.DistancePermyriad, l.DaysDelta select l).ToArray();
|
(from l in collection orderby l.DistancePermyriad, l.DaysDelta select l).ToArray();
|
||||||
|
|
||||||
Models.Sorting TestStatic_Get(int faceDistancePermyriad, double rangeDistanceTolerance, Models.FaceDistance faceDistanceEncoding, Models.FaceDistance faceDistanceLength) =>
|
Models.Sorting TestStatic_Get(int faceDistancePermyriad, float distanceTolerance, Models.FaceDistance faceDistanceEncoding, Models.FaceDistance faceDistanceLength) =>
|
||||||
Get(faceDistancePermyriad, rangeDistanceTolerance, faceDistanceEncoding, faceDistanceLength);
|
Get(faceDistancePermyriad, distanceTolerance, faceDistanceEncoding, faceDistanceLength);
|
||||||
static Models.Sorting Get(int faceDistancePermyriad, double rangeDistanceTolerance, Models.FaceDistance faceDistanceEncoding, Models.FaceDistance faceDistanceLength) =>
|
static Models.Sorting Get(int faceDistancePermyriad, float distanceTolerance, Models.FaceDistance faceDistanceEncoding, Models.FaceDistance faceDistanceLength) =>
|
||||||
Sorting.Get(faceDistancePermyriad, rangeDistanceTolerance, faceDistanceEncoding, faceDistanceLength);
|
Sorting.Get(faceDistancePermyriad, distanceTolerance, faceDistanceEncoding, faceDistanceLength);
|
||||||
|
|
||||||
}
|
}
|
@ -3,7 +3,7 @@ namespace View_by_Distance.Shared.Models.Stateless.Methods;
|
|||||||
internal abstract class Sorting
|
internal abstract class Sorting
|
||||||
{
|
{
|
||||||
|
|
||||||
internal static Models.Sorting Get(int faceDistancePermyriad, double rangeDistanceTolerance, Models.FaceDistance faceDistanceEncoding, Models.FaceDistance faceDistanceLength)
|
internal static Models.Sorting Get(int faceDistancePermyriad, float distanceTolerance, Models.FaceDistance faceDistanceEncoding, Models.FaceDistance faceDistanceLength)
|
||||||
{
|
{
|
||||||
Models.Sorting result;
|
Models.Sorting result;
|
||||||
if (faceDistanceLength.Length is null)
|
if (faceDistanceLength.Length is null)
|
||||||
@ -13,7 +13,7 @@ internal abstract class Sorting
|
|||||||
TimeSpan timeSpan = new(faceDistanceLength.DateTimeOriginalThenMinimumDateTime.Ticks - faceDistanceEncoding.DateTimeOriginalThenMinimumDateTime.Ticks);
|
TimeSpan timeSpan = new(faceDistanceLength.DateTimeOriginalThenMinimumDateTime.Ticks - faceDistanceEncoding.DateTimeOriginalThenMinimumDateTime.Ticks);
|
||||||
bool older = timeSpan.TotalMilliseconds < 0;
|
bool older = timeSpan.TotalMilliseconds < 0;
|
||||||
int daysDelta = (int)Math.Round(Math.Abs(timeSpan.TotalDays), 0);
|
int daysDelta = (int)Math.Round(Math.Abs(timeSpan.TotalDays), 0);
|
||||||
int distancePermyriad = (int)(faceDistanceLength.Length.Value / rangeDistanceTolerance * faceDistancePermyriad);
|
int distancePermyriad = (int)(faceDistanceLength.Length.Value / distanceTolerance * faceDistancePermyriad);
|
||||||
result = new(daysDelta, distancePermyriad, faceDistanceLength.Id, older, faceDistanceLength.WholePercentages.Value);
|
result = new(daysDelta, distancePermyriad, faceDistanceLength.Id, older, faceDistanceLength.WholePercentages.Value);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user