Filter same id

RelationLogic
LookForAbandoned
This commit is contained in:
Mike Phares 2023-09-09 14:59:15 -07:00
parent 331d98793e
commit 4b8b942528
29 changed files with 709 additions and 430 deletions

View File

@ -12,13 +12,7 @@ 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, internal record Record(string File, FaceRecognitionDotNet.FaceEncoding FaceRecognitionDotNetFaceEncoding);
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;
@ -446,10 +440,10 @@ public partial class E_Distance : IDistance<MetadataExtractor.Directory>
continue; continue;
if (faceDistanceContainer.Face.Mapping.MappingFromFilterPre.InSkipCollection is not null && faceDistanceContainer.Face.Mapping.MappingFromFilterPre.InSkipCollection.Value) if (faceDistanceContainer.Face.Mapping.MappingFromFilterPre.InSkipCollection is not null && faceDistanceContainer.Face.Mapping.MappingFromFilterPre.InSkipCollection.Value)
throw new NotSupportedException(nameof(PreFilterSetFaceDistances)); throw new NotSupportedException(nameof(PreFilterSetFaceDistances));
if (faceDistanceContainer.Face.Mapping.MappingFromFilterPre.IsFocusModel is not null && faceDistanceContainer.Face.Mapping.MappingFromFilterPre.IsFocusModel.Value) if (faceDistanceContainer.Face.Mapping.MappingFromFilterPre.IsFocusModel is not null && !faceDistanceContainer.Face.Mapping.MappingFromFilterPre.IsFocusModel.Value)
throw new NotSupportedException(nameof(PreFilterSetFaceDistances)); continue;
if (faceDistanceContainer.Face.Mapping.MappingFromFilterPre.IsFocusRelativePath is not null && faceDistanceContainer.Face.Mapping.MappingFromFilterPre.IsFocusRelativePath.Value) if (faceDistanceContainer.Face.Mapping.MappingFromFilterPre.IsFocusRelativePath is not null && !faceDistanceContainer.Face.Mapping.MappingFromFilterPre.IsFocusRelativePath.Value)
throw new NotSupportedException(nameof(PreFilterSetFaceDistances)); continue;
if (faceDistanceContainer.Face.Mapping.MappingFromFilterPost.InSkipCollection is not null && faceDistanceContainer.Face.Mapping.MappingFromFilterPost.InSkipCollection.Value) if (faceDistanceContainer.Face.Mapping.MappingFromFilterPost.InSkipCollection is not null && faceDistanceContainer.Face.Mapping.MappingFromFilterPost.InSkipCollection.Value)
continue; continue;
if (faceDistanceContainer.Face.Mapping.MappingFromFilterPost.IsFocusPerson is not null && !faceDistanceContainer.Face.Mapping.MappingFromFilterPost.IsFocusPerson.Value) if (faceDistanceContainer.Face.Mapping.MappingFromFilterPost.IsFocusPerson is not null && !faceDistanceContainer.Face.Mapping.MappingFromFilterPost.IsFocusPerson.Value)
@ -489,122 +483,27 @@ public partial class E_Distance : IDistance<MetadataExtractor.Directory>
return new(results); return new(results);
} }
private static void WriteVsCodeFiles(string eDistanceContentDirectory, string? displayDirectoryName, string directory) private static ReadOnlyCollection<RelationContainer> GetRelationCollections(int faceDistancePermyriad, int locationContainerDistanceTake, float distanceTolerance, List<Record> records)
{ {
string json; List<RelationContainer> results = new();
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(string locationContainerDebugDirectory, bool isCounterPersonYear, string? displayDirectoryName, Dictionary<string, int> keyValuePairs, List<string> linkedOnce, List<string> linkedTwice, List<string> linkedThrice, List<string> linkedFour, List<string> linkedFive)
{
string checkFile;
string debugFile;
string checkDirectory;
string? yearDirectory;
string? personNameDirectory;
string? maybeTicksDirectoryName;
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 (string file in linkedFour)
keyValuePairs[file] += 1;
foreach (string file in linkedFive)
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);
maybeTicksDirectoryName = Path.GetFileName(personKeyFormattedDirectory);
if (string.IsNullOrEmpty(personNameDirectory) || string.IsNullOrEmpty(yearDirectory) || string.IsNullOrEmpty(personKeyFormattedDirectory) || string.IsNullOrEmpty(personNameDirectoryName))
continue;
if (maybeTicksDirectoryName == locationContainerDebugDirectory)
checkDirectory = Path.Combine(yearDirectory, $"{keyValuePair.Value}{new string(Convert.ToChar(65 + keyValuePair.Value), 7)}");
else
{
if (!string.IsNullOrEmpty(locationContainerDebugDirectory))
continue;
checkDirectory = Path.Combine(personKeyFormattedDirectory, $"{keyValuePair.Value}{new string(Convert.ToChar(65 + keyValuePair.Value), 7)}");
}
if (maybeTicksDirectoryName != locationContainerDebugDirectory)
{
if (isCounterPersonYear || string.IsNullOrEmpty(displayDirectoryName))
checkDirectory = Path.Combine(checkDirectory, personNameDirectoryName);
else
checkDirectory = Path.Combine(checkDirectory, displayDirectoryName[0].ToString());
}
if (checkDirectory == personNameDirectory)
continue;
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);
debugFile = $"{keyValuePair.Key[..^4]}.gif";
if (File.Exists(debugFile))
{
checkFile = Path.Combine(checkDirectory, $"{Path.GetFileName(keyValuePair.Key)[..^4]}.gif");
if (File.Exists(checkFile))
continue;
File.Move(debugFile, checkFile);
}
if (maybeTicksDirectoryName == locationContainerDebugDirectory && !string.IsNullOrEmpty(displayDirectoryName))
{
checkDirectory = Path.Combine(checkDirectory, displayDirectoryName);
if (!Directory.Exists(checkDirectory))
_ = Directory.CreateDirectory(checkDirectory);
}
}
}
private static void SaveMappedForOutputResolutions(string locationContainerDebugDirectory, string eDistanceContentDirectory, float distanceTolerance, long personKey, bool isCounterPersonYear, string personKeyFormatted, string? displayDirectoryName, List<Record> records, string directory)
{
int years;
string text;
string fileName; string fileName;
FileInfo fileInfo; FileHolder fileHolder;
int distancePermyriad;
List<string> files = new(); List<string> files = new();
List<string> lines = new();
List<Mapped> results = new();
List<string> linkedFive = new();
List<string> linkedFour = new();
List<string> linkedOnce = new();
long ticks = DateTime.Now.Ticks; long ticks = DateTime.Now.Ticks;
string fileNameWithoutExtension;
List<string> linkedTwice = new();
List<string> linkedThrice = new();
FaceDistance? faceDistanceEncoding; FaceDistance? faceDistanceEncoding;
List<string> relativePaths = new(); List<Relation> mappedRelations;
List<FaceDistance> faceDistanceLengths; List<FaceDistance> faceDistanceLengths;
Uri uri = new(eDistanceContentDirectory);
Dictionary<string, int> keyValuePairs = new();
List<FaceDistance> faceDistanceEncodings = new(); List<FaceDistance> faceDistanceEncodings = new();
foreach (Record record in records) foreach (Record record in records)
{ {
files.Add(record.File); files.Add(record.File);
relativePaths.Add(uri.MakeRelativeUri(new(record.File)).OriginalString);
faceDistanceEncodings.Add(new(record.FaceRecognitionDotNetFaceEncoding)); faceDistanceEncodings.Add(new(record.FaceRecognitionDotNetFaceEncoding));
} }
foreach (Record record in records) foreach (Record record in records)
{ {
lines.Clear(); mappedRelations = new();
results.Clear(); fileHolder = new(record.File);
fileInfo = new(record.File);
if (files.Count > 1) if (files.Count > 1)
{ {
faceDistanceEncoding = new(record.FaceRecognitionDotNetFaceEncoding); faceDistanceEncoding = new(record.FaceRecognitionDotNetFaceEncoding);
@ -613,77 +512,25 @@ public partial class E_Distance : IDistance<MetadataExtractor.Directory>
faceDistanceLengths = FaceRecognition.FaceDistances(new(faceDistanceEncodings), faceDistanceEncoding); faceDistanceLengths = FaceRecognition.FaceDistances(new(faceDistanceEncodings), faceDistanceEncoding);
for (int i = 0; i < faceDistanceLengths.Count; i++) for (int i = 0; i < faceDistanceLengths.Count; i++)
{ {
fileName = Path.GetFileName(relativePaths[i]); fileName = Path.GetFileName(files[i]);
if (fileName == fileInfo.Name) if (fileName == fileHolder.Name)
continue; continue;
FaceDistance faceDistance = faceDistanceLengths[i]; FaceDistance faceDistance = faceDistanceLengths[i];
if (faceDistance.Length > distanceTolerance) if (faceDistance.Length is null || faceDistance.Length.Value > distanceTolerance)
continue; continue;
fileNameWithoutExtension = Path.GetFileNameWithoutExtension(Path.GetFileNameWithoutExtension(fileName)); distancePermyriad = (int)(faceDistance.Length.Value * faceDistancePermyriad);
results.Add(new(files[i], faceDistance.Length, $"[[{fileNameWithoutExtension}]]", $"![{faceDistance.Length}]({relativePaths[i]})")); mappedRelations.Add(new(distancePermyriad, files[i]));
} }
} }
results = (from l in results orderby l.Length select l).Take(3).ToList(); mappedRelations = (from l in mappedRelations orderby l.DistancePermyriad select l).Take(locationContainerDistanceTake).ToList();
keyValuePairs.Add(record.File, results.Count); results.Add(new(fileHolder, new(mappedRelations)));
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;
}
if (!linkedFour.Contains(mapped.File))
{
linkedFour.Add(mapped.File);
continue;
}
if (!linkedFive.Contains(mapped.File))
{
linkedFive.Add(mapped.File);
continue;
}
}
if (isCounterPersonYear)
(years, _) = Shared.Models.Stateless.Methods.IAge.GetAge(ticks, fileInfo.CreationTime.Ticks);
else
(years, _) = Shared.Models.Stateless.Methods.IAge.GetAge(fileInfo.CreationTime.Ticks, personKey);
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($"![0]({uri.MakeRelativeUri(new(record.File)).OriginalString})");
lines.Add($"__{fileNameWithoutExtension}__");
if (isCounterPersonYear)
lines.Add($"#{years}yrs-ago");
else
lines.Add($"#{years}yrs-old");
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(locationContainerDebugDirectory, isCounterPersonYear, displayDirectoryName, keyValuePairs, linkedOnce, linkedTwice, linkedThrice, linkedFour, linkedFive); return new(results);
} }
void IDistance<MetadataExtractor.Directory>.SaveMappedForOutputResolutions(string locationContainerDebugDirectory, string a2PeopleContentDirectory, string eDistanceContentDirectory, float locationContainerDistanceTolerance, ReadOnlyCollection<LocationContainer<MetadataExtractor.Directory>> locationContainers, long personKey, bool isCounterPersonYear, string personKeyFormatted, string? displayDirectoryName) ReadOnlyCollection<RelationContainer> IDistance<MetadataExtractor.Directory>.GetRelationContainers(int faceDistancePermyriad, int locationContainerDistanceTake, float locationContainerDistanceTolerance, ReadOnlyCollection<LocationContainer<MetadataExtractor.Directory>> locationContainers)
{ {
ReadOnlyCollection<RelationContainer> result;
string? json; string? json;
List<Record> records = new(); List<Record> records = new();
Shared.Models.FaceEncoding? modelsFaceEncoding; Shared.Models.FaceEncoding? modelsFaceEncoding;
@ -699,15 +546,8 @@ public partial class E_Distance : IDistance<MetadataExtractor.Directory>
faceRecognitionDotNetFaceEncoding = FaceRecognition.LoadFaceEncoding(modelsFaceEncoding.RawEncoding); faceRecognitionDotNetFaceEncoding = FaceRecognition.LoadFaceEncoding(modelsFaceEncoding.RawEncoding);
records.Add(new(locationContainer.File, faceRecognitionDotNetFaceEncoding)); records.Add(new(locationContainer.File, faceRecognitionDotNetFaceEncoding));
} }
string directory = Path.Combine(a2PeopleContentDirectory, locationContainerDistanceTolerance.ToString(), personKeyFormatted); result = GetRelationCollections(faceDistancePermyriad, locationContainerDistanceTake, locationContainerDistanceTolerance, records);
if (!Directory.Exists(directory)) return result;
_ = Directory.CreateDirectory(directory);
if (records.Count > 0)
{
WriteVsCodeFiles(eDistanceContentDirectory, displayDirectoryName, directory);
SaveMappedForOutputResolutions(locationContainerDebugDirectory, eDistanceContentDirectory, locationContainerDistanceTolerance, personKey, isCounterPersonYear, personKeyFormatted, displayDirectoryName, records, directory);
}
_ = Shared.Models.Stateless.Methods.IPath.DeleteEmptyDirectories(directory);
} }
} }

