From 4b8b9425287d4bf3d3642a7beebce832a9775a09 Mon Sep 17 00:00:00 2001 From: Mike Phares Date: Sat, 9 Sep 2023 14:59:15 -0700 Subject: [PATCH] Filter same id RelationLogic LookForAbandoned --- Distance/Models/_E_Distance.cs | 208 ++------- Instance/DlibDotNet.cs | 1 + Instance/Models/Binder/Configuration.cs | 3 + Instance/Models/Configuration.cs | 1 + Map/Models/Configuration.cs | 1 + Map/Models/MapLogic.cs | 22 +- Map/Models/Stateless/DecadeLogic.cs | 72 ++++ Map/Models/Stateless/LookForAbandonedLogic.cs | 51 +++ Map/Models/Stateless/MapLogic.cs | 205 --------- Map/Models/Stateless/Methods/IMapLogic.cs | 4 +- Map/Models/Stateless/RelationLogic.cs | 400 ++++++++++++++++++ Shared/.kanbn/index.md | 19 +- Shared/.kanbn/tasks/can-re-map.md | 5 +- Shared/.kanbn/tasks/cluster-questioning.md | 7 +- Shared/.kanbn/tasks/filter-same-id.md | 11 + .../tasks/find-incorrectly-mapped-faces.md | 6 +- .../.kanbn/tasks/google-timeline-for-geo.md | 8 +- Shared/.kanbn/tasks/linked-to-9.md | 13 + ...4064000000000-verify-manual-still-works.md | 10 + Shared/.kanbn/tasks/neo4j-db-import.md | 9 + ...r-distance-tolerance-needs-to-be-unique.md | 11 + ...w-location-container-distance-tolerance.md | 10 - Shared/.kanbn/tasks/run-limiting-on-days.md | 10 + ...ngle-over-person-in-full-image-for-some.md | 2 +- ...d-drop-to-work-with-new-resize-location.md | 9 + .../tasks/verify-camera-model-still-works.md | 10 + Shared/Models/Methods/IDistance.cs | 2 +- Shared/Models/Relation.cs | 14 + Shared/Models/RelationContainer.cs | 15 + 29 files changed, 709 insertions(+), 430 deletions(-) create mode 100644 Map/Models/Stateless/DecadeLogic.cs create mode 100644 Map/Models/Stateless/LookForAbandonedLogic.cs create mode 100644 Map/Models/Stateless/RelationLogic.cs create mode 100644 Shared/.kanbn/tasks/filter-same-id.md create mode 100644 Shared/.kanbn/tasks/linked-to-9.md create mode 100644 Shared/.kanbn/tasks/name-some-from-638324064000000000-verify-manual-still-works.md create mode 100644 Shared/.kanbn/tasks/neo4j-db-import.md create mode 100644 Shared/.kanbn/tasks/review-location-container-distance-tolerance-needs-to-be-unique.md delete mode 100644 Shared/.kanbn/tasks/review-location-container-distance-tolerance.md create mode 100644 Shared/.kanbn/tasks/run-limiting-on-days.md create mode 100644 Shared/.kanbn/tasks/update-drag-and-drop-to-work-with-new-resize-location.md create mode 100644 Shared/.kanbn/tasks/verify-camera-model-still-works.md create mode 100644 Shared/Models/Relation.cs create mode 100644 Shared/Models/RelationContainer.cs diff --git a/Distance/Models/_E_Distance.cs b/Distance/Models/_E_Distance.cs index a6d9d54..72a9971 100644 --- a/Distance/Models/_E_Distance.cs +++ b/Distance/Models/_E_Distance.cs @@ -12,13 +12,7 @@ namespace View_by_Distance.Distance.Models; public partial class E_Distance : IDistance { - internal record Mapped(string File, - double? Length, - string Link, - string Image); - - internal record Record(string File, - FaceRecognitionDotNet.FaceEncoding FaceRecognitionDotNetFaceEncoding); + internal record Record(string File, FaceRecognitionDotNet.FaceEncoding FaceRecognitionDotNetFaceEncoding); private readonly List _Moved; private readonly List _Debug; @@ -446,10 +440,10 @@ public partial class E_Distance : IDistance continue; if (faceDistanceContainer.Face.Mapping.MappingFromFilterPre.InSkipCollection is not null && faceDistanceContainer.Face.Mapping.MappingFromFilterPre.InSkipCollection.Value) throw new NotSupportedException(nameof(PreFilterSetFaceDistances)); - if (faceDistanceContainer.Face.Mapping.MappingFromFilterPre.IsFocusModel is not null && faceDistanceContainer.Face.Mapping.MappingFromFilterPre.IsFocusModel.Value) - throw new NotSupportedException(nameof(PreFilterSetFaceDistances)); - if (faceDistanceContainer.Face.Mapping.MappingFromFilterPre.IsFocusRelativePath is not null && faceDistanceContainer.Face.Mapping.MappingFromFilterPre.IsFocusRelativePath.Value) - throw new NotSupportedException(nameof(PreFilterSetFaceDistances)); + if (faceDistanceContainer.Face.Mapping.MappingFromFilterPre.IsFocusModel is not null && !faceDistanceContainer.Face.Mapping.MappingFromFilterPre.IsFocusModel.Value) + continue; + if (faceDistanceContainer.Face.Mapping.MappingFromFilterPre.IsFocusRelativePath is not null && !faceDistanceContainer.Face.Mapping.MappingFromFilterPre.IsFocusRelativePath.Value) + continue; if (faceDistanceContainer.Face.Mapping.MappingFromFilterPost.InSkipCollection is not null && faceDistanceContainer.Face.Mapping.MappingFromFilterPost.InSkipCollection.Value) continue; 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 return new(results); } - private static void WriteVsCodeFiles(string eDistanceContentDirectory, string? displayDirectoryName, string directory) + private static ReadOnlyCollection GetRelationCollections(int faceDistancePermyriad, int locationContainerDistanceTake, float distanceTolerance, List records) { - 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(string locationContainerDebugDirectory, bool isCounterPersonYear, string? displayDirectoryName, Dictionary keyValuePairs, List linkedOnce, List linkedTwice, List linkedThrice, List linkedFour, List 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 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 records, string directory) - { - int years; - string text; + List results = new(); string fileName; - FileInfo fileInfo; + FileHolder fileHolder; + int distancePermyriad; List files = new(); - List lines = new(); - List results = new(); - List linkedFive = new(); - List linkedFour = new(); - List linkedOnce = new(); long ticks = DateTime.Now.Ticks; - string fileNameWithoutExtension; - List linkedTwice = new(); - List linkedThrice = new(); FaceDistance? faceDistanceEncoding; - List relativePaths = new(); + List mappedRelations; List faceDistanceLengths; - Uri uri = new(eDistanceContentDirectory); - Dictionary keyValuePairs = new(); List faceDistanceEncodings = 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); + mappedRelations = new(); + fileHolder = new(record.File); if (files.Count > 1) { faceDistanceEncoding = new(record.FaceRecognitionDotNetFaceEncoding); @@ -613,77 +512,25 @@ public partial class E_Distance : IDistance faceDistanceLengths = FaceRecognition.FaceDistances(new(faceDistanceEncodings), faceDistanceEncoding); for (int i = 0; i < faceDistanceLengths.Count; i++) { - fileName = Path.GetFileName(relativePaths[i]); - if (fileName == fileInfo.Name) + fileName = Path.GetFileName(files[i]); + if (fileName == fileHolder.Name) continue; FaceDistance faceDistance = faceDistanceLengths[i]; - if (faceDistance.Length > distanceTolerance) + if (faceDistance.Length is null || faceDistance.Length.Value > distanceTolerance) continue; - fileNameWithoutExtension = Path.GetFileNameWithoutExtension(Path.GetFileNameWithoutExtension(fileName)); - results.Add(new(files[i], faceDistance.Length, $"[[{fileNameWithoutExtension}]]", $"![{faceDistance.Length}]({relativePaths[i]})")); + distancePermyriad = (int)(faceDistance.Length.Value * faceDistancePermyriad); + mappedRelations.Add(new(distancePermyriad, files[i])); } } - 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; - } - 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; + mappedRelations = (from l in mappedRelations orderby l.DistancePermyriad select l).Take(locationContainerDistanceTake).ToList(); + results.Add(new(fileHolder, new(mappedRelations))); } - MoveFiles(locationContainerDebugDirectory, isCounterPersonYear, displayDirectoryName, keyValuePairs, linkedOnce, linkedTwice, linkedThrice, linkedFour, linkedFive); + return new(results); } - void IDistance.SaveMappedForOutputResolutions(string locationContainerDebugDirectory, string a2PeopleContentDirectory, string eDistanceContentDirectory, float locationContainerDistanceTolerance, ReadOnlyCollection> locationContainers, long personKey, bool isCounterPersonYear, string personKeyFormatted, string? displayDirectoryName) + ReadOnlyCollection IDistance.GetRelationContainers(int faceDistancePermyriad, int locationContainerDistanceTake, float locationContainerDistanceTolerance, ReadOnlyCollection> locationContainers) { + ReadOnlyCollection result; string? json; List records = new(); Shared.Models.FaceEncoding? modelsFaceEncoding; @@ -699,15 +546,8 @@ public partial class E_Distance : IDistance faceRecognitionDotNetFaceEncoding = FaceRecognition.LoadFaceEncoding(modelsFaceEncoding.RawEncoding); records.Add(new(locationContainer.File, faceRecognitionDotNetFaceEncoding)); } - string directory = Path.Combine(a2PeopleContentDirectory, locationContainerDistanceTolerance.ToString(), personKeyFormatted); - if (!Directory.Exists(directory)) - _ = 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); + result = GetRelationCollections(faceDistancePermyriad, locationContainerDistanceTake, locationContainerDistanceTolerance, records); + return result; } } \ No newline at end of file diff --git a/Instance/DlibDotNet.cs b/Instance/DlibDotNet.cs index 0d0fe2e..422c9d6 100644 --- a/Instance/DlibDotNet.cs +++ b/Instance/DlibDotNet.cs @@ -843,6 +843,7 @@ public partial class DlibDotNet configuration.FaceConfidencePercent, configuration.FaceDistancePermyriad, configuration.LocationContainerDebugDirectory, + configuration.LocationContainerDistanceTake, configuration.LocationContainerDistanceTolerance, configuration.LocationDigits, configuration.MappingDefaultName, diff --git a/Instance/Models/Binder/Configuration.cs b/Instance/Models/Binder/Configuration.cs index db2faf5..d8a87b9 100644 --- a/Instance/Models/Binder/Configuration.cs +++ b/Instance/Models/Binder/Configuration.cs @@ -33,6 +33,7 @@ public class Configuration public string[]? LoadOrCreateThenSaveImageFacesResultsForOutputResolutions { get; set; } public bool? LoadPhotoPrismLocations { get; set; } public string? LocationContainerDebugDirectory { get; set; } + public int? LocationContainerDistanceTake { get; set; } public float? LocationContainerDistanceTolerance { get; set; } public int? LocationDigits { 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?.LoadPhotoPrismLocations is null) throw new NullReferenceException(nameof(configuration.LoadPhotoPrismLocations)); 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?.LocationDigits is null) throw new NullReferenceException(nameof(configuration.LocationDigits)); if (configuration?.LocationFactor is null) throw new NullReferenceException(nameof(configuration.LocationFactor)); @@ -218,6 +220,7 @@ public class Configuration configuration.LoadOrCreateThenSaveImageFacesResultsForOutputResolutions ?? Array.Empty(), configuration.LoadPhotoPrismLocations.Value, configuration.LocationContainerDebugDirectory, + configuration.LocationContainerDistanceTake.Value, configuration.LocationContainerDistanceTolerance, configuration.LocationDigits.Value, configuration.LocationFactor.Value, diff --git a/Instance/Models/Configuration.cs b/Instance/Models/Configuration.cs index 7f64f77..7e31b4a 100644 --- a/Instance/Models/Configuration.cs +++ b/Instance/Models/Configuration.cs @@ -27,6 +27,7 @@ public record Configuration(Property.Models.Configuration PropertyConfiguration, string[] LoadOrCreateThenSaveImageFacesResultsForOutputResolutions, bool LoadPhotoPrismLocations, string LocationContainerDebugDirectory, + int LocationContainerDistanceTake, float? LocationContainerDistanceTolerance, int LocationDigits, int LocationFactor, diff --git a/Map/Models/Configuration.cs b/Map/Models/Configuration.cs index c3c4667..4a78e01 100644 --- a/Map/Models/Configuration.cs +++ b/Map/Models/Configuration.cs @@ -6,6 +6,7 @@ public record Configuration(bool DeletePossibleDuplicates, int FaceConfidencePercent, int FaceDistancePermyriad, string LocationContainerDebugDirectory, + int LocationContainerDistanceTake, float? LocationContainerDistanceTolerance, int LocationDigits, string MappingDefaultName, diff --git a/Map/Models/MapLogic.cs b/Map/Models/MapLogic.cs index 3b77de5..9545c01 100644 --- a/Map/Models/MapLogic.cs +++ b/Map/Models/MapLogic.cs @@ -315,7 +315,7 @@ public partial class MapLogic : Shared.Models.Methods.IMapLogic if (lossCount != 0 || unableToMatchCount != 0) { } 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)) throw new Exception($"{nameof(configuration.LocationContainerDebugDirectory)} is not IsNullOrEmpty!"); } @@ -681,9 +681,9 @@ public partial class MapLogic : Shared.Models.Methods.IMapLogic continue; if (face.Mapping.MappingFromFilterPre.InSkipCollection is not null && face.Mapping.MappingFromFilterPre.InSkipCollection.Value) throw new NotSupportedException(nameof(Shared.Models.Methods.IDistance)); - if (face.Mapping.MappingFromFilterPre.IsFocusModel is not null && face.Mapping.MappingFromFilterPre.IsFocusModel.Value) + if (face.Mapping.MappingFromFilterPre.IsFocusModel is not null && !face.Mapping.MappingFromFilterPre.IsFocusModel.Value) throw new NotSupportedException(nameof(Shared.Models.Methods.IDistance)); - if (face.Mapping.MappingFromFilterPre.IsFocusRelativePath is not null && face.Mapping.MappingFromFilterPre.IsFocusRelativePath.Value) + if (face.Mapping.MappingFromFilterPre.IsFocusRelativePath is not null && !face.Mapping.MappingFromFilterPre.IsFocusRelativePath.Value) throw new NotSupportedException(nameof(Shared.Models.Methods.IDistance)); if (face.Mapping.MappingFromFilterPost.InSkipCollection is not null && face.Mapping.MappingFromFilterPost.InSkipCollection.Value) throw new NotSupportedException(nameof(Shared.Models.Methods.IDistance)); @@ -696,6 +696,8 @@ public partial class MapLogic : Shared.Models.Methods.IMapLogic throw new NotSupportedException(); if (faceDistanceLength.Length == 0) continue; + if (faceDistanceLength.Id == faceDistanceEncoding.Id) + continue; if (faceDistanceLength.MappingFromFilterPost is null) throw new NotSupportedException(); if (faceDistanceLength.MappingFromFilterPost.CanReMap is not null && !_Configuration.ReMap) @@ -890,9 +892,9 @@ public partial class MapLogic : Shared.Models.Methods.IMapLogic mappingFromFilterPost = sortingContainer.Source.MappingFromFilterPost; if (sortingContainer.Source.MappingFromFilterPre.InSkipCollection is not null && sortingContainer.Source.MappingFromFilterPre.InSkipCollection.Value) throw new NotSupportedException(nameof(GetSortingCollection)); - if (sortingContainer.Source.MappingFromFilterPre.IsFocusModel is not null && sortingContainer.Source.MappingFromFilterPre.IsFocusModel.Value) + if (sortingContainer.Source.MappingFromFilterPre.IsFocusModel is not null && !sortingContainer.Source.MappingFromFilterPre.IsFocusModel.Value) throw new NotSupportedException(nameof(GetSortingCollection)); - if (sortingContainer.Source.MappingFromFilterPre.IsFocusRelativePath is not null && sortingContainer.Source.MappingFromFilterPre.IsFocusRelativePath.Value) + if (sortingContainer.Source.MappingFromFilterPre.IsFocusRelativePath is not null && !sortingContainer.Source.MappingFromFilterPre.IsFocusRelativePath.Value) throw new NotSupportedException(nameof(GetSortingCollection)); if (sortingContainer.Source.MappingFromFilterPost.InSkipCollection is not null && sortingContainer.Source.MappingFromFilterPost.InSkipCollection.Value) throw new NotSupportedException(nameof(GetSortingCollection)); @@ -905,6 +907,8 @@ public partial class MapLogic : Shared.Models.Methods.IMapLogic throw new NotSupportedException(); if (!wholePercentagesToMapping.TryGetValue(sorting.WholePercentages, out keyMapping)) throw new NotSupportedException(); + if (sortingContainer.Source.MappingFromItem.Id == keyMapping.MappingFromItem.Id) + throw new NotSupportedException(nameof(GetSortingCollection)); if (keyMapping.MappingFromFilterPost.CanReMap is not null && !_Configuration.ReMap) throw new NotSupportedException(nameof(GetSortingCollection)); if (keyMapping.MappingFromFilterPost.CanReMap is not null && !keyMapping.MappingFromFilterPost.CanReMap.Value) @@ -1337,14 +1341,14 @@ public partial class MapLogic : Shared.Models.Methods.IMapLogic string? directoryName; List distinctFilteredIds = IContainer.GetFilteredDistinctIds(propertyConfiguration, containers); LookForAbandoned(propertyConfiguration, distinctFilteredIds); - Stateless.MapLogic.LookForAbandoned(bResultsFullGroupDirectory, distinctFilteredIds); + Stateless.LookForAbandonedLogic.LookForAbandoned(bResultsFullGroupDirectory, distinctFilteredIds); directories = Directory.GetDirectories(cResultsFullGroupDirectory, "*", SearchOption.TopDirectoryOnly); foreach (string directory in directories) { directoryName = Path.GetFileName(directory); if (string.IsNullOrEmpty(directoryName) || directoryName.Length != 2 && directoryName.Length != 4) continue; - Stateless.MapLogic.LookForAbandoned(distinctFilteredIds, directory, directoryName); + Stateless.LookForAbandonedLogic.LookForAbandoned(distinctFilteredIds, directory, directoryName); } directories = Directory.GetDirectories(dResultsFullGroupDirectory, "*", SearchOption.TopDirectoryOnly); foreach (string directory in directories) @@ -1352,7 +1356,7 @@ public partial class MapLogic : Shared.Models.Methods.IMapLogic directoryName = Path.GetFileName(directory); if (string.IsNullOrEmpty(directoryName) || directoryName.Length != 2 && directoryName.Length != 4) continue; - Stateless.MapLogic.LookForAbandoned(distinctFilteredIds, directory, directoryName); + Stateless.LookForAbandonedLogic.LookForAbandoned(distinctFilteredIds, directory, directoryName); } directories = Directory.GetDirectories(d2ResultsFullGroupDirectory, "*", SearchOption.TopDirectoryOnly); foreach (string directory in directories) @@ -1360,7 +1364,7 @@ public partial class MapLogic : Shared.Models.Methods.IMapLogic directoryName = Path.GetFileName(directory); if (string.IsNullOrEmpty(directoryName) || directoryName.Length != 2 && directoryName.Length != 4) continue; - Stateless.MapLogic.LookForAbandoned(distinctFilteredIds, directory, directoryName); + Stateless.LookForAbandonedLogic.LookForAbandoned(distinctFilteredIds, directory, directoryName); } } diff --git a/Map/Models/Stateless/DecadeLogic.cs b/Map/Models/Stateless/DecadeLogic.cs new file mode 100644 index 0000000..786ef8e --- /dev/null +++ b/Map/Models/Stateless/DecadeLogic.cs @@ -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> locationContainers) + { + DateTime dateTime; + FileInfo fileInfo; + string halfDecade; + string checkDirectory; + string? yearDirectory; + string yearDirectoryName; + string? personNameDirectory; + string personNameDirectoryName; + string? personKeyFormattedDirectory; + string? personKeyFormattedDirectoryName; + foreach (LocationContainer 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))); + } + } + +} \ No newline at end of file diff --git a/Map/Models/Stateless/LookForAbandonedLogic.cs b/Map/Models/Stateless/LookForAbandonedLogic.cs new file mode 100644 index 0000000..fa588cd --- /dev/null +++ b/Map/Models/Stateless/LookForAbandonedLogic.cs @@ -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 distinctFilteredIds, string directory, string directoryName) + { + string fileNameWithoutExtension; + bool nameWithoutExtensionIsIdFormat; + List 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 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); + } + } + +} \ No newline at end of file diff --git a/Map/Models/Stateless/MapLogic.cs b/Map/Models/Stateless/MapLogic.cs index d29a4eb..f400452 100644 --- a/Map/Models/Stateless/MapLogic.cs +++ b/Map/Models/Stateless/MapLogic.cs @@ -841,37 +841,6 @@ internal abstract class MapLogic return results; } - internal static void LookForAbandoned(List distinctFilteredIds, string directory, string directoryName) - { - string fileNameWithoutExtension; - bool nameWithoutExtensionIsIdFormat; - List 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 GetRecords(Configuration configuration, bool? isDefault, string[] files, int directoryNumber, string personKeyFormatted, List distinct, string? personDisplayDirectoryName) { List results = new(); @@ -1652,18 +1621,6 @@ internal abstract class MapLogic } } - internal static void LookForAbandoned(string bResultsFullGroupDirectory, List 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> ConvertSkip(Dictionary> skipCollection) { Dictionary> results = new(); @@ -1712,168 +1669,6 @@ internal abstract class MapLogic 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> locationContainers) - { - DateTime dateTime; - FileInfo fileInfo; - string halfDecade; - string checkDirectory; - string? yearDirectory; - string yearDirectoryName; - string? personNameDirectory; - string personNameDirectoryName; - string? personKeyFormattedDirectory; - string? personKeyFormattedDirectoryName; - foreach (LocationContainer 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>> GetCollections(List> locationContainers) - { - List>> results = new(); - List>? collection; - Dictionary>> keyValuePairs = new(); - foreach (LocationContainer 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>> keyValuePair in keyValuePairs) - results.Add(new(keyValuePair.Value)); - return new(results); - } - - private static string? GetDisplayDirectoryName(ReadOnlyDictionary> readOnlyPersonKeyToPersonContainerCollection, ReadOnlyDictionary readOnlyPersonKeyFormattedToPersonContainer, long personKey, string personKeyFormatted) - { - string? result; - PersonContainer? personContainer; - List? 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 readOnlyPersonKeyFormattedToPersonContainer, ReadOnlyDictionary> readOnlyPersonKeyToPersonContainerCollection, ReadOnlyCollection>> collections) - { - bool isCounterPersonYear; - string personKeyFormatted; - string? displayDirectoryName; - string? checkDirectory = Path.Combine(eDistanceContentDirectory, configuration.LocationContainerDebugDirectory); - _ = IPath.DeleteEmptyDirectories(checkDirectory); - foreach (ReadOnlyCollection> 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 distance, string a2PeopleContentDirectory, string eDistanceContentDirectory, long ticks, List> locationContainers, ReadOnlyDictionary readOnlyPersonKeyFormattedToPersonContainer, ReadOnlyDictionary> 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>> collections = GetCollections(locationContainers); - using ProgressBar progressBar = new(collections.Count, message, options); - foreach (ReadOnlyCollection> 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>? wholePercentagesToPersonContainers, MappingFromLocation mappingFromLocation) { bool? result; diff --git a/Map/Models/Stateless/Methods/IMapLogic.cs b/Map/Models/Stateless/Methods/IMapLogic.cs index 2a6e95f..4b6fcf8 100644 --- a/Map/Models/Stateless/Methods/IMapLogic.cs +++ b/Map/Models/Stateless/Methods/IMapLogic.cs @@ -38,7 +38,7 @@ public interface IMapLogic void TestStatic_SetCreationTimeMaybeMoveToDecade(Property.Models.Configuration propertyConfiguration, bool moveToDecade, Shared.Models.MappingFromItem mappingFromItem, ReadOnlyCollection> locationContainers) => SetCreationTimeMaybeMoveToDecade(propertyConfiguration, moveToDecade, mappingFromItem, locationContainers); static void SetCreationTimeMaybeMoveToDecade(Property.Models.Configuration propertyConfiguration, bool moveToDecade, Shared.Models.MappingFromItem mappingFromItem, ReadOnlyCollection> locationContainers) => - MapLogic.SetCreationTimeMaybeMoveToDecade(propertyConfiguration, moveToDecade, mappingFromItem, locationContainers); + DecadeLogic.SetCreationTimeMaybeMoveToDecade(propertyConfiguration, moveToDecade, mappingFromItem, locationContainers); bool? TestStatic_CanReMap(long[] jLinkResolvedPersonKeys, ReadOnlyDictionary>? wholePercentagesToPersonContainers, Shared.Models.MappingFromLocation mappingFromLocation) => CanReMap(jLinkResolvedPersonKeys, wholePercentagesToPersonContainers, mappingFromLocation); @@ -48,6 +48,6 @@ public interface IMapLogic string TestStatic_GetDecade(Shared.Models.MappingFromItem mappingFromItem) => GetDecade(mappingFromItem); static string GetDecade(Shared.Models.MappingFromItem mappingFromItem) => - MapLogic.GetDecade(mappingFromItem); + DecadeLogic.GetDecade(mappingFromItem); } \ No newline at end of file diff --git a/Map/Models/Stateless/RelationLogic.cs b/Map/Models/Stateless/RelationLogic.cs new file mode 100644 index 0000000..428fc69 --- /dev/null +++ b/Map/Models/Stateless/RelationLogic.cs @@ -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 RelationContainers, + ReadOnlyCollection Linked1, + ReadOnlyCollection Linked2, + ReadOnlyCollection Linked3, + ReadOnlyCollection Linked4, + ReadOnlyCollection Linked5, + ReadOnlyCollection Linked6, + ReadOnlyCollection Linked7, + ReadOnlyCollection Linked8, + ReadOnlyCollection Linked9, + ReadOnlyDictionary MovedFiles); + + private static ReadOnlyCollection>> GetCollections(List> locationContainers) + { + List>> results = new(); + List>? collection; + Dictionary>> keyValuePairs = new(); + foreach (LocationContainer 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>> keyValuePair in keyValuePairs) + results.Add(new(keyValuePair.Value)); + return new(results); + } + + private static string? GetDisplayDirectoryName(ReadOnlyDictionary> readOnlyPersonKeyToPersonContainerCollection, ReadOnlyDictionary readOnlyPersonKeyFormattedToPersonContainer, long personKey, string personKeyFormatted) + { + string? result; + PersonContainer? personContainer; + List? 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 readOnlyPersonKeyFormattedToPersonContainer, ReadOnlyDictionary> readOnlyPersonKeyToPersonContainerCollection, ReadOnlyCollection>> collections) + { + bool isCounterPersonYear; + string personKeyFormatted; + string? displayDirectoryName; + string? checkDirectory = Path.Combine(eDistanceContentDirectory, configuration.LocationContainerDebugDirectory); + _ = IPath.DeleteEmptyDirectories(checkDirectory); + foreach (ReadOnlyCollection> 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 MoveFiles(string locationContainerDebugDirectory, bool isCounterPersonYear, string? displayDirectoryName, List linked1, List linked2, List linked3, List linked4, List linked5, List linked6, List linked7, List linked8, List linked9) + { + Dictionary results = new(); + char c; + string checkFile; + string debugFile; + string checkDirectory; + string? yearDirectory; + string? personNameDirectory; + string? maybeTicksDirectoryName; + string? personNameDirectoryName; + string? personKeyFormattedDirectory; + Dictionary 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 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 relationContainers) + { + RelationCollection result; + List linked1 = new(); + List linked2 = new(); + List linked3 = new(); + List linked4 = new(); + List linked5 = new(); + List linked6 = new(); + List linked7 = new(); + List linked8 = new(); + List linked9 = new(); + foreach ((FileHolder fileHolder, ReadOnlyCollection 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 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 lines = new(); + string fileNameWithoutExtension; + foreach ((FileHolder relationFileHolder, ReadOnlyCollection 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 distance, string a2PeopleContentDirectory, string eDistanceContentDirectory, long ticks, List> locationContainers, ReadOnlyDictionary readOnlyPersonKeyFormattedToPersonContainer, ReadOnlyDictionary> readOnlyPersonKeyToPersonContainerCollection) + { + int take; + string directory; + bool isCounterPersonYear; + string personKeyFormatted; + string? displayDirectoryName; + Uri uri = new(eDistanceContentDirectory); + RelationCollection relationCollection; + ReadOnlyCollection 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>> collections = GetCollections(locationContainers); + using ProgressBar progressBar = new(collections.Count, message, options); + foreach (ReadOnlyCollection> 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); + } + +} \ No newline at end of file diff --git a/Shared/.kanbn/index.md b/Shared/.kanbn/index.md index 6f2158d..d55e124 100644 --- a/Shared/.kanbn/index.md +++ b/Shared/.kanbn/index.md @@ -15,39 +15,46 @@ taskTemplate: '^+^_${overdue ? ''^R'' : ''''}${name}^: ${relations ? (''\n^-^/^g ## Backlog - [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) - [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) - [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) - [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) -- [cluster-questioning](tasks/cluster-questioning.md) ## 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) -- [find-incorrectly-mapped-faces](tasks/find-incorrectly-mapped-faces.md) - [nef-support](tasks/nef-support.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 +- [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) -- [review-location-container-distance-tolerance](tasks/review-location-container-distance-tolerance.md) -- [can-re-map](tasks/can-re-map.md) ## Done - [eof-error](tasks/eof-error.md) - [shrink-percent](tasks/shrink-percent.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) +- [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) - [rename-files-to-padded-number-string](tasks/rename-files-to-padded-number-string.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) - [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) diff --git a/Shared/.kanbn/tasks/can-re-map.md b/Shared/.kanbn/tasks/can-re-map.md index 81fd11d..c615c90 100644 --- a/Shared/.kanbn/tasks/can-re-map.md +++ b/Shared/.kanbn/tasks/can-re-map.md @@ -1,10 +1,11 @@ --- created: 2023-09-06T01:48:53.593Z -updated: 2023-09-06T01:48:53.588Z +updated: 2023-09-09T15:16:04.076Z assigned: "" progress: 0 tags: [] started: 2023-09-06T01:48:53.593Z +completed: 2023-09-09T15:16:04.076Z --- # CanReMap @@ -38,4 +39,4 @@ public List GetSaveContainers(string dFacesContentDirectory, stri MapLogic.SaveContainers; public void SaveContainers(int? updated, List saveContainers) // ... -``` \ No newline at end of file +``` diff --git a/Shared/.kanbn/tasks/cluster-questioning.md b/Shared/.kanbn/tasks/cluster-questioning.md index 55529ab..e9129cb 100644 --- a/Shared/.kanbn/tasks/cluster-questioning.md +++ b/Shared/.kanbn/tasks/cluster-questioning.md @@ -1,9 +1,10 @@ --- -created: "2023-07-17T06:39:53.148Z" -updated: "2023-07-21T21:36:44.190Z" +created: 2023-07-17T06:39:53.148Z +updated: 2023-09-09T06:30:37.280Z assigned: "" progress: 0 -type: "kanbn" +type: kanbn +started: 2023-09-09T06:30:28.358Z --- # Cluster Questioning diff --git a/Shared/.kanbn/tasks/filter-same-id.md b/Shared/.kanbn/tasks/filter-same-id.md new file mode 100644 index 0000000..c2200c9 --- /dev/null +++ b/Shared/.kanbn/tasks/filter-same-id.md @@ -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 diff --git a/Shared/.kanbn/tasks/find-incorrectly-mapped-faces.md b/Shared/.kanbn/tasks/find-incorrectly-mapped-faces.md index 2b2a48a..992d4be 100644 --- a/Shared/.kanbn/tasks/find-incorrectly-mapped-faces.md +++ b/Shared/.kanbn/tasks/find-incorrectly-mapped-faces.md @@ -1,11 +1,11 @@ --- -created: "2023-07-21T18:26:38.901Z" -updated: "2023-07-21T18:26:38.902Z" +created: 2023-07-21T18:26:38.901Z +updated: 2023-09-09T06:30:12.385Z assigned: "" progress: 0 tags: [] status: '3-In Progress' -type: "kanbn" +type: kanbn --- # Find Incorrectly Mapped Faces diff --git a/Shared/.kanbn/tasks/google-timeline-for-geo.md b/Shared/.kanbn/tasks/google-timeline-for-geo.md index a663d05..33534a2 100644 --- a/Shared/.kanbn/tasks/google-timeline-for-geo.md +++ b/Shared/.kanbn/tasks/google-timeline-for-geo.md @@ -1,10 +1,10 @@ --- -created: "2023-07-21T18:26:38.903Z" -updated: "2023-07-21T18:26:38.903Z" +created: 2023-07-21T18:26:38.903Z +updated: 2023-09-09T06:31:23.591Z assigned: "" progress: 0 -status: "1-Backlog" -type: "kanbn" +status: 1-Backlog +type: kanbn --- # Google Timeline for Geo diff --git a/Shared/.kanbn/tasks/linked-to-9.md b/Shared/.kanbn/tasks/linked-to-9.md new file mode 100644 index 0000000..e953433 --- /dev/null +++ b/Shared/.kanbn/tasks/linked-to-9.md @@ -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) diff --git a/Shared/.kanbn/tasks/name-some-from-638324064000000000-verify-manual-still-works.md b/Shared/.kanbn/tasks/name-some-from-638324064000000000-verify-manual-still-works.md new file mode 100644 index 0000000..05e91e8 --- /dev/null +++ b/Shared/.kanbn/tasks/name-some-from-638324064000000000-verify-manual-still-works.md @@ -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 diff --git a/Shared/.kanbn/tasks/neo4j-db-import.md b/Shared/.kanbn/tasks/neo4j-db-import.md new file mode 100644 index 0000000..56f589d --- /dev/null +++ b/Shared/.kanbn/tasks/neo4j-db-import.md @@ -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 diff --git a/Shared/.kanbn/tasks/review-location-container-distance-tolerance-needs-to-be-unique.md b/Shared/.kanbn/tasks/review-location-container-distance-tolerance-needs-to-be-unique.md new file mode 100644 index 0000000..5bafce8 --- /dev/null +++ b/Shared/.kanbn/tasks/review-location-container-distance-tolerance-needs-to-be-unique.md @@ -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 diff --git a/Shared/.kanbn/tasks/review-location-container-distance-tolerance.md b/Shared/.kanbn/tasks/review-location-container-distance-tolerance.md deleted file mode 100644 index 9304d8d..0000000 --- a/Shared/.kanbn/tasks/review-location-container-distance-tolerance.md +++ /dev/null @@ -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 diff --git a/Shared/.kanbn/tasks/run-limiting-on-days.md b/Shared/.kanbn/tasks/run-limiting-on-days.md new file mode 100644 index 0000000..011c2bc --- /dev/null +++ b/Shared/.kanbn/tasks/run-limiting-on-days.md @@ -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 diff --git a/Shared/.kanbn/tasks/triangle-over-person-in-full-image-for-some.md b/Shared/.kanbn/tasks/triangle-over-person-in-full-image-for-some.md index b0616e7..d51fcc9 100644 --- a/Shared/.kanbn/tasks/triangle-over-person-in-full-image-for-some.md +++ b/Shared/.kanbn/tasks/triangle-over-person-in-full-image-for-some.md @@ -1,6 +1,6 @@ --- created: 2023-08-08T23:48:54.260Z -updated: 2023-08-08T23:48:54.257Z +updated: 2023-09-09T06:31:43.028Z assigned: "" progress: 0 tags: [] diff --git a/Shared/.kanbn/tasks/update-drag-and-drop-to-work-with-new-resize-location.md b/Shared/.kanbn/tasks/update-drag-and-drop-to-work-with-new-resize-location.md new file mode 100644 index 0000000..928c1d2 --- /dev/null +++ b/Shared/.kanbn/tasks/update-drag-and-drop-to-work-with-new-resize-location.md @@ -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 diff --git a/Shared/.kanbn/tasks/verify-camera-model-still-works.md b/Shared/.kanbn/tasks/verify-camera-model-still-works.md new file mode 100644 index 0000000..4dd9546 --- /dev/null +++ b/Shared/.kanbn/tasks/verify-camera-model-still-works.md @@ -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 diff --git a/Shared/Models/Methods/IDistance.cs b/Shared/Models/Methods/IDistance.cs index 2d4efa7..f029a4a 100644 --- a/Shared/Models/Methods/IDistance.cs +++ b/Shared/Models/Methods/IDistance.cs @@ -5,6 +5,6 @@ namespace View_by_Distance.Shared.Models.Methods; public interface IDistance { - void SaveMappedForOutputResolutions(string locationContainerDebugDirectory, string a2PeopleContentDirectory, string eDistanceContentDirectory, float locationContainerDistanceTolerance, ReadOnlyCollection> locationContainers, long personKey, bool isCounterPersonYear, string personKeyFormatted, string? displayDirectoryName); + ReadOnlyCollection GetRelationContainers(int faceDistancePermyriad, int locationContainerDistanceTake, float locationContainerDistanceTolerance, ReadOnlyCollection> locationContainers); } \ No newline at end of file diff --git a/Shared/Models/Relation.cs b/Shared/Models/Relation.cs new file mode 100644 index 0000000..2d6b1b5 --- /dev/null +++ b/Shared/Models/Relation.cs @@ -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; + } + +} diff --git a/Shared/Models/RelationContainer.cs b/Shared/Models/RelationContainer.cs new file mode 100644 index 0000000..c30e45d --- /dev/null +++ b/Shared/Models/RelationContainer.cs @@ -0,0 +1,15 @@ +using System.Collections.ObjectModel; +using System.Text.Json; + +namespace View_by_Distance.Shared.Models; + +public record RelationContainer(FileHolder FileHolder, ReadOnlyCollection RelationCollections) +{ + + public override string ToString() + { + string result = JsonSerializer.Serialize(this, new JsonSerializerOptions() { WriteIndented = true }); + return result; + } + +}