From c9dbce3b57386071e25c1965204a4e660dab2065 Mon Sep 17 00:00:00 2001 From: Mike Phares Date: Sun, 28 Apr 2024 17:30:55 -0700 Subject: [PATCH] IEnumerable Filtered => ValidImage GetMappings => if (face.FaceEncoding is null || face.Location is null || face.OutputResolution is null) PreFilter skip done Removed sort Better names break out RootAmazon FilteredOriginalImage DeleteContinueFiles AppSetting PreVerify Settings Tasks --- .vscode/settings.json | 4 +- Compare/Models/Binder/AppSettings.cs | 20 +++ Compare/Models/Binder/Configuration.cs | 3 - Copy-Distinct/Models/Binder/AppSettings.cs | 18 ++ Copy-Distinct/Models/Binder/Configuration.cs | 33 +++- Date-Group/Models/Binder/AppSettings.cs | 20 +++ Date-Group/Models/Binder/Configuration.cs | 30 +++- .../Models/Binder/AppSettings.cs | 20 +++ .../Models/Binder/AppSettings.cs | 20 +++ Distance/Models/DistanceLimits.cs | 2 + Distance/Models/_E_Distance.cs | 60 ++++--- .../Models/Binder/AppSettings.cs | 20 +++ Drag-Drop-Move/Models/Binder/AppSettings.cs | 20 +++ Drag-Drop-Search/Models/Binder/AppSettings.cs | 20 +++ .../Models/Binder/Configuration.cs | 64 ++++--- .../Models/Binder/AppSettings.cs | 20 +++ Duplicate-Search/DuplicateSearch.cs | 11 +- Duplicate-Search/Models/Binder/AppSettings.cs | 20 +++ Face/Models/_D_Face.cs | 2 +- FaceParts/Models/_D2_FaceParts.cs | 8 +- Instance/DlibDotNet.cs | 167 ++++++++++-------- Instance/Models/Binder/AppSettings.cs | 18 ++ Instance/Models/Binder/Configuration.cs | 22 ++- Instance/Models/_F_Random.cs | 10 +- Map/Models/Configuration.cs | 4 +- Map/Models/MapLogic.cs | 91 ++++++---- Map/Models/Stateless/DistanceLogic.cs | 21 ++- Map/Models/Stateless/MapLogic.cs | 13 +- Map/Models/Stateless/Methods/IMapLogic.cs | 8 +- Map/Models/Stateless/RelationLogic.cs | 2 +- Metadata-Query/Models/Binder/AppSettings.cs | 20 +++ Metadata-Query/Models/Binder/Configuration.cs | 33 +++- Mirror-Length/Models/Binder/AppSettings.cs | 20 +++ Mirror-Length/Models/Binder/Configuration.cs | 33 +++- Move-By-Id/Models/Binder/AppSettings.cs | 20 +++ Move-By-Id/Models/Binder/Configuration.cs | 33 +++- .../Models/Binder/AppSettings.cs | 20 +++ .../Models/Binder/Configuration.cs | 33 +++- PhotoPrism/Models/_F_PhotoPrism.cs | 4 +- PrepareForOld/Models/Binder/AppSettings.cs | 20 +++ PrepareForOld/Models/Binder/Configuration.cs | 8 +- Property/Models/A_Property.cs | 2 +- Property/Models/Binder/Configuration.cs | 23 ++- Rename/Models/Binder/AppSettings.cs | 18 ++ Rename/Models/Binder/Configuration.cs | 22 +++ Set-Created-Date/Models/Binder/AppSettings.cs | 20 +++ .../Models/Binder/Configuration.cs | 33 +++- Shared/Models/Aggregations.cs | 19 ++ Shared/Models/AllPerson.cs | 15 ++ Shared/Models/ClusterId.cs | 15 ++ Shared/Models/Container.cs | 3 +- Shared/Models/ContentProperties.cs | 20 +++ Shared/Models/ContentSignature.cs | 14 ++ Shared/Models/Datum.cs | 45 +++++ Shared/Models/ImageAmazon.cs | 36 ++++ Shared/Models/LocationAmazon.cs | 15 ++ Shared/Models/LocationInfo.cs | 17 ++ Shared/Models/Methods/IDistance.cs | 2 +- Shared/Models/Methods/IDistanceLimits.cs | 1 + Shared/Models/ParentMap.cs | 13 ++ Shared/Models/PersonAmazon.cs | 15 ++ Shared/Models/RootAmazon.cs | 15 ++ Shared/Models/SearchData.cs | 16 ++ Shared/Models/Stateless/Methods/Container.cs | 37 ++-- Shared/Models/Stateless/Methods/IContainer.cs | 20 +-- .../Stateless/Methods/IPersonContainer.cs | 6 +- Shared/Models/Stateless/Methods/IProperty.cs | 4 +- .../Stateless/Methods/PersonContainer.cs | 4 +- Shared/Models/Stateless/Methods/Property.cs | 6 +- Shared/Models/Thing.cs | 15 ++ Shared/Models/Time.cs | 15 ++ Shared/Models/Type.cs | 15 ++ Shared/Models/XAccntParentMap.cs | 13 ++ Tests/Models/Binder/AppSettings.cs | 18 ++ Tests/Models/Binder/Configuration.cs | 22 ++- Tests/UnitTestHardCoded.cs | 2 +- .../Models/Binder/AppSettings.cs | 18 ++ .../Models/Binder/Configuration.cs | 22 ++- 78 files changed, 1321 insertions(+), 290 deletions(-) create mode 100644 Shared/Models/Aggregations.cs create mode 100644 Shared/Models/AllPerson.cs create mode 100644 Shared/Models/ClusterId.cs create mode 100644 Shared/Models/ContentProperties.cs create mode 100644 Shared/Models/ContentSignature.cs create mode 100644 Shared/Models/Datum.cs create mode 100644 Shared/Models/ImageAmazon.cs create mode 100644 Shared/Models/LocationAmazon.cs create mode 100644 Shared/Models/LocationInfo.cs create mode 100644 Shared/Models/ParentMap.cs create mode 100644 Shared/Models/PersonAmazon.cs create mode 100644 Shared/Models/RootAmazon.cs create mode 100644 Shared/Models/SearchData.cs create mode 100644 Shared/Models/Thing.cs create mode 100644 Shared/Models/Time.cs create mode 100644 Shared/Models/Type.cs create mode 100644 Shared/Models/XAccntParentMap.cs diff --git a/.vscode/settings.json b/.vscode/settings.json index 82493c8..84ebc62 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -22,8 +22,6 @@ "Hmmssfff", "jfif", "JOSN", - "Makernote", - "Makernotes", "mmod", "Nicéphore", "Niépce", @@ -33,10 +31,10 @@ "permyriad", "Phares", "Phgtv", - "photoshop", "RDHC", "Rects", "resnet", + "Rijndael", "Serilog", "Subfile", "Subfiles", diff --git a/Compare/Models/Binder/AppSettings.cs b/Compare/Models/Binder/AppSettings.cs index db68777..80e9319 100644 --- a/Compare/Models/Binder/AppSettings.cs +++ b/Compare/Models/Binder/AppSettings.cs @@ -20,6 +20,23 @@ public class AppSettings return result; } + private static void PreVerify(IConfigurationRoot configurationRoot, AppSettings? appSettings) + { + if (appSettings?.Company is null) + { + List paths = []; + foreach (IConfigurationProvider configurationProvider in configurationRoot.Providers) + { + if (configurationProvider is not Microsoft.Extensions.Configuration.Json.JsonConfigurationProvider jsonConfigurationProvider) + continue; + if (jsonConfigurationProvider.Source.FileProvider is not Microsoft.Extensions.FileProviders.PhysicalFileProvider physicalFileProvider) + continue; + paths.Add(physicalFileProvider.Root); + } + throw new NotSupportedException($"Not found!{Environment.NewLine}{string.Join(Environment.NewLine, paths.Distinct())}"); + } + } + private static Models.AppSettings Get(AppSettings? appSettings) { Models.AppSettings result; @@ -36,7 +53,10 @@ public class AppSettings public static Models.AppSettings Get(IConfigurationRoot configurationRoot) { Models.AppSettings result; +#pragma warning disable IL3050, IL2026 AppSettings? appSettings = configurationRoot.Get(); +#pragma warning restore IL3050, IL2026 + PreVerify(configurationRoot, appSettings); result = Get(appSettings); return result; } diff --git a/Compare/Models/Binder/Configuration.cs b/Compare/Models/Binder/Configuration.cs index 682bb5f..0811f7a 100644 --- a/Compare/Models/Binder/Configuration.cs +++ b/Compare/Models/Binder/Configuration.cs @@ -5,7 +5,6 @@ namespace View_by_Distance.Compare.Models.Binder; public class Configuration { -#nullable disable public string DiffPropertyDirectory { get; set; } public Property.Models.Configuration PropertyConfiguration { get; set; } public string[] Rename { get; set; } @@ -13,8 +12,6 @@ public class Configuration public string[] RenameC { get; set; } public string[] Spelling { get; set; } -#nullable restore - public override string ToString() { string result = JsonSerializer.Serialize(this, new JsonSerializerOptions() { WriteIndented = true }); diff --git a/Copy-Distinct/Models/Binder/AppSettings.cs b/Copy-Distinct/Models/Binder/AppSettings.cs index 5707d0c..16d06ba 100644 --- a/Copy-Distinct/Models/Binder/AppSettings.cs +++ b/Copy-Distinct/Models/Binder/AppSettings.cs @@ -21,6 +21,23 @@ public class AppSettings return result; } + private static void PreVerify(IConfigurationRoot configurationRoot, AppSettings? appSettings) + { + if (appSettings?.Company is null) + { + List paths = []; + foreach (IConfigurationProvider configurationProvider in configurationRoot.Providers) + { + if (configurationProvider is not Microsoft.Extensions.Configuration.Json.JsonConfigurationProvider jsonConfigurationProvider) + continue; + if (jsonConfigurationProvider.Source.FileProvider is not Microsoft.Extensions.FileProviders.PhysicalFileProvider physicalFileProvider) + continue; + paths.Add(physicalFileProvider.Root); + } + throw new NotSupportedException($"Not found!{Environment.NewLine}{string.Join(Environment.NewLine, paths.Distinct())}"); + } + } + private static Models.AppSettings Get(AppSettings? appSettings) { Models.AppSettings result; @@ -56,6 +73,7 @@ public class AppSettings #pragma warning disable IL3050, IL2026 AppSettings? appSettings = configurationRoot.Get(); #pragma warning restore IL3050, IL2026 + PreVerify(configurationRoot, appSettings); result = Get(appSettings); return result; } diff --git a/Copy-Distinct/Models/Binder/Configuration.cs b/Copy-Distinct/Models/Binder/Configuration.cs index ba69497..ec27498 100644 --- a/Copy-Distinct/Models/Binder/Configuration.cs +++ b/Copy-Distinct/Models/Binder/Configuration.cs @@ -7,13 +7,9 @@ namespace View_by_Distance.Copy.Distinct.Models.Binder; public class Configuration { -#nullable disable - - public string[] IgnoreExtensions { get; set; } - public Property.Models.Configuration PropertyConfiguration { get; set; } - public string PersonBirthdayFormat { get; set; } - -#nullable restore + public string[]? IgnoreExtensions { get; set; } + public Property.Models.Configuration? PropertyConfiguration { get; set; } + public string? PersonBirthdayFormat { get; set; } public override string ToString() { @@ -21,12 +17,30 @@ public class Configuration return result; } + private static void PreVerify(IConfigurationRoot configurationRoot, Configuration? configuration) + { + if (configuration?.IgnoreExtensions is null) + { + List paths = []; + foreach (IConfigurationProvider configurationProvider in configurationRoot.Providers) + { + if (configurationProvider is not Microsoft.Extensions.Configuration.Json.JsonConfigurationProvider jsonConfigurationProvider) + continue; + if (jsonConfigurationProvider.Source.FileProvider is not Microsoft.Extensions.FileProviders.PhysicalFileProvider physicalFileProvider) + continue; + paths.Add(physicalFileProvider.Root); + } + throw new NotSupportedException($"Not found!{Environment.NewLine}{string.Join(Environment.NewLine, paths.Distinct())}"); + } + } + private static Models.Configuration Get(Configuration? configuration) { Models.Configuration result; if (configuration is null) throw new NullReferenceException(nameof(configuration)); if (configuration.IgnoreExtensions is null) throw new NullReferenceException(nameof(configuration.IgnoreExtensions)); if (configuration.PersonBirthdayFormat is null) throw new NullReferenceException(nameof(configuration.PersonBirthdayFormat)); + if (configuration.PropertyConfiguration is null) throw new NullReferenceException(nameof(configuration.PropertyConfiguration)); result = new( configuration.IgnoreExtensions, configuration.PersonBirthdayFormat, @@ -39,14 +53,19 @@ public class Configuration Models.Configuration result; Configuration? configuration; if (isEnvironment is null) +#pragma warning disable IL3050, IL2026 configuration = configurationRoot.Get(); +#pragma warning restore IL3050, IL2026 else { string environmentName = IsEnvironment.GetEnvironmentName(isEnvironment); string section = string.Concat(environmentName, ":", nameof(Configuration)); IConfigurationSection configurationSection = configurationRoot.GetSection(section); +#pragma warning disable IL3050, IL2026 configuration = configurationSection.Get(); +#pragma warning restore IL3050, IL2026 } + PreVerify(configurationRoot, configuration); result = Get(configuration); return result; } diff --git a/Date-Group/Models/Binder/AppSettings.cs b/Date-Group/Models/Binder/AppSettings.cs index 50825ef..d74c58b 100644 --- a/Date-Group/Models/Binder/AppSettings.cs +++ b/Date-Group/Models/Binder/AppSettings.cs @@ -20,6 +20,23 @@ public class AppSettings return result; } + private static void PreVerify(IConfigurationRoot configurationRoot, AppSettings? appSettings) + { + if (appSettings?.Company is null) + { + List paths = []; + foreach (IConfigurationProvider configurationProvider in configurationRoot.Providers) + { + if (configurationProvider is not Microsoft.Extensions.Configuration.Json.JsonConfigurationProvider jsonConfigurationProvider) + continue; + if (jsonConfigurationProvider.Source.FileProvider is not Microsoft.Extensions.FileProviders.PhysicalFileProvider physicalFileProvider) + continue; + paths.Add(physicalFileProvider.Root); + } + throw new NotSupportedException($"Not found!{Environment.NewLine}{string.Join(Environment.NewLine, paths.Distinct())}"); + } + } + private static Models.AppSettings Get(AppSettings? appSettings) { Models.AppSettings result; @@ -36,7 +53,10 @@ public class AppSettings public static Models.AppSettings Get(IConfigurationRoot configurationRoot) { Models.AppSettings result; +#pragma warning disable IL3050, IL2026 AppSettings? appSettings = configurationRoot.Get(); +#pragma warning restore IL3050, IL2026 + PreVerify(configurationRoot, appSettings); result = Get(appSettings); return result; } diff --git a/Date-Group/Models/Binder/Configuration.cs b/Date-Group/Models/Binder/Configuration.cs index 3ee612c..41b3614 100644 --- a/Date-Group/Models/Binder/Configuration.cs +++ b/Date-Group/Models/Binder/Configuration.cs @@ -7,17 +7,13 @@ namespace View_by_Distance.Date.Group.Models.Binder; public class Configuration { -#nullable disable - public bool? ByCreateDateShortcut { get; set; } public bool? ByDay { get; set; } public bool? ByHash { get; set; } public bool? BySeason { get; set; } public bool? ByWeek { get; set; } public bool? KeepFullPath { get; set; } - public Property.Models.Configuration PropertyConfiguration { get; set; } - -#nullable restore + public Property.Models.Configuration? PropertyConfiguration { get; set; } public override string ToString() { @@ -25,10 +21,28 @@ public class Configuration return result; } + private static void PreVerify(IConfigurationRoot configurationRoot, Configuration? configuration) + { + if (configuration?.ByCreateDateShortcut is null) + { + List paths = []; + foreach (IConfigurationProvider configurationProvider in configurationRoot.Providers) + { + if (configurationProvider is not Microsoft.Extensions.Configuration.Json.JsonConfigurationProvider jsonConfigurationProvider) + continue; + if (jsonConfigurationProvider.Source.FileProvider is not Microsoft.Extensions.FileProviders.PhysicalFileProvider physicalFileProvider) + continue; + paths.Add(physicalFileProvider.Root); + } + throw new NotSupportedException($"Not found!{Environment.NewLine}{string.Join(Environment.NewLine, paths.Distinct())}"); + } + } + private static Models.Configuration Get(Configuration? configuration) { Models.Configuration result; if (configuration is null) throw new NullReferenceException(nameof(configuration)); + if (configuration.PropertyConfiguration is null) throw new NullReferenceException(nameof(configuration.PropertyConfiguration)); if (configuration.ByCreateDateShortcut is null) throw new NullReferenceException(nameof(configuration.ByCreateDateShortcut)); if (configuration.ByDay is null) throw new NullReferenceException(nameof(configuration.ByDay)); if (configuration.ByHash is null) throw new NullReferenceException(nameof(configuration.ByHash)); @@ -51,16 +65,20 @@ public class Configuration Models.Configuration result; Configuration? configuration; if (isEnvironment is null) +#pragma warning disable IL3050, IL2026 configuration = configurationRoot.Get(); +#pragma warning restore IL3050, IL2026 else { string environmentName = IsEnvironment.GetEnvironmentName(isEnvironment); string section = string.Concat(environmentName, ":", nameof(Configuration)); IConfigurationSection configurationSection = configurationRoot.GetSection(section); +#pragma warning disable IL3050, IL2026 configuration = configurationSection.Get(); +#pragma warning restore IL3050, IL2026 } + PreVerify(configurationRoot, configuration); result = Get(configuration); - if (configuration is null) throw new NullReferenceException(nameof(configuration)); return result; } diff --git a/Delete-By-Distinct/Models/Binder/AppSettings.cs b/Delete-By-Distinct/Models/Binder/AppSettings.cs index 1fade2a..1618fa1 100644 --- a/Delete-By-Distinct/Models/Binder/AppSettings.cs +++ b/Delete-By-Distinct/Models/Binder/AppSettings.cs @@ -27,6 +27,23 @@ public class AppSettings return result; } + private static void PreVerify(IConfigurationRoot configurationRoot, AppSettings? appSettings) + { + if (appSettings?.Company is null) + { + List paths = []; + foreach (IConfigurationProvider configurationProvider in configurationRoot.Providers) + { + if (configurationProvider is not Microsoft.Extensions.Configuration.Json.JsonConfigurationProvider jsonConfigurationProvider) + continue; + if (jsonConfigurationProvider.Source.FileProvider is not Microsoft.Extensions.FileProviders.PhysicalFileProvider physicalFileProvider) + continue; + paths.Add(physicalFileProvider.Root); + } + throw new NotSupportedException($"Not found!{Environment.NewLine}{string.Join(Environment.NewLine, paths.Distinct())}"); + } + } + private static Models.AppSettings Get(AppSettings? appSettings) { Models.AppSettings result; @@ -58,7 +75,10 @@ public class AppSettings public static Models.AppSettings Get(IConfigurationRoot configurationRoot) { Models.AppSettings result; +#pragma warning disable IL3050, IL2026 AppSettings? appSettings = configurationRoot.Get(); +#pragma warning restore IL3050, IL2026 + PreVerify(configurationRoot, appSettings); result = Get(appSettings); return result; } diff --git a/Delete-By-Relative/Models/Binder/AppSettings.cs b/Delete-By-Relative/Models/Binder/AppSettings.cs index b6c3b82..406b601 100644 --- a/Delete-By-Relative/Models/Binder/AppSettings.cs +++ b/Delete-By-Relative/Models/Binder/AppSettings.cs @@ -22,6 +22,23 @@ public class AppSettings return result; } + private static void PreVerify(IConfigurationRoot configurationRoot, AppSettings? appSettings) + { + if (appSettings?.Company is null) + { + List paths = []; + foreach (IConfigurationProvider configurationProvider in configurationRoot.Providers) + { + if (configurationProvider is not Microsoft.Extensions.Configuration.Json.JsonConfigurationProvider jsonConfigurationProvider) + continue; + if (jsonConfigurationProvider.Source.FileProvider is not Microsoft.Extensions.FileProviders.PhysicalFileProvider physicalFileProvider) + continue; + paths.Add(physicalFileProvider.Root); + } + throw new NotSupportedException($"Not found!{Environment.NewLine}{string.Join(Environment.NewLine, paths.Distinct())}"); + } + } + private static Models.AppSettings Get(AppSettings? appSettings) { Models.AppSettings result; @@ -40,7 +57,10 @@ public class AppSettings public static Models.AppSettings Get(IConfigurationRoot configurationRoot) { Models.AppSettings result; +#pragma warning disable IL3050, IL2026 AppSettings? appSettings = configurationRoot.Get(); +#pragma warning restore IL3050, IL2026 + PreVerify(configurationRoot, appSettings); result = Get(appSettings); return result; } diff --git a/Distance/Models/DistanceLimits.cs b/Distance/Models/DistanceLimits.cs index 1632175..0c858e4 100644 --- a/Distance/Models/DistanceLimits.cs +++ b/Distance/Models/DistanceLimits.cs @@ -14,6 +14,7 @@ public class DistanceLimits : IDistanceLimits public double FaceDistancePermyriad { init; get; } public int SortingMaximumPerFaceShouldBeHigh { init; get; } public bool RangeDaysDeltaTargetLessThenUpper { init; get; } + public double RangeDistanceToleranceUpperLimit { init; get; } public DistanceLimits(int faceAreaPermyriad, int faceConfidencePercent, @@ -25,6 +26,7 @@ public class DistanceLimits : IDistanceLimits int sortingMaximumPerFaceShouldBeHigh, int? useFiltersCounter = null) { + RangeDistanceToleranceUpperLimit = rangeDistanceTolerance[2]; SortingMaximumPerFaceShouldBeHigh = sortingMaximumPerFaceShouldBeHigh; RangeDaysDeltaTargetLessThenUpper = rangeDaysDeltaTolerance[1] > rangeDaysDeltaTolerance[2]; if (useFiltersCounter is null) diff --git a/Distance/Models/_E_Distance.cs b/Distance/Models/_E_Distance.cs index e830ec8..19e8207 100644 --- a/Distance/Models/_E_Distance.cs +++ b/Distance/Models/_E_Distance.cs @@ -50,6 +50,7 @@ public partial class E_Distance : IDistance private FaceDistanceContainer[] GetFaceDistanceContainers(MappingFromItem mappingFromItem, List intersectFaces) { FaceDistanceContainer[] results; + DateTime dateTime; int wholePercentages; int confidencePercent; FaceDistance faceDistance; @@ -61,14 +62,15 @@ public partial class E_Distance : IDistance throw new NotSupportedException(); if (face.Mapping?.MappingFromFilterPost is null) throw new NotSupportedException(); + dateTime = mappingFromItem.GetDateTimeOriginalThenMinimumDateTime(); confidencePercent = Shared.Models.Stateless.Methods.ILocation.GetConfidencePercent(_FaceConfidencePercent, face.Location.Confidence); wholePercentages = Shared.Models.Stateless.Methods.ILocation.GetWholePercentages(face.Location, Shared.Models.Stateless.ILocation.Digits, face.OutputResolution); if (face.FaceDistance?.Encoding is not null && face.FaceDistance.Encoding is FaceRecognitionDotNet.FaceEncoding faceEncoding) - faceDistance = new(confidencePercent, mappingFromItem.GetDateTimeOriginalThenMinimumDateTime(), faceEncoding, face.Mapping?.MappingFromFilterPost, mappingFromItem.Id, mappingFromItem.IsWrongYear, wholePercentages); + faceDistance = new(confidencePercent, dateTime, faceEncoding, face.Mapping?.MappingFromFilterPost, mappingFromItem.Id, mappingFromItem.IsWrongYear, wholePercentages); else { faceEncoding = FaceRecognition.LoadFaceEncoding(face.FaceEncoding.RawEncoding); - faceDistance = new(confidencePercent, mappingFromItem.GetDateTimeOriginalThenMinimumDateTime(), faceEncoding, face.Mapping?.MappingFromFilterPost, mappingFromItem.Id, mappingFromItem.IsWrongYear, wholePercentages); + faceDistance = new(confidencePercent, dateTime, faceEncoding, face.Mapping?.MappingFromFilterPost, mappingFromItem.Id, mappingFromItem.IsWrongYear, wholePercentages); lock (intersectFaces) face.SetFaceDistance(faceDistance); } @@ -91,7 +93,7 @@ public partial class E_Distance : IDistance return new(faceDistanceEncodings); } - private List<(Face Face, double? Length)> GetValues(MappingFromItem mappingFromItem, List intersectFaces, Shared.Models.FaceEncoding modelsFaceEncoding) + private List<(Face Face, double? Length)> GetValues(IDistanceLimits distanceLimits, MappingFromItem mappingFromItem, List intersectFaces, Shared.Models.FaceEncoding modelsFaceEncoding) { List<(Face Face, double? Length)> results = []; Face face; @@ -112,6 +114,8 @@ public partial class E_Distance : IDistance { face = intersectFaces[i]; faceDistanceLength = faceDistanceLengths[i]; + if (faceDistanceLength.Length is null || faceDistanceLength.Length > distanceLimits.RangeDistanceToleranceUpperLimit) + continue; if (faceDistanceLength.Length is null) throw new NotSupportedException(); results.Add(new(face, faceDistanceLength.Length.Value)); @@ -119,10 +123,10 @@ public partial class E_Distance : IDistance return results; } - private (Face, double?)[] GetClosestFaceByDistanceIgnoringTolerance(MappingFromItem mappingFromItem, List intersectFaces, Shared.Models.FaceEncoding modelsFaceEncoding) + private (Face, double?)[] GetClosestFaceByDistanceIgnoringTolerance(IDistanceLimits distanceLimits, MappingFromItem mappingFromItem, List intersectFaces, Shared.Models.FaceEncoding modelsFaceEncoding) { (Face, double?)[] results; - List<(Face Face, double? Length)> collection = GetValues(mappingFromItem, intersectFaces, modelsFaceEncoding); + List<(Face Face, double? Length)> collection = GetValues(distanceLimits, mappingFromItem, intersectFaces, modelsFaceEncoding); results = (from l in collection where l.Length < _RangeDistanceToleranceAverage orderby l.Length select l).Take(1).ToArray(); if (results.Length > 0) { @@ -201,7 +205,7 @@ public partial class E_Distance : IDistance } } - public void LookForMatchFacesAndPossiblyRename(string facesFileNameExtension, FilePath filePath, MappingFromItem mappingFromItem, List faces, ReadOnlyCollection locationContainers) + public void LookForMatchFacesAndPossiblyRename(IDistanceLimits distanceLimits, string facesFileNameExtension, FilePath filePath, MappingFromItem mappingFromItem, List faces, ReadOnlyCollection locationContainers) { string? json; string[] matches; @@ -246,7 +250,7 @@ public partial class E_Distance : IDistance { intersectFaces = Shared.Models.Stateless.Methods.ILocation.FilterByIntersect(filteredFaces, _RectangleIntersectMinimum, locationContainer.WholePercentages); if (intersectFaces.Count > 0) - checkFaces.AddRange(GetClosestFaceByDistanceIgnoringTolerance(mappingFromItem, intersectFaces, modelsFaceEncoding)); + checkFaces.AddRange(GetClosestFaceByDistanceIgnoringTolerance(distanceLimits, mappingFromItem, intersectFaces, modelsFaceEncoding)); } } if (checkFaces.Count == 0) @@ -322,10 +326,10 @@ public partial class E_Distance : IDistance File.WriteAllLines(eDistanceContentFileName, results); } - public static void PreFilterSetFaceDistances(int maxDegreeOfParallelism, long ticks, ReadOnlyCollection distinctFilteredFaces) + public static void PreFilterSetFaceDistances(int maxDegreeOfParallelism, Map.Models.Configuration configuration, long ticks, ReadOnlyCollection distinctValidImageFaces) { List faces = []; - foreach (Face face in distinctFilteredFaces) + foreach (Face face in distinctValidImageFaces) { if (face.Mapping?.MappingFromFilterPre is null) throw new NotSupportedException(); @@ -335,8 +339,10 @@ public partial class E_Distance : IDistance continue; if (face.Mapping.MappingFromFilterPre.IsFocusRelativePath is not null && !face.Mapping.MappingFromFilterPre.IsFocusRelativePath.Value) continue; - if (face.FaceEncoding is not null && face.FaceDistance?.Encoding is not null && face.FaceDistance.Encoding is FaceRecognitionDotNet.FaceEncoding _) + if (!configuration.ReMap && face.Mapping.MappingFromPerson is not null) continue; + if (!configuration.ReMap && face.FaceEncoding is not null && face.FaceDistance?.Encoding is not null && face.FaceDistance.Encoding is FaceRecognitionDotNet.FaceEncoding _) + throw new NotSupportedException($"{face.Mapping.MappingFromPerson} should not be null!"); faces.Add(face); } int totalSeconds = (int)Math.Floor(new TimeSpan(DateTime.Now.Ticks - ticks).TotalSeconds); @@ -352,7 +358,8 @@ public partial class E_Distance : IDistance throw new NotSupportedException(); progressBar.Tick(); faceEncoding = FaceRecognition.LoadFaceEncoding(face.FaceEncoding.RawEncoding); - FaceDistance faceDistance = new(face.Mapping.MappingFromLocation.ConfidencePercent, face.Mapping.MappingFromItem.GetDateTimeOriginalThenMinimumDateTime(), faceEncoding, face.Mapping.MappingFromFilterPost, face.Mapping.MappingFromItem.Id, face.Mapping.MappingFromItem.IsWrongYear, face.Mapping.MappingFromLocation.WholePercentages); + DateTime dateTime = face.Mapping.MappingFromItem.GetDateTimeOriginalThenMinimumDateTime(); + FaceDistance faceDistance = new(face.Mapping.MappingFromLocation.ConfidencePercent, dateTime, faceEncoding, face.Mapping.MappingFromFilterPost, face.Mapping.MappingFromItem.Id, face.Mapping.MappingFromItem.IsWrongYear, face.Mapping.MappingFromLocation.WholePercentages); lock (face) face.SetFaceDistance(faceDistance); }); @@ -361,8 +368,8 @@ public partial class E_Distance : IDistance private static List GetSortingContainers(Map.Models.Configuration mapConfiguration, IDistanceLimits distanceLimits, Face face, FaceDistance faceDistanceEncoding, List sortingCollection) { List results = []; - SortingContainer sortingContainer; int days = 0, distance = 0; + SortingContainer sortingContainer; Sorting[] collection = Shared.Models.Stateless.Methods.ISorting.Sort(sortingCollection); foreach (Sorting sorting in collection) { @@ -389,27 +396,29 @@ public partial class E_Distance : IDistance return results; } - private static List GetSortingCollection(Map.Models.MapLogic mapLogic, ReadOnlyCollection faceDistanceEncodings, int i, Face face, FaceDistance faceDistanceEncoding) + private static List GetSortingCollection(Map.Models.MapLogic mapLogic, IDistanceLimits distanceLimits, ReadOnlyCollection faceDistanceEncodings, int i, Face face, FaceDistance faceDistanceEncoding) { List results; List faceDistanceLengths = FaceRecognition.FaceDistances(faceDistanceEncodings, faceDistanceEncoding); - results = mapLogic.GetSortingCollection(i, face, faceDistanceEncoding, faceDistanceLengths); + results = mapLogic.GetSortingCollection(distanceLimits, i, face, faceDistanceEncoding, faceDistanceLengths); return results; } - public static ReadOnlyCollection GetFaceDistanceContainers(ReadOnlyCollection distinctFilteredFaces) + public static ReadOnlyCollection GetFaceDistanceContainers(ReadOnlyCollection distinctValidImageFaces) { ReadOnlyCollection results; + DateTime dateTime; FaceDistance faceDistance; FaceDistanceContainer faceDistanceContainer; List collection = []; - foreach (Face face in distinctFilteredFaces) + foreach (Face face in distinctValidImageFaces) { if (face.Mapping?.MappingFromLocation is null) throw new NotSupportedException(); if (face.FaceDistance?.Encoding is not FaceRecognitionDotNet.FaceEncoding faceEncoding) continue; - faceDistance = new(face.Mapping.MappingFromLocation.ConfidencePercent, face.Mapping.MappingFromItem.GetDateTimeOriginalThenMinimumDateTime(), faceEncoding, face.Mapping.MappingFromFilterPost, face.Mapping.MappingFromItem.Id, face.Mapping.MappingFromItem.IsWrongYear, face.Mapping.MappingFromLocation.WholePercentages); + dateTime = face.Mapping.MappingFromItem.GetDateTimeOriginalThenMinimumDateTime(); + faceDistance = new(face.Mapping.MappingFromLocation.ConfidencePercent, dateTime, faceEncoding, face.Mapping.MappingFromFilterPost, face.Mapping.MappingFromItem.Id, face.Mapping.MappingFromItem.IsWrongYear, face.Mapping.MappingFromLocation.WholePercentages); faceDistanceContainer = new(face, faceDistance); collection.Add(faceDistanceContainer); } @@ -459,7 +468,7 @@ public partial class E_Distance : IDistance progressBar.Tick(); Face face = filteredFaceDistanceContainers[i].Face; FaceDistance faceDistanceEncoding = filteredFaceDistanceContainers[i].FaceDistance; - List sortingCollection = GetSortingCollection(mapLogic, faceDistanceEncodings, i, face, faceDistanceEncoding); + List sortingCollection = GetSortingCollection(mapLogic, distanceLimits, faceDistanceEncodings, i, face, faceDistanceEncoding); if (sortingCollection.Count == 0) return; List sortingContainers = GetSortingContainers(mapConfiguration, distanceLimits, face, faceDistanceEncoding, sortingCollection); @@ -476,7 +485,7 @@ public partial class E_Distance : IDistance return new(results); } - private static ReadOnlyCollection GetRelationCollections(int faceDistancePermyriad, int locationContainerDistanceTake, float distanceTolerance, List records) + private static ReadOnlyCollection GetRelationCollections(IDistanceLimits distanceLimits, int faceDistancePermyriad, int locationContainerDistanceTake, float distanceTolerance, List records) { List results = []; string fileName; @@ -496,6 +505,7 @@ public partial class E_Distance : IDistance foreach (Record record in records) { mappedRelations = []; + FaceDistance faceDistanceLength; fileHolder = Shared.Models.Stateless.Methods.IFileHolder.Get(record.FilePath.FullName); if (files.Count > 1) { @@ -508,10 +518,12 @@ public partial class E_Distance : IDistance fileName = Path.GetFileName(files[i]); if (fileName == fileHolder.Name) continue; - FaceDistance faceDistance = faceDistanceLengths[i]; - if (faceDistance.Length is null || faceDistance.Length.Value > distanceTolerance) + faceDistanceLength = faceDistanceLengths[i]; + if (faceDistanceLength.Length is null || faceDistanceLength.Length > distanceLimits.RangeDistanceToleranceUpperLimit) continue; - distancePermyriad = (int)(faceDistance.Length.Value * faceDistancePermyriad); + if (faceDistanceLength.Length is null || faceDistanceLength.Length.Value > distanceTolerance) + continue; + distancePermyriad = (int)(faceDistanceLength.Length.Value * faceDistancePermyriad); mappedRelations.Add(new(distancePermyriad, files[i])); } } @@ -521,7 +533,7 @@ public partial class E_Distance : IDistance return new(results); } - ReadOnlyCollection IDistance.GetRelationContainers(int faceDistancePermyriad, int locationContainerDistanceTake, float locationContainerDistanceTolerance, ReadOnlyCollection locationContainers) + ReadOnlyCollection IDistance.GetRelationContainers(IDistanceLimits distanceLimits, int faceDistancePermyriad, int locationContainerDistanceTake, float locationContainerDistanceTolerance, ReadOnlyCollection locationContainers) { ReadOnlyCollection result; string? json; @@ -539,7 +551,7 @@ public partial class E_Distance : IDistance faceRecognitionDotNetFaceEncoding = FaceRecognition.LoadFaceEncoding(modelsFaceEncoding.RawEncoding); records.Add(new(locationContainer.FilePath, faceRecognitionDotNetFaceEncoding)); } - result = GetRelationCollections(faceDistancePermyriad, locationContainerDistanceTake, locationContainerDistanceTolerance, records); + result = GetRelationCollections(distanceLimits, faceDistancePermyriad, locationContainerDistanceTake, locationContainerDistanceTolerance, records); return result; } diff --git a/Drag-Drop-Explorer/Models/Binder/AppSettings.cs b/Drag-Drop-Explorer/Models/Binder/AppSettings.cs index 3f35cb0..e32ad9d 100644 --- a/Drag-Drop-Explorer/Models/Binder/AppSettings.cs +++ b/Drag-Drop-Explorer/Models/Binder/AppSettings.cs @@ -20,6 +20,23 @@ public class AppSettings return result; } + private static void PreVerify(IConfigurationRoot configurationRoot, AppSettings? appSettings) + { + if (appSettings?.Company is null) + { + List paths = []; + foreach (IConfigurationProvider configurationProvider in configurationRoot.Providers) + { + if (configurationProvider is not Microsoft.Extensions.Configuration.Json.JsonConfigurationProvider jsonConfigurationProvider) + continue; + if (jsonConfigurationProvider.Source.FileProvider is not Microsoft.Extensions.FileProviders.PhysicalFileProvider physicalFileProvider) + continue; + paths.Add(physicalFileProvider.Root); + } + throw new NotSupportedException($"Not found!{Environment.NewLine}{string.Join(Environment.NewLine, paths.Distinct())}"); + } + } + private static Models.AppSettings Get(AppSettings? appSettings) { Models.AppSettings result; @@ -36,7 +53,10 @@ public class AppSettings public static Models.AppSettings Get(IConfigurationRoot configurationRoot) { Models.AppSettings result; +#pragma warning disable IL3050, IL2026 AppSettings? appSettings = configurationRoot.Get(); +#pragma warning restore IL3050, IL2026 + PreVerify(configurationRoot, appSettings); result = Get(appSettings); return result; } diff --git a/Drag-Drop-Move/Models/Binder/AppSettings.cs b/Drag-Drop-Move/Models/Binder/AppSettings.cs index ff613f6..108f26c 100644 --- a/Drag-Drop-Move/Models/Binder/AppSettings.cs +++ b/Drag-Drop-Move/Models/Binder/AppSettings.cs @@ -16,6 +16,23 @@ public class AppSettings return result; } + private static void PreVerify(IConfigurationRoot configurationRoot, AppSettings? appSettings) + { + if (appSettings?.Company is null) + { + List paths = []; + foreach (IConfigurationProvider configurationProvider in configurationRoot.Providers) + { + if (configurationProvider is not Microsoft.Extensions.Configuration.Json.JsonConfigurationProvider jsonConfigurationProvider) + continue; + if (jsonConfigurationProvider.Source.FileProvider is not Microsoft.Extensions.FileProviders.PhysicalFileProvider physicalFileProvider) + continue; + paths.Add(physicalFileProvider.Root); + } + throw new NotSupportedException($"Not found!{Environment.NewLine}{string.Join(Environment.NewLine, paths.Distinct())}"); + } + } + private static Models.AppSettings Get(AppSettings? appSettings) { Models.AppSettings result; @@ -36,7 +53,10 @@ public class AppSettings public static Models.AppSettings Get(IConfigurationRoot configurationRoot) { Models.AppSettings result; +#pragma warning disable IL3050, IL2026 AppSettings? appSettings = configurationRoot.Get(); +#pragma warning restore IL3050, IL2026 + PreVerify(configurationRoot, appSettings); result = Get(appSettings); return result; } diff --git a/Drag-Drop-Search/Models/Binder/AppSettings.cs b/Drag-Drop-Search/Models/Binder/AppSettings.cs index 853d9c3..5b759b8 100644 --- a/Drag-Drop-Search/Models/Binder/AppSettings.cs +++ b/Drag-Drop-Search/Models/Binder/AppSettings.cs @@ -20,6 +20,23 @@ public class AppSettings return result; } + private static void PreVerify(IConfigurationRoot configurationRoot, AppSettings? appSettings) + { + if (appSettings?.Company is null) + { + List paths = []; + foreach (IConfigurationProvider configurationProvider in configurationRoot.Providers) + { + if (configurationProvider is not Microsoft.Extensions.Configuration.Json.JsonConfigurationProvider jsonConfigurationProvider) + continue; + if (jsonConfigurationProvider.Source.FileProvider is not Microsoft.Extensions.FileProviders.PhysicalFileProvider physicalFileProvider) + continue; + paths.Add(physicalFileProvider.Root); + } + throw new NotSupportedException($"Not found!{Environment.NewLine}{string.Join(Environment.NewLine, paths.Distinct())}"); + } + } + private static Models.AppSettings Get(AppSettings? appSettings) { Models.AppSettings result; @@ -36,7 +53,10 @@ public class AppSettings public static Models.AppSettings Get(IConfigurationRoot configurationRoot) { Models.AppSettings result; +#pragma warning disable IL3050, IL2026 AppSettings? appSettings = configurationRoot.Get(); +#pragma warning restore IL3050, IL2026 + PreVerify(configurationRoot, appSettings); result = Get(appSettings); return result; } diff --git a/Drag-Drop-Search/Models/Binder/Configuration.cs b/Drag-Drop-Search/Models/Binder/Configuration.cs index 2a33d67..d2584f1 100644 --- a/Drag-Drop-Search/Models/Binder/Configuration.cs +++ b/Drag-Drop-Search/Models/Binder/Configuration.cs @@ -7,8 +7,6 @@ namespace View_by_Distance.Drag_Drop.Models.Binder; public class Configuration { -#nullable disable - public bool? CheckDFaceAndUpWriteDates { get; set; } public bool? CheckJsonForDistanceResults { get; set; } public int? CrossDirectoryMaxItemsInDistanceCollection { get; set; } @@ -16,40 +14,38 @@ public class Configuration public bool? ForceFaceLastWriteTimeToCreationTime { get; set; } public bool? ForceMetadataLastWriteTimeToCreationTime { get; set; } public bool? ForceResizeLastWriteTimeToCreationTime { get; set; } - public string[] IgnoreExtensions { get; set; } - public string[] JLinks { get; set; } - public string[] LoadOrCreateThenSaveDistanceResultsForOutputResolutions { get; set; } - public string[] LoadOrCreateThenSaveImageFacesResultsForOutputResolutions { get; set; } - public string[] MixedYearRelativePaths { get; set; } - public string ModelDirectory { get; set; } - public string ModelName { get; set; } + public string[]? IgnoreExtensions { get; set; } + public string[]? JLinks { get; set; } + public string[]? LoadOrCreateThenSaveDistanceResultsForOutputResolutions { get; set; } + public string[]? LoadOrCreateThenSaveImageFacesResultsForOutputResolutions { get; set; } + public string[]? MixedYearRelativePaths { get; set; } + public string? ModelDirectory { get; set; } + public string? ModelName { get; set; } public int? NumberOfJitters { get; set; } public int? NumberOfTimesToUpsample { get; set; } - public string OutputExtension { get; set; } + public string? OutputExtension { get; set; } public int? OutputQuality { get; set; } - public string[] OutputResolutions { get; set; } + public string[]? OutputResolutions { get; set; } public bool? OverrideForFaceImages { get; set; } public bool? OverrideForFaceLandmarkImages { get; set; } public bool? OverrideForResizeImages { get; set; } - public string PersonBirthdayFormat { get; set; } - public string PredictorModelName { get; set; } + public string? PersonBirthdayFormat { get; set; } + public string? PredictorModelName { get; set; } public bool? PropertiesChangedForDistance { get; set; } public bool? PropertiesChangedForFaces { get; set; } public bool? PropertiesChangedForIndex { get; set; } public bool? PropertiesChangedForMetadata { get; set; } public bool? PropertiesChangedForResize { get; set; } - public Property.Models.Configuration PropertyConfiguration { get; set; } + public Property.Models.Configuration? PropertyConfiguration { get; set; } public bool? Reverse { get; set; } - public string[] SaveFaceLandmarkForOutputResolutions { get; set; } + public string[]? SaveFaceLandmarkForOutputResolutions { get; set; } public bool? SaveFullYearOfRandomFiles { get; set; } - public string[] SaveFilteredOriginalImagesFromJLinksForOutputResolutions { get; set; } - public string[] SaveShortcutsForOutputResolutions { get; set; } + public string[]? SaveFilteredOriginalImagesFromJLinksForOutputResolutions { get; set; } + public string[]? SaveShortcutsForOutputResolutions { get; set; } public bool? SaveResizedSubfiles { get; set; } public bool? SkipSearch { get; set; } public bool? TestDistanceResults { get; set; } - public string[] ValidResolutions { get; set; } - -#nullable restore + public string[]? ValidResolutions { get; set; } public override string ToString() { @@ -57,10 +53,28 @@ public class Configuration return result; } + private static void PreVerify(IConfigurationRoot configurationRoot, Configuration? configuration) + { + if (configuration?.CheckDFaceAndUpWriteDates is null) + { + List paths = []; + foreach (IConfigurationProvider configurationProvider in configurationRoot.Providers) + { + if (configurationProvider is not Microsoft.Extensions.Configuration.Json.JsonConfigurationProvider jsonConfigurationProvider) + continue; + if (jsonConfigurationProvider.Source.FileProvider is not Microsoft.Extensions.FileProviders.PhysicalFileProvider physicalFileProvider) + continue; + paths.Add(physicalFileProvider.Root); + } + throw new NotSupportedException($"Not found!{Environment.NewLine}{string.Join(Environment.NewLine, paths.Distinct())}"); + } + } + private static Models.Configuration Get(Configuration? configuration) { Models.Configuration result; if (configuration is null) throw new NullReferenceException(nameof(configuration)); + if (configuration.PropertyConfiguration is null) throw new NullReferenceException(nameof(configuration.PropertyConfiguration)); if (configuration.CheckDFaceAndUpWriteDates is null) throw new NullReferenceException(nameof(configuration.CheckDFaceAndUpWriteDates)); if (configuration.CheckJsonForDistanceResults is null) throw new NullReferenceException(nameof(configuration.CheckJsonForDistanceResults)); if (configuration.CrossDirectoryMaxItemsInDistanceCollection is null) throw new NullReferenceException(nameof(configuration.CrossDirectoryMaxItemsInDistanceCollection)); @@ -68,18 +82,23 @@ public class Configuration if (configuration.ForceFaceLastWriteTimeToCreationTime is null) throw new NullReferenceException(nameof(configuration.ForceFaceLastWriteTimeToCreationTime)); if (configuration.ForceMetadataLastWriteTimeToCreationTime is null) throw new NullReferenceException(nameof(configuration.ForceMetadataLastWriteTimeToCreationTime)); if (configuration.ForceResizeLastWriteTimeToCreationTime is null) throw new NullReferenceException(nameof(configuration.ForceResizeLastWriteTimeToCreationTime)); + if (configuration.JLinks is null) throw new NullReferenceException(nameof(configuration.JLinks)); if (configuration.IgnoreExtensions is null) throw new NullReferenceException(nameof(configuration.IgnoreExtensions)); configuration.LoadOrCreateThenSaveDistanceResultsForOutputResolutions ??= []; configuration.LoadOrCreateThenSaveImageFacesResultsForOutputResolutions ??= []; if (configuration.MixedYearRelativePaths is null) throw new NullReferenceException(nameof(configuration.MixedYearRelativePaths)); + if (configuration.ModelDirectory is null) throw new NullReferenceException(nameof(configuration.ModelDirectory)); + if (configuration.ModelName is null) throw new NullReferenceException(nameof(configuration.ModelName)); if (configuration.NumberOfJitters is null) throw new NullReferenceException(nameof(configuration.NumberOfJitters)); if (configuration.NumberOfTimesToUpsample is null) throw new NullReferenceException(nameof(configuration.NumberOfTimesToUpsample)); + if (configuration.OutputExtension is null) throw new NullReferenceException(nameof(configuration.OutputExtension)); if (configuration.OutputQuality is null) throw new NullReferenceException(nameof(configuration.OutputQuality)); if (configuration.OutputResolutions is null) throw new NullReferenceException(nameof(configuration.OutputResolutions)); if (configuration.OverrideForFaceImages is null) throw new NullReferenceException(nameof(configuration.OverrideForFaceImages)); if (configuration.OverrideForFaceLandmarkImages is null) 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.PredictorModelName is null) throw new NullReferenceException(nameof(configuration.PredictorModelName)); if (configuration.PropertiesChangedForDistance is null) throw new NullReferenceException(nameof(configuration.PropertiesChangedForDistance)); if (configuration.PropertiesChangedForFaces is null) throw new NullReferenceException(nameof(configuration.PropertiesChangedForFaces)); if (configuration.PropertiesChangedForIndex is null) throw new NullReferenceException(nameof(configuration.PropertiesChangedForIndex)); @@ -141,14 +160,19 @@ public class Configuration Models.Configuration result; Configuration? configuration; if (isEnvironment is null) +#pragma warning disable IL3050, IL2026 configuration = configurationRoot.Get(); +#pragma warning restore IL3050, IL2026 else { string environmentName = IsEnvironment.GetEnvironmentName(isEnvironment); string section = string.Concat(environmentName, ":", nameof(Configuration)); IConfigurationSection configurationSection = configurationRoot.GetSection(section); +#pragma warning disable IL3050, IL2026 configuration = configurationSection.Get(); +#pragma warning restore IL3050, IL2026 } + PreVerify(configurationRoot, configuration); result = Get(configuration); return result; } diff --git a/Drag-Drop-Set-Property-Item/Models/Binder/AppSettings.cs b/Drag-Drop-Set-Property-Item/Models/Binder/AppSettings.cs index 1ba9c25..f9a9f91 100644 --- a/Drag-Drop-Set-Property-Item/Models/Binder/AppSettings.cs +++ b/Drag-Drop-Set-Property-Item/Models/Binder/AppSettings.cs @@ -17,6 +17,23 @@ public class AppSettings return result; } + private static void PreVerify(IConfigurationRoot configurationRoot, AppSettings? appSettings) + { + if (appSettings?.Company is null) + { + List paths = []; + foreach (IConfigurationProvider configurationProvider in configurationRoot.Providers) + { + if (configurationProvider is not Microsoft.Extensions.Configuration.Json.JsonConfigurationProvider jsonConfigurationProvider) + continue; + if (jsonConfigurationProvider.Source.FileProvider is not Microsoft.Extensions.FileProviders.PhysicalFileProvider physicalFileProvider) + continue; + paths.Add(physicalFileProvider.Root); + } + throw new NotSupportedException($"Not found!{Environment.NewLine}{string.Join(Environment.NewLine, paths.Distinct())}"); + } + } + private static Models.AppSettings Get(AppSettings? appSettings) { Models.AppSettings result; @@ -36,7 +53,10 @@ public class AppSettings public static Models.AppSettings Get(IConfigurationRoot configurationRoot) { Models.AppSettings result; +#pragma warning disable IL3050, IL2026 AppSettings? appSettings = configurationRoot.Get(); +#pragma warning restore IL3050, IL2026 + PreVerify(configurationRoot, appSettings); result = Get(appSettings); return result; } diff --git a/Duplicate-Search/DuplicateSearch.cs b/Duplicate-Search/DuplicateSearch.cs index 0bdd6b2..6272518 100644 --- a/Duplicate-Search/DuplicateSearch.cs +++ b/Duplicate-Search/DuplicateSearch.cs @@ -2,6 +2,7 @@ using Microsoft.Extensions.Logging; using Phares.Shared; using ShellProgressBar; +using System.Collections.ObjectModel; using System.Text; using System.Text.Json; using View_by_Distance.Duplicate.Search.Models; @@ -145,11 +146,11 @@ public class DuplicateSearch Dictionary> results = []; string directory; const int zero = 0; - Item[] filteredItems; FileHolder resizedFileHolder; DateTime[] containerDateTimes; MappingFromItem? mappingFromItem; List? collection; + ReadOnlyCollection validImageItems; const string duplicates = "-Duplicate(s)"; if (containers.Length != 0) { @@ -162,11 +163,11 @@ public class DuplicateSearch continue; if (!argZeroIsConfigurationRootDirectory && !container.SourceDirectory.StartsWith(argZero)) continue; - filteredItems = Shared.Models.Stateless.Methods.IContainer.GetFilterItems(configuration, container); - if (filteredItems.Length == 0) + validImageItems = Shared.Models.Stateless.Methods.IContainer.GetValidImageItems(configuration, container); + if (validImageItems.Count == 0) continue; - containerDateTimes = Shared.Models.Stateless.Methods.IContainer.GetContainerDateTimes(filteredItems); - foreach (Item item in filteredItems) + containerDateTimes = Shared.Models.Stateless.Methods.IContainer.GetContainerDateTimes(validImageItems); + foreach (Item item in validImageItems) { if (item.Property?.Id is null) { diff --git a/Duplicate-Search/Models/Binder/AppSettings.cs b/Duplicate-Search/Models/Binder/AppSettings.cs index 8dcdd62..534481a 100644 --- a/Duplicate-Search/Models/Binder/AppSettings.cs +++ b/Duplicate-Search/Models/Binder/AppSettings.cs @@ -23,6 +23,23 @@ public class AppSettings return result; } + private static void PreVerify(IConfigurationRoot configurationRoot, AppSettings? appSettings) + { + if (appSettings?.Company is null) + { + List paths = []; + foreach (IConfigurationProvider configurationProvider in configurationRoot.Providers) + { + if (configurationProvider is not Microsoft.Extensions.Configuration.Json.JsonConfigurationProvider jsonConfigurationProvider) + continue; + if (jsonConfigurationProvider.Source.FileProvider is not Microsoft.Extensions.FileProviders.PhysicalFileProvider physicalFileProvider) + continue; + paths.Add(physicalFileProvider.Root); + } + throw new NotSupportedException($"Not found!{Environment.NewLine}{string.Join(Environment.NewLine, paths.Distinct())}"); + } + } + private static Models.AppSettings Get(AppSettings? appSettings) { Models.AppSettings result; @@ -46,7 +63,10 @@ public class AppSettings public static Models.AppSettings Get(IConfigurationRoot configurationRoot) { Models.AppSettings result; +#pragma warning disable IL3050, IL2026 AppSettings? appSettings = configurationRoot.Get(); +#pragma warning restore IL3050, IL2026 + PreVerify(configurationRoot, appSettings); result = Get(appSettings); return result; } diff --git a/Face/Models/_D_Face.cs b/Face/Models/_D_Face.cs index 33e4970..64ff2af 100644 --- a/Face/Models/_D_Face.cs +++ b/Face/Models/_D_Face.cs @@ -265,8 +265,8 @@ public class D_Face List results = []; string? json; Location? location; - Rectangle? rectangle; List skip = []; + Rectangle? rectangle; OutputResolution? outputResolutionCheck = null; (int outputResolutionWidth, int outputResolutionHeight, int outputResolutionOrientation) = Resize.Models.Stateless.Methods.IResize.Get(outputResolution, outputResolutionToResize); foreach (Shared.Models.Face face in faces) diff --git a/FaceParts/Models/_D2_FaceParts.cs b/FaceParts/Models/_D2_FaceParts.cs index 0fbba9f..99710f0 100644 --- a/FaceParts/Models/_D2_FaceParts.cs +++ b/FaceParts/Models/_D2_FaceParts.cs @@ -57,10 +57,10 @@ public class D2_FaceParts _FileGroups.Add(keyValuePair.Key, keyValuePair.Value); } - public void SetAngleBracketCollection(Configuration configuration, string d2ResultsFullGroupDirectory, string sourceDirectory) + public void SetAngleBracketCollection(IPropertyConfiguration propertyConfiguration, string d2ResultsFullGroupDirectory, string sourceDirectory) { _AngleBracketCollection.Clear(); - _AngleBracketCollection.AddRange(IResult.GetDirectoryInfoCollection(configuration, + _AngleBracketCollection.AddRange(IResult.GetDirectoryInfoCollection(propertyConfiguration, sourceDirectory, d2ResultsFullGroupDirectory, contentDescription: "n gif file(s) for each face found", @@ -69,7 +69,7 @@ public class D2_FaceParts converted: true)); } - public string GetFacePartsDirectory(Configuration configuration, string dResultsFullGroupDirectory, Item item, bool includeNameWithoutExtension) + public string GetFacePartsDirectory(IPropertyConfiguration propertyConfiguration, string dResultsFullGroupDirectory, Item item, bool includeNameWithoutExtension) { string result; bool angleBracketCollectionAny = _AngleBracketCollection.Count != 0; @@ -77,7 +77,7 @@ public class D2_FaceParts { if (item.FilePath.DirectoryName is null) throw new NullReferenceException(nameof(item.FilePath.DirectoryName)); - SetAngleBracketCollection(configuration, dResultsFullGroupDirectory, item.FilePath.DirectoryName); + SetAngleBracketCollection(propertyConfiguration, dResultsFullGroupDirectory, item.FilePath.DirectoryName); } if (includeNameWithoutExtension) result = Path.Combine(_AngleBracketCollection[0].Replace("<>", _PropertyConfiguration.ResultContent), item.FilePath.NameWithoutExtension); diff --git a/Instance/DlibDotNet.cs b/Instance/DlibDotNet.cs index 84027e9..70f488d 100644 --- a/Instance/DlibDotNet.cs +++ b/Instance/DlibDotNet.cs @@ -39,6 +39,7 @@ public partial class DlibDotNet private readonly List _Exceptions; private readonly ILogger? _Logger; private readonly IsEnvironment _IsEnvironment; + private readonly DistanceLimits _DistanceLimits; private readonly bool _PropertyRootExistedBefore; private readonly Models.Configuration _Configuration; private readonly bool _ArgZeroIsConfigurationRootDirectory; @@ -111,7 +112,8 @@ public partial class DlibDotNet (ImageCodecInfo imageCodecInfo, EncoderParameters encoderParameters, string filenameExtension) = C_Resize.GetGifLowQuality(); _FaceParts = new D2_FaceParts(_Configuration.PropertyConfiguration, imageCodecInfo, encoderParameters, filenameExtension, configuration.CheckDFaceAndUpWriteDates, configuration.OverrideForFaceLandmarkImages); } - _MapConfiguration = Get(configuration, _Faces.FileNameExtension, _Faces.HiddenFileNameExtension, _FaceParts.FileNameExtension); + _DistanceLimits = new(_Configuration.FaceAreaPermyriad, _Configuration.FaceConfidencePercent, _Configuration.FaceDistancePermyriad, _Configuration.RangeDaysDeltaTolerance, _Configuration.RangeDistanceTolerance, _Configuration.RangeFaceAreaPermyriadTolerance, _Configuration.RangeFaceConfidence, _Configuration.SortingMaximumPerFaceShouldBeHigh); + _MapConfiguration = Get(configuration, _DistanceLimits, _Faces.FileNameExtension, _Faces.HiddenFileNameExtension, _FaceParts.FileNameExtension); _Distance = new(configuration.DistanceMoveUnableToMatch, configuration.DistanceRenameToMatch, configuration.FaceConfidencePercent, configuration.RangeDistanceTolerance, configuration.RectangleIntersectMinimums); if (_PropertyRootExistedBefore || !_ArgZeroIsConfigurationRootDirectory) personContainers = new(new List()); @@ -232,6 +234,12 @@ public partial class DlibDotNet throw new Exception("Configuration has to match interface!"); if (configuration.LocationFactor != Shared.Models.Stateless.ILocation.Factor) throw new Exception("Configuration has to match interface!"); + if (configuration.SaveSortingWithoutPerson && configuration.JLinks.Length > 0) + throw new Exception("Configuration has SaveSortingWithoutPerson and JLinks!"); + if (configuration.SaveSortingWithoutPerson && !string.IsNullOrEmpty(configuration.FocusModel)) + throw new Exception("Configuration has SaveSortingWithoutPerson and FocusModel!"); + if (configuration.SaveSortingWithoutPerson && !string.IsNullOrEmpty(configuration.FocusDirectory)) + throw new Exception("Configuration has SaveSortingWithoutPerson and FocusDirectory!"); } private ReadOnlyCollection GetNotNineCollection(ReadOnlyCollection filesCollection) @@ -255,6 +263,19 @@ public partial class DlibDotNet return new(results); } + private static void DeleteContinueFiles(Property.Models.Configuration propertyConfiguration, ReadOnlyCollection personContainers) + { + foreach (PersonContainer personContainer in personContainers) + { + foreach (FilePath filePath in personContainer.DisplayDirectoryAllFilePaths) + { + if (filePath.ExtensionLowered != ".continue") + continue; + File.Delete(filePath.FullName); + } + } + } + private void Search(long ticks, ReadOnlyCollection personContainers, string argZero, string propertyRoot) { int t; @@ -352,8 +373,9 @@ public partial class DlibDotNet ReadOnlyCollection readOnlyContainers = new(containers); SaveDistinctIds(_Configuration.PropertyConfiguration, bResultsFullGroupDirectory, readOnlyContainers); mapLogic ??= new(_AppSettings.MaxDegreeOfParallelism, _Configuration.PropertyConfiguration, _MapConfiguration, _Distance, personContainers, ticks, a2PeopleContentDirectory, a2PeopleSingletonDirectory, eDistanceContentDirectory); + DeleteContinueFiles(_Configuration.PropertyConfiguration, personContainers); FullDoWork(argZero, propertyRoot, ticks, aResultsFullGroupDirectory, bResultsFullGroupDirectory, fPhotoPrismSingletonDirectory, t, readOnlyContainers, propertyLogic, mapLogic); - ReadOnlyCollection distinctFilteredItems = Shared.Models.Stateless.Methods.IContainer.GetItems(_Configuration.PropertyConfiguration, readOnlyContainers, distinctItems: true, filterItems: true); + ReadOnlyCollection distinctValidImageItems = Shared.Models.Stateless.Methods.IContainer.GetValidImageItems(_Configuration.PropertyConfiguration, readOnlyContainers, distinctItems: true, filterItems: true); if (_Configuration.LookForAbandoned) { string dResultsFullGroupDirectory; @@ -365,13 +387,13 @@ public partial class DlibDotNet } } _Distance.Clear(); - ReadOnlyCollection distinctFilteredFaces = Map.Models.Stateless.Methods.IMapLogic.GetFaces(distinctFilteredItems); - ReadOnlyCollection distinctFilteredMappingCollection = GetMappings(_Configuration.PropertyConfiguration, eDistanceContentDirectory, readOnlyContainers, mapLogic, distinctItems: true); + ReadOnlyCollection distinctValidImageFaces = Map.Models.Stateless.Methods.IMapLogic.GetFaces(distinctValidImageItems); + ReadOnlyCollection distinctValidImageMappingCollection = GetMappings(_Configuration.PropertyConfiguration, eDistanceContentDirectory, readOnlyContainers, mapLogic, distinctItems: true); if (runToDoCollectionFirst) { if (!Directory.Exists(eDistanceContentDirectory)) _ = Directory.CreateDirectory(eDistanceContentDirectory); - string json = JsonSerializer.Serialize(distinctFilteredMappingCollection); + string json = JsonSerializer.Serialize(distinctValidImageMappingCollection); File.WriteAllText(Path.Combine(eDistanceContentDirectory, $"{ticks}.json"), json); } foreach (string outputResolution in _Configuration.OutputResolutions) @@ -380,19 +402,19 @@ public partial class DlibDotNet break; personKeyToIds = mapLogic.GetPersonKeyToIds(); if (_Configuration.SavePropertyShortcutsForOutputResolutions.Contains(outputResolution)) - SavePropertyShortcutsForOutputResolutions(eDistanceContentDirectory, distinctFilteredItems); + SavePropertyShortcutsForOutputResolutions(eDistanceContentDirectory, distinctValidImageItems); if (!string.IsNullOrEmpty(a2PeopleContentDirectory) && _Configuration.SaveShortcutsForOutputResolutions.Contains(outputResolution)) - mapLogic.SaveShortcutsForOutputResolutionsPreMapLogic(eDistanceContentDirectory, personKeyToIds, distinctFilteredMappingCollection); + mapLogic.SaveShortcutsForOutputResolutionsPreMapLogic(eDistanceContentDirectory, personKeyToIds, distinctValidImageMappingCollection); if (!string.IsNullOrEmpty(a2PeopleContentDirectory) && _Configuration.JLinks.Where(l => !string.IsNullOrEmpty(l)).Any() && _Configuration.SaveFilteredOriginalImagesFromJLinksForOutputResolutions.Contains(outputResolution)) - mapLogic.SaveFilteredOriginalImagesFromJLinks(_Configuration.JLinks, personContainers, a2PeopleContentDirectory, personKeyToIds, distinctFilteredMappingCollection); + mapLogic.SaveFilteredOriginalImagesFromJLinks(_Configuration.JLinks, personContainers, a2PeopleContentDirectory, personKeyToIds, distinctValidImageMappingCollection); if (_ArgZeroIsConfigurationRootDirectory && _Configuration.SaveResizedSubfiles && outputResolution == _Configuration.OutputResolutions[0] && _Configuration.LoadOrCreateThenSaveDistanceResultsForOutputResolutions.Contains(outputResolution) && _Exceptions.Count == 0) - MapLogic(ticks, readOnlyContainers, fPhotoPrismContentDirectory, mapLogic, outputResolution, new(personKeyToIds), distinctFilteredFaces, distinctFilteredMappingCollection); - if (runToDoCollectionFirst && _Configuration.SaveRandomForOutputResolutions.Contains(outputResolution) && personKeyToIds.Count > 0 && distinctFilteredMappingCollection.Count > 0) - _Random.Random(_Configuration.PropertyConfiguration, _Configuration.RadomUseBirthdayMinimum, _Configuration.ValidKeyWordsToIgnoreInRandom, personKeyToIds, notNineCollection, distinctFilteredMappingCollection); + MapLogic(ticks, readOnlyContainers, fPhotoPrismContentDirectory, mapLogic, outputResolution, new(personKeyToIds), distinctValidImageFaces, distinctValidImageMappingCollection); + if (runToDoCollectionFirst && _Configuration.SaveRandomForOutputResolutions.Contains(outputResolution) && personKeyToIds.Count > 0 && distinctValidImageMappingCollection.Count > 0) + _Random.Random(_Configuration.PropertyConfiguration, _Configuration.RadomUseBirthdayMinimum, _Configuration.ValidKeyWordsToIgnoreInRandom, personKeyToIds, notNineCollection, distinctValidImageMappingCollection); if (_IsEnvironment.Development) continue; if (!_IsEnvironment.Development) @@ -516,7 +538,6 @@ public partial class DlibDotNet bool exceptions; int totalSeconds; Container container; - Item[] filteredItems; int totalNotMapped = 0; bool outputResolutionHasNumber; bool anyNullOrNoIsUniqueFileName; @@ -524,6 +545,7 @@ public partial class DlibDotNet string dResultsFullGroupDirectory; string c2ResultsFullGroupDirectory; string d2ResultsFullGroupDirectory; + ReadOnlyCollection filteredItems; int containersLength = readOnlyContainers.Count; List> sourceDirectoryChanges = []; int maxDegreeOfParallelism = _AppSettings.MaxDegreeOfParallelism; @@ -546,13 +568,13 @@ public partial class DlibDotNet continue; if (!_ArgZeroIsConfigurationRootDirectory && !container.SourceDirectory.StartsWith(argZero)) continue; - filteredItems = Shared.Models.Stateless.Methods.IContainer.GetFilterItems(_Configuration.PropertyConfiguration, container); - if (filteredItems.Length == 0) + filteredItems = Shared.Models.Stateless.Methods.IContainer.GetValidImageItems(_Configuration.PropertyConfiguration, container); + if (filteredItems.Count == 0) continue; sourceDirectoryChanges.Clear(); anyNullOrNoIsUniqueFileName = filteredItems.Any(l => !l.IsUniqueFileName); totalSeconds = (int)Math.Floor(new TimeSpan(DateTime.Now.Ticks - ticks).TotalSeconds); - message = $"{i + 1:000} [{filteredItems.Length:000}] / {containersLength:000} - {total} / {t} total - {totalSeconds} total second(s) - {outputResolution} - <{container.SourceDirectory}> - total not mapped {totalNotMapped:000000}"; + message = $"{i + 1:000} [{filteredItems.Count:000}] / {containersLength:000} - {total} / {t} total - {totalSeconds} total second(s) - {outputResolution} - <{container.SourceDirectory}> - total not mapped {totalNotMapped:000000}"; propertyLogic.SetAngleBracketCollection(aResultsFullGroupDirectory, container.SourceDirectory, anyNullOrNoIsUniqueFileName); if (outputResolutionHasNumber) _Resize.SetAngleBracketCollection(cResultsFullGroupDirectory, container.SourceDirectory); @@ -627,7 +649,7 @@ public partial class DlibDotNet private ReadOnlyCollection GetMappings(Property.Models.Configuration propertyConfiguration, string eDistanceContentDirectory, ReadOnlyCollection readOnlyContainers, MapLogic mapLogic, bool distinctItems) { - ReadOnlyCollection results; + List results = []; int count = 0; int notMapped; Mapping mapping; @@ -636,15 +658,14 @@ public partial class DlibDotNet string focusRelativePath; bool? isFocusRelativePath; DateTime[] containerDateTimes; - IEnumerable filteredItems; MappingFromItem mappingFromItem; - List mappingCollection = []; + ReadOnlyCollection filteredItems; foreach (Container container in readOnlyContainers) { if (container.Items.Count == 0) continue; - filteredItems = Shared.Models.Stateless.Methods.IContainer.GetFilterItems(propertyConfiguration, container); - if (!filteredItems.Any()) + filteredItems = Shared.Models.Stateless.Methods.IContainer.GetValidImageItems(propertyConfiguration, container); + if (filteredItems.Count == 0) continue; containerDateTimes = Shared.Models.Stateless.Methods.IContainer.GetContainerDateTimes(filteredItems); focusRelativePath = Path.GetFullPath(string.Concat(_Configuration.PropertyConfiguration.RootDirectory, _Configuration.FocusDirectory)); @@ -665,24 +686,25 @@ public partial class DlibDotNet foreach (Shared.Models.Face face in item.Faces) { if (face.Mapping is null) + throw new NotSupportedException(); + if (face.FaceEncoding is null || face.Location is null || face.OutputResolution is null) continue; anyValidFaces = true; - mappingCollection.Add(face.Mapping); + results.Add(face.Mapping); } if (!anyValidFaces) { (mapping, notMapped) = GetMappingAndUpdateMappingFromPerson(mapLogic, item, isFocusRelativePath, mappingFromItem); - mappingCollection.Add(mapping); + results.Add(mapping); } } } if (_Configuration.MoveToDecade && _Configuration.LocationContainerDistanceTolerance is null) _ = Shared.Models.Stateless.Methods.IPath.DeleteEmptyDirectories(eDistanceContentDirectory); - results = new((from l in mappingCollection orderby l.MappingFromItem.Id select l).ToArray()); - return results; + return new(results); } - private static void SavePropertyShortcutsForOutputResolutions(string eDistanceContentDirectory, ReadOnlyCollection distinctFilteredItems) + private static void SavePropertyShortcutsForOutputResolutions(string eDistanceContentDirectory, ReadOnlyCollection distinctValidImageItems) { #if VerifyItem bool found; @@ -713,7 +735,7 @@ public partial class DlibDotNet List distinct = []; WindowsShortcut windowsShortcut; List<(string, string, string)> collection = []; - foreach (Item item in distinctFilteredItems) + foreach (Item item in distinctValidImageItems) { if (item.Property?.Id is null) continue; @@ -726,7 +748,7 @@ public partial class DlibDotNet continue; distinct.Add(directory); } - foreach (Item item in distinctFilteredItems) + foreach (Item item in distinctValidImageItems) { if (item.Property?.Id is null || item.Property.DateTimeOriginal is null) continue; @@ -771,27 +793,27 @@ public partial class DlibDotNet } } - private void MapLogic(long ticks, ReadOnlyCollection containers, string fPhotoPrismContentDirectory, MapLogic mapLogic, string outputResolution, ReadOnlyDictionary> personKeyToIds, ReadOnlyCollection distinctFilteredFaces, ReadOnlyCollection distinctFilteredMappingCollection) + private void MapLogic(long ticks, ReadOnlyCollection containers, string fPhotoPrismContentDirectory, MapLogic mapLogic, string outputResolution, ReadOnlyDictionary> personKeyToIds, ReadOnlyCollection distinctValidImageFaces, ReadOnlyCollection distinctValidImageMappingCollection) { (_, _, string dResultsFullGroupDirectory, string d2ResultsFullGroupDirectory) = GetResultsFullGroupDirectories(outputResolution); string dFacesContentDirectory = Path.Combine(dResultsFullGroupDirectory, _Configuration.PropertyConfiguration.ResultContent); string d2FacePartsContentDirectory = Path.Combine(d2ResultsFullGroupDirectory, _Configuration.PropertyConfiguration.ResultContent); string d2FacePartsContentCollectionDirectory = Path.Combine(d2ResultsFullGroupDirectory, "[()]"); - if (distinctFilteredMappingCollection.Count > 0) + if (distinctValidImageMappingCollection.Count > 0) { Shared.Models.Stateless.Methods.IPath.ChangeDateForEmptyDirectories(d2FacePartsContentDirectory, ticks); if (Directory.Exists(d2FacePartsContentCollectionDirectory)) Shared.Models.Stateless.Methods.IPath.MakeHiddenIfAllItemsAreHidden(d2FacePartsContentCollectionDirectory); } if (Directory.Exists(fPhotoPrismContentDirectory)) - F_PhotoPrism.WriteMatches(fPhotoPrismContentDirectory, _Configuration.PersonBirthdayFormat, _Configuration.RectangleIntersectMinimums, ticks, distinctFilteredFaces, mapLogic); + F_PhotoPrism.WriteMatches(fPhotoPrismContentDirectory, _Configuration.PersonBirthdayFormat, _Configuration.RectangleIntersectMinimums, ticks, distinctValidImageFaces, mapLogic); if (_Configuration.SaveShortcutsForOutputResolutions.Contains(outputResolution)) - mapLogic.SaveShortcutsForOutputResolutionsDuringMapLogic(containers, personKeyToIds, dFacesContentDirectory, distinctFilteredMappingCollection); - ReadOnlyDictionary> idToWholePercentagesToMapping = Map.Models.Stateless.Methods.IMapLogic.GetIdToWholePercentagesToFace(distinctFilteredMappingCollection); + mapLogic.SaveShortcutsForOutputResolutionsDuringMapLogic(containers, personKeyToIds, dFacesContentDirectory, distinctValidImageMappingCollection); + ReadOnlyDictionary> idToWholePercentagesToMapping = Map.Models.Stateless.Methods.IMapLogic.GetIdToWholePercentagesToFace(distinctValidImageMappingCollection); if (_Configuration.SaveMappedForOutputResolutions.Contains(outputResolution)) - mapLogic.SaveMapped(dFacesContentDirectory, d2FacePartsContentDirectory, d2FacePartsContentCollectionDirectory, personKeyToIds, distinctFilteredMappingCollection, idToWholePercentagesToMapping); + mapLogic.SaveMapped(dFacesContentDirectory, d2FacePartsContentDirectory, d2FacePartsContentCollectionDirectory, personKeyToIds, distinctValidImageMappingCollection, idToWholePercentagesToMapping); if (_Configuration.SaveFaceDistancesForOutputResolutions.Contains(outputResolution)) - SaveFaceDistances(ticks, mapLogic, distinctFilteredFaces, dFacesContentDirectory, d2FacePartsContentDirectory, d2FacePartsContentCollectionDirectory, idToWholePercentagesToMapping); + SaveFaceDistances(ticks, mapLogic, distinctValidImageFaces, dFacesContentDirectory, d2FacePartsContentDirectory, d2FacePartsContentCollectionDirectory, idToWholePercentagesToMapping); } private bool? GetIsFocusModel(Shared.Models.Property? property) @@ -880,36 +902,37 @@ public partial class DlibDotNet return result; } - private static Map.Models.Configuration Get(Models.Configuration configuration, string facesFileNameExtension, string facesHiddenFileNameExtension, string facePartsFileNameExtension) + private static Map.Models.Configuration Get(Models.Configuration configuration, IDistanceLimits distanceLimits, string facesFileNameExtension, string facesHiddenFileNameExtension, string facePartsFileNameExtension) { - Map.Models.Configuration result = new( - configuration.DeletePossibleDuplicates, - configuration.DistanceMoveUnableToMatch, - configuration.DistanceRenameToMatch, - configuration.FaceConfidencePercent, - configuration.FaceDistancePermyriad, - configuration.LinkedAlpha, - configuration.LocationContainerDebugDirectory, - configuration.LocationContainerDirectoryPattern, - configuration.LocationContainerDistanceGroupMinimum, - configuration.LocationContainerDistanceTake, - configuration.LocationContainerDistanceTolerance, - configuration.LocationDigits, - configuration.MappingDefaultName, - configuration.PersonBirthdayFirstYear, - configuration.PersonBirthdayFormat, - configuration.PersonCharacters.ToArray(), - configuration.RangeDaysDeltaTolerance, - configuration.RangeDistanceTolerance, - configuration.ReMap, - configuration.SaveIndividually, - configuration.SaveSortingWithoutPerson, - configuration.SkipNotSkipDirectories, - configuration.SortingMaximumPerKey, - configuration.SortingMinimumToUseSigma, - facesFileNameExtension, - facesHiddenFileNameExtension, - facePartsFileNameExtension); + Map.Models.Configuration result = new(distanceLimits, + configuration.PropertyConfiguration, + configuration.DeletePossibleDuplicates, + configuration.DistanceMoveUnableToMatch, + configuration.DistanceRenameToMatch, + configuration.FaceConfidencePercent, + configuration.FaceDistancePermyriad, + configuration.LinkedAlpha, + configuration.LocationContainerDebugDirectory, + configuration.LocationContainerDirectoryPattern, + configuration.LocationContainerDistanceGroupMinimum, + configuration.LocationContainerDistanceTake, + configuration.LocationContainerDistanceTolerance, + configuration.LocationDigits, + configuration.MappingDefaultName, + configuration.PersonBirthdayFirstYear, + configuration.PersonBirthdayFormat, + configuration.PersonCharacters.ToArray(), + configuration.RangeDaysDeltaTolerance, + configuration.RangeDistanceTolerance, + configuration.ReMap, + configuration.SaveIndividually, + configuration.SaveSortingWithoutPerson, + configuration.SkipNotSkipDirectories, + configuration.SortingMaximumPerKey, + configuration.SortingMinimumToUseSigma, + facesFileNameExtension, + facesHiddenFileNameExtension, + facePartsFileNameExtension); return result; } @@ -961,8 +984,8 @@ public partial class DlibDotNet List parseExceptions = []; string[] changesFrom = [nameof(A_Property)]; List> subFileTuples = []; - FileHolder resizedFileHolder = _Resize.GetResizedFileHolder(cResultsFullGroupDirectory, item, outputResolutionHasNumber); ReadOnlyCollection locationContainers = mapLogic.GetLocationContainers(item); + FileHolder resizedFileHolder = _Resize.GetResizedFileHolder(cResultsFullGroupDirectory, item, outputResolutionHasNumber); if (item.Property is null || item.Property.Id is null || !item.SourceDirectoryFileHolder.Exists || item.SourceDirectoryFileHolder.CreationTime is null || item.SourceDirectoryFileHolder.LastWriteTime is null || item.Any()) { LogItemPropertyIsNull(item); @@ -1047,7 +1070,7 @@ public partial class DlibDotNet if ((_Configuration.DistanceMoveUnableToMatch || _Configuration.DistanceRenameToMatch) && _Configuration.LoadOrCreateThenSaveDistanceResultsForOutputResolutions.Contains(outputResolution) && locationContainers is not null && faceCollection.All(l => !l.Saved)) - _Distance.LookForMatchFacesAndPossiblyRename(_Faces.FileNameExtension, item.FilePath, mappingFromItem, faces, locationContainers); + _Distance.LookForMatchFacesAndPossiblyRename(_DistanceLimits, _Faces.FileNameExtension, item.FilePath, mappingFromItem, faces, locationContainers); (bool review, int[] eyesCollection) = Shared.Models.Stateless.Methods.IFace.GetEyeCollection(_Configuration.EyeThreshold, faces); if (review || _Configuration.SaveFaceLandmarkForOutputResolutions.Contains(outputResolution)) { @@ -1076,7 +1099,7 @@ public partial class DlibDotNet List> sourceDirectoryChanges, Dictionary> fileNameToCollection, Container container, - Item[] filteredItems, + ReadOnlyCollection filteredItems, string message) { int result = 0; @@ -1088,8 +1111,8 @@ public partial class DlibDotNet bool? isFocusRelativePath = string.IsNullOrEmpty(_Configuration.FocusDirectory) ? null : container.SourceDirectory.StartsWith(focusRelativePath); string facePartsCollectionDirectory = _Configuration.CopyFacesAndSaveFaceLandmarkForOutputResolutions.Contains(outputResolution) ? _FaceParts.GetFacePartsDirectory(_Configuration.PropertyConfiguration, d2ResultsFullGroupDirectory, item: filteredItems.First(), includeNameWithoutExtension: false) : string.Empty; bool anyPropertiesChangedForX = _Configuration.PropertyConfiguration.PropertiesChangedForProperty || _Configuration.PropertiesChangedForDistance || _Configuration.PropertiesChangedForFaces || _Configuration.PropertiesChangedForIndex || _Configuration.PropertiesChangedForMetadata || _Configuration.PropertiesChangedForResize; - using ProgressBar progressBar = new(filteredItems.Length, message, options); - _ = Parallel.For(0, filteredItems.Length, parallelOptions, (i, state) => + using ProgressBar progressBar = new(filteredItems.Count, message, options); + _ = Parallel.For(0, filteredItems.Count, parallelOptions, (i, state) => { try { @@ -1115,7 +1138,7 @@ public partial class DlibDotNet catch (Exception) { exceptionsCount++; - if (exceptionsCount == filteredItems.Length) + if (exceptionsCount == filteredItems.Count) throw new Exception(string.Concat("All in [", container.SourceDirectory, "] failed!")); } }); @@ -1218,10 +1241,10 @@ public partial class DlibDotNet } } - private void SaveFaceDistances(long ticks, MapLogic mapLogic, ReadOnlyCollection distinctFilteredFaces, string dFacesContentDirectory, string d2FacePartsContentDirectory, string d2FacePartsContentCollectionDirectory, ReadOnlyDictionary> idToWholePercentagesToMapping) + private void SaveFaceDistances(long ticks, MapLogic mapLogic, ReadOnlyCollection distinctValidImageFaces, string dFacesContentDirectory, string d2FacePartsContentDirectory, string d2FacePartsContentCollectionDirectory, ReadOnlyDictionary> idToWholePercentagesToMapping) { - E_Distance.PreFilterSetFaceDistances(_AppSettings.MaxDegreeOfParallelism, ticks, distinctFilteredFaces); - ReadOnlyCollection faceDistanceContainers = E_Distance.GetFaceDistanceContainers(distinctFilteredFaces); + E_Distance.PreFilterSetFaceDistances(_AppSettings.MaxDegreeOfParallelism, _MapConfiguration, ticks, distinctValidImageFaces); + ReadOnlyCollection faceDistanceContainers = E_Distance.GetFaceDistanceContainers(distinctValidImageFaces); if (faceDistanceContainers.Count > 0) { List faceDistanceEncodings = []; diff --git a/Instance/Models/Binder/AppSettings.cs b/Instance/Models/Binder/AppSettings.cs index 8a21406..a7b540f 100644 --- a/Instance/Models/Binder/AppSettings.cs +++ b/Instance/Models/Binder/AppSettings.cs @@ -19,6 +19,23 @@ public class AppSettings return result; } + private static void PreVerify(IConfigurationRoot configurationRoot, AppSettings? appSettings) + { + if (appSettings?.Company is null) + { + List paths = []; + foreach (IConfigurationProvider configurationProvider in configurationRoot.Providers) + { + if (configurationProvider is not Microsoft.Extensions.Configuration.Json.JsonConfigurationProvider jsonConfigurationProvider) + continue; + if (jsonConfigurationProvider.Source.FileProvider is not Microsoft.Extensions.FileProviders.PhysicalFileProvider physicalFileProvider) + continue; + paths.Add(physicalFileProvider.Root); + } + throw new NotSupportedException($"Not found!{Environment.NewLine}{string.Join(Environment.NewLine, paths.Distinct())}"); + } + } + private static Models.AppSettings Get(AppSettings? appSettings) { Models.AppSettings result; @@ -42,6 +59,7 @@ public class AppSettings #pragma warning disable IL3050, IL2026 AppSettings? appSettings = configurationRoot.Get(); #pragma warning restore IL3050, IL2026 + PreVerify(configurationRoot, appSettings); result = Get(appSettings); return result; } diff --git a/Instance/Models/Binder/Configuration.cs b/Instance/Models/Binder/Configuration.cs index 38cac67..a0699f1 100644 --- a/Instance/Models/Binder/Configuration.cs +++ b/Instance/Models/Binder/Configuration.cs @@ -103,7 +103,22 @@ public class Configuration return result; } -#pragma warning restore csharp_preserve_single_line_statements + private static void PreVerify(IConfigurationRoot configurationRoot, Configuration? configuration) + { + if (configuration?.CheckDFaceAndUpWriteDates is null) + { + List paths = []; + foreach (IConfigurationProvider configurationProvider in configurationRoot.Providers) + { + if (configurationProvider is not Microsoft.Extensions.Configuration.Json.JsonConfigurationProvider jsonConfigurationProvider) + continue; + if (jsonConfigurationProvider.Source.FileProvider is not Microsoft.Extensions.FileProviders.PhysicalFileProvider physicalFileProvider) + continue; + paths.Add(physicalFileProvider.Root); + } + throw new NotSupportedException($"Not found!{Environment.NewLine}{string.Join(Environment.NewLine, paths.Distinct())}"); + } + } private static Models.Configuration Get(Configuration? configuration, Property.Models.Configuration propertyConfiguration) { @@ -297,14 +312,19 @@ public class Configuration Models.Configuration result; Configuration? configuration; if (isEnvironment is null) +#pragma warning disable IL3050, IL2026 configuration = configurationRoot.Get(); +#pragma warning restore IL3050, IL2026 else { string environmentName = IsEnvironment.GetEnvironmentName(isEnvironment); string section = string.Concat(environmentName, ":", nameof(Configuration)); IConfigurationSection configurationSection = configurationRoot.GetSection(section); +#pragma warning disable IL3050, IL2026 configuration = configurationSection.Get(); +#pragma warning restore IL3050, IL2026 } + PreVerify(configurationRoot, configuration); result = Get(configuration, propertyConfiguration); return result; } diff --git a/Instance/Models/_F_Random.cs b/Instance/Models/_F_Random.cs index b3e1649..4339675 100644 --- a/Instance/Models/_F_Random.cs +++ b/Instance/Models/_F_Random.cs @@ -24,14 +24,14 @@ internal class F_Random return result; } - private static ReadOnlyDictionary> GetDayToRelativePaths(ReadOnlyCollection mappingCollection, string dateFormat, ReadOnlyDictionary> idToPersonKeys) + private static ReadOnlyDictionary> GetDayToRelativePaths(ReadOnlyCollection distinctValidImageMappingCollection, string dateFormat, ReadOnlyDictionary> idToPersonKeys) { Dictionary> results = []; string key; DateTime dateTime; List? personKeys; List? relativePaths; - foreach (Shared.Models.Mapping mapping in mappingCollection) + foreach (Shared.Models.Mapping mapping in distinctValidImageMappingCollection) { if (mapping.MappingFromItem.FilePath.DirectoryName is null || mapping.MappingFromPerson is null) continue; @@ -54,7 +54,7 @@ internal class F_Random return new(results); } - internal void Random(Property.Models.Configuration configuration, int radomUseBirthdayMinimum, string[] validKeyWordsToIgnoreInRandom, ReadOnlyDictionary> personKeyToIds, ReadOnlyCollection? notNineCollection, ReadOnlyCollection mappingCollection) + internal void Random(Property.Models.Configuration configuration, int radomUseBirthdayMinimum, string[] validKeyWordsToIgnoreInRandom, ReadOnlyDictionary> personKeyToIds, ReadOnlyCollection? notNineCollection, ReadOnlyCollection distinctValidImageMappingCollection) { string key; string json; @@ -66,12 +66,12 @@ internal class F_Random List distinctCollection = []; DateTime dateTime = new(2024, 1, 1); //Leap year ReadOnlyDictionary> idToPersonKeys = Map.Models.Stateless.Methods.IMapLogic.GetIdToPersonKeys(personKeyToIds); - ReadOnlyDictionary> dayToRelativePaths = GetDayToRelativePaths(mappingCollection, dateFormat, idToPersonKeys); + ReadOnlyDictionary> dayToRelativePaths = GetDayToRelativePaths(distinctValidImageMappingCollection, dateFormat, idToPersonKeys); string fRandomCollectionDirectory = Property.Models.Stateless.IResult.GetResultsDateGroupDirectory(configuration, nameof(F_Random), "[]"); string[] files = Directory.GetFiles(fRandomCollectionDirectory, "*", SearchOption.TopDirectoryOnly); foreach (string file in files) File.Delete(file); - foreach (Shared.Models.Mapping mapping in mappingCollection) + foreach (Shared.Models.Mapping mapping in distinctValidImageMappingCollection) { if (distinctCollection.Contains(mapping.MappingFromItem.Id)) continue; diff --git a/Map/Models/Configuration.cs b/Map/Models/Configuration.cs index 96280f3..808f17d 100644 --- a/Map/Models/Configuration.cs +++ b/Map/Models/Configuration.cs @@ -1,6 +1,8 @@ namespace View_by_Distance.Map.Models; -public record Configuration(bool DeletePossibleDuplicates, +public record Configuration(Shared.Models.Methods.IDistanceLimits DistanceLimits, + Shared.Models.Properties.IPropertyConfiguration PropertyConfiguration, + bool DeletePossibleDuplicates, bool DistanceMoveUnableToMatch, bool DistanceRenameToMatch, int FaceConfidencePercent, diff --git a/Map/Models/MapLogic.cs b/Map/Models/MapLogic.cs index 17f7327..2f5e905 100644 --- a/Map/Models/MapLogic.cs +++ b/Map/Models/MapLogic.cs @@ -23,6 +23,14 @@ public partial class MapLogic : Shared.Models.Methods.IMapLogic long? Ticks, string? PersonDirectory); + internal record FilteredOriginalImage(int Id, + FilePath FilePath, + int ApproximateYears, + string PersonKeyFormatted, + string Directory, + string PersonDirectory, + string CheckFile); + public void SaveContainers(int? updated, List saveContainers) { if (_Configuration is null) @@ -137,7 +145,7 @@ public partial class MapLogic : Shared.Models.Methods.IMapLogic } } - private List GetCollectionForSaveShortcutsForOutputResolutionsPreMapLogic(string eDistanceContentDirectory, ReadOnlyDictionary> personKeyToIds, ReadOnlyCollection mappingCollection) + private List GetCollectionForSaveShortcutsForOutputResolutionsPreMapLogic(string eDistanceContentDirectory, ReadOnlyDictionary> personKeyToIds, ReadOnlyCollection distinctValidImageMappingCollection) { List results = []; if (_Configuration is null) @@ -153,7 +161,7 @@ public partial class MapLogic : Shared.Models.Methods.IMapLogic string personKeyFormatted; Calendar calendar = new CultureInfo("en-US").Calendar; ReadOnlyDictionary> idToPersonKeys = IMapLogic.GetIdToPersonKeys(personKeyToIds); - foreach (Mapping mapping in mappingCollection) + foreach (Mapping mapping in distinctValidImageMappingCollection) { dateTime = mapping.MappingFromItem.GetDateTimeOriginalThenMinimumDateTime(); description = mapping.MappingFromLocation is null ? mapping.MappingFromItem.Id.ToString() : mapping.MappingFromLocation.DeterministicHashCodeKey; @@ -181,12 +189,12 @@ public partial class MapLogic : Shared.Models.Methods.IMapLogic personKeyFormatted = IPersonBirthday.GetFormatted(_Configuration.PersonBirthdayFormat, mapping.MappingFromPerson.PersonKey); directory = Path.Combine($"{eDistanceContentDirectory}---", "Person Key Shortcuts", personKeyFormatted, directoryName); fileName = Path.Combine(directory, $"{mapping.MappingFromItem.FilePath.Name}.lnk"); - results.Add(new(mapping.MappingFromItem.FilePath.FullName, directory, mapping.MappingFromItem.GetDateTimeOriginalThenMinimumDateTime(), fileName, description, MakeAllHidden: false)); + results.Add(new(mapping.MappingFromItem.FilePath.FullName, directory, dateTime, fileName, description, MakeAllHidden: false)); if (IPerson.IsDefaultName(mapping.MappingFromPerson)) continue; directory = Path.Combine($"{eDistanceContentDirectory}---", "Name Shortcuts", mapping.MappingFromPerson.DisplayDirectoryName, directoryName); fileName = Path.Combine(directory, $"{mapping.MappingFromItem.FilePath.Name}.lnk"); - results.Add(new(mapping.MappingFromItem.FilePath.FullName, directory, mapping.MappingFromItem.GetDateTimeOriginalThenMinimumDateTime(), fileName, description, MakeAllHidden: false)); + results.Add(new(mapping.MappingFromItem.FilePath.FullName, directory, dateTime, fileName, description, MakeAllHidden: false)); } return results; } @@ -230,7 +238,7 @@ public partial class MapLogic : Shared.Models.Methods.IMapLogic ReadOnlyDictionary readOnlyPersonKeyToCount; Dictionary> skipCollection = []; Dictionary> skipNotSkipCollection = []; - ReadOnlyDictionary> readOnlyskipCollection; + ReadOnlyDictionary> readOnlySkipCollection; string? rootDirectoryParent = Path.GetDirectoryName(propertyConfiguration.RootDirectory); string eDistanceContentTicksDirectory = Path.Combine(eDistanceContentDirectory, ticks.ToString()); ReadOnlyDictionary>> idThenWholePercentagesToPersonContainers; @@ -297,7 +305,7 @@ public partial class MapLogic : Shared.Models.Methods.IMapLogic skipCollection, readOnlyPersonKeyFormattedToPersonContainer, personKeyFormattedIdThenWholePercentagesCollection); - readOnlyskipCollection = new(skipCollection); + readOnlySkipCollection = new(skipCollection); notMappedPersonContainers.AddRange(Stateless.MapLogic.GetNotMappedPersonContainers(configuration, ticks, personContainers, @@ -307,7 +315,7 @@ public partial class MapLogic : Shared.Models.Methods.IMapLogic configuration, ticks, personContainers, - readOnlyskipCollection, + readOnlySkipCollection, records)); int lossCount = records.Count - locationContainers.Count; int unableToMatchCount = records.Count - personKeyFormattedIdThenWholePercentagesCollection.Count; @@ -532,7 +540,7 @@ public partial class MapLogic : Shared.Models.Methods.IMapLogic return new(debugDirectory, directory, ticks, personDirectory); } - private List GetSaveContainers(string dFacesContentDirectory, string d2FacePartsContentDirectory, ReadOnlyCollection mappingCollection, ReadOnlyDictionary> idToWholePercentagesToMapping, ReadOnlyDictionary> personKeyToIds, int? useFiltersCounter, bool saveMapped, bool saveIndividually, bool sortingContainersAny) + private List GetSaveContainers(string dFacesContentDirectory, string d2FacePartsContentDirectory, ReadOnlyCollection distinctValidImageMappingCollection, ReadOnlyDictionary> idToWholePercentagesToMapping, ReadOnlyDictionary> personKeyToIds, int? useFiltersCounter, bool saveMapped, bool saveIndividually, bool sortingContainersAny) { if (_Configuration is null) throw new NullReferenceException(nameof(_Configuration)); @@ -557,7 +565,7 @@ public partial class MapLogic : Shared.Models.Methods.IMapLogic ReadOnlyDictionary? wholePercentagesToMapping; int padLeft = _Configuration.FaceDistancePermyriad.ToString().Length; string forceSingleImageHumanized = nameof(Shared.Models.Stateless.IMapLogic.ForceSingleImage).Humanize(LetterCasing.Title); - foreach (Mapping mapping in mappingCollection) + foreach (Mapping mapping in distinctValidImageMappingCollection) { if (mapping.MappingFromLocation is null) continue; @@ -651,7 +659,7 @@ public partial class MapLogic : Shared.Models.Methods.IMapLogic return results; } - public void SaveMapped(string dFacesContentDirectory, string d2FacePartsContentDirectory, string d2FacePartsContentCollectionDirectory, ReadOnlyDictionary> personKeyToIds, ReadOnlyCollection mappingCollection, ReadOnlyDictionary> idToWholePercentagesToMapping) + public void SaveMapped(string dFacesContentDirectory, string d2FacePartsContentDirectory, string d2FacePartsContentCollectionDirectory, ReadOnlyDictionary> personKeyToIds, ReadOnlyCollection distinctValidImageMappingCollection, ReadOnlyDictionary> idToWholePercentagesToMapping) { if (_Configuration is null) throw new NullReferenceException(nameof(_Configuration)); @@ -659,13 +667,13 @@ public partial class MapLogic : Shared.Models.Methods.IMapLogic bool saveMapped = true; int? useFiltersCounter = null; string mappingDirectory = Path.Combine(_EDistanceContentTicksDirectory, nameof(Shared.Models.Stateless.IMapLogic.Mapping)); - List saveContainers = GetSaveContainers(dFacesContentDirectory, d2FacePartsContentDirectory, mappingCollection, idToWholePercentagesToMapping, personKeyToIds, useFiltersCounter, saveMapped, sortingContainersAny: true, saveIndividually: false); + List saveContainers = GetSaveContainers(dFacesContentDirectory, d2FacePartsContentDirectory, distinctValidImageMappingCollection, idToWholePercentagesToMapping, personKeyToIds, useFiltersCounter, saveMapped, sortingContainersAny: true, saveIndividually: false); SaveContainers(updated, saveContainers); if (!string.IsNullOrEmpty(_EDistanceContentTicksDirectory) && Directory.Exists(mappingDirectory)) Stateless.MapLogic.SaveMappingShortcuts(mappingDirectory); } - public List GetSortingCollection(int i, Face face, FaceDistance faceDistanceEncoding, List faceDistanceLengths) + public List GetSortingCollection(Shared.Models.Methods.IDistanceLimits distanceLimits, int i, Face face, FaceDistance faceDistanceEncoding, List faceDistanceLengths) { if (_Configuration is null) throw new NullReferenceException(nameof(_Configuration)); @@ -753,7 +761,7 @@ public partial class MapLogic : Shared.Models.Methods.IMapLogic keyToCount.Add(key, new()); _ = keyToCount.TryAdd(key, 0); keyToCount[key]++; - if (!_Configuration.SaveIndividually && keyToCount[key] < _Configuration.SortingMaximumPerKey) + if (!_Configuration.SaveIndividually && keyToCount[key] <= _Configuration.SortingMaximumPerKey) segmentC = null; else segmentC = sortingContainer.Sorting.DistancePermyriad.ToString(); @@ -1029,7 +1037,7 @@ public partial class MapLogic : Shared.Models.Methods.IMapLogic collection.Add(new(personBirthday.Value.Ticks, Path.Combine(checkDirectory, personKeyFormatted, fileNameWithoutExtension, $"{ids.Count} Face(s)"))); foreach ((long personKey, string displayDirectoryName) in collection) { - matches = (from l in personContainers where l.Key == personKey && l.ApproximateYears.HasValue select l).ToArray(); + matches = (from l in personContainers where l.Key == personKey select l).ToArray(); if (matches.Length == 0) continue; personKeyFormatted = IPersonBirthday.GetFormatted(_Configuration.PersonBirthdayFormat, personKey); @@ -1044,11 +1052,11 @@ public partial class MapLogic : Shared.Models.Methods.IMapLogic return results; } - private (int, FilePath, int, string, string, string, string)[] GetCollectionForSaveFilteredOriginalImagesFromJLinks(string[] jLinks, string a2PeopleContentDirectory, ReadOnlyCollection personContainers, ReadOnlyCollection mappingCollection, ReadOnlyDictionary> personKeyToIds) + private FilteredOriginalImage[] GetCollectionForSaveFilteredOriginalImagesFromJLinks(string[] jLinks, string a2PeopleContentDirectory, ReadOnlyCollection personContainers, ReadOnlyCollection distinctValidImageMappingCollection, ReadOnlyDictionary> personKeyToIds) { if (_Configuration is null) throw new NullReferenceException(nameof(_Configuration)); - (int, FilePath, int, string, string, string, string)[] results; + FilteredOriginalImage[] results; int count = 0; int group = 65; string checkFile; @@ -1058,9 +1066,9 @@ public partial class MapLogic : Shared.Models.Methods.IMapLogic string personKeyFormatted; List distinctCollection = []; bool usePersonKeyAndDeterministicHashCodeKey = false; + List filteredOriginalImages = []; List personKeyFormattedCollection = GetPersonKeyFormattedCollection(jLinks, a2PeopleContentDirectory, personContainers, personKeyToIds); - List<(int Id, FilePath FilePath, int ApproximateYears, string PersonKeyFormatted, string CheckFile, string Directory, string PersonDirectory)> collection = []; - foreach (Mapping mapping in mappingCollection) + foreach (Mapping mapping in distinctValidImageMappingCollection) { if (distinctCollection.Contains(mapping.MappingFromItem.Id)) continue; @@ -1069,7 +1077,7 @@ public partial class MapLogic : Shared.Models.Methods.IMapLogic throw new NotSupportedException(); if (mapping.By is null or Shared.Models.Stateless.IMapLogic.Sorting) continue; - if (mapping.MappingFromPerson?.ApproximateYears is null || mapping.MappingFromLocation is null) + if (mapping.MappingFromPerson is null || mapping.MappingFromLocation is null) continue; if (string.IsNullOrEmpty(mapping.MappingFromPerson.SegmentB)) throw new NotSupportedException(); @@ -1097,39 +1105,44 @@ public partial class MapLogic : Shared.Models.Methods.IMapLogic personDirectory = Path.Combine(directory, mapping.MappingFromPerson.DisplayDirectoryName); checkFile = Path.Combine(directory, $"{mapping.MappingFromLocation.DeterministicHashCodeKey}{mapping.MappingFromItem.FilePath.ExtensionLowered}"); } - collection.Add(new(mapping.MappingFromItem.Id, mapping.MappingFromItem.FilePath, mapping.MappingFromPerson.ApproximateYears.Value, personKeyFormatted, directory, personDirectory, checkFile)); + if (mapping is null) + continue; + if (mapping.MappingFromPerson.ApproximateYears is null) + filteredOriginalImages.Add(new(mapping.MappingFromItem.Id, mapping.MappingFromItem.FilePath, -1, personKeyFormatted, directory, personDirectory, checkFile)); + else + filteredOriginalImages.Add(new(mapping.MappingFromItem.Id, mapping.MappingFromItem.FilePath, mapping.MappingFromPerson.ApproximateYears.Value, personKeyFormatted, directory, personDirectory, checkFile)); distinctCollection.Add(mapping.MappingFromItem.Id); count += 1; } - results = (from l in collection orderby l.ApproximateYears descending, l.PersonKeyFormatted descending select l).ToArray(); + results = (from l in filteredOriginalImages orderby l.ApproximateYears descending, l.PersonKeyFormatted descending select l).ToArray(); return results; } - public void SaveFilteredOriginalImagesFromJLinks(string[] jLinks, ReadOnlyCollection personContainers, string a2PeopleContentDirectory, ReadOnlyDictionary> personKeyToIds, ReadOnlyCollection mappingCollection) + public void SaveFilteredOriginalImagesFromJLinks(string[] jLinks, ReadOnlyCollection personContainers, string a2PeopleContentDirectory, ReadOnlyDictionary> personKeyToIds, ReadOnlyCollection distinctValidImageMappingCollection) { if (_Configuration is null) throw new NullReferenceException(nameof(_Configuration)); FileHolder fileHolder; SaveContainer? saveContainer; List saveContainers = []; - (int, FilePath, int, string, string, string, string)[] collection = GetCollectionForSaveFilteredOriginalImagesFromJLinks(jLinks, a2PeopleContentDirectory, personContainers, mappingCollection, personKeyToIds); - foreach ((int id, FilePath filePath, int approximateYears, string personKeyFormatted, string directory, string personDirectory, string checkFile) in collection) + FilteredOriginalImage[] filteredOriginalImages = GetCollectionForSaveFilteredOriginalImagesFromJLinks(jLinks, a2PeopleContentDirectory, personContainers, distinctValidImageMappingCollection, personKeyToIds); + foreach (FilteredOriginalImage filteredOriginalImage in filteredOriginalImages) { - fileHolder = FileHolder.Get(filePath); - saveContainer = new(personDirectory); + fileHolder = FileHolder.Get(filteredOriginalImage.FilePath); + saveContainer = new(filteredOriginalImage.PersonDirectory); saveContainers.Add(saveContainer); - saveContainer = new(fileHolder, checkFile, directory); + saveContainer = new(fileHolder, filteredOriginalImage.CheckFile, filteredOriginalImage.Directory); saveContainers.Add(saveContainer); } SaveContainers(null, saveContainers); } - public void SaveShortcutsForOutputResolutionsPreMapLogic(string eDistanceContentDirectory, ReadOnlyDictionary> personKeyToIds, ReadOnlyCollection mappingCollection) + public void SaveShortcutsForOutputResolutionsPreMapLogic(string eDistanceContentDirectory, ReadOnlyDictionary> personKeyToIds, ReadOnlyCollection distinctValidImageMappingCollection) { string hiddenFile; WindowsShortcut windowsShortcut; List collection = []; - collection = GetCollectionForSaveShortcutsForOutputResolutionsPreMapLogic(eDistanceContentDirectory, personKeyToIds, mappingCollection); + collection = GetCollectionForSaveShortcutsForOutputResolutionsPreMapLogic(eDistanceContentDirectory, personKeyToIds, distinctValidImageMappingCollection); string[] distinctDirectories = (from l in collection select l.Directory).Distinct().ToArray(); foreach (string directory in distinctDirectories) { @@ -1163,7 +1176,7 @@ public partial class MapLogic : Shared.Models.Methods.IMapLogic } } - private (List<(string, DateTime[])>, List) GetCollectionForSaveShortcutsForOutputResolutionsDuringMapLogic(ReadOnlyDictionary> personKeyToIds, string dFacesContentDirectory, ReadOnlyCollection filteredItems, ReadOnlyCollection mappingCollection) + private (List<(string, DateTime[])>, List) GetCollectionForSaveShortcutsForOutputResolutionsDuringMapLogic(ReadOnlyDictionary> personKeyToIds, string dFacesContentDirectory, ReadOnlyCollection validImageItems, ReadOnlyCollection distinctValidImageMappingCollection) { if (_Configuration is null) throw new NullReferenceException(nameof(_Configuration)); @@ -1171,6 +1184,7 @@ public partial class MapLogic : Shared.Models.Methods.IMapLogic string fileName; string fullName; string directory; + DateTime dateTime; string facesDirectory; string? directoryName; string personDirectory; @@ -1178,7 +1192,7 @@ public partial class MapLogic : Shared.Models.Methods.IMapLogic List distinct = []; List collection = []; List<(string, DateTime[])> directoriesAndDateTimes = []; - foreach (Item item in filteredItems) + foreach (Item item in validImageItems) { if (item.ResizedFileHolder is null) continue; @@ -1204,13 +1218,14 @@ public partial class MapLogic : Shared.Models.Methods.IMapLogic } } } - foreach (Mapping mapping in mappingCollection) + foreach (Mapping mapping in distinctValidImageMappingCollection) { directoryName = Path.GetDirectoryName(mapping.MappingFromItem.RelativePath); if (directoryName is null) throw new NotSupportedException(); if (mapping.MappingFromItem.ResizedFileHolder.DirectoryName is null || !mapping.MappingFromItem.ResizedFileHolder.Exists) continue; + dateTime = mapping.MappingFromItem.GetDateTimeOriginalThenMinimumDateTime(); if (mapping.By is null or Shared.Models.Stateless.IMapLogic.Sorting || mapping.MappingFromPerson?.ApproximateYears is null) { if (mapping.MappingFromItem.ContainerDateTimes.Length > 0 && !distinct.Contains(mapping.MappingFromItem.ResizedFileHolder.DirectoryName)) @@ -1221,13 +1236,13 @@ public partial class MapLogic : Shared.Models.Methods.IMapLogic directory = Path.Combine(mapping.MappingFromItem.ResizedFileHolder.DirectoryName, $"{_PropertyConfiguration.ResultAllInOne}Shortcuts", _PropertyConfiguration.ResultAllInOne); personDirectory = Path.Combine(directory, "Unknown"); fileName = Path.Combine(personDirectory, $"{mapping.MappingFromItem.ResizedFileHolder.Name}.lnk"); - collection.Add(new(mapping.MappingFromItem.ResizedFileHolder.FullName, personDirectory, mapping.MappingFromItem.GetDateTimeOriginalThenMinimumDateTime(), fileName, mapping.MappingFromLocation?.DeterministicHashCodeKey, MakeAllHidden: false)); + collection.Add(new(mapping.MappingFromItem.ResizedFileHolder.FullName, personDirectory, dateTime, fileName, mapping.MappingFromLocation?.DeterministicHashCodeKey, MakeAllHidden: false)); facesDirectory = Stateless.MapLogic.GetFacesDirectory(_PropertyConfiguration, dFacesContentDirectory, mapping.FilePath, mapping.MappingFromItem); if (mapping.MappingFromLocation is null) continue; fullName = Path.Combine(facesDirectory, $"{mapping.MappingFromLocation.DeterministicHashCodeKey}{mapping.MappingFromItem.FilePath.ExtensionLowered}{_Configuration.FacesFileNameExtension}"); fileName = Path.Combine(personDirectory, $"{mapping.MappingFromLocation.DeterministicHashCodeKey}{mapping.MappingFromItem.ResizedFileHolder.ExtensionLowered}{_Configuration.FacesFileNameExtension}.lnk"); - collection.Add(new(fullName, personDirectory, mapping.MappingFromItem.GetDateTimeOriginalThenMinimumDateTime(), fileName, mapping.MappingFromLocation.DeterministicHashCodeKey, MakeAllHidden: true)); + collection.Add(new(fullName, personDirectory, dateTime, fileName, mapping.MappingFromLocation.DeterministicHashCodeKey, MakeAllHidden: true)); } else { @@ -1247,21 +1262,21 @@ public partial class MapLogic : Shared.Models.Methods.IMapLogic else personDirectory = Path.Combine(directory, mapping.MappingFromPerson.DisplayDirectoryName, $"{ids.Count} Face(s)"); fileName = Path.Combine(directory, $"{mapping.MappingFromItem.ResizedFileHolder.Name}.lnk"); - collection.Add(new(mapping.MappingFromItem.ResizedFileHolder.FullName, personDirectory, mapping.MappingFromItem.GetDateTimeOriginalThenMinimumDateTime(), fileName, mapping.MappingFromLocation?.DeterministicHashCodeKey, MakeAllHidden: false)); + collection.Add(new(mapping.MappingFromItem.ResizedFileHolder.FullName, personDirectory, dateTime, fileName, mapping.MappingFromLocation?.DeterministicHashCodeKey, MakeAllHidden: false)); } } return new(directoriesAndDateTimes, collection); } - public void SaveShortcutsForOutputResolutionsDuringMapLogic(ReadOnlyCollection containers, ReadOnlyDictionary> personKeyToIds, string dFacesContentDirectory, ReadOnlyCollection mappingCollection) + public void SaveShortcutsForOutputResolutionsDuringMapLogic(ReadOnlyCollection containers, ReadOnlyDictionary> personKeyToIds, string dFacesContentDirectory, ReadOnlyCollection distinctValidImageMappingCollection) { if (_Configuration is null) throw new NullReferenceException(nameof(_Configuration)); WindowsShortcut windowsShortcut; List<(string, DateTime[])> directoriesAndDateTimes; List collection; - ReadOnlyCollection filteredItems = IContainer.GetItems(_PropertyConfiguration, containers, distinctItems: true, filterItems: true); - (directoriesAndDateTimes, collection) = GetCollectionForSaveShortcutsForOutputResolutionsDuringMapLogic(personKeyToIds, dFacesContentDirectory, filteredItems, mappingCollection); + ReadOnlyCollection validImageItems = IContainer.GetValidImageItems(_PropertyConfiguration, containers, distinctItems: true, filterItems: true); + (directoriesAndDateTimes, collection) = GetCollectionForSaveShortcutsForOutputResolutionsDuringMapLogic(personKeyToIds, dFacesContentDirectory, validImageItems, distinctValidImageMappingCollection); string[] directories = (from l in collection select l.Directory).Distinct().ToArray(); foreach (string directory in directories) { diff --git a/Map/Models/Stateless/DistanceLogic.cs b/Map/Models/Stateless/DistanceLogic.cs index ff418a8..351c628 100644 --- a/Map/Models/Stateless/DistanceLogic.cs +++ b/Map/Models/Stateless/DistanceLogic.cs @@ -250,14 +250,27 @@ internal abstract class DistanceLogic return results; } - private static void RenameUnknown(string[] files) + private static string[] RenameBirth(string[] files) { + List results = []; + string checkFile; foreach (string file in files) { - if (file.EndsWith(".unk")) + if (file.EndsWith(".brt")) + { + results.Add(file); continue; - File.Move(file, $"{file}.unk"); + } + checkFile = $"{file}.brt"; + if (File.Exists(checkFile)) + { + results.Add(file); + continue; + } + File.Move(file, checkFile); + results.Add(checkFile); } + return results.ToArray(); } private static void MovedToNewestPersonKeyFormatted(string personKeyFormatted, string newestPersonKeyFormatted, TicksDirectory ticksDirectory, string personKeyDirectory) @@ -422,7 +435,7 @@ internal abstract class DistanceLogic if (!isDefault.Value) { if (personKeyFormattedToNewestPersonKeyFormatted.Count > 0 && newestPersonKeyFormatted is null) - RenameUnknown(files); + files = RenameBirth(files); else if (newestPersonKeyFormatted is not null && personKeyFormatted != newestPersonKeyFormatted) { if (!check) diff --git a/Map/Models/Stateless/MapLogic.cs b/Map/Models/Stateless/MapLogic.cs index 837f75a..e93803b 100644 --- a/Map/Models/Stateless/MapLogic.cs +++ b/Map/Models/Stateless/MapLogic.cs @@ -106,8 +106,9 @@ internal abstract class MapLogic internal static string GetMappingSegmentB(long ticks, long personKey, int? approximateYears, MappingFromItem mappingFromItem) { string result; + DateTime dateTime = mappingFromItem.GetDateTimeOriginalThenMinimumDateTime(); PersonBirthday personBirthday = IPersonBirthday.GetPersonBirthday(personKey); - result = GetMappingSegmentB(ticks, personBirthday, approximateYears, mappingFromItem.GetDateTimeOriginalThenMinimumDateTime(), mappingFromItem.IsWrongYear); + result = GetMappingSegmentB(ticks, personBirthday, approximateYears, dateTime, mappingFromItem.IsWrongYear); return result; } @@ -178,7 +179,9 @@ internal abstract class MapLogic internal static string GetMappingSegmentB(long ticks, PersonBirthday personBirthday, int? approximateYears, MappingFromItem mappingFromItem) { - string result = GetMappingSegmentB(ticks, personBirthday, approximateYears, mappingFromItem.GetDateTimeOriginalThenMinimumDateTime(), mappingFromItem.IsWrongYear); + string result; + DateTime dateTime = mappingFromItem.GetDateTimeOriginalThenMinimumDateTime(); + result = GetMappingSegmentB(ticks, personBirthday, approximateYears, dateTime, mappingFromItem.IsWrongYear); return result; } @@ -464,7 +467,7 @@ internal abstract class MapLogic results.RemoveAt(i); continue; } - if (!filePath.Name.EndsWith(".dup") && !filePath.Name.EndsWith(".unk") && !filePath.Name.EndsWith(".abd")) + if (!filePath.Name.EndsWith(".abd") && !filePath.Name.EndsWith(".brt") && !filePath.Name.EndsWith(".dup") && !filePath.Name.EndsWith(".unk")) continue; if (!File.Exists(filePath.FullName)) continue; @@ -1095,11 +1098,11 @@ internal abstract class MapLogic return new(results); } - internal static ReadOnlyDictionary> GetIdToWholePercentagesToFace(ReadOnlyCollection mappingCollection) + internal static ReadOnlyDictionary> GetIdToWholePercentagesToFace(ReadOnlyCollection distinctValidImageMappingCollection) { Dictionary> results = []; Dictionary? keyValuePairs; - foreach (Mapping mapping in mappingCollection) + foreach (Mapping mapping in distinctValidImageMappingCollection) { if (mapping.MappingFromLocation is null) continue; diff --git a/Map/Models/Stateless/Methods/IMapLogic.cs b/Map/Models/Stateless/Methods/IMapLogic.cs index 889f001..a5931dd 100644 --- a/Map/Models/Stateless/Methods/IMapLogic.cs +++ b/Map/Models/Stateless/Methods/IMapLogic.cs @@ -25,10 +25,10 @@ public interface IMapLogic static Shared.Models.Mapping[] GetSelectedMappingCollection(ReadOnlyCollection faces) => MapLogic.GetSelectedMappingCollection(faces); - ReadOnlyDictionary> TestStatic_GetIdToWholePercentagesToFace(ReadOnlyCollection mappingCollection) => - GetIdToWholePercentagesToFace(mappingCollection); - static ReadOnlyDictionary> GetIdToWholePercentagesToFace(ReadOnlyCollection mappingCollection) => - MapLogic.GetIdToWholePercentagesToFace(mappingCollection); + ReadOnlyDictionary> TestStatic_GetIdToWholePercentagesToFace(ReadOnlyCollection distinctValidImageMappingCollection) => + GetIdToWholePercentagesToFace(distinctValidImageMappingCollection); + static ReadOnlyDictionary> GetIdToWholePercentagesToFace(ReadOnlyCollection distinctValidImageMappingCollection) => + MapLogic.GetIdToWholePercentagesToFace(distinctValidImageMappingCollection); List<(string, long)> TestStatic_GetJLinkDirectories(string genealogicalDataCommunicationFile, string[] jLinks, string personBirthdayFormat, char[] personCharacters, string a2PeopleSingletonDirectory, string a2PeopleContentDirectory) => GetJLinkDirectories(genealogicalDataCommunicationFile, jLinks, personBirthdayFormat, personCharacters, a2PeopleSingletonDirectory, a2PeopleContentDirectory); diff --git a/Map/Models/Stateless/RelationLogic.cs b/Map/Models/Stateless/RelationLogic.cs index 25ad46f..4ddb0d9 100644 --- a/Map/Models/Stateless/RelationLogic.cs +++ b/Map/Models/Stateless/RelationLogic.cs @@ -422,7 +422,7 @@ internal abstract class RelationLogic if (!Directory.Exists(directory)) _ = Directory.CreateDirectory(directory); WriteVsCodeFiles(eDistanceContentDirectory, displayDirectoryName, directory); - relationContainers = distance.GetRelationContainers(configuration.FaceDistancePermyriad, configuration.LocationContainerDistanceTake, configuration.LocationContainerDistanceTolerance.Value, group.RelationContainersCollection); + relationContainers = distance.GetRelationContainers(configuration.DistanceLimits, configuration.FaceDistancePermyriad, configuration.LocationContainerDistanceTake, configuration.LocationContainerDistanceTolerance.Value, group.RelationContainersCollection); movedFiles = GetMoveFiles(configuration, group.Key, take, isCounterPersonYear, displayDirectoryName, relationContainers); WriteFile(take, group.PersonKey, isCounterPersonYear, personKeyFormatted, displayDirectoryName, directory, ticks, uri, relationContainers, movedFiles); } diff --git a/Metadata-Query/Models/Binder/AppSettings.cs b/Metadata-Query/Models/Binder/AppSettings.cs index 25603a8..ce5f313 100644 --- a/Metadata-Query/Models/Binder/AppSettings.cs +++ b/Metadata-Query/Models/Binder/AppSettings.cs @@ -16,6 +16,23 @@ public class AppSettings return result; } + private static void PreVerify(IConfigurationRoot configurationRoot, AppSettings? appSettings) + { + if (appSettings?.Company is null) + { + List paths = []; + foreach (IConfigurationProvider configurationProvider in configurationRoot.Providers) + { + if (configurationProvider is not Microsoft.Extensions.Configuration.Json.JsonConfigurationProvider jsonConfigurationProvider) + continue; + if (jsonConfigurationProvider.Source.FileProvider is not Microsoft.Extensions.FileProviders.PhysicalFileProvider physicalFileProvider) + continue; + paths.Add(physicalFileProvider.Root); + } + throw new NotSupportedException($"Not found!{Environment.NewLine}{string.Join(Environment.NewLine, paths.Distinct())}"); + } + } + private static Models.AppSettings Get(AppSettings? appSettings) { Models.AppSettings result; @@ -36,7 +53,10 @@ public class AppSettings public static Models.AppSettings Get(IConfigurationRoot configurationRoot) { Models.AppSettings result; +#pragma warning disable IL3050, IL2026 AppSettings? appSettings = configurationRoot.Get(); +#pragma warning restore IL3050, IL2026 + PreVerify(configurationRoot, appSettings); result = Get(appSettings); return result; } diff --git a/Metadata-Query/Models/Binder/Configuration.cs b/Metadata-Query/Models/Binder/Configuration.cs index fc47217..e254f19 100644 --- a/Metadata-Query/Models/Binder/Configuration.cs +++ b/Metadata-Query/Models/Binder/Configuration.cs @@ -7,13 +7,9 @@ namespace View_by_Distance.Metadata.Query.Models.Binder; public class Configuration { -#nullable disable - - public string[] IgnoreExtensions { get; set; } - public Property.Models.Configuration PropertyConfiguration { get; set; } - public string PersonBirthdayFormat { get; set; } - -#nullable restore + public string[]? IgnoreExtensions { get; set; } + public Property.Models.Configuration? PropertyConfiguration { get; set; } + public string? PersonBirthdayFormat { get; set; } public override string ToString() { @@ -21,12 +17,30 @@ public class Configuration return result; } + private static void PreVerify(IConfigurationRoot configurationRoot, Configuration? configuration) + { + if (configuration?.IgnoreExtensions is null) + { + List paths = []; + foreach (IConfigurationProvider configurationProvider in configurationRoot.Providers) + { + if (configurationProvider is not Microsoft.Extensions.Configuration.Json.JsonConfigurationProvider jsonConfigurationProvider) + continue; + if (jsonConfigurationProvider.Source.FileProvider is not Microsoft.Extensions.FileProviders.PhysicalFileProvider physicalFileProvider) + continue; + paths.Add(physicalFileProvider.Root); + } + throw new NotSupportedException($"Not found!{Environment.NewLine}{string.Join(Environment.NewLine, paths.Distinct())}"); + } + } + private static Models.Configuration Get(Configuration? configuration) { Models.Configuration result; if (configuration is null) throw new NullReferenceException(nameof(configuration)); if (configuration.IgnoreExtensions is null) throw new NullReferenceException(nameof(configuration.IgnoreExtensions)); if (configuration.PersonBirthdayFormat is null) throw new NullReferenceException(nameof(configuration.PersonBirthdayFormat)); + if (configuration.PropertyConfiguration is null) throw new NullReferenceException(nameof(configuration.PropertyConfiguration)); result = new( configuration.IgnoreExtensions, configuration.PersonBirthdayFormat, @@ -39,14 +53,19 @@ public class Configuration Models.Configuration result; Configuration? configuration; if (isEnvironment is null) +#pragma warning disable IL3050, IL2026 configuration = configurationRoot.Get(); +#pragma warning restore IL3050, IL2026 else { string environmentName = IsEnvironment.GetEnvironmentName(isEnvironment); string section = string.Concat(environmentName, ":", nameof(Configuration)); IConfigurationSection configurationSection = configurationRoot.GetSection(section); +#pragma warning disable IL3050, IL2026 configuration = configurationSection.Get(); +#pragma warning restore IL3050, IL2026 } + PreVerify(configurationRoot, configuration); result = Get(configuration); return result; } diff --git a/Mirror-Length/Models/Binder/AppSettings.cs b/Mirror-Length/Models/Binder/AppSettings.cs index 65b6938..7fd4fe3 100644 --- a/Mirror-Length/Models/Binder/AppSettings.cs +++ b/Mirror-Length/Models/Binder/AppSettings.cs @@ -17,6 +17,23 @@ public class AppSettings return result; } + private static void PreVerify(IConfigurationRoot configurationRoot, AppSettings? appSettings) + { + if (appSettings?.Company is null) + { + List paths = []; + foreach (IConfigurationProvider configurationProvider in configurationRoot.Providers) + { + if (configurationProvider is not Microsoft.Extensions.Configuration.Json.JsonConfigurationProvider jsonConfigurationProvider) + continue; + if (jsonConfigurationProvider.Source.FileProvider is not Microsoft.Extensions.FileProviders.PhysicalFileProvider physicalFileProvider) + continue; + paths.Add(physicalFileProvider.Root); + } + throw new NotSupportedException($"Not found!{Environment.NewLine}{string.Join(Environment.NewLine, paths.Distinct())}"); + } + } + private static Models.AppSettings Get(AppSettings? appSettings) { Models.AppSettings result; @@ -40,7 +57,10 @@ public class AppSettings public static Models.AppSettings Get(IConfigurationRoot configurationRoot) { Models.AppSettings result; +#pragma warning disable IL3050, IL2026 AppSettings? appSettings = configurationRoot.Get(); +#pragma warning restore IL3050, IL2026 + PreVerify(configurationRoot, appSettings); result = Get(appSettings); return result; } diff --git a/Mirror-Length/Models/Binder/Configuration.cs b/Mirror-Length/Models/Binder/Configuration.cs index 2cc0080..8ee19b7 100644 --- a/Mirror-Length/Models/Binder/Configuration.cs +++ b/Mirror-Length/Models/Binder/Configuration.cs @@ -7,13 +7,9 @@ namespace View_by_Distance.Mirror.Length.Models.Binder; public class Configuration { -#nullable disable - - public string[] IgnoreExtensions { get; set; } - public Property.Models.Configuration PropertyConfiguration { get; set; } - public string PersonBirthdayFormat { get; set; } - -#nullable restore + public string[]? IgnoreExtensions { get; set; } + public Property.Models.Configuration? PropertyConfiguration { get; set; } + public string? PersonBirthdayFormat { get; set; } public override string ToString() { @@ -21,12 +17,30 @@ public class Configuration return result; } + private static void PreVerify(IConfigurationRoot configurationRoot, Configuration? configuration) + { + if (configuration?.IgnoreExtensions is null) + { + List paths = []; + foreach (IConfigurationProvider configurationProvider in configurationRoot.Providers) + { + if (configurationProvider is not Microsoft.Extensions.Configuration.Json.JsonConfigurationProvider jsonConfigurationProvider) + continue; + if (jsonConfigurationProvider.Source.FileProvider is not Microsoft.Extensions.FileProviders.PhysicalFileProvider physicalFileProvider) + continue; + paths.Add(physicalFileProvider.Root); + } + throw new NotSupportedException($"Not found!{Environment.NewLine}{string.Join(Environment.NewLine, paths.Distinct())}"); + } + } + private static Models.Configuration Get(Configuration? configuration) { Models.Configuration result; if (configuration is null) throw new NullReferenceException(nameof(configuration)); if (configuration.IgnoreExtensions is null) throw new NullReferenceException(nameof(configuration.IgnoreExtensions)); if (configuration.PersonBirthdayFormat is null) throw new NullReferenceException(nameof(configuration.PersonBirthdayFormat)); + if (configuration.PropertyConfiguration is null) throw new NullReferenceException(nameof(configuration.PropertyConfiguration)); result = new( configuration.IgnoreExtensions, configuration.PersonBirthdayFormat, @@ -39,14 +53,19 @@ public class Configuration Models.Configuration result; Configuration? configuration; if (isEnvironment is null) +#pragma warning disable IL3050, IL2026 configuration = configurationRoot.Get(); +#pragma warning restore IL3050, IL2026 else { string environmentName = IsEnvironment.GetEnvironmentName(isEnvironment); string section = string.Concat(environmentName, ":", nameof(Configuration)); IConfigurationSection configurationSection = configurationRoot.GetSection(section); +#pragma warning disable IL3050, IL2026 configuration = configurationSection.Get(); +#pragma warning restore IL3050, IL2026 } + PreVerify(configurationRoot, configuration); result = Get(configuration); return result; } diff --git a/Move-By-Id/Models/Binder/AppSettings.cs b/Move-By-Id/Models/Binder/AppSettings.cs index 6907b44..e38efa2 100644 --- a/Move-By-Id/Models/Binder/AppSettings.cs +++ b/Move-By-Id/Models/Binder/AppSettings.cs @@ -23,6 +23,23 @@ public class AppSettings return result; } + private static void PreVerify(IConfigurationRoot configurationRoot, AppSettings? appSettings) + { + if (appSettings?.Company is null) + { + List paths = []; + foreach (IConfigurationProvider configurationProvider in configurationRoot.Providers) + { + if (configurationProvider is not Microsoft.Extensions.Configuration.Json.JsonConfigurationProvider jsonConfigurationProvider) + continue; + if (jsonConfigurationProvider.Source.FileProvider is not Microsoft.Extensions.FileProviders.PhysicalFileProvider physicalFileProvider) + continue; + paths.Add(physicalFileProvider.Root); + } + throw new NotSupportedException($"Not found!{Environment.NewLine}{string.Join(Environment.NewLine, paths.Distinct())}"); + } + } + private static Models.AppSettings Get(AppSettings? appSettings) { Models.AppSettings result; @@ -44,7 +61,10 @@ public class AppSettings public static Models.AppSettings Get(IConfigurationRoot configurationRoot) { Models.AppSettings result; +#pragma warning disable IL3050, IL2026 AppSettings? appSettings = configurationRoot.Get(); +#pragma warning restore IL3050, IL2026 + PreVerify(configurationRoot, appSettings); result = Get(appSettings); return result; } diff --git a/Move-By-Id/Models/Binder/Configuration.cs b/Move-By-Id/Models/Binder/Configuration.cs index 0e0f992..270af33 100644 --- a/Move-By-Id/Models/Binder/Configuration.cs +++ b/Move-By-Id/Models/Binder/Configuration.cs @@ -7,13 +7,9 @@ namespace View_by_Distance.Move.By.Id.Models.Binder; public class Configuration { -#nullable disable - - public string[] IgnoreExtensions { get; set; } - public Property.Models.Configuration PropertyConfiguration { get; set; } - public string PersonBirthdayFormat { get; set; } - -#nullable restore + public string[]? IgnoreExtensions { get; set; } + public Property.Models.Configuration? PropertyConfiguration { get; set; } + public string? PersonBirthdayFormat { get; set; } public override string ToString() { @@ -21,12 +17,30 @@ public class Configuration return result; } + private static void PreVerify(IConfigurationRoot configurationRoot, Configuration? configuration) + { + if (configuration?.IgnoreExtensions is null) + { + List paths = []; + foreach (IConfigurationProvider configurationProvider in configurationRoot.Providers) + { + if (configurationProvider is not Microsoft.Extensions.Configuration.Json.JsonConfigurationProvider jsonConfigurationProvider) + continue; + if (jsonConfigurationProvider.Source.FileProvider is not Microsoft.Extensions.FileProviders.PhysicalFileProvider physicalFileProvider) + continue; + paths.Add(physicalFileProvider.Root); + } + throw new NotSupportedException($"Not found!{Environment.NewLine}{string.Join(Environment.NewLine, paths.Distinct())}"); + } + } + private static Models.Configuration Get(Configuration? configuration) { Models.Configuration result; if (configuration is null) throw new NullReferenceException(nameof(configuration)); if (configuration.IgnoreExtensions is null) throw new NullReferenceException(nameof(configuration.IgnoreExtensions)); if (configuration.PersonBirthdayFormat is null) throw new NullReferenceException(nameof(configuration.PersonBirthdayFormat)); + if (configuration.PropertyConfiguration is null) throw new NullReferenceException(nameof(configuration.PropertyConfiguration)); result = new( configuration.IgnoreExtensions, configuration.PersonBirthdayFormat, @@ -39,14 +53,19 @@ public class Configuration Models.Configuration result; Configuration? configuration; if (isEnvironment is null) +#pragma warning disable IL3050, IL2026 configuration = configurationRoot.Get(); +#pragma warning restore IL3050, IL2026 else { string environmentName = IsEnvironment.GetEnvironmentName(isEnvironment); string section = string.Concat(environmentName, ":", nameof(Configuration)); IConfigurationSection configurationSection = configurationRoot.GetSection(section); +#pragma warning disable IL3050, IL2026 configuration = configurationSection.Get(); +#pragma warning restore IL3050, IL2026 } + PreVerify(configurationRoot, configuration); result = Get(configuration); return result; } diff --git a/Offset-Date-Time-Original/Models/Binder/AppSettings.cs b/Offset-Date-Time-Original/Models/Binder/AppSettings.cs index f904add..5eb243a 100644 --- a/Offset-Date-Time-Original/Models/Binder/AppSettings.cs +++ b/Offset-Date-Time-Original/Models/Binder/AppSettings.cs @@ -16,6 +16,23 @@ public class AppSettings return result; } + private static void PreVerify(IConfigurationRoot configurationRoot, AppSettings? appSettings) + { + if (appSettings?.Company is null) + { + List paths = []; + foreach (IConfigurationProvider configurationProvider in configurationRoot.Providers) + { + if (configurationProvider is not Microsoft.Extensions.Configuration.Json.JsonConfigurationProvider jsonConfigurationProvider) + continue; + if (jsonConfigurationProvider.Source.FileProvider is not Microsoft.Extensions.FileProviders.PhysicalFileProvider physicalFileProvider) + continue; + paths.Add(physicalFileProvider.Root); + } + throw new NotSupportedException($"Not found!{Environment.NewLine}{string.Join(Environment.NewLine, paths.Distinct())}"); + } + } + private static Models.AppSettings Get(AppSettings? appSettings) { Models.AppSettings result; @@ -36,7 +53,10 @@ public class AppSettings public static Models.AppSettings Get(IConfigurationRoot configurationRoot) { Models.AppSettings result; +#pragma warning disable IL3050, IL2026 AppSettings? appSettings = configurationRoot.Get(); +#pragma warning restore IL3050, IL2026 + PreVerify(configurationRoot, appSettings); result = Get(appSettings); return result; } diff --git a/Offset-Date-Time-Original/Models/Binder/Configuration.cs b/Offset-Date-Time-Original/Models/Binder/Configuration.cs index 0181e88..e7e453b 100644 --- a/Offset-Date-Time-Original/Models/Binder/Configuration.cs +++ b/Offset-Date-Time-Original/Models/Binder/Configuration.cs @@ -7,13 +7,9 @@ namespace View_by_Distance.Offset.Date.Time.Original.Models.Binder; public class Configuration { -#nullable disable - - public string[] IgnoreExtensions { get; set; } - public Property.Models.Configuration PropertyConfiguration { get; set; } - public string PersonBirthdayFormat { get; set; } - -#nullable restore + public string[]? IgnoreExtensions { get; set; } + public Property.Models.Configuration? PropertyConfiguration { get; set; } + public string? PersonBirthdayFormat { get; set; } public override string ToString() { @@ -21,12 +17,30 @@ public class Configuration return result; } + private static void PreVerify(IConfigurationRoot configurationRoot, Configuration? configuration) + { + if (configuration?.IgnoreExtensions is null) + { + List paths = []; + foreach (IConfigurationProvider configurationProvider in configurationRoot.Providers) + { + if (configurationProvider is not Microsoft.Extensions.Configuration.Json.JsonConfigurationProvider jsonConfigurationProvider) + continue; + if (jsonConfigurationProvider.Source.FileProvider is not Microsoft.Extensions.FileProviders.PhysicalFileProvider physicalFileProvider) + continue; + paths.Add(physicalFileProvider.Root); + } + throw new NotSupportedException($"Not found!{Environment.NewLine}{string.Join(Environment.NewLine, paths.Distinct())}"); + } + } + private static Models.Configuration Get(Configuration? configuration) { Models.Configuration result; if (configuration is null) throw new NullReferenceException(nameof(configuration)); if (configuration.IgnoreExtensions is null) throw new NullReferenceException(nameof(configuration.IgnoreExtensions)); if (configuration.PersonBirthdayFormat is null) throw new NullReferenceException(nameof(configuration.PersonBirthdayFormat)); + if (configuration.PropertyConfiguration is null) throw new NullReferenceException(nameof(configuration.PropertyConfiguration)); result = new( configuration.IgnoreExtensions, configuration.PersonBirthdayFormat, @@ -39,14 +53,19 @@ public class Configuration Models.Configuration result; Configuration? configuration; if (isEnvironment is null) +#pragma warning disable IL3050, IL2026 configuration = configurationRoot.Get(); +#pragma warning restore IL3050, IL2026 else { string environmentName = IsEnvironment.GetEnvironmentName(isEnvironment); string section = string.Concat(environmentName, ":", nameof(Configuration)); IConfigurationSection configurationSection = configurationRoot.GetSection(section); +#pragma warning disable IL3050, IL2026 configuration = configurationSection.Get(); +#pragma warning restore IL3050, IL2026 } + PreVerify(configurationRoot, configuration); result = Get(configuration); return result; } diff --git a/PhotoPrism/Models/_F_PhotoPrism.cs b/PhotoPrism/Models/_F_PhotoPrism.cs index b821be4..9b4d055 100644 --- a/PhotoPrism/Models/_F_PhotoPrism.cs +++ b/PhotoPrism/Models/_F_PhotoPrism.cs @@ -169,7 +169,7 @@ public class F_PhotoPrism } } - public static void WriteMatches(string fPhotoPrismContentDirectory, string personBirthdayFormat, float[] rectangleIntersectMinimums, long ticks, ReadOnlyCollection distinctFilteredFaces, Shared.Models.Methods.IMapLogic mapLogic) + public static void WriteMatches(string fPhotoPrismContentDirectory, string personBirthdayFormat, float[] rectangleIntersectMinimums, long ticks, ReadOnlyCollection distinctValidImageFaces, Shared.Models.Methods.IMapLogic mapLogic) { string file; string text; @@ -189,7 +189,7 @@ public class F_PhotoPrism ReadOnlyDictionary>? wholePercentagesToPersonContainers; (MappingFromPhotoPrism MappingFromPhotoPrism, Shared.Models.Marker Marker, float Percent)[] sortedCollection; List<(MappingFromPhotoPrism MappingFromPhotoPrism, Shared.Models.Marker Marker, float Percent)> collection = []; - foreach (Face face in distinctFilteredFaces) + foreach (Face face in distinctValidImageFaces) { collection.Clear(); wholePercentages = face.Mapping?.MappingFromLocation?.WholePercentages; diff --git a/PrepareForOld/Models/Binder/AppSettings.cs b/PrepareForOld/Models/Binder/AppSettings.cs index b5f8b4b..69af755 100644 --- a/PrepareForOld/Models/Binder/AppSettings.cs +++ b/PrepareForOld/Models/Binder/AppSettings.cs @@ -20,6 +20,23 @@ public class AppSettings return result; } + private static void PreVerify(IConfigurationRoot configurationRoot, AppSettings? appSettings) + { + if (appSettings?.Company is null) + { + List paths = []; + foreach (IConfigurationProvider configurationProvider in configurationRoot.Providers) + { + if (configurationProvider is not Microsoft.Extensions.Configuration.Json.JsonConfigurationProvider jsonConfigurationProvider) + continue; + if (jsonConfigurationProvider.Source.FileProvider is not Microsoft.Extensions.FileProviders.PhysicalFileProvider physicalFileProvider) + continue; + paths.Add(physicalFileProvider.Root); + } + throw new NotSupportedException($"Not found!{Environment.NewLine}{string.Join(Environment.NewLine, paths.Distinct())}"); + } + } + private static Models.AppSettings Get(AppSettings? appSettings) { Models.AppSettings result; @@ -36,7 +53,10 @@ public class AppSettings public static Models.AppSettings Get(IConfigurationRoot configurationRoot) { Models.AppSettings result; +#pragma warning disable IL3050, IL2026 AppSettings? appSettings = configurationRoot.Get(); +#pragma warning restore IL3050, IL2026 + PreVerify(configurationRoot, appSettings); result = Get(appSettings); return result; } diff --git a/PrepareForOld/Models/Binder/Configuration.cs b/PrepareForOld/Models/Binder/Configuration.cs index 18ae21a..6d16b76 100644 --- a/PrepareForOld/Models/Binder/Configuration.cs +++ b/PrepareForOld/Models/Binder/Configuration.cs @@ -5,12 +5,8 @@ namespace View_by_Distance.PrepareForOld.Models.Binder; public class Configuration { -#nullable disable - - public Property.Models.Configuration PropertyConfiguration { get; set; } - public string[] Spelling { get; set; } - -#nullable restore + public Property.Models.Configuration? PropertyConfiguration { get; set; } + public string[]? Spelling { get; set; } public override string ToString() { diff --git a/Property/Models/A_Property.cs b/Property/Models/A_Property.cs index af31aea..4cc9d3f 100644 --- a/Property/Models/A_Property.cs +++ b/Property/Models/A_Property.cs @@ -209,7 +209,7 @@ public class A_Property SetAngleBracketCollection(aResultsFullGroupDirectory, sourceDirectory, anyNullOrNoIsUniqueFileName); } - private void SavePropertyParallelWork(int maxDegreeOfParallelism, Shared.Models.Methods.IMetadata metadata, List exceptions, List> sourceDirectoryChanges, Container container, List items, string message) + private void SavePropertyParallelWork(int maxDegreeOfParallelism, Shared.Models.Methods.IMetadata metadata, List exceptions, List> sourceDirectoryChanges, Container container, ReadOnlyCollection items, string message) { List> sourceDirectoryFileTuples = []; ParallelOptions parallelOptions = new() { MaxDegreeOfParallelism = maxDegreeOfParallelism }; diff --git a/Property/Models/Binder/Configuration.cs b/Property/Models/Binder/Configuration.cs index 21fa898..8151bd1 100644 --- a/Property/Models/Binder/Configuration.cs +++ b/Property/Models/Binder/Configuration.cs @@ -39,6 +39,23 @@ public class Configuration return result; } + private static void PreVerify(IConfigurationRoot configurationRoot, Configuration? configuration) + { + if (configuration?.DateGroup is null) + { + List paths = []; + foreach (IConfigurationProvider configurationProvider in configurationRoot.Providers) + { + if (configurationProvider is not Microsoft.Extensions.Configuration.Json.JsonConfigurationProvider jsonConfigurationProvider) + continue; + if (jsonConfigurationProvider.Source.FileProvider is not Microsoft.Extensions.FileProviders.PhysicalFileProvider physicalFileProvider) + continue; + paths.Add(physicalFileProvider.Root); + } + throw new NotSupportedException($"Not found!{Environment.NewLine}{string.Join(Environment.NewLine, paths.Distinct())}"); + } + } + private static Models.Configuration Get(Configuration? configuration) { Models.Configuration result; @@ -101,15 +118,19 @@ public class Configuration Models.Configuration result; Configuration? configuration; if (isEnvironment is null) +#pragma warning disable IL3050, IL2026 configuration = configurationRoot.Get(); +#pragma warning restore IL3050, IL2026 else { string environmentName = IsEnvironment.GetEnvironmentName(isEnvironment); string section = string.Concat(environmentName, ":", nameof(Configuration)); IConfigurationSection configurationSection = configurationRoot.GetSection(section); +#pragma warning disable IL3050, IL2026 configuration = configurationSection.Get(); +#pragma warning restore IL3050, IL2026 } - if (configuration is null) throw new NullReferenceException(nameof(configuration)); + PreVerify(configurationRoot, configuration); result = Get(configuration); return result; } diff --git a/Rename/Models/Binder/AppSettings.cs b/Rename/Models/Binder/AppSettings.cs index e90405c..6dcf383 100644 --- a/Rename/Models/Binder/AppSettings.cs +++ b/Rename/Models/Binder/AppSettings.cs @@ -21,6 +21,23 @@ public class AppSettings return result; } + private static void PreVerify(IConfigurationRoot configurationRoot, AppSettings? appSettings) + { + if (appSettings?.Company is null) + { + List paths = []; + foreach (IConfigurationProvider configurationProvider in configurationRoot.Providers) + { + if (configurationProvider is not Microsoft.Extensions.Configuration.Json.JsonConfigurationProvider jsonConfigurationProvider) + continue; + if (jsonConfigurationProvider.Source.FileProvider is not Microsoft.Extensions.FileProviders.PhysicalFileProvider physicalFileProvider) + continue; + paths.Add(physicalFileProvider.Root); + } + throw new NotSupportedException($"Not found!{Environment.NewLine}{string.Join(Environment.NewLine, paths.Distinct())}"); + } + } + private static Models.AppSettings Get(AppSettings? appSettings) { Models.AppSettings result; @@ -49,6 +66,7 @@ public class AppSettings #pragma warning disable IL3050, IL2026 AppSettings? appSettings = configurationRoot.Get(); #pragma warning restore IL3050, IL2026 + PreVerify(configurationRoot, appSettings); result = Get(appSettings); return result; } diff --git a/Rename/Models/Binder/Configuration.cs b/Rename/Models/Binder/Configuration.cs index ab4030a..b12ca62 100644 --- a/Rename/Models/Binder/Configuration.cs +++ b/Rename/Models/Binder/Configuration.cs @@ -18,6 +18,23 @@ public class Configuration return result; } + private static void PreVerify(IConfigurationRoot configurationRoot, Configuration? configuration) + { + if (configuration?.ForceMetadataLastWriteTimeToCreationTime is null) + { + List paths = []; + foreach (IConfigurationProvider configurationProvider in configurationRoot.Providers) + { + if (configurationProvider is not Microsoft.Extensions.Configuration.Json.JsonConfigurationProvider jsonConfigurationProvider) + continue; + if (jsonConfigurationProvider.Source.FileProvider is not Microsoft.Extensions.FileProviders.PhysicalFileProvider physicalFileProvider) + continue; + paths.Add(physicalFileProvider.Root); + } + throw new NotSupportedException($"Not found!{Environment.NewLine}{string.Join(Environment.NewLine, paths.Distinct())}"); + } + } + private static Models.Configuration Get(Configuration? configuration, Property.Models.Configuration propertyConfiguration) { Models.Configuration result; @@ -39,14 +56,19 @@ public class Configuration Models.Configuration result; Configuration? configuration; if (isEnvironment is null) +#pragma warning disable IL3050, IL2026 configuration = configurationRoot.Get(); +#pragma warning restore IL3050, IL2026 else { string environmentName = IsEnvironment.GetEnvironmentName(isEnvironment); string section = string.Concat(environmentName, ":", nameof(Configuration)); IConfigurationSection configurationSection = configurationRoot.GetSection(section); +#pragma warning disable IL3050, IL2026 configuration = configurationSection.Get(); +#pragma warning restore IL3050, IL2026 } + PreVerify(configurationRoot, configuration); result = Get(configuration, propertyConfiguration); return result; } diff --git a/Set-Created-Date/Models/Binder/AppSettings.cs b/Set-Created-Date/Models/Binder/AppSettings.cs index bd562be..3b52bc4 100644 --- a/Set-Created-Date/Models/Binder/AppSettings.cs +++ b/Set-Created-Date/Models/Binder/AppSettings.cs @@ -21,6 +21,23 @@ public class AppSettings return result; } + private static void PreVerify(IConfigurationRoot configurationRoot, AppSettings? appSettings) + { + if (appSettings?.Company is null) + { + List paths = []; + foreach (IConfigurationProvider configurationProvider in configurationRoot.Providers) + { + if (configurationProvider is not Microsoft.Extensions.Configuration.Json.JsonConfigurationProvider jsonConfigurationProvider) + continue; + if (jsonConfigurationProvider.Source.FileProvider is not Microsoft.Extensions.FileProviders.PhysicalFileProvider physicalFileProvider) + continue; + paths.Add(physicalFileProvider.Root); + } + throw new NotSupportedException($"Not found!{Environment.NewLine}{string.Join(Environment.NewLine, paths.Distinct())}"); + } + } + private static Models.AppSettings Get(AppSettings? appSettings) { Models.AppSettings result; @@ -38,7 +55,10 @@ public class AppSettings public static Models.AppSettings Get(IConfigurationRoot configurationRoot) { Models.AppSettings result; +#pragma warning disable IL3050, IL2026 AppSettings? appSettings = configurationRoot.Get(); +#pragma warning restore IL3050, IL2026 + PreVerify(configurationRoot, appSettings); result = Get(appSettings); return result; } diff --git a/Set-Created-Date/Models/Binder/Configuration.cs b/Set-Created-Date/Models/Binder/Configuration.cs index 603eea1..bd2c821 100644 --- a/Set-Created-Date/Models/Binder/Configuration.cs +++ b/Set-Created-Date/Models/Binder/Configuration.cs @@ -7,13 +7,9 @@ namespace View_by_Distance.Set.Created.Date.Models.Binder; public class Configuration { -#nullable disable - - public string[] IgnoreExtensions { get; set; } - public Property.Models.Configuration PropertyConfiguration { get; set; } - public string PersonBirthdayFormat { get; set; } - -#nullable restore + public string[]? IgnoreExtensions { get; set; } + public Property.Models.Configuration? PropertyConfiguration { get; set; } + public string? PersonBirthdayFormat { get; set; } public override string ToString() { @@ -21,12 +17,30 @@ public class Configuration return result; } + private static void PreVerify(IConfigurationRoot configurationRoot, Configuration? configuration) + { + if (configuration?.IgnoreExtensions is null) + { + List paths = []; + foreach (IConfigurationProvider configurationProvider in configurationRoot.Providers) + { + if (configurationProvider is not Microsoft.Extensions.Configuration.Json.JsonConfigurationProvider jsonConfigurationProvider) + continue; + if (jsonConfigurationProvider.Source.FileProvider is not Microsoft.Extensions.FileProviders.PhysicalFileProvider physicalFileProvider) + continue; + paths.Add(physicalFileProvider.Root); + } + throw new NotSupportedException($"Not found!{Environment.NewLine}{string.Join(Environment.NewLine, paths.Distinct())}"); + } + } + private static Models.Configuration Get(Configuration? configuration) { Models.Configuration result; if (configuration is null) throw new NullReferenceException(nameof(configuration)); if (configuration.IgnoreExtensions is null) throw new NullReferenceException(nameof(configuration.IgnoreExtensions)); if (configuration.PersonBirthdayFormat is null) throw new NullReferenceException(nameof(configuration.PersonBirthdayFormat)); + if (configuration.PropertyConfiguration is null) throw new NullReferenceException(nameof(configuration.PropertyConfiguration)); result = new( configuration.IgnoreExtensions, configuration.PersonBirthdayFormat, @@ -39,14 +53,19 @@ public class Configuration Models.Configuration result; Configuration? configuration; if (isEnvironment is null) +#pragma warning disable IL3050, IL2026 configuration = configurationRoot.Get(); +#pragma warning restore IL3050, IL2026 else { string environmentName = IsEnvironment.GetEnvironmentName(isEnvironment); string section = string.Concat(environmentName, ":", nameof(Configuration)); IConfigurationSection configurationSection = configurationRoot.GetSection(section); +#pragma warning disable IL3050, IL2026 configuration = configurationSection.Get(); +#pragma warning restore IL3050, IL2026 } + PreVerify(configurationRoot, configuration); result = Get(configuration); return result; } diff --git a/Shared/Models/Aggregations.cs b/Shared/Models/Aggregations.cs new file mode 100644 index 0000000..5182aab --- /dev/null +++ b/Shared/Models/Aggregations.cs @@ -0,0 +1,19 @@ +using System.Text.Json.Serialization; + +namespace View_by_Distance.Shared.Models; + +public record Aggregations( + [property: JsonPropertyName("allPeople")] IReadOnlyList AllPeople, + [property: JsonPropertyName("clusterId")] IReadOnlyList ClusterId, + [property: JsonPropertyName("location")] IReadOnlyList Location, + [property: JsonPropertyName("people")] IReadOnlyList People, + [property: JsonPropertyName("things")] IReadOnlyList Things, + [property: JsonPropertyName("time")] IReadOnlyList