View File

@ -843,6 +843,7 @@ public partial class DlibDotNet
configuration.FaceConfidencePercent, configuration.FaceConfidencePercent,
configuration.FaceDistancePermyriad, configuration.FaceDistancePermyriad,
configuration.LocationContainerDebugDirectory, configuration.LocationContainerDebugDirectory,
configuration.LocationContainerDistanceTake,
configuration.LocationContainerDistanceTolerance, configuration.LocationContainerDistanceTolerance,
configuration.LocationDigits, configuration.LocationDigits,
configuration.MappingDefaultName, configuration.MappingDefaultName,

View File

@ -33,6 +33,7 @@ public class Configuration
public string[]? LoadOrCreateThenSaveImageFacesResultsForOutputResolutions { get; set; } public string[]? LoadOrCreateThenSaveImageFacesResultsForOutputResolutions { get; set; }
public bool? LoadPhotoPrismLocations { get; set; } public bool? LoadPhotoPrismLocations { get; set; }
public string? LocationContainerDebugDirectory { get; set; } public string? LocationContainerDebugDirectory { get; set; }
public int? LocationContainerDistanceTake { get; set; }
public float? LocationContainerDistanceTolerance { get; set; } public float? LocationContainerDistanceTolerance { get; set; }
public int? LocationDigits { get; set; } public int? LocationDigits { get; set; }
public int? LocationFactor { get; set; } public int? LocationFactor { get; set; }
@ -132,6 +133,7 @@ public class Configuration
// if (configuration?.LoadOrCreateThenSaveImageFacesResultsForOutputResolutions is null) throw new NullReferenceException(nameof(configuration.LoadOrCreateThenSaveImageFacesResultsForOutputResolutions)); // if (configuration?.LoadOrCreateThenSaveImageFacesResultsForOutputResolutions is null) throw new NullReferenceException(nameof(configuration.LoadOrCreateThenSaveImageFacesResultsForOutputResolutions));
if (configuration?.LoadPhotoPrismLocations is null) throw new NullReferenceException(nameof(configuration.LoadPhotoPrismLocations)); if (configuration?.LoadPhotoPrismLocations is null) throw new NullReferenceException(nameof(configuration.LoadPhotoPrismLocations));
if (configuration?.LocationContainerDebugDirectory is null) throw new NullReferenceException(nameof(configuration.LocationContainerDebugDirectory)); if (configuration?.LocationContainerDebugDirectory is null) throw new NullReferenceException(nameof(configuration.LocationContainerDebugDirectory));
if (configuration?.LocationContainerDistanceTake is null) throw new NullReferenceException(nameof(configuration.LocationContainerDistanceTake));
// if (configuration?.LocationContainerDistanceTolerance is null) throw new NullReferenceException(nameof(configuration.LocationContainerDistanceTolerance)); // if (configuration?.LocationContainerDistanceTolerance is null) throw new NullReferenceException(nameof(configuration.LocationContainerDistanceTolerance));
if (configuration?.LocationDigits is null) throw new NullReferenceException(nameof(configuration.LocationDigits)); if (configuration?.LocationDigits is null) throw new NullReferenceException(nameof(configuration.LocationDigits));
if (configuration?.LocationFactor is null) throw new NullReferenceException(nameof(configuration.LocationFactor)); if (configuration?.LocationFactor is null) throw new NullReferenceException(nameof(configuration.LocationFactor));
@ -218,6 +220,7 @@ public class Configuration
configuration.LoadOrCreateThenSaveImageFacesResultsForOutputResolutions ?? Array.Empty<string>(), configuration.LoadOrCreateThenSaveImageFacesResultsForOutputResolutions ?? Array.Empty<string>(),
configuration.LoadPhotoPrismLocations.Value, configuration.LoadPhotoPrismLocations.Value,
configuration.LocationContainerDebugDirectory, configuration.LocationContainerDebugDirectory,
configuration.LocationContainerDistanceTake.Value,
configuration.LocationContainerDistanceTolerance, configuration.LocationContainerDistanceTolerance,
configuration.LocationDigits.Value, configuration.LocationDigits.Value,
configuration.LocationFactor.Value, configuration.LocationFactor.Value,

View File

