From ae1baaaf46e9562a8a9015d44c1394ba3c7f15e9 Mon Sep 17 00:00:00 2001 From: Mike Phares Date: Tue, 22 Nov 2022 22:24:43 -0700 Subject: [PATCH] Drag Drop sorting by distance attempt --- Distance/Distance.csproj | 1 + Distance/Models/_E_Distance.cs | 58 +---- Drag-Drop/Drag-Drop.csproj | 4 +- Drag-Drop/Form.cs | 292 ++++++++++++++++++----- Drag-Drop/Models/Binder/Configuration.cs | 4 + Drag-Drop/Models/Configuration.cs | 3 + Drag-Drop/Program.cs | 13 +- Map/Models/MapLogic.cs | 39 +-- Metadata/Models/Stateless/IMetadata.cs | 16 ++ Metadata/Models/Stateless/Metadata.cs | 58 +++++ Property/Models/Stateless/IResult.cs | 56 +++-- View-by-Distance-MKLink-Console.sln | 6 + 12 files changed, 385 insertions(+), 165 deletions(-) create mode 100644 Metadata/Models/Stateless/IMetadata.cs create mode 100644 Metadata/Models/Stateless/Metadata.cs diff --git a/Distance/Distance.csproj b/Distance/Distance.csproj index 94917fd..0e64d91 100644 --- a/Distance/Distance.csproj +++ b/Distance/Distance.csproj @@ -43,6 +43,7 @@ + diff --git a/Distance/Models/_E_Distance.cs b/Distance/Models/_E_Distance.cs index 3db9ae9..f11c82d 100644 --- a/Distance/Models/_E_Distance.cs +++ b/Distance/Models/_E_Distance.cs @@ -85,58 +85,6 @@ public partial class E_Distance _Moved.Add(mappedFaceFile); } - public static string? GetFaceEncoding(string file) - { - string? result; - List results = new(); - const string comment = "Comment: "; - if (File.Exists(file)) - { - IReadOnlyList directories = MetadataExtractor.ImageMetadataReader.ReadMetadata(file); - foreach (MetadataExtractor.Directory directory in directories) - { - if (directory.Name != "PNG-tEXt") - continue; - foreach (MetadataExtractor.Tag tag in directory.Tags) - { - if (tag.Name != "Textual Data" || string.IsNullOrEmpty(tag.Description)) - continue; - if (!tag.Description.StartsWith(comment)) - continue; - results.Add(tag.Description); - } - } - } - result = results.Any() ? results[0][comment.Length..] : null; - return result; - } - - public static string? GetFaceLocation(string file) - { - string? result; - List results = new(); - const string artist = "Artist: "; - if (File.Exists(file)) - { - IReadOnlyList directories = MetadataExtractor.ImageMetadataReader.ReadMetadata(file); - foreach (MetadataExtractor.Directory directory in directories) - { - if (directory.Name != "PNG-tEXt") - continue; - foreach (MetadataExtractor.Tag tag in directory.Tags) - { - if (tag.Name != "Textual Data" || string.IsNullOrEmpty(tag.Description)) - continue; - if (!tag.Description.StartsWith(artist)) - continue; - results.Add(tag.Description); - } - } - } - result = results.Any() ? results[0][artist.Length..] : null; - return result; - } - private FaceDistanceContainer[] GetFaceDistanceContainers(MappingFromItem mappingFromItem, Face[] filteredFaces) { FaceDistanceContainer[] results; @@ -221,7 +169,7 @@ public partial class E_Distance return results; } - static (int?, int?) GetXY(int normalizedPixelPercentage, OutputResolution? outputResolution) + private static (int?, int?) GetXY(int normalizedPixelPercentage, OutputResolution? outputResolution) { int? x; int? y; @@ -382,7 +330,7 @@ public partial class E_Distance if (_DuplicateMappedFaceFiles.Contains(mappedFaceFileName)) continue; checkFaces.Clear(); - json = GetFaceEncoding(mappedFaceFile); + json = Metadata.Models.Stateless.IMetadata.GetFaceEncoding(mappedFaceFile); if (json is null) { if (!string.IsNullOrEmpty(eDistanceContentDirectory) && _DistanceMoveUnableToMatch) @@ -402,7 +350,7 @@ public partial class E_Distance if (checkFaces.Count != 1 && _DistancePixelDistanceTolerance > 0) { checkFaces.Clear(); - json = GetFaceLocation(mappedFaceFile); + json = Metadata.Models.Stateless.IMetadata.GetFaceLocation(mappedFaceFile); if (json is not null) checkFaces.AddRange(GetClosestFaceByPixel(filteredFaces, json)); else diff --git a/Drag-Drop/Drag-Drop.csproj b/Drag-Drop/Drag-Drop.csproj index 8027297..d73bef4 100644 --- a/Drag-Drop/Drag-Drop.csproj +++ b/Drag-Drop/Drag-Drop.csproj @@ -38,9 +38,11 @@ - + + + diff --git a/Drag-Drop/Form.cs b/Drag-Drop/Form.cs index 2472a75..d39038e 100644 --- a/Drag-Drop/Form.cs +++ b/Drag-Drop/Form.cs @@ -3,8 +3,11 @@ using Microsoft.WindowsAPICodePack.Shell; using Phares.Shared; using Serilog; using System.Diagnostics; +using System.Globalization; using System.Reflection; +using System.Text.Json; using View_by_Distance.Drag_Drop.Models; +using View_by_Distance.FaceRecognitionDotNet; using View_by_Distance.Resize.Models; using View_by_Distance.Shared.Models; using View_by_Distance.Shared.Models.Stateless.Methods; @@ -22,10 +25,10 @@ public partial class Form : System.Windows.Forms.Form private readonly string _WorkingDirectory; private readonly Configuration _Configuration; private readonly IsEnvironment _IsEnvironment; + private readonly Dictionary _IdToItem; private readonly string _ResizeFileNameExtension; private readonly IConfigurationRoot _ConfigurationRoot; private readonly Property.Models.Configuration _PropertyConfiguration; - private readonly Dictionary _IdToMappingFromItem; public Form() { @@ -36,7 +39,7 @@ public partial class Form : System.Windows.Forms.Form string workingDirectory; Configuration configuration; IsEnvironment isEnvironment; - _IdToMappingFromItem = new(); + _IdToItem = new(); IConfigurationRoot configurationRoot; LoggerConfiguration loggerConfiguration = new(); Property.Models.Configuration propertyConfiguration; @@ -118,12 +121,14 @@ public partial class Form : System.Windows.Forms.Form Container[] containers; Property.Models.A_Property propertyLogic = new(_AppSettings.MaxDegreeOfParallelism, _Configuration.PropertyConfiguration, _ResizeFileNameExtension, _Configuration.Reverse); (_, _, _, containers) = Property.Models.Stateless.Container.GetContainers(_Configuration.PropertyConfiguration, propertyLogic); - List collection = Program.GetMappingFromItemCollection(_Configuration, containers); - foreach (MappingFromItem mappingFromItem in collection) + List collection = Program.GetItemCollection(_Configuration, containers); + foreach (Item item in collection) { - if (_IdToMappingFromItem.ContainsKey(mappingFromItem.Id)) + if (item.Property?.Id is null) continue; - _IdToMappingFromItem.Add(mappingFromItem.Id, mappingFromItem); + if (_IdToItem.ContainsKey(item.Property.Id.Value)) + continue; + _IdToItem.Add(item.Property.Id.Value, item); } if (_Logger is null) throw new NullReferenceException(nameof(_Logger)); @@ -135,11 +140,34 @@ public partial class Form : System.Windows.Forms.Form _Logger.Debug((_PropertyConfiguration is null).ToString()); } - private void RenameDirectory(string path, string searchPattern) + public static string? GetFaceEncoding(string file) + { + string? result; + List results = new(); + const string comment = "Comment: "; + if (File.Exists(file)) + { + IReadOnlyList directories = MetadataExtractor.ImageMetadataReader.ReadMetadata(file); + foreach (MetadataExtractor.Directory directory in directories) + { + if (directory.Name != "PNG-tEXt") + continue; + foreach (MetadataExtractor.Tag tag in directory.Tags) + { + if (tag.Name != "Textual Data" || string.IsNullOrEmpty(tag.Description)) + continue; + if (!tag.Description.StartsWith(comment)) + continue; + results.Add(tag.Description); + } + } + } + result = results.Any() ? results[0][comment.Length..] : null; + return result; + } + + private void RenameFilesInDirectory(string directory, string searchPattern) { - string[] directories = Directory.GetDirectories(path, "*", SearchOption.TopDirectoryOnly); - foreach (string directory in directories) - RenameDirectory(directory, searchPattern); int? id; string? message; string checkFile; @@ -152,10 +180,11 @@ public partial class Form : System.Windows.Forms.Form _ProgressBar.Visible = true; bool isValidImageFormatExtension; string? extraLargeBitmapThumbnail; - string[] files = Directory.GetFiles(path, searchPattern, SearchOption.TopDirectoryOnly); + string[] files = Directory.GetFiles(directory, searchPattern, SearchOption.TopDirectoryOnly); _ProgressBar.Maximum = files.Length; foreach (string file in files) { + _ProgressBar.PerformStep(); fileHolder = new(file); _Lines.Add(fileHolder.NameWithoutExtension); isValidImageFormatExtension = _Configuration.PropertyConfiguration.ValidImageFormatExtensions.Contains(fileHolder.ExtensionLowered); @@ -166,8 +195,6 @@ public partial class Form : System.Windows.Forms.Form continue; if (fileHolder.NameWithoutExtension.Length == 1 || fileHolder.NameWithoutExtension[1..].All(l => char.IsNumber(l))) continue; - if (fileHolder.NameWithoutExtension.Length == 1 || fileHolder.NameWithoutExtension[1..].All(l => char.IsNumber(l))) - continue; if (!isIgnoreExtension && isValidImageFormatExtension) extraLargeBitmapThumbnail = null; else @@ -200,11 +227,10 @@ public partial class Form : System.Windows.Forms.Form if (fileHolder.DirectoryName is null) continue; } - checkFile = Path.Combine(fileHolder.DirectoryName, $"{id}{fileHolder.ExtensionLowered}"); + checkFile = Path.Combine(fileHolder.DirectoryName, $"{id.Value}{fileHolder.ExtensionLowered}"); if (File.Exists(checkFile)) continue; File.Move(fileHolder.FullName, checkFile); - _ProgressBar.PerformStep(); } _ProgressBar.Visible = false; } @@ -225,55 +251,174 @@ public partial class Form : System.Windows.Forms.Form return result; } + private List<(string, FaceDistance)> GetFileAndFaceDistanceCollection(string[] files) + { + // int? id; + string? json; + // string? message; + // DateTime? dateTime; + // FileHolder fileHolder; + // bool isIgnoreExtension; + // DateTime? minimumDateTime; + FaceDistance faceDistance; + // bool isValidImageFormatExtension; + List<(string, FaceDistance)> collection = new(); + Shared.Models.FaceEncoding? modelsFaceEncoding; + FaceRecognitionDotNet.FaceEncoding faceRecognitionDotNetFaceEncoding; + _ProgressBar.Maximum = files.Length; + foreach (string file in files) + { + _ProgressBar.PerformStep(); + json = Metadata.Models.Stateless.IMetadata.GetFaceEncoding(file); + if (json is null) + break; + modelsFaceEncoding = JsonSerializer.Deserialize(json); + if (modelsFaceEncoding is null) + throw new NotSupportedException(); + faceRecognitionDotNetFaceEncoding = FaceRecognition.LoadFaceEncoding(modelsFaceEncoding.RawEncoding); + faceDistance = new(faceRecognitionDotNetFaceEncoding); + collection.Add(new(file, faceDistance)); + // fileHolder = new(file); + // _Lines.Add(fileHolder.NameWithoutExtension); + // isValidImageFormatExtension = _Configuration.PropertyConfiguration.ValidImageFormatExtensions.Contains(fileHolder.ExtensionLowered); + // isIgnoreExtension = isValidImageFormatExtension && _Configuration.IgnoreExtensions.Contains(fileHolder.ExtensionLowered); + // if (isIgnoreExtension || !isValidImageFormatExtension) + // continue; + // if (fileHolder.CreationTime is null || fileHolder.Name.Contains(fileHolder.CreationTime.Value.ToString("yy"))) + // continue; + // if (fileHolder.LastWriteTime is null || fileHolder.Name.Contains(fileHolder.LastWriteTime.Value.ToString("yy"))) + // continue; + // if (fileHolder.NameWithoutExtension.Length == 1 || fileHolder.NameWithoutExtension[1..].All(l => char.IsNumber(l))) + // continue; + // if (fileHolder.DirectoryName is null) + // continue; + // dateTime = IProperty.GetDateTimeFromName(fileHolder); + // if (dateTime is not null && fileHolder.Name.Contains(dateTime.Value.ToString("yy"))) + // continue; + // (minimumDateTime, id, message) = IProperty.Get(fileHolder); + // if (minimumDateTime is null || id is null) + // continue; + // if (fileHolder.Name.Contains(minimumDateTime.Value.ToString("yy"))) + // continue; + // if (dateTime is not null && minimumDateTime.Value != dateTime.Value) + // continue; + } + return collection; + } + + private static List<(string File, double? Sum)> GetFileAndSum(List<(string File, FaceDistance FaceDistance)> collection) + { + List<(string File, double? Sum)> results = new(); + List lengths = new(); + List faceDistanceLengths; + int take = (int)(collection.Count * .3333); + List faceDistances = collection.Select(l => l.FaceDistance).ToList(); + foreach ((string file, FaceDistance faceDistance) in collection) + { + lengths.Clear(); + faceDistanceLengths = FaceRecognition.FaceDistances(faceDistances, faceDistance); + if (faceDistanceLengths.Count != faceDistances.Count) + throw new NotSupportedException(); + lengths.AddRange(from l in faceDistanceLengths orderby l.Length is not null, l.Length select l.Length); + results.Add(new(file, lengths.Take(take).Sum())); + } + return results; + } + + private void ChangeDate(string directory, DateTime dateTime, string searchPattern) + { + string[] files = Directory.GetFiles(directory, searchPattern, SearchOption.TopDirectoryOnly); + _ProgressBar.Step = 1; + _ProgressBar.Value = 0; + _ProgressBar.Visible = true; + List<(string File, double? Sum)> results; + List<(string File, FaceDistance FaceDistance)> collection = GetFileAndFaceDistanceCollection(files); + _ProgressBar.Maximum = files.Length; + if (collection.Count != files.Length) + results = new(); + else + results = GetFileAndSum(collection); + if (results.Count == files.Length) + { + foreach ((string file, double? sum) in results) + { + if (sum is null) + continue; + File.SetCreationTime(file, dateTime.AddSeconds(sum.Value)); + } + } + if (results.Count == files.Length) + { } + } + + private List GetBirthDates(string directory) + { + List results = new(); + string[] directoryNames = IPath.GetDirectoryNames(directory); + foreach (string directoryName in directoryNames) + { + if (directoryName.Length != _Configuration.PersonBirthdayFormat.Length) + continue; + if (!DateTime.TryParseExact(directoryName, _Configuration.PersonBirthdayFormat, CultureInfo.InvariantCulture, DateTimeStyles.None, out DateTime dateTime)) + continue; + results.Add(dateTime); + } + return results; + } + + private void RenameFilesInDirectories(List directories) + { + string directoryName; + ReadOnlySpan span; + for (int i = 1; i < 3; i++) + { + foreach (string directory in directories) + { + if (directory.Length < 6) + continue; + directoryName = Path.GetFileName(directory); + if (directory.Contains("!---")) + span = "0"; + else + span = directory.AsSpan(directory.Length - 5, 3); + if (directoryName.Length != 1 || !int.TryParse(span, out int age)) + { + if (i == 1) + RenameFilesInDirectory(directory, "*Rename*"); + else if (i == 2) + RenameFilesInDirectory(directory, "*"); + else + continue; + } + else + { + if (i == 1) + { + List birthDates = GetBirthDates(directory); + if (birthDates.Count != 1) + continue; + ChangeDate(directory, birthDates[0].AddYears(age), "*"); + } + else + continue; + } + } + } + File.WriteAllLines($"D:/Tmp/Phares/{DateTime.Now.Ticks}.tsv", _Lines); + _Lines.Clear(); + } + void Form1_DragDrop(object? sender, DragEventArgs e) { try { - if (e.Data is null) + if (e.Data is null || e.Data.GetData(DataFormats.FileDrop) is not string[] paths) _TextBox.Text = string.Empty; else { - string name; - string[] segments; - for (int i = 1; i < 3; i++) - { - if (e.Data.GetData(DataFormats.FileDrop) is not string[] paths) - continue; - foreach (string path in paths) - { - name = Path.GetFileNameWithoutExtension(path); - Text = name; - segments = name.Split('.'); - if (Directory.Exists(path)) - { - if (i == 1) - RenameDirectory(path, "*Rename*"); - else if (i == 2) - RenameDirectory(path, "*"); - else - continue; - } - else - { - if (i != 1) - continue; - if (!_IdToMappingFromItem.Any()) - LoadData(); - if (int.TryParse(segments[0], out int id) && _IdToMappingFromItem.TryGetValue(id, out MappingFromItem? value)) - { - MappingFromItem mappingFromItem = value; - Text = mappingFromItem.ImageFileHolder.Name; - _TextBox.Text = mappingFromItem.ImageFileHolder.FullName; - if (mappingFromItem.ImageFileHolder.DirectoryName is not null) - _Logger.Information(mappingFromItem.ImageFileHolder.DirectoryName); - if (!string.IsNullOrEmpty(mappingFromItem.ImageFileHolder.DirectoryName)) - _ = Process.Start("explorer.exe", string.Concat("\"", mappingFromItem.ImageFileHolder.DirectoryName, "\"")); - } - } - } - File.WriteAllLines($"D:/Tmp/Phares/{DateTime.Now.Ticks}.tsv", _Lines); - _Lines.Clear(); - } + List directories = GetDirectoriesOrDoDragDrop(paths); + if (directories.Any()) + RenameFilesInDirectories(directories); } } catch (Exception) @@ -282,4 +427,37 @@ public partial class Form : System.Windows.Forms.Form } } + private List GetDirectoriesOrDoDragDrop(string[] paths) + { + List results = new(); + string name; + string[] segments; + foreach (string path in paths) + { + name = Path.GetFileNameWithoutExtension(path); + Text = name; + segments = name.Split('.'); + if (Directory.Exists(path)) + { + results.Add(path); + results.AddRange(Directory.GetDirectories(path, "*", SearchOption.AllDirectories)); + } + else + { + if (!_IdToItem.Any()) + LoadData(); + if (int.TryParse(segments[0], out int id) && _IdToItem.TryGetValue(id, out Item? item)) + { + Text = item.ImageFileHolder.Name; + _TextBox.Text = item.ImageFileHolder.FullName; + if (item.ImageFileHolder.DirectoryName is not null) + _Logger.Information(item.ImageFileHolder.DirectoryName); + if (!string.IsNullOrEmpty(item.ImageFileHolder.DirectoryName)) + _ = Process.Start("explorer.exe", string.Concat("\"", item.ImageFileHolder.DirectoryName, "\"")); + } + } + } + return results; + } + } \ No newline at end of file diff --git a/Drag-Drop/Models/Binder/Configuration.cs b/Drag-Drop/Models/Binder/Configuration.cs index 2713d8d..97c6d25 100644 --- a/Drag-Drop/Models/Binder/Configuration.cs +++ b/Drag-Drop/Models/Binder/Configuration.cs @@ -35,6 +35,7 @@ public class Configuration [Display(Name = "Override For Face Images"), Required] public bool? OverrideForFaceImages { get; set; } [Display(Name = "Override For Face Landmark Images"), Required] public bool? OverrideForFaceLandmarkImages { get; set; } [Display(Name = "Override For Resize Images"), Required] public bool? OverrideForResizeImages { get; set; } + [Display(Name = "Person Birthday Format"), Required] public string PersonBirthdayFormat { get; set; } [Display(Name = "Predictor Model Name"), Required] public string PredictorModelName { get; set; } [Display(Name = "Properties Changed For Distance"), Required] public bool? PropertiesChangedForDistance { get; set; } [Display(Name = "Properties Changed For Faces"), Required] public bool? PropertiesChangedForFaces { get; set; } @@ -103,6 +104,8 @@ public class Configuration throw new NullReferenceException(nameof(configuration.OverrideForFaceLandmarkImages)); if (configuration.OverrideForResizeImages is null) throw new NullReferenceException(nameof(configuration.OverrideForResizeImages)); + if (configuration.PersonBirthdayFormat is null) + throw new NullReferenceException(nameof(configuration.PersonBirthdayFormat)); if (configuration.PropertiesChangedForDistance is null) throw new NullReferenceException(nameof(configuration.PropertiesChangedForDistance)); if (configuration.PropertiesChangedForFaces is null) @@ -154,6 +157,7 @@ public class Configuration configuration.OverrideForFaceImages.Value, configuration.OverrideForFaceLandmarkImages.Value, configuration.OverrideForResizeImages.Value, + configuration.PersonBirthdayFormat, configuration.PredictorModelName, configuration.PropertiesChangedForDistance.Value, configuration.PropertiesChangedForFaces.Value, diff --git a/Drag-Drop/Models/Configuration.cs b/Drag-Drop/Models/Configuration.cs index a9ff9f3..4604bb2 100644 --- a/Drag-Drop/Models/Configuration.cs +++ b/Drag-Drop/Models/Configuration.cs @@ -34,6 +34,7 @@ public class Configuration public bool OverrideForFaceImages { init; get; } public bool OverrideForFaceLandmarkImages { init; get; } public bool OverrideForResizeImages { init; get; } + public string PersonBirthdayFormat { init; get; } public string PredictorModelName { init; get; } public bool PropertiesChangedForDistance { init; get; } public bool PropertiesChangedForFaces { init; get; } @@ -77,6 +78,7 @@ public class Configuration bool overrideForFaceImages, bool overrideForFaceLandmarkImages, bool overrideForResizeImages, + string personBirthdayFormat, string predictorModelName, bool propertiesChangedForDistance, bool propertiesChangedForFaces, @@ -119,6 +121,7 @@ public class Configuration OverrideForFaceImages = overrideForFaceImages; OverrideForFaceLandmarkImages = overrideForFaceLandmarkImages; OverrideForResizeImages = overrideForResizeImages; + PersonBirthdayFormat = personBirthdayFormat; PredictorModelName = predictorModelName; PropertiesChangedForDistance = propertiesChangedForDistance; PropertiesChangedForFaces = propertiesChangedForFaces; diff --git a/Drag-Drop/Program.cs b/Drag-Drop/Program.cs index 7072468..27591b5 100644 --- a/Drag-Drop/Program.cs +++ b/Drag-Drop/Program.cs @@ -1,5 +1,4 @@ using View_by_Distance.Shared.Models; -using View_by_Distance.Shared.Models.Stateless.Methods; namespace View_by_Distance.Drag_Drop; @@ -47,11 +46,10 @@ static class Program return result; } - public static List GetMappingFromItemCollection(Models.Configuration configuration, Container[] containers) + public static List GetItemCollection(Models.Configuration configuration, Container[] containers) { - List results = new(); + List results = new(); Item[] filteredItems; - MappingFromItem mappingFromItem; foreach (Container container in containers) { if (!container.Items.Any()) @@ -62,12 +60,7 @@ static class Program if (!filteredItems.Any()) continue; foreach (Item item in filteredItems) - { - if (item.Property?.Id is null) - continue; - mappingFromItem = IMappingFromItem.GetMappingFromItem(item); - results.Add(mappingFromItem); - } + results.Add(item); } return results; } diff --git a/Map/Models/MapLogic.cs b/Map/Models/MapLogic.cs index e65098b..043b877 100644 --- a/Map/Models/MapLogic.cs +++ b/Map/Models/MapLogic.cs @@ -797,15 +797,14 @@ public class MapLogic return new(personKeyFormatted, personBirthday); } - private List<(string, PersonContainer)> GetPersonContainers(string[] jLinks, string a2PeopleSingletonDirectory, PersonContainer[] personContainers, Dictionary personKeyToCount) + private List GetPersonKeyFormattedCollection(string[] jLinks, string a2PeopleSingletonDirectory, PersonContainer[] personContainers, Dictionary personKeyToCount) { if (_Configuration is null) throw new NullReferenceException(nameof(_Configuration)); if (_MapLogicSupport is null) throw new NullReferenceException(nameof(_MapLogicSupport)); - List<(string, PersonContainer)> results = new(); + List results = new(); string[] files; - const int zero = 0; string[] directories; string checkDirectory; string[] checkDirectories; @@ -865,24 +864,18 @@ public class MapLogic matches = (from l in personContainers where l.Key == personKey && l.ApproximateYears.HasValue select l).ToArray(); if (!matches.Any()) continue; + personKeyFormatted = IPersonBirthday.GetFormatted(_Configuration.PersonBirthdayFormat, personKey); + if (!displayDirectoryName.Contains(personKeyFormatted)) + continue; if (!Directory.Exists(displayDirectoryName)) _ = Directory.CreateDirectory(displayDirectoryName); - personKeyFormatted = IPersonBirthday.GetFormatted(_Configuration.PersonBirthdayFormat, personKey); - results.Add(new(personKeyFormatted, matches[zero])); + results.Add(personKeyFormatted); } } } return results; } - private string[] GetPersonKeyFormattedCollection(string[] jLinks, string a2PeopleSingletonDirectory, PersonContainer[] personContainers, Dictionary personKeyToCount) - { - string[] results; - List<(string PersonKeyFormatted, PersonContainer PersonContainer)> collection = GetPersonContainers(jLinks, a2PeopleSingletonDirectory, personContainers, personKeyToCount); - results = (from l in collection orderby l.PersonKeyFormatted select l.PersonKeyFormatted).ToArray(); - return results; - } - private (int, FileHolder, int, string, string, string, string)[] GetCollectionForSaveResizedImagesByPersonKeyFormatted(string[] jLinks, string a2PeopleSingletonDirectory, PersonContainer[] personContainers, Mapping[] mappingCollection, Dictionary personKeyToCount) { if (_Configuration is null) @@ -893,7 +886,8 @@ public class MapLogic string? directoryName; string personDirectory; string personKeyFormatted; - string[] personKeyFormattedCollection = GetPersonKeyFormattedCollection(jLinks, a2PeopleSingletonDirectory, personContainers, personKeyToCount); + bool usePersonKeyAndDeterministicHashCodeKey = false; + List personKeyFormattedCollection = GetPersonKeyFormattedCollection(jLinks, a2PeopleSingletonDirectory, personContainers, personKeyToCount); List<(int Id, FileHolder ResizedFileHolder, int ApproximateYears, string PersonKeyFormatted, string CheckFile, string Directory, string PersonDirectory)> collection = new(); foreach (Mapping mapping in mappingCollection) { @@ -913,9 +907,18 @@ public class MapLogic continue; if (!personKeyFormattedCollection.Contains(personKeyFormatted)) continue; - directory = Path.Combine(_EDistanceContentTicksDirectory, "Images", personKeyFormatted); - personDirectory = Path.Combine(directory, mapping.MappingFromPerson.DisplayDirectoryName); - checkFile = Path.Combine(directory, $"{mapping.MappingFromLocation.DeterministicHashCodeKey}{mapping.MappingFromItem.ImageFileHolder.ExtensionLowered}"); + if (!usePersonKeyAndDeterministicHashCodeKey) + { + directory = Path.Combine(_EDistanceContentTicksDirectory, "Images"); + personDirectory = Path.Combine(directory, mapping.MappingFromPerson.DisplayDirectoryName); + checkFile = Path.Combine(directory, $"{mapping.MappingFromItem.Id}{mapping.MappingFromItem.ImageFileHolder.ExtensionLowered}"); + } + else + { + directory = Path.Combine(_EDistanceContentTicksDirectory, "Images", personKeyFormatted); + personDirectory = Path.Combine(directory, mapping.MappingFromPerson.DisplayDirectoryName); + checkFile = Path.Combine(directory, $"{mapping.MappingFromLocation.DeterministicHashCodeKey}{mapping.MappingFromItem.ImageFileHolder.ExtensionLowered}"); + } collection.Add(new(mapping.MappingFromItem.Id, mapping.MappingFromItem.ResizedFileHolder, mapping.MappingFromPerson.ApproximateYears.Value, personKeyFormatted, directory, personDirectory, checkFile)); } results = (from l in collection orderby l.ApproximateYears descending, l.PersonKeyFormatted descending select l).ToArray(); @@ -954,7 +957,7 @@ public class MapLogic string personDirectory; string personKeyFormatted; List<(string, string, string, string)> collection = new(); - string[] personKeyFormattedCollection = GetPersonKeyFormattedCollection(jLinks, a2PeopleSingletonDirectory, personContainers, personKeyToCount); + List personKeyFormattedCollection = GetPersonKeyFormattedCollection(jLinks, a2PeopleSingletonDirectory, personContainers, personKeyToCount); foreach (Item item in filteredItems) { directoryName = Path.GetDirectoryName(item.RelativePath); diff --git a/Metadata/Models/Stateless/IMetadata.cs b/Metadata/Models/Stateless/IMetadata.cs new file mode 100644 index 0000000..1821fcd --- /dev/null +++ b/Metadata/Models/Stateless/IMetadata.cs @@ -0,0 +1,16 @@ +namespace View_by_Distance.Metadata.Models.Stateless; + +public interface IMetadata +{ + + string? TestStatic_GetFaceEncoding(string file) => + GetFaceEncoding(file); + static string? GetFaceEncoding(string file) => + Metadata.GetFaceEncoding(file); + + string? TestStatic_GetFaceLocation(string file) => + GetFaceLocation(file); + static string? GetFaceLocation(string file) => + Metadata.GetFaceLocation(file); + +} \ No newline at end of file diff --git a/Metadata/Models/Stateless/Metadata.cs b/Metadata/Models/Stateless/Metadata.cs new file mode 100644 index 0000000..a2b83e7 --- /dev/null +++ b/Metadata/Models/Stateless/Metadata.cs @@ -0,0 +1,58 @@ +namespace View_by_Distance.Metadata.Models.Stateless; + +internal class Metadata +{ + + internal static string? GetFaceEncoding(string file) + { + string? result; + List results = new(); + const string comment = "Comment: "; + if (File.Exists(file)) + { + IReadOnlyList directories = MetadataExtractor.ImageMetadataReader.ReadMetadata(file); + foreach (MetadataExtractor.Directory directory in directories) + { + if (directory.Name != "PNG-tEXt") + continue; + foreach (MetadataExtractor.Tag tag in directory.Tags) + { + if (tag.Name != "Textual Data" || string.IsNullOrEmpty(tag.Description)) + continue; + if (!tag.Description.StartsWith(comment)) + continue; + results.Add(tag.Description); + } + } + } + result = results.Any() ? results[0][comment.Length..] : null; + return result; + } + + internal static string? GetFaceLocation(string file) + { + string? result; + List results = new(); + const string artist = "Artist: "; + if (File.Exists(file)) + { + IReadOnlyList directories = MetadataExtractor.ImageMetadataReader.ReadMetadata(file); + foreach (MetadataExtractor.Directory directory in directories) + { + if (directory.Name != "PNG-tEXt") + continue; + foreach (MetadataExtractor.Tag tag in directory.Tags) + { + if (tag.Name != "Textual Data" || string.IsNullOrEmpty(tag.Description)) + continue; + if (!tag.Description.StartsWith(artist)) + continue; + results.Add(tag.Description); + } + } + } + result = results.Any() ? results[0][artist.Length..] : null; + return result; + } + +} \ No newline at end of file diff --git a/Property/Models/Stateless/IResult.cs b/Property/Models/Stateless/IResult.cs index 1e407c4..23fb238 100644 --- a/Property/Models/Stateless/IResult.cs +++ b/Property/Models/Stateless/IResult.cs @@ -3,36 +3,44 @@ namespace View_by_Distance.Property.Models.Stateless; public interface IResult { - string TestStatic_GetRelativePath(Shared.Models.Properties.IPropertyConfiguration propertyConfiguration, string path); - static string GetRelativePath(Shared.Models.Properties.IPropertyConfiguration propertyConfiguration, string path) - => Result.GetRelativePath(propertyConfiguration, path); + string TestStatic_GetRelativePath(Shared.Models.Properties.IPropertyConfiguration propertyConfiguration, string path) => + GetRelativePath(propertyConfiguration, path); + static string GetRelativePath(Shared.Models.Properties.IPropertyConfiguration propertyConfiguration, string path) => + Result.GetRelativePath(propertyConfiguration, path); - string TestStatic_GetResultsGroupDirectory(Shared.Models.Properties.IPropertyConfiguration propertyConfiguration, string description, bool create); - static string GetResultsGroupDirectory(Shared.Models.Properties.IPropertyConfiguration propertyConfiguration, string description, bool create) - => Result.GetResultsGroupDirectory(propertyConfiguration, description, create); + string TestStatic_GetResultsGroupDirectory(Shared.Models.Properties.IPropertyConfiguration propertyConfiguration, string description, bool create) => + GetResultsGroupDirectory(propertyConfiguration, description, create); + static string GetResultsGroupDirectory(Shared.Models.Properties.IPropertyConfiguration propertyConfiguration, string description, bool create) => + Result.GetResultsGroupDirectory(propertyConfiguration, description, create); - string TestStatic_GetResultsGroupDirectory(Shared.Models.Properties.IPropertyConfiguration propertyConfiguration, string description); - static string GetResultsGroupDirectory(Shared.Models.Properties.IPropertyConfiguration propertyConfiguration, string description) - => Result.GetResultsGroupDirectory(propertyConfiguration, description, create: true); + string TestStatic_GetResultsGroupDirectory(Shared.Models.Properties.IPropertyConfiguration propertyConfiguration, string description) => + GetResultsGroupDirectory(propertyConfiguration, description); + static string GetResultsGroupDirectory(Shared.Models.Properties.IPropertyConfiguration propertyConfiguration, string description) => + Result.GetResultsGroupDirectory(propertyConfiguration, description, create: true); - string TestStatic_GetResultsDateGroupDirectory(Shared.Models.Properties.IPropertyConfiguration propertyConfiguration, string description); - static string GetResultsDateGroupDirectory(Shared.Models.Properties.IPropertyConfiguration propertyConfiguration, string description) - => Result.GetResultsDateGroupDirectory(propertyConfiguration, description); + string TestStatic_GetResultsDateGroupDirectory(Shared.Models.Properties.IPropertyConfiguration propertyConfiguration, string description) => + GetResultsDateGroupDirectory(propertyConfiguration, description); + static string GetResultsDateGroupDirectory(Shared.Models.Properties.IPropertyConfiguration propertyConfiguration, string description) => + Result.GetResultsDateGroupDirectory(propertyConfiguration, description); - string TestStatic_GetResultsDateGroupDirectory(Shared.Models.Properties.IPropertyConfiguration propertyConfiguration, string description, string jsonGroup); - static string GetResultsDateGroupDirectory(Shared.Models.Properties.IPropertyConfiguration propertyConfiguration, string description, string jsonGroup) - => Result.GetResultsDateGroupDirectory(propertyConfiguration, description, jsonGroup); + string TestStatic_GetResultsDateGroupDirectory(Shared.Models.Properties.IPropertyConfiguration propertyConfiguration, string description, string jsonGroup) => + GetResultsDateGroupDirectory(propertyConfiguration, description, jsonGroup); + static string GetResultsDateGroupDirectory(Shared.Models.Properties.IPropertyConfiguration propertyConfiguration, string description, string jsonGroup) => + Result.GetResultsDateGroupDirectory(propertyConfiguration, description, jsonGroup); - List TestStatic_GetDirectoryInfoCollection(Shared.Models.Properties.IPropertyConfiguration propertyConfiguration, string sourceDirectory, string dateGroupDirectory, string contentDescription, string singletonDescription, string collectionDescription); - static List GetDirectoryInfoCollection(Shared.Models.Properties.IPropertyConfiguration propertyConfiguration, string sourceDirectory, string dateGroupDirectory, string contentDescription, string singletonDescription, string collectionDescription, bool converted) - => Result.GetDirectoryInfoCollection(propertyConfiguration, sourceDirectory, dateGroupDirectory, contentDescription, singletonDescription, collectionDescription, converted); + List TestStatic_GetDirectoryInfoCollection(Shared.Models.Properties.IPropertyConfiguration propertyConfiguration, string sourceDirectory, string dateGroupDirectory, string contentDescription, string singletonDescription, string collectionDescription, bool converted) => + GetDirectoryInfoCollection(propertyConfiguration, sourceDirectory, dateGroupDirectory, contentDescription, singletonDescription, collectionDescription, converted); + static List GetDirectoryInfoCollection(Shared.Models.Properties.IPropertyConfiguration propertyConfiguration, string sourceDirectory, string dateGroupDirectory, string contentDescription, string singletonDescription, string collectionDescription, bool converted) => + Result.GetDirectoryInfoCollection(propertyConfiguration, sourceDirectory, dateGroupDirectory, contentDescription, singletonDescription, collectionDescription, converted); - string TestStatic_GetResultsFullGroupDirectory(Shared.Models.Properties.IPropertyConfiguration propertyConfiguration, string description, string outputResolution, bool includeResizeGroup, bool includeModel, bool includePredictorModel); - static string GetResultsFullGroupDirectory(Shared.Models.Properties.IPropertyConfiguration propertyConfiguration, string description, string outputResolution, bool includeResizeGroup, bool includeModel, bool includePredictorModel) - => Result.GetResultsFullGroupDirectory(propertyConfiguration, description, outputResolution, includeResizeGroup, includeModel, includePredictorModel); + string TestStatic_GetResultsFullGroupDirectory(Shared.Models.Properties.IPropertyConfiguration propertyConfiguration, string description, string outputResolution, bool includeResizeGroup, bool includeModel, bool includePredictorModel) => + GetResultsFullGroupDirectory(propertyConfiguration, description, outputResolution, includeResizeGroup, includeModel, includePredictorModel); + static string GetResultsFullGroupDirectory(Shared.Models.Properties.IPropertyConfiguration propertyConfiguration, string description, string outputResolution, bool includeResizeGroup, bool includeModel, bool includePredictorModel) => + Result.GetResultsFullGroupDirectory(propertyConfiguration, description, outputResolution, includeResizeGroup, includeModel, includePredictorModel); - List TestStatic_GetDirectoryInfoCollection(Shared.Models.Properties.IPropertyConfiguration propertyConfiguration, string sourceDirectory, string description, string outputResolution, bool includeResizeGroup, bool includeModel, bool includePredictorModel, string contentDescription, string singletonDescription, string collectionDescription); - static List GetDirectoryInfoCollection(Shared.Models.Properties.IPropertyConfiguration propertyConfiguration, string sourceDirectory, string description, string outputResolution, bool includeResizeGroup, bool includeModel, bool includePredictorModel, string contentDescription, string singletonDescription, string collectionDescription) - => Result.GetDirectoryInfoCollection(propertyConfiguration, sourceDirectory, description, outputResolution, includeResizeGroup, includeModel, includePredictorModel, contentDescription, singletonDescription, collectionDescription); + List TestStatic_GetDirectoryInfoCollection(Shared.Models.Properties.IPropertyConfiguration propertyConfiguration, string sourceDirectory, string description, string outputResolution, bool includeResizeGroup, bool includeModel, bool includePredictorModel, string contentDescription, string singletonDescription, string collectionDescription) => + GetDirectoryInfoCollection(propertyConfiguration, sourceDirectory, description, outputResolution, includeResizeGroup, includeModel, includePredictorModel, contentDescription, singletonDescription, collectionDescription); + static List GetDirectoryInfoCollection(Shared.Models.Properties.IPropertyConfiguration propertyConfiguration, string sourceDirectory, string description, string outputResolution, bool includeResizeGroup, bool includeModel, bool includePredictorModel, string contentDescription, string singletonDescription, string collectionDescription) => + Result.GetDirectoryInfoCollection(propertyConfiguration, sourceDirectory, description, outputResolution, includeResizeGroup, includeModel, includePredictorModel, contentDescription, singletonDescription, collectionDescription); } \ No newline at end of file diff --git a/View-by-Distance-MKLink-Console.sln b/View-by-Distance-MKLink-Console.sln index a66c5b4..8a93968 100644 --- a/View-by-Distance-MKLink-Console.sln +++ b/View-by-Distance-MKLink-Console.sln @@ -37,6 +37,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Face", "Face\Face.csproj", EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FaceParts", "FaceParts\FaceParts.csproj", "{919525B1-60BA-40C6-BA66-6F7F4C526E01}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Drag-Drop", "Drag-Drop\Drag-Drop.csproj", "{87EB76BC-32A9-4FD0-922A-BD7E9B6E7D8B}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -114,5 +116,9 @@ Global {919525B1-60BA-40C6-BA66-6F7F4C526E01}.Debug|Any CPU.Build.0 = Debug|Any CPU {919525B1-60BA-40C6-BA66-6F7F4C526E01}.Release|Any CPU.ActiveCfg = Release|Any CPU {919525B1-60BA-40C6-BA66-6F7F4C526E01}.Release|Any CPU.Build.0 = Release|Any CPU + {87EB76BC-32A9-4FD0-922A-BD7E9B6E7D8B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {87EB76BC-32A9-4FD0-922A-BD7E9B6E7D8B}.Debug|Any CPU.Build.0 = Debug|Any CPU + {87EB76BC-32A9-4FD0-922A-BD7E9B6E7D8B}.Release|Any CPU.ActiveCfg = Release|Any CPU + {87EB76BC-32A9-4FD0-922A-BD7E9B6E7D8B}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection EndGlobal