@ -27,6 +27,7 @@ public record Configuration(Property.Models.Configuration PropertyConfiguration,
string[] LoadOrCreateThenSaveImageFacesResultsForOutputResolutions, string[] LoadOrCreateThenSaveImageFacesResultsForOutputResolutions,
bool LoadPhotoPrismLocations, bool LoadPhotoPrismLocations,
string LocationContainerDebugDirectory, string LocationContainerDebugDirectory,
int LocationContainerDistanceTake,
float? LocationContainerDistanceTolerance, float? LocationContainerDistanceTolerance,
int LocationDigits, int LocationDigits,
int LocationFactor, int LocationFactor,

View File

@ -6,6 +6,7 @@ public record Configuration(bool DeletePossibleDuplicates,
int FaceConfidencePercent, int FaceConfidencePercent,
int FaceDistancePermyriad, int FaceDistancePermyriad,
string LocationContainerDebugDirectory, string LocationContainerDebugDirectory,
int LocationContainerDistanceTake,
float? LocationContainerDistanceTolerance, float? LocationContainerDistanceTolerance,
int LocationDigits, int LocationDigits,
string MappingDefaultName, string MappingDefaultName,

View File

@ -315,7 +315,7 @@ public partial class MapLogic : Shared.Models.Methods.IMapLogic
if (lossCount != 0 || unableToMatchCount != 0) if (lossCount != 0 || unableToMatchCount != 0)
{ } { }
if (!string.IsNullOrEmpty(a2PeopleContentDirectory) && configuration.LocationContainerDistanceTolerance is not null) if (!string.IsNullOrEmpty(a2PeopleContentDirectory) && configuration.LocationContainerDistanceTolerance is not null)
Stateless.MapLogic.SaveMappedRelations(configuration, distance, a2PeopleContentDirectory, eDistanceContentDirectory, ticks, locationContainers, readOnlyPersonKeyFormattedToPersonContainer, readOnlyPersonKeyToPersonContainerCollection); Stateless.RelationLogic.SaveMappedRelations(configuration, distance, a2PeopleContentDirectory, eDistanceContentDirectory, ticks, locationContainers, readOnlyPersonKeyFormattedToPersonContainer, readOnlyPersonKeyToPersonContainerCollection);
if (!string.IsNullOrEmpty(configuration.LocationContainerDebugDirectory)) if (!string.IsNullOrEmpty(configuration.LocationContainerDebugDirectory))
throw new Exception($"{nameof(configuration.LocationContainerDebugDirectory)} is not IsNullOrEmpty!"); throw new Exception($"{nameof(configuration.LocationContainerDebugDirectory)} is not IsNullOrEmpty!");
} }
@ -681,9 +681,9 @@ public partial class MapLogic : Shared.Models.Methods.IMapLogic
continue; continue;
if (face.Mapping.MappingFromFilterPre.InSkipCollection is not null && face.Mapping.MappingFromFilterPre.InSkipCollection.Value) if (face.Mapping.MappingFromFilterPre.InSkipCollection is not null && face.Mapping.MappingFromFilterPre.InSkipCollection.Value)
throw new NotSupportedException(nameof(Shared.Models.Methods.IDistance<object>)); throw new NotSupportedException(nameof(Shared.Models.Methods.IDistance<object>));
if (face.Mapping.MappingFromFilterPre.IsFocusModel is not null && face.Mapping.MappingFromFilterPre.IsFocusModel.Value) if (face.Mapping.MappingFromFilterPre.IsFocusModel is not null && !face.Mapping.MappingFromFilterPre.IsFocusModel.Value)
throw new NotSupportedException(nameof(Shared.Models.Methods.IDistance<object>)); throw new NotSupportedException(nameof(Shared.Models.Methods.IDistance<object>));
if (face.Mapping.MappingFromFilterPre.IsFocusRelativePath is not null && face.Mapping.MappingFromFilterPre.IsFocusRelativePath.Value) if (face.Mapping.MappingFromFilterPre.IsFocusRelativePath is not null && !face.Mapping.MappingFromFilterPre.IsFocusRelativePath.Value)
throw new NotSupportedException(nameof(Shared.Models.Methods.IDistance<object>)); throw new NotSupportedException(nameof(Shared.Models.Methods.IDistance<object>));
if (face.Mapping.MappingFromFilterPost.InSkipCollection is not null && face.Mapping.MappingFromFilterPost.InSkipCollection.Value) if (face.Mapping.MappingFromFilterPost.InSkipCollection is not null && face.Mapping.MappingFromFilterPost.InSkipCollection.Value)
throw new NotSupportedException(nameof(Shared.Models.Methods.IDistance<object>)); throw new NotSupportedException(nameof(Shared.Models.Methods.IDistance<object>));
@ -696,6 +696,8 @@ public partial class MapLogic : Shared.Models.Methods.IMapLogic
throw new NotSupportedException(); throw new NotSupportedException();
if (faceDistanceLength.Length == 0) if (faceDistanceLength.Length == 0)
continue; continue;
if (faceDistanceLength.Id == faceDistanceEncoding.Id)
continue;
if (faceDistanceLength.MappingFromFilterPost is null) if (faceDistanceLength.MappingFromFilterPost is null)
throw new NotSupportedException(); throw new NotSupportedException();
if (faceDistanceLength.MappingFromFilterPost.CanReMap is not null && !_Configuration.ReMap) if (faceDistanceLength.MappingFromFilterPost.CanReMap is not null && !_Configuration.ReMap)
@ -890,9 +892,9 @@ public partial class MapLogic : Shared.Models.Methods.IMapLogic
mappingFromFilterPost = sortingContainer.Source.MappingFromFilterPost; mappingFromFilterPost = sortingContainer.Source.MappingFromFilterPost;
if (sortingContainer.Source.MappingFromFilterPre.InSkipCollection is not null && sortingContainer.Source.MappingFromFilterPre.InSkipCollection.Value) if (sortingContainer.Source.MappingFromFilterPre.InSkipCollection is not null && sortingContainer.Source.MappingFromFilterPre.InSkipCollection.Value)
throw new NotSupportedException(nameof(GetSortingCollection)); throw new NotSupportedException(nameof(GetSortingCollection));
if (sortingContainer.Source.MappingFromFilterPre.IsFocusModel is not null && sortingContainer.Source.MappingFromFilterPre.IsFocusModel.Value) if (sortingContainer.Source.MappingFromFilterPre.IsFocusModel is not null && !sortingContainer.Source.MappingFromFilterPre.IsFocusModel.Value)
throw new NotSupportedException(nameof(GetSortingCollection)); throw new NotSupportedException(nameof(GetSortingCollection));
if (sortingContainer.Source.MappingFromFilterPre.IsFocusRelativePath is not null && sortingContainer.Source.MappingFromFilterPre.IsFocusRelativePath.Value) if (sortingContainer.Source.MappingFromFilterPre.IsFocusRelativePath is not null && !sortingContainer.Source.MappingFromFilterPre.IsFocusRelativePath.Value)
throw new NotSupportedException(nameof(GetSortingCollection)); throw new NotSupportedException(nameof(GetSortingCollection));
if (sortingContainer.Source.MappingFromFilterPost.InSkipCollection is not null && sortingContainer.Source.MappingFromFilterPost.InSkipCollection.Value) if (sortingContainer.Source.MappingFromFilterPost.InSkipCollection is not null && sortingContainer.Source.MappingFromFilterPost.InSkipCollection.Value)
throw new NotSupportedException(nameof(GetSortingCollection)); throw new NotSupportedException(nameof(GetSortingCollection));
@ -905,6 +907,8 @@ public partial class MapLogic : Shared.Models.Methods.IMapLogic
throw new NotSupportedException(); throw new NotSupportedException();
if (!wholePercentagesToMapping.TryGetValue(sorting.WholePercentages, out keyMapping)) if (!wholePercentagesToMapping.TryGetValue(sorting.WholePercentages, out keyMapping))
throw new NotSupportedException(); 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) if (keyMapping.MappingFromFilterPost.CanReMap is not null && !_Configuration.ReMap)
throw new NotSupportedException(nameof(GetSortingCollection)); throw new NotSupportedException(nameof(GetSortingCollection));
if (keyMapping.MappingFromFilterPost.CanReMap is not null && !keyMapping.MappingFromFilterPost.CanReMap.Value) if (keyMapping.MappingFromFilterPost.CanReMap is not null && !keyMapping.MappingFromFilterPost.CanReMap.Value)
@ -1337,14 +1341,14 @@ public partial class MapLogic : Shared.Models.Methods.IMapLogic
string? directoryName; string? directoryName;
List<int> distinctFilteredIds = IContainer.GetFilteredDistinctIds(propertyConfiguration, containers); List<int> distinctFilteredIds = IContainer.GetFilteredDistinctIds(propertyConfiguration, containers);
LookForAbandoned(propertyConfiguration, distinctFilteredIds); LookForAbandoned(propertyConfiguration, distinctFilteredIds);
Stateless.MapLogic.LookForAbandoned(bResultsFullGroupDirectory, distinctFilteredIds); Stateless.LookForAbandonedLogic.LookForAbandoned(bResultsFullGroupDirectory, distinctFilteredIds);
directories = Directory.GetDirectories(cResultsFullGroupDirectory, "*", SearchOption.TopDirectoryOnly); directories = Directory.GetDirectories(cResultsFullGroupDirectory, "*", SearchOption.TopDirectoryOnly);
foreach (string directory in directories) foreach (string directory in directories)
{ {
directoryName = Path.GetFileName(directory); directoryName = Path.GetFileName(directory);
if (string.IsNullOrEmpty(directoryName) || directoryName.Length != 2 && directoryName.Length != 4) if (string.IsNullOrEmpty(directoryName) || directoryName.Length != 2 && directoryName.Length != 4)
continue; continue;
Stateless.MapLogic.LookForAbandoned(distinctFilteredIds, directory, directoryName); Stateless.LookForAbandonedLogic.LookForAbandoned(distinctFilteredIds, directory, directoryName);
} }
directories = Directory.GetDirectories(dResultsFullGroupDirectory, "*", SearchOption.TopDirectoryOnly); directories = Directory.GetDirectories(dResultsFullGroupDirectory, "*", SearchOption.TopDirectoryOnly);
foreach (string directory in directories) foreach (string directory in directories)
@ -1352,7 +1356,7 @@ public partial class MapLogic : Shared.Models.Methods.IMapLogic
directoryName = Path.GetFileName(directory); directoryName = Path.GetFileName(directory);
if (string.IsNullOrEmpty(directoryName) || directoryName.Length != 2 && directoryName.Length != 4) if (string.IsNullOrEmpty(directoryName) || directoryName.Length != 2 && directoryName.Length != 4)
continue; continue;
Stateless.MapLogic.LookForAbandoned(distinctFilteredIds, directory, directoryName); Stateless.LookForAbandonedLogic.LookForAbandoned(distinctFilteredIds, directory, directoryName);
} }
directories = Directory.GetDirectories(d2ResultsFullGroupDirectory, "*", SearchOption.TopDirectoryOnly); directories = Directory.GetDirectories(d2ResultsFullGroupDirectory, "*", SearchOption.TopDirectoryOnly);
foreach (string directory in directories) foreach (string directory in directories)
@ -1360,7 +1364,7 @@ public partial class MapLogic : Shared.Models.Methods.IMapLogic
directoryName = Path.GetFileName(directory); directoryName = Path.GetFileName(directory);
if (string.IsNullOrEmpty(directoryName) || directoryName.Length != 2 && directoryName.Length != 4) if (string.IsNullOrEmpty(directoryName) || directoryName.Length != 2 && directoryName.Length != 4)
continue; continue;
Stateless.MapLogic.LookForAbandoned(distinctFilteredIds, directory, directoryName); Stateless.LookForAbandonedLogic.LookForAbandoned(distinctFilteredIds, directory, directoryName);
} }
} }

View File

@ -0,0 +1,72 @@
using System.Collections.ObjectModel;
using View_by_Distance.Shared.Models;
namespace View_by_Distance.Map.Models.Stateless;
internal abstract class DecadeLogic
{
internal static string GetDecade(MappingFromItem mappingFromItem)
{
string result;
string year;
if (mappingFromItem.DateTimeOriginal is null)
{
year = mappingFromItem.MinimumDateTime.Year.ToString();
result = year[3] > '4' ? $"#{year[..3]}+" : $"#{year[..3]}-";
}
else
{
year = mappingFromItem.DateTimeOriginal.Value.Year.ToString();
result = year[3] > '4' ? $"^{year[..3]}+" : $"^{year[..3]}-";
}
return result;
}
internal static void SetCreationTimeMaybeMoveToDecade(Property.Models.Configuration propertyConfiguration, bool moveToDecade, MappingFromItem mappingFromItem, ReadOnlyCollection<LocationContainer<MetadataExtractor.Directory>> locationContainers)
{
DateTime dateTime;
FileInfo fileInfo;
string halfDecade;
string checkDirectory;
string? yearDirectory;
string yearDirectoryName;
string? personNameDirectory;
string personNameDirectoryName;
string? personKeyFormattedDirectory;
string? personKeyFormattedDirectoryName;
foreach (LocationContainer<MetadataExtractor.Directory> locationContainer in locationContainers)
{
fileInfo = new(locationContainer.File);
if (!fileInfo.Exists)
continue;
dateTime = mappingFromItem.DateTimeOriginal is null ? mappingFromItem.MinimumDateTime : mappingFromItem.DateTimeOriginal.Value;
if (fileInfo.CreationTime != dateTime)
File.SetCreationTime(locationContainer.File, dateTime);
if (!moveToDecade)
continue;
personNameDirectory = Path.GetDirectoryName(locationContainer.File);
if (string.IsNullOrEmpty(personNameDirectory))
continue;
personNameDirectoryName = Path.GetFileName(personNameDirectory);
yearDirectory = Path.GetDirectoryName(personNameDirectory);
if (string.IsNullOrEmpty(yearDirectory))
continue;
yearDirectoryName = Path.GetFileName(yearDirectory);
personKeyFormattedDirectory = Path.GetDirectoryName(yearDirectory);
if (string.IsNullOrEmpty(personKeyFormattedDirectory))
continue;
personKeyFormattedDirectoryName = Path.GetFileName(personKeyFormattedDirectory);
if (personKeyFormattedDirectoryName.Length != propertyConfiguration.PersonBirthdayFormat.Length)
break;
halfDecade = GetDecade(mappingFromItem);
if (halfDecade == yearDirectoryName)
continue;
checkDirectory = Path.Combine(personKeyFormattedDirectory, halfDecade, personNameDirectoryName);
if (!Directory.Exists(checkDirectory))
_ = Directory.CreateDirectory(checkDirectory);
File.Move(locationContainer.File, Path.Combine(checkDirectory, Path.GetFileName(locationContainer.File)));
}
}
}

View File

@ -0,0 +1,51 @@
using View_by_Distance.Shared.Models.Stateless.Methods;
namespace View_by_Distance.Map.Models.Stateless;
internal abstract class LookForAbandonedLogic
{
internal static void LookForAbandoned(List<int> distinctFilteredIds, string directory, string directoryName)
{
string fileNameWithoutExtension;
bool nameWithoutExtensionIsIdFormat;
List<string> renameCollection = new();
bool nameWithoutExtensionIsPaddedIdFormat;
int sortOrderOnlyLengthIndex = IDirectory.GetSortOrderOnlyLengthIndex();
string[] distinctFilteredIdsValues = distinctFilteredIds.Select(l => l.ToString()).ToArray();
string[] files = Directory.GetFiles(directory, "*", SearchOption.AllDirectories);
foreach (string file in files)
{
fileNameWithoutExtension = Path.GetFileNameWithoutExtension(Path.GetFileNameWithoutExtension(Path.GetFileNameWithoutExtension(file)));
nameWithoutExtensionIsIdFormat = IProperty.NameWithoutExtensionIsIdFormat(fileNameWithoutExtension);
nameWithoutExtensionIsPaddedIdFormat = IDirectory.NameWithoutExtensionIsPaddedIdFormat(fileNameWithoutExtension, sortOrderOnlyLengthIndex);
if (!nameWithoutExtensionIsIdFormat && !nameWithoutExtensionIsPaddedIdFormat)
continue;
if (distinctFilteredIdsValues.Contains(fileNameWithoutExtension))
continue;
renameCollection.Add(file);
}
if (renameCollection.Count > 0)
{
if (directoryName.Length == 2)
IDirectory.MoveFiles(renameCollection, directoryName, $"{directoryName[0]}abd{directoryName[^1]}");
else if (directoryName.Length == 4)
IDirectory.MoveFiles(renameCollection, directoryName, $"{directoryName[..2]}abd{directoryName[^2..]}");
else
throw new NotSupportedException();
}
}
internal static void LookForAbandoned(string bResultsFullGroupDirectory, List<int> distinctFilteredIds)
{
string[] directories = Directory.GetDirectories(bResultsFullGroupDirectory, "*", SearchOption.TopDirectoryOnly);
foreach (string directory in directories)
{
string? directoryName = Path.GetFileName(directory);
if (string.IsNullOrEmpty(directoryName) || (directoryName.Length != 2 && directoryName.Length != 4))
continue;
LookForAbandoned(distinctFilteredIds, directory, directoryName);
}
}
}

View File

@ -841,37 +841,6 @@ internal abstract class MapLogic
return results; return results;
} }
internal static void LookForAbandoned(List<int> distinctFilteredIds, string directory, string directoryName)
{
string fileNameWithoutExtension;
bool nameWithoutExtensionIsIdFormat;
List<string> renameCollection = new();
bool nameWithoutExtensionIsPaddedIdFormat;
int sortOrderOnlyLengthIndex = IDirectory.GetSortOrderOnlyLengthIndex();
string[] distinctFilteredIdsValues = distinctFilteredIds.Select(l => l.ToString()).ToArray();
string[] files = Directory.GetFiles(directory, "*", SearchOption.AllDirectories);
foreach (string file in files)
{
fileNameWithoutExtension = Path.GetFileNameWithoutExtension(Path.GetFileNameWithoutExtension(Path.GetFileNameWithoutExtension(file)));
nameWithoutExtensionIsIdFormat = IProperty.NameWithoutExtensionIsIdFormat(fileNameWithoutExtension);
nameWithoutExtensionIsPaddedIdFormat = IDirectory.NameWithoutExtensionIsPaddedIdFormat(fileNameWithoutExtension, sortOrderOnlyLengthIndex);
if (!nameWithoutExtensionIsIdFormat && !nameWithoutExtensionIsPaddedIdFormat)
continue;
if (distinctFilteredIdsValues.Contains(fileNameWithoutExtension))
continue;
renameCollection.Add(file);
}
if (renameCollection.Count > 0)
{
if (directoryName.Length == 2)
IDirectory.MoveFiles(renameCollection, directoryName, $"{directoryName[0]}abd{directoryName[^1]}");
else if (directoryName.Length == 4)
IDirectory.MoveFiles(renameCollection, directoryName, $"{directoryName[..2]}abd{directoryName[^2..]}");
else
throw new NotSupportedException();
}
}
private static List<Record> GetRecords(Configuration configuration, bool? isDefault, string[] files, int directoryNumber, string personKeyFormatted, List<string> distinct, string? personDisplayDirectoryName) private static List<Record> GetRecords(Configuration configuration, bool? isDefault, string[] files, int directoryNumber, string personKeyFormatted, List<string> distinct, string? personDisplayDirectoryName)
{ {
List<Record> results = new(); List<Record> results = new();
@ -1652,18 +1621,6 @@ internal abstract class MapLogic
} }
} }
internal static void LookForAbandoned(string bResultsFullGroupDirectory, List<int> distinctFilteredIds)
{
string[] directories = Directory.GetDirectories(bResultsFullGroupDirectory, "*", SearchOption.TopDirectoryOnly);
foreach (string directory in directories)
{
string? directoryName = Path.GetFileName(directory);
if (string.IsNullOrEmpty(directoryName) || (directoryName.Length != 2 && directoryName.Length != 4))
continue;
LookForAbandoned(distinctFilteredIds, directory, directoryName);
}
}
internal static ReadOnlyDictionary<int, List<int>> ConvertSkip(Dictionary<int, List<(string, int)>> skipCollection) internal static ReadOnlyDictionary<int, List<int>> ConvertSkip(Dictionary<int, List<(string, int)>> skipCollection)
{ {
Dictionary<int, List<int>> results = new(); Dictionary<int, List<int>> results = new();
@ -1712,168 +1669,6 @@ internal abstract class MapLogic
return new(results); return new(results);
} }
internal static string GetDecade(MappingFromItem mappingFromItem)
{
string result;
string year;
if (mappingFromItem.DateTimeOriginal is null)
{
year = mappingFromItem.MinimumDateTime.Year.ToString();
result = year[3] > '4' ? $"#{year[..3]}+" : $"#{year[..3]}-";
}
else
{
year = mappingFromItem.DateTimeOriginal.Value.Year.ToString();
result = year[3] > '4' ? $"^{year[..3]}+" : $"^{year[..3]}-";
}
return result;
}
internal static void SetCreationTimeMaybeMoveToDecade(Property.Models.Configuration propertyConfiguration, bool moveToDecade, MappingFromItem mappingFromItem, ReadOnlyCollection<LocationContainer<MetadataExtractor.Directory>> locationContainers)
{
DateTime dateTime;
FileInfo fileInfo;
string halfDecade;
string checkDirectory;
string? yearDirectory;
string yearDirectoryName;
string? personNameDirectory;
string personNameDirectoryName;
string? personKeyFormattedDirectory;
string? personKeyFormattedDirectoryName;
foreach (LocationContainer<MetadataExtractor.Directory> locationContainer in locationContainers)
{
fileInfo = new(locationContainer.File);
if (!fileInfo.Exists)
continue;
dateTime = mappingFromItem.DateTimeOriginal is null ? mappingFromItem.MinimumDateTime : mappingFromItem.DateTimeOriginal.Value;
if (fileInfo.CreationTime != dateTime)
File.SetCreationTime(locationContainer.File, dateTime);
if (!moveToDecade)
continue;
personNameDirectory = Path.GetDirectoryName(locationContainer.File);
if (string.IsNullOrEmpty(personNameDirectory))
continue;
personNameDirectoryName = Path.GetFileName(personNameDirectory);
yearDirectory = Path.GetDirectoryName(personNameDirectory);
if (string.IsNullOrEmpty(yearDirectory))
continue;
yearDirectoryName = Path.GetFileName(yearDirectory);
personKeyFormattedDirectory = Path.GetDirectoryName(yearDirectory);
if (string.IsNullOrEmpty(personKeyFormattedDirectory))
continue;
personKeyFormattedDirectoryName = Path.GetFileName(personKeyFormattedDirectory);
if (personKeyFormattedDirectoryName.Length != propertyConfiguration.PersonBirthdayFormat.Length)
break;
halfDecade = GetDecade(mappingFromItem);
if (halfDecade == yearDirectoryName)
continue;
checkDirectory = Path.Combine(personKeyFormattedDirectory, halfDecade, personNameDirectoryName);
if (!Directory.Exists(checkDirectory))
_ = Directory.CreateDirectory(checkDirectory);
File.Move(locationContainer.File, Path.Combine(checkDirectory, Path.GetFileName(locationContainer.File)));
}
}
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;
}
private static void AddDisplayDirectoryNames(Configuration configuration, string eDistanceContentDirectory, ReadOnlyDictionary<string, PersonContainer> readOnlyPersonKeyFormattedToPersonContainer, ReadOnlyDictionary<long, List<PersonContainer>> readOnlyPersonKeyToPersonContainerCollection, ReadOnlyCollection<ReadOnlyCollection<LocationContainer<MetadataExtractor.Directory>>> collections)
{
bool isCounterPersonYear;
string personKeyFormatted;
string? displayDirectoryName;
string? checkDirectory = Path.Combine(eDistanceContentDirectory, configuration.LocationContainerDebugDirectory);
_ = IPath.DeleteEmptyDirectories(checkDirectory);
foreach (ReadOnlyCollection<LocationContainer<MetadataExtractor.Directory>> collection in collections)
{
if (configuration.LocationContainerDistanceTolerance is null)
break;
isCounterPersonYear = IPersonBirthday.IsCounterPersonYear(new DateTime(collection[0].PersonKey).Year);
if (isCounterPersonYear)
continue;
personKeyFormatted = IPersonBirthday.GetFormatted(configuration.PersonBirthdayFormat, collection[0].PersonKey);
checkDirectory = Path.Combine(eDistanceContentDirectory, configuration.LocationContainerDebugDirectory, personKeyFormatted);
if (!Directory.Exists(checkDirectory))
continue;
displayDirectoryName = GetDisplayDirectoryName(readOnlyPersonKeyToPersonContainerCollection, readOnlyPersonKeyFormattedToPersonContainer, collection[0].PersonKey, personKeyFormatted);
if (string.IsNullOrEmpty(displayDirectoryName))
continue;
foreach (string yearDirectory in Directory.GetDirectories(checkDirectory, "*", SearchOption.TopDirectoryOnly))
{
checkDirectory = Path.Combine(yearDirectory, displayDirectoryName);
if (!Directory.Exists(checkDirectory))
_ = Directory.CreateDirectory(checkDirectory);
}
checkDirectory = Path.Combine(eDistanceContentDirectory, configuration.LocationContainerDebugDirectory, personKeyFormatted, displayDirectoryName);
if (!Directory.Exists(checkDirectory))
_ = Directory.CreateDirectory(checkDirectory);
}
}
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)
{
bool isCounterPersonYear;
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)
{
if (configuration.LocationContainerDistanceTolerance is null)
break;
progressBar.Tick();
if (collection.Count == 0)
continue;
isCounterPersonYear = IPersonBirthday.IsCounterPersonYear(new DateTime(collection[0].PersonKey).Year);
personKeyFormatted = IPersonBirthday.GetFormatted(configuration.PersonBirthdayFormat, collection[0].PersonKey);
displayDirectoryName = GetDisplayDirectoryName(readOnlyPersonKeyToPersonContainerCollection, readOnlyPersonKeyFormattedToPersonContainer, collection[0].PersonKey, personKeyFormatted);
distance.SaveMappedForOutputResolutions(configuration.LocationContainerDebugDirectory, a2PeopleContentDirectory, eDistanceContentDirectory, configuration.LocationContainerDistanceTolerance.Value, collection, collection[0].PersonKey, isCounterPersonYear, personKeyFormatted, displayDirectoryName);
}
if (!string.IsNullOrEmpty(configuration.LocationContainerDebugDirectory))
AddDisplayDirectoryNames(configuration, eDistanceContentDirectory, readOnlyPersonKeyFormattedToPersonContainer, readOnlyPersonKeyToPersonContainerCollection, collections);
}
internal static bool? CanReMap(long[] jLinkResolvedPersonKeys, ReadOnlyDictionary<int, ReadOnlyCollection<PersonContainer>>? wholePercentagesToPersonContainers, MappingFromLocation mappingFromLocation) internal static bool? CanReMap(long[] jLinkResolvedPersonKeys, ReadOnlyDictionary<int, ReadOnlyCollection<PersonContainer>>? wholePercentagesToPersonContainers, MappingFromLocation mappingFromLocation)
{ {
bool? result; bool? result;

View File

@ -38,7 +38,7 @@ public interface IMapLogic
void TestStatic_SetCreationTimeMaybeMoveToDecade(Property.Models.Configuration propertyConfiguration, bool moveToDecade, Shared.Models.MappingFromItem mappingFromItem, ReadOnlyCollection<Shared.Models.LocationContainer<MetadataExtractor.Directory>> locationContainers) => void TestStatic_SetCreationTimeMaybeMoveToDecade(Property.Models.Configuration propertyConfiguration, bool moveToDecade, Shared.Models.MappingFromItem mappingFromItem, ReadOnlyCollection<Shared.Models.LocationContainer<MetadataExtractor.Directory>> locationContainers) =>
SetCreationTimeMaybeMoveToDecade(propertyConfiguration, moveToDecade, mappingFromItem, locationContainers); SetCreationTimeMaybeMoveToDecade(propertyConfiguration, moveToDecade, mappingFromItem, locationContainers);
static void SetCreationTimeMaybeMoveToDecade(Property.Models.Configuration propertyConfiguration, bool moveToDecade, Shared.Models.MappingFromItem mappingFromItem, ReadOnlyCollection<Shared.Models.LocationContainer<MetadataExtractor.Directory>> locationContainers) => static void SetCreationTimeMaybeMoveToDecade(Property.Models.Configuration propertyConfiguration, bool moveToDecade, Shared.Models.MappingFromItem mappingFromItem, ReadOnlyCollection<Shared.Models.LocationContainer<MetadataExtractor.Directory>> locationContainers) =>
MapLogic.SetCreationTimeMaybeMoveToDecade(propertyConfiguration, moveToDecade, mappingFromItem, locationContainers); DecadeLogic.SetCreationTimeMaybeMoveToDecade(propertyConfiguration, moveToDecade, mappingFromItem, locationContainers);
bool? TestStatic_CanReMap(long[] jLinkResolvedPersonKeys, ReadOnlyDictionary<int, ReadOnlyCollection<Shared.Models.PersonContainer>>? wholePercentagesToPersonContainers, Shared.Models.MappingFromLocation mappingFromLocation) => bool? TestStatic_CanReMap(long[] jLinkResolvedPersonKeys, ReadOnlyDictionary<int, ReadOnlyCollection<Shared.Models.PersonContainer>>? wholePercentagesToPersonContainers, Shared.Models.MappingFromLocation mappingFromLocation) =>
CanReMap(jLinkResolvedPersonKeys, wholePercentagesToPersonContainers, mappingFromLocation); CanReMap(jLinkResolvedPersonKeys, wholePercentagesToPersonContainers, mappingFromLocation);
@ -48,6 +48,6 @@ public interface IMapLogic
string TestStatic_GetDecade(Shared.Models.MappingFromItem mappingFromItem) => string TestStatic_GetDecade(Shared.Models.MappingFromItem mappingFromItem) =>
GetDecade(mappingFromItem); GetDecade(mappingFromItem);
static string GetDecade(Shared.Models.MappingFromItem mappingFromItem) => static string GetDecade(Shared.Models.MappingFromItem mappingFromItem) =>
MapLogic.GetDecade(mappingFromItem); DecadeLogic.GetDecade(mappingFromItem);
} }

View File

@ -0,0 +1,400 @@
using ShellProgressBar;
using System.Collections.ObjectModel;
using View_by_Distance.Shared.Models;
using View_by_Distance.Shared.Models.Stateless.Methods;
namespace View_by_Distance.Map.Models.Stateless;
internal abstract class RelationLogic
{
internal record RelationCollection(ReadOnlyCollection<RelationContainer> RelationContainers,
ReadOnlyCollection<string> Linked1,
ReadOnlyCollection<string> Linked2,
ReadOnlyCollection<string> Linked3,
ReadOnlyCollection<string> Linked4,
ReadOnlyCollection<string> Linked5,
ReadOnlyCollection<string> Linked6,
ReadOnlyCollection<string> Linked7,
ReadOnlyCollection<string> Linked8,
ReadOnlyCollection<string> Linked9,
ReadOnlyDictionary<string, string> MovedFiles);
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;
}
private static void AddDisplayDirectoryNames(Configuration configuration, string eDistanceContentDirectory, ReadOnlyDictionary<string, PersonContainer> readOnlyPersonKeyFormattedToPersonContainer, ReadOnlyDictionary<long, List<PersonContainer>> readOnlyPersonKeyToPersonContainerCollection, ReadOnlyCollection<ReadOnlyCollection<LocationContainer<MetadataExtractor.Directory>>> collections)
{
bool isCounterPersonYear;
string personKeyFormatted;
string? displayDirectoryName;
string? checkDirectory = Path.Combine(eDistanceContentDirectory, configuration.LocationContainerDebugDirectory);
_ = IPath.DeleteEmptyDirectories(checkDirectory);
foreach (ReadOnlyCollection<LocationContainer<MetadataExtractor.Directory>> collection in collections)
{
if (configuration.LocationContainerDistanceTolerance is null)
break;
isCounterPersonYear = IPersonBirthday.IsCounterPersonYear(new DateTime(collection[0].PersonKey).Year);
if (isCounterPersonYear)
continue;
personKeyFormatted = IPersonBirthday.GetFormatted(configuration.PersonBirthdayFormat, collection[0].PersonKey);
checkDirectory = Path.Combine(eDistanceContentDirectory, configuration.LocationContainerDebugDirectory, personKeyFormatted);
if (!Directory.Exists(checkDirectory))
continue;
displayDirectoryName = GetDisplayDirectoryName(readOnlyPersonKeyToPersonContainerCollection, readOnlyPersonKeyFormattedToPersonContainer, collection[0].PersonKey, personKeyFormatted);
if (string.IsNullOrEmpty(displayDirectoryName))
continue;
foreach (string yearDirectory in Directory.GetDirectories(checkDirectory, "*", SearchOption.TopDirectoryOnly))
{
checkDirectory = Path.Combine(yearDirectory, displayDirectoryName);
if (!Directory.Exists(checkDirectory))
_ = Directory.CreateDirectory(checkDirectory);
}
checkDirectory = Path.Combine(eDistanceContentDirectory, configuration.LocationContainerDebugDirectory, personKeyFormatted, displayDirectoryName);
if (!Directory.Exists(checkDirectory))
_ = Directory.CreateDirectory(checkDirectory);
}
}
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\", } } }";
_ = 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\": [] } ] }");
_ = IPath.WriteAllText(Path.Combine(vsCodeDirectory, "tasks.json"), json, updateDateWhenMatches: false, compareBeforeWrite: true, updateToWhenMatches: null);
}
private static ReadOnlyDictionary<string, string> MoveFiles(string locationContainerDebugDirectory, bool isCounterPersonYear, string? displayDirectoryName, List<string> linked1, List<string> linked2, List<string> linked3, List<string> linked4, List<string> linked5, List<string> linked6, List<string> linked7, List<string> linked8, List<string> linked9)
{
Dictionary<string, string> results = new();
char c;
string checkFile;
string debugFile;
string checkDirectory;
string? yearDirectory;
string? personNameDirectory;
string? maybeTicksDirectoryName;
string? personNameDirectoryName;
string? personKeyFormattedDirectory;
Dictionary<string, int> fullNameToCount = new();
foreach (string file in linked1)
fullNameToCount.Add(file, 1);
foreach (string file in linked2)
fullNameToCount[file] += 1;
foreach (string file in linked3)
fullNameToCount[file] += 1;
foreach (string file in linked4)
fullNameToCount[file] += 1;
foreach (string file in linked5)
fullNameToCount[file] += 1;
foreach (string file in linked6)
fullNameToCount[file] += 1;
foreach (string file in linked7)
fullNameToCount[file] += 1;
foreach (string file in linked8)
fullNameToCount[file] += 1;
foreach (string file in linked9)
fullNameToCount[file] += 1;
foreach (KeyValuePair<string, int> keyValuePair in fullNameToCount)
{
personNameDirectory = Path.GetDirectoryName(keyValuePair.Key);
yearDirectory = Path.GetDirectoryName(personNameDirectory);
personNameDirectoryName = Path.GetFileName(personNameDirectory);
personKeyFormattedDirectory = Path.GetDirectoryName(yearDirectory);
maybeTicksDirectoryName = Path.GetFileName(personKeyFormattedDirectory);
if (string.IsNullOrEmpty(personNameDirectory) || string.IsNullOrEmpty(yearDirectory) || string.IsNullOrEmpty(personKeyFormattedDirectory) || string.IsNullOrEmpty(personNameDirectoryName))
continue;
c = Convert.ToChar(48 + keyValuePair.Value);
if (c is ':' or ';' or '<' or '=' or '>' or '?')
c = '_';
if (maybeTicksDirectoryName == locationContainerDebugDirectory)
checkDirectory = Path.Combine(yearDirectory, $"{keyValuePair.Value}{new string(c, 7)}");
else
{
if (!string.IsNullOrEmpty(locationContainerDebugDirectory))
continue;
checkDirectory = Path.Combine(personKeyFormattedDirectory, $"{keyValuePair.Value}{new string(c, 7)}");
}
if (maybeTicksDirectoryName != locationContainerDebugDirectory)
{
if (isCounterPersonYear || string.IsNullOrEmpty(displayDirectoryName))
checkDirectory = Path.Combine(checkDirectory, personNameDirectoryName);
else
checkDirectory = Path.Combine(checkDirectory, displayDirectoryName[0].ToString());
}
if (checkDirectory == personNameDirectory)
continue;
if (!Directory.Exists(checkDirectory))
_ = Directory.CreateDirectory(checkDirectory);
checkFile = Path.Combine(checkDirectory, Path.GetFileName(keyValuePair.Key));
if (File.Exists(checkFile))
continue;
results.Add(keyValuePair.Key, checkFile);
File.Move(keyValuePair.Key, checkFile);
debugFile = $"{keyValuePair.Key[..^4]}.gif";
if (File.Exists(debugFile))
{
checkFile = Path.Combine(checkDirectory, $"{Path.GetFileName(keyValuePair.Key)[..^4]}.gif");
if (File.Exists(checkFile))
continue;
File.Move(debugFile, checkFile);
}
if (maybeTicksDirectoryName == locationContainerDebugDirectory && !string.IsNullOrEmpty(displayDirectoryName))
{
checkDirectory = Path.Combine(checkDirectory, displayDirectoryName);
if (!Directory.Exists(checkDirectory))
_ = Directory.CreateDirectory(checkDirectory);
}
}
return new(results);
}
private static RelationCollection GetMappedRelationCollection(string locationContainerDebugDirectory, int take, bool isCounterPersonYear, string? displayDirectoryName, ReadOnlyCollection<RelationContainer> relationContainers)
{
RelationCollection result;
List<string> linked1 = new();
List<string> linked2 = new();
List<string> linked3 = new();
List<string> linked4 = new();
List<string> linked5 = new();
List<string> linked6 = new();
List<string> linked7 = new();
List<string> linked8 = new();
List<string> linked9 = new();
foreach ((FileHolder fileHolder, ReadOnlyCollection<Relation> relations) in relationContainers)
{
foreach (Relation relation in relations.Take(take))
{
if (!linked1.Contains(relation.File))
{
linked1.Add(relation.File);
continue;
}
if (!linked2.Contains(relation.File))
{
linked2.Add(relation.File);
continue;
}
if (!linked3.Contains(relation.File))
{
linked3.Add(relation.File);
continue;
}
if (!linked4.Contains(relation.File))
{
linked4.Add(relation.File);
continue;
}
if (!linked5.Contains(relation.File))
{
linked5.Add(relation.File);
continue;
}
if (!linked6.Contains(relation.File))
{
linked6.Add(relation.File);
continue;
}
if (!linked7.Contains(relation.File))
{
linked7.Add(relation.File);
continue;
}
if (!linked8.Contains(relation.File))
{
linked8.Add(relation.File);
continue;
}
if (!linked9.Contains(relation.File))
{
linked9.Add(relation.File);
continue;
}
}
}
ReadOnlyDictionary<string, string> movedFiles = MoveFiles(locationContainerDebugDirectory, isCounterPersonYear, displayDirectoryName, linked1, linked2, linked3, linked4, linked5, linked6, linked7, linked8, linked9);
result = new(relationContainers, new(linked1), new(linked2), new(linked3), new(linked4), new(linked5), new(linked6), new(linked7), new(linked8), new(linked9), movedFiles);
return result;
}
private static void WriteFile(int take, long personKey, bool isCounterPersonYear, string personKeyFormatted, string? displayDirectoryName, string directory, long ticks, Uri uri, RelationCollection relationCollection)
{
string a;
string b;
int years;
string text;
string? file;
Relation relation;
string markDownFile;
FileHolder fileHolder;
string originalString;
List<string> lines = new();
string fileNameWithoutExtension;
foreach ((FileHolder relationFileHolder, ReadOnlyCollection<Relation> relations) in relationCollection.RelationContainers)
{
lines.Clear();
if (relationCollection.MovedFiles.TryGetValue(relationFileHolder.FullName, out file))
fileHolder = new(file);
else
fileHolder = new(relationFileHolder.FullName);
if (!relationFileHolder.Exists || relationFileHolder.CreationTime is null)
continue;
if (isCounterPersonYear)
(years, _) = IAge.GetAge(ticks, relationFileHolder.CreationTime.Value.Ticks);
else
(years, _) = IAge.GetAge(relationFileHolder.CreationTime.Value.Ticks, personKey);
fileNameWithoutExtension = Path.GetFileNameWithoutExtension(fileHolder.NameWithoutExtension);
markDownFile = $"{fileNameWithoutExtension}.md";
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($"![0]({uri.MakeRelativeUri(new(relationFileHolder.FullName)).OriginalString})");
lines.Add($"__{fileNameWithoutExtension}__");
if (isCounterPersonYear)
lines.Add($"#{years}yrs-ago");
else
lines.Add($"#{years}yrs-old");
lines.Add($"~~{relations.Count}~~");
lines.Add(string.Empty);
for (int i = 0; i < relations.Count; i++)
{
relation = relations[i];
if (relationCollection.MovedFiles.TryGetValue(relation.File, out file))
fileHolder = new(file);
else
fileHolder = new(relation.File);
if (!fileHolder.Exists || fileHolder.CreationTime is null)
continue;
fileNameWithoutExtension = Path.GetFileNameWithoutExtension(fileHolder.NameWithoutExtension);
originalString = uri.MakeRelativeUri(new(fileHolder.FullName)).OriginalString;
if (i < take)
(a, b) = ("[[", "]]");
else
(a, b) = ("~~", "~~");
lines.Add($"![{relation.DistancePermyriad}]({originalString}){Environment.NewLine}{a}{fileNameWithoutExtension}{b}");
lines.Add(string.Empty);
}
text = string.Join(Environment.NewLine, lines);
File.WriteAllText(Path.Combine(directory, markDownFile), text);
}
}
private static int GetTake(int locationContainerDistanceTake, int count)
{
int result = locationContainerDistanceTake;
int subtract = (int)(locationContainerDistanceTake * .05);
if (subtract < 1)
subtract = 1;
if (count > 9000)
result -= subtract;
if (count > 8000)
result -= subtract;
if (count > 7000)
result -= subtract;
if (count > 6000)
result -= subtract;
if (count > 5000)
result -= subtract;
if (count > 4000)
result -= subtract;
if (count > 3000)
result -= subtract;
if (count > 2000)
result -= subtract;
if (count > 1000)
result -= subtract;
if (result < 3)
result = 3;
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)
{
int take;
string directory;
bool isCounterPersonYear;
string personKeyFormatted;
string? displayDirectoryName;
Uri uri = new(eDistanceContentDirectory);
RelationCollection relationCollection;
ReadOnlyCollection<RelationContainer> relationContainers;
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)
{
if (configuration.LocationContainerDistanceTolerance is null)
break;
progressBar.Tick();
if (collection.Count == 0)
continue;
take = GetTake(configuration.LocationContainerDistanceTake, collection.Count);
isCounterPersonYear = IPersonBirthday.IsCounterPersonYear(new DateTime(collection[0].PersonKey).Year);
personKeyFormatted = IPersonBirthday.GetFormatted(configuration.PersonBirthdayFormat, collection[0].PersonKey);
displayDirectoryName = GetDisplayDirectoryName(readOnlyPersonKeyToPersonContainerCollection, readOnlyPersonKeyFormattedToPersonContainer, collection[0].PersonKey, personKeyFormatted);
directory = Path.Combine(a2PeopleContentDirectory, $"{ticks}-{configuration.LocationContainerDistanceTolerance.Value}", personKeyFormatted);
if (!Directory.Exists(directory))
_ = Directory.CreateDirectory(directory);
WriteVsCodeFiles(eDistanceContentDirectory, displayDirectoryName, directory);
relationContainers = distance.GetRelationContainers(configuration.FaceDistancePermyriad, configuration.LocationContainerDistanceTake, configuration.LocationContainerDistanceTolerance.Value, collection);
relationCollection = GetMappedRelationCollection(configuration.LocationContainerDebugDirectory, take, isCounterPersonYear, displayDirectoryName, relationContainers);
WriteFile(take, collection[0].PersonKey, isCounterPersonYear, personKeyFormatted, displayDirectoryName, directory, ticks, uri, relationCollection);
}
if (string.IsNullOrEmpty(configuration.LocationContainerDebugDirectory))
_ = IPath.DeleteEmptyDirectories(eDistanceContentDirectory);
else
AddDisplayDirectoryNames(configuration, eDistanceContentDirectory, readOnlyPersonKeyFormattedToPersonContainer, readOnlyPersonKeyToPersonContainerCollection, collections);
}
}

View File

@ -15,39 +15,46 @@ taskTemplate: '^+^_${overdue ? ''^R'' : ''''}${name}^: ${relations ? (''\n^-^/^g
## Backlog ## Backlog
- [use-photo-prism-to-map](tasks/use-photo-prism-to-map.md) - [use-photo-prism-to-map](tasks/use-photo-prism-to-map.md)
- [google-timeline-for-geo](tasks/google-timeline-for-geo.md)
- [import-face-region-metadata](tasks/import-face-region-metadata.md) - [import-face-region-metadata](tasks/import-face-region-metadata.md)
- [setup-syncthing-server](tasks/setup-syncthing-server.md) - [setup-syncthing-server](tasks/setup-syncthing-server.md)
- [cluster-questioning](tasks/cluster-questioning.md)
- [photoview-in-docker-for-a-viewer-only](tasks/photoview-in-docker-for-a-viewer-only.md) - [photoview-in-docker-for-a-viewer-only](tasks/photoview-in-docker-for-a-viewer-only.md)
- [image-size-distribution-per-exif-model-directory-when-no-model](tasks/image-size-distribution-per-exif-model-directory-when-no-model.md) - [image-size-distribution-per-exif-model-directory-when-no-model](tasks/image-size-distribution-per-exif-model-directory-when-no-model.md)
- [import-know-faces-into-db](tasks/import-know-faces-into-db.md) - [import-know-faces-into-db](tasks/import-know-faces-into-db.md)
- [skip-metadata-load-after-first-each-day](tasks/skip-metadata-load-after-first-each-day.md) - [skip-metadata-load-after-first-each-day](tasks/skip-metadata-load-after-first-each-day.md)
- [determine-if-location-container-collection-is-needed-in-get-faces](tasks/determine-if-location-container-collection-is-needed-in-get-faces.md) - [determine-if-location-container-collection-is-needed-in-get-faces](tasks/determine-if-location-container-collection-is-needed-in-get-faces.md)
- [cluster-questioning](tasks/cluster-questioning.md)
## Todo ## Todo
- [verify-camera-model-still-works](tasks/verify-camera-model-still-works.md)
- [run-limiting-on-days](tasks/run-limiting-on-days.md)
- [update-drag-and-drop-to-work-with-new-resize-location](tasks/update-drag-and-drop-to-work-with-new-resize-location.md)
- [triangle-over-person-in-full-image-for-some](tasks/triangle-over-person-in-full-image-for-some.md)
- [use-eyes-to-find-orientation](tasks/use-eyes-to-find-orientation.md) - [use-eyes-to-find-orientation](tasks/use-eyes-to-find-orientation.md)
- [find-incorrectly-mapped-faces](tasks/find-incorrectly-mapped-faces.md)
- [nef-support](tasks/nef-support.md) - [nef-support](tasks/nef-support.md)
- [set-date-taken-when-missing](tasks/set-date-taken-when-missing.md) - [set-date-taken-when-missing](tasks/set-date-taken-when-missing.md)
- [triangle-over-person-in-full-image-for-some](tasks/triangle-over-person-in-full-image-for-some.md) - [find-incorrectly-mapped-faces](tasks/find-incorrectly-mapped-faces.md)
- [google-timeline-for-geo](tasks/google-timeline-for-geo.md)
- [neo4j-db-import](tasks/neo4j-db-import.md)
## In Progress ## In Progress
- [name-some-from-638324064000000000-verify-manual-still-works](tasks/name-some-from-638324064000000000-verify-manual-still-works.md)
- [merge-kristy-files](tasks/merge-kristy-files.md) - [merge-kristy-files](tasks/merge-kristy-files.md)
- [review-location-container-distance-tolerance](tasks/review-location-container-distance-tolerance.md)
- [can-re-map](tasks/can-re-map.md)
## Done ## Done
- [eof-error](tasks/eof-error.md) - [eof-error](tasks/eof-error.md)
- [shrink-percent](tasks/shrink-percent.md) - [shrink-percent](tasks/shrink-percent.md)
- [setup-photo-prism-again-in-wsl-docker](tasks/setup-photo-prism-again-in-wsl-docker.md) - [setup-photo-prism-again-in-wsl-docker](tasks/setup-photo-prism-again-in-wsl-docker.md)
- [linked-to-9](tasks/linked-to-9.md)
- [fix-random-logic](tasks/fix-random-logic.md) - [fix-random-logic](tasks/fix-random-logic.md)
- [filter-same-id](tasks/filter-same-id.md)
- [can-re-map](tasks/can-re-map.md)
- [move-copy-manual-files-to-get-display-directory-all-files](tasks/move-copy-manual-files-to-get-display-directory-all-files.md) - [move-copy-manual-files-to-get-display-directory-all-files](tasks/move-copy-manual-files-to-get-display-directory-all-files.md)
- [rename-files-to-padded-number-string](tasks/rename-files-to-padded-number-string.md) - [rename-files-to-padded-number-string](tasks/rename-files-to-padded-number-string.md)
- [reload-slideshow](tasks/reload-slideshow.md) - [reload-slideshow](tasks/reload-slideshow.md)
- [review-location-container-distance-tolerance-needs-to-be-unique](tasks/review-location-container-distance-tolerance-needs-to-be-unique.md)
- [genealogical-data-communication-as-golden](tasks/genealogical-data-communication-as-golden.md) - [genealogical-data-communication-as-golden](tasks/genealogical-data-communication-as-golden.md)
- [look-for-family-from-jlink-in-x-mapped](tasks/look-for-family-from-jlink-in-x-mapped.md) - [look-for-family-from-jlink-in-x-mapped](tasks/look-for-family-from-jlink-in-x-mapped.md)
- [move-over-2023-california-pictures](tasks/move-over-2023-california-pictures.md) - [move-over-2023-california-pictures](tasks/move-over-2023-california-pictures.md)

View File

@ -1,10 +1,11 @@
--- ---
created: 2023-09-06T01:48:53.593Z created: 2023-09-06T01:48:53.593Z
updated: 2023-09-06T01:48:53.588Z updated: 2023-09-09T15:16:04.076Z
assigned: "" assigned: ""
progress: 0 progress: 0
tags: [] tags: []
started: 2023-09-06T01:48:53.593Z started: 2023-09-06T01:48:53.593Z
completed: 2023-09-09T15:16:04.076Z
--- ---
# CanReMap # CanReMap
@ -38,4 +39,4 @@ public List<SaveContainer> GetSaveContainers(string dFacesContentDirectory, stri
MapLogic.SaveContainers; MapLogic.SaveContainers;
public void SaveContainers(int? updated, List<SaveContainer> saveContainers) public void SaveContainers(int? updated, List<SaveContainer> saveContainers)
// ... // ...
``` ```

View File

@ -1,9 +1,10 @@
--- ---
created: "2023-07-17T06:39:53.148Z" created: 2023-07-17T06:39:53.148Z
updated: "2023-07-21T21:36:44.190Z" updated: 2023-09-09T06:30:37.280Z
assigned: "" assigned: ""
progress: 0 progress: 0
type: "kanbn" type: kanbn
started: 2023-09-09T06:30:28.358Z
--- ---
# Cluster Questioning # Cluster Questioning

View File

@ -0,0 +1,11 @@
---
created: 2023-09-09T15:00:50.872Z
updated: 2023-09-09T15:37:00.549Z
assigned: ""
progress: 0
tags: []
started: 2023-09-09T15:00:50.872Z
completed: 2023-09-09T15:37:00.549Z
---
# Filter same id

View File

@ -1,11 +1,11 @@
--- ---
created: "2023-07-21T18:26:38.901Z" created: 2023-07-21T18:26:38.901Z
updated: "2023-07-21T18:26:38.902Z" updated: 2023-09-09T06:30:12.385Z
assigned: "" assigned: ""
progress: 0 progress: 0
tags: [] tags: []
status: '3-In Progress' status: '3-In Progress'
type: "kanbn" type: kanbn
--- ---
# Find Incorrectly Mapped Faces # Find Incorrectly Mapped Faces

View File

@ -1,10 +1,10 @@
--- ---
created: "2023-07-21T18:26:38.903Z" created: 2023-07-21T18:26:38.903Z
updated: "2023-07-21T18:26:38.903Z" updated: 2023-09-09T06:31:23.591Z
assigned: "" assigned: ""
progress: 0 progress: 0
status: "1-Backlog" status: 1-Backlog
type: "kanbn" type: kanbn
--- ---
# Google Timeline for Geo # Google Timeline for Geo

View File

@ -0,0 +1,13 @@
---
created: 2023-09-09T15:36:54.752Z
updated: 2023-09-09T21:51:25.431Z
assigned: ""
progress: 0
tags: []
started: 2023-09-09T15:36:54.752Z
completed: 2023-09-09T21:51:25.432Z
---
# Linked to 9
Convert.ToChar(48 + keyValuePair.Value)

View File

@ -0,0 +1,10 @@
---
created: 2023-09-09T06:28:12.578Z
updated: 2023-09-09T21:51:56.736Z
assigned: ""
progress: 0
tags: []
started: 2023-09-08T00:00:00.000Z
---
# Name some from 638324064000000000 verify Manual still works

View File

@ -0,0 +1,9 @@
---
created: 2023-09-09T06:33:28.795Z
updated: 2023-09-09T06:33:28.790Z
assigned: ""
progress: 0
tags: []
---
# Neo4j DB import

View File

@ -0,0 +1,11 @@
---
created: 2023-08-07T00:19:34.160Z
updated: 2023-09-09T15:12:01.657Z
assigned: ""
progress: 1
tags: []
started: 2023-08-05T00:00:00.000Z
completed: 2023-09-08T00:00:00.000Z
---
# ReviewLocationContainerDistanceTolerance needs to be unique

View File

@ -1,10 +0,0 @@
---
created: 2023-08-07T00:19:34.160Z
updated: 2023-08-07T05:46:42.946Z
assigned: ""
progress: 0
tags: []
started: 2023-08-06T00:00:00.000Z
---
# ReviewLocationContainerDistanceTolerance

View File

@ -0,0 +1,10 @@
---
created: 2023-09-09T15:01:12.800Z
updated: 2023-09-09T21:51:53.090Z
assigned: ""
progress: 0
tags: []
started: 2023-09-09T15:01:12.800Z
---
# Run limiting on days

View File

@ -1,6 +1,6 @@
--- ---
created: 2023-08-08T23:48:54.260Z created: 2023-08-08T23:48:54.260Z
updated: 2023-08-08T23:48:54.257Z updated: 2023-09-09T06:31:43.028Z
assigned: "" assigned: ""
progress: 0 progress: 0
tags: [] tags: []

View File

@ -0,0 +1,9 @@
---
created: 2023-09-09T06:29:03.734Z
updated: 2023-09-09T06:31:45.781Z
assigned: ""
progress: 0
tags: []
---
# Update drag and drop to work with new resize location

View File

@ -0,0 +1,10 @@
---
created: 2023-09-09T15:01:28.239Z
updated: 2023-09-09T21:51:54.599Z
assigned: ""
progress: 0
tags: []
started: 2023-09-09T15:01:28.239Z
---
# Verify camera model still works

View File

@ -5,6 +5,6 @@ namespace View_by_Distance.Shared.Models.Methods;
public interface IDistance<T> public interface IDistance<T>
{ {
void SaveMappedForOutputResolutions(string locationContainerDebugDirectory, string a2PeopleContentDirectory, string eDistanceContentDirectory, float locationContainerDistanceTolerance, ReadOnlyCollection<LocationContainer<T>> locationContainers, long personKey, bool isCounterPersonYear, string personKeyFormatted, string? displayDirectoryName); ReadOnlyCollection<RelationContainer> GetRelationContainers(int faceDistancePermyriad, int locationContainerDistanceTake, float locationContainerDistanceTolerance, ReadOnlyCollection<LocationContainer<T>> locationContainers);
} }

14
Shared/Models/Relation.cs Normal file
View File

@ -0,0 +1,14 @@
using System.Text.Json;
namespace View_by_Distance.Shared.Models;
public record Relation(int DistancePermyriad, string File)
{
public override string ToString()
{
string result = JsonSerializer.Serialize(this, new JsonSerializerOptions() { WriteIndented = true });
return result;
}
}

View File

@ -0,0 +1,15 @@
using System.Collections.ObjectModel;
using System.Text.Json;
namespace View_by_Distance.Shared.Models;
public record RelationContainer(FileHolder FileHolder, ReadOnlyCollection<Relation> RelationCollections)
{
public override string ToString()
{
string result = JsonSerializer.Serialize(this, new JsonSerializerOptions() { WriteIndented = true });
return result;
}
}