diff --git a/Compare/Models/AppSettings.cs b/Compare/Models/AppSettings.cs index bae2431..9aa2f2c 100644 --- a/Compare/Models/AppSettings.cs +++ b/Compare/Models/AppSettings.cs @@ -3,25 +3,21 @@ using System.Text.Json.Serialization; namespace View_by_Distance.Compare.Models; -public class AppSettings +public record AppSettings(string Company, + int MaxDegreeOfParallelism, + string WorkingDirectoryName) { - public string Company { init; get; } - public int MaxDegreeOfParallelism { init; get; } - public string WorkingDirectoryName { init; get; } - - [JsonConstructor] - public AppSettings(string company, int maxDegreeOfParallelism, string workingDirectoryName) - { - Company = company; - MaxDegreeOfParallelism = maxDegreeOfParallelism; - WorkingDirectoryName = workingDirectoryName; - } - public override string ToString() { - string result = JsonSerializer.Serialize(this, new JsonSerializerOptions() { WriteIndented = true }); + string result = JsonSerializer.Serialize(this, AppSettingsSourceGenerationContext.Default.AppSettings); return result; } +} + +[JsonSourceGenerationOptions(WriteIndented = true)] +[JsonSerializable(typeof(AppSettings))] +internal partial class AppSettingsSourceGenerationContext : JsonSerializerContext +{ } \ No newline at end of file diff --git a/Compare/Models/Binder/.editorconfig b/Compare/Models/Binder/.editorconfig new file mode 100644 index 0000000..1c444cd --- /dev/null +++ b/Compare/Models/Binder/.editorconfig @@ -0,0 +1,2 @@ +[*.cs] +csharp_preserve_single_line_statements = true \ No newline at end of file diff --git a/Compare/Models/Binder/Configuration.cs b/Compare/Models/Binder/Configuration.cs index 1fa648f..682bb5f 100644 --- a/Compare/Models/Binder/Configuration.cs +++ b/Compare/Models/Binder/Configuration.cs @@ -1,4 +1,3 @@ -using System.ComponentModel.DataAnnotations; using System.Text.Json; namespace View_by_Distance.Compare.Models.Binder; @@ -7,12 +6,12 @@ public class Configuration { #nullable disable - [Display(Name = "Diff Property Directory"), Required] public string DiffPropertyDirectory { get; set; } - [Display(Name = "Property Configuration"), Required] public Property.Models.Configuration PropertyConfiguration { get; set; } - [Display(Name = "Rename"), Required] public string[] Rename { get; set; } - [Display(Name = "Rename B"), Required] public string[] RenameB { get; set; } - [Display(Name = "Rename C"), Required] public string[] RenameC { get; set; } - [Display(Name = "Spelling"), Required] public string[] Spelling { get; set; } + public string DiffPropertyDirectory { get; set; } + public Property.Models.Configuration PropertyConfiguration { get; set; } + public string[] Rename { get; set; } + public string[] RenameB { get; set; } + public string[] RenameC { get; set; } + public string[] Spelling { get; set; } #nullable restore diff --git a/Compare/Models/Stateless/Configuration.cs b/Compare/Models/Stateless/Configuration.cs index fd93569..33be1f1 100644 --- a/Compare/Models/Stateless/Configuration.cs +++ b/Compare/Models/Stateless/Configuration.cs @@ -16,8 +16,7 @@ public abstract class Configuration Binder.Configuration? configuration = configurationSection.Get(); string json = JsonSerializer.Serialize(configuration, new JsonSerializerOptions() { WriteIndented = true }); result = JsonSerializer.Deserialize(json); - if (result is null) - throw new Exception(json); + if (result is null) throw new Exception(json); string jsonThis = result.ToString(); if (jsonThis != json) { @@ -30,11 +29,10 @@ public abstract class Configuration check = i; break; } - if (check is null) - throw new Exception(); + if (check is null) throw new Exception(); string a = json[..check.Value].Split(',')[^1]; string b = json[check.Value..].Split(',')[0]; - throw new Exception($"{a}{b}"); +throw new Exception($"{a}{b}"); } return result; } diff --git a/Copy-Distinct/Models/Binder/.editorconfig b/Copy-Distinct/Models/Binder/.editorconfig new file mode 100644 index 0000000..1c444cd --- /dev/null +++ b/Copy-Distinct/Models/Binder/.editorconfig @@ -0,0 +1,2 @@ +[*.cs] +csharp_preserve_single_line_statements = true \ No newline at end of file diff --git a/Copy-Distinct/Models/Binder/Configuration.cs b/Copy-Distinct/Models/Binder/Configuration.cs index 32d35fe..ba69497 100644 --- a/Copy-Distinct/Models/Binder/Configuration.cs +++ b/Copy-Distinct/Models/Binder/Configuration.cs @@ -1,6 +1,5 @@ using Microsoft.Extensions.Configuration; using Phares.Shared; -using System.ComponentModel.DataAnnotations; using System.Text.Json; namespace View_by_Distance.Copy.Distinct.Models.Binder; @@ -10,9 +9,9 @@ public class Configuration #nullable disable - [Display(Name = "Ignore Extensions"), Required] public string[] IgnoreExtensions { get; set; } - [Display(Name = "Property Configuration"), Required] public Property.Models.Configuration PropertyConfiguration { get; set; } - [Display(Name = "Person Birthday Format"), Required] public string PersonBirthdayFormat { get; set; } + public string[] IgnoreExtensions { get; set; } + public Property.Models.Configuration PropertyConfiguration { get; set; } + public string PersonBirthdayFormat { get; set; } #nullable restore @@ -25,12 +24,9 @@ public class Configuration 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 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)); result = new( configuration.IgnoreExtensions, configuration.PersonBirthdayFormat, diff --git a/Date-Group/Models/AppSettings.cs b/Date-Group/Models/AppSettings.cs index e30a6e2..8fc4042 100644 --- a/Date-Group/Models/AppSettings.cs +++ b/Date-Group/Models/AppSettings.cs @@ -3,25 +3,21 @@ using System.Text.Json.Serialization; namespace View_by_Distance.Date.Group.Models; -public class AppSettings +public record AppSettings(string Company, + int MaxDegreeOfParallelism, + string WorkingDirectoryName) { - public string Company { init; get; } - public int MaxDegreeOfParallelism { init; get; } - public string WorkingDirectoryName { init; get; } - - [JsonConstructor] - public AppSettings(string company, int maxDegreeOfParallelism, string workingDirectoryName) - { - Company = company; - MaxDegreeOfParallelism = maxDegreeOfParallelism; - WorkingDirectoryName = workingDirectoryName; - } - public override string ToString() { - string result = JsonSerializer.Serialize(this, new JsonSerializerOptions() { WriteIndented = true }); + string result = JsonSerializer.Serialize(this, AppSettingsSourceGenerationContext.Default.AppSettings); return result; } +} + +[JsonSourceGenerationOptions(WriteIndented = true)] +[JsonSerializable(typeof(AppSettings))] +internal partial class AppSettingsSourceGenerationContext : JsonSerializerContext +{ } \ No newline at end of file diff --git a/Date-Group/Models/Binder/.editorconfig b/Date-Group/Models/Binder/.editorconfig new file mode 100644 index 0000000..1c444cd --- /dev/null +++ b/Date-Group/Models/Binder/.editorconfig @@ -0,0 +1,2 @@ +[*.cs] +csharp_preserve_single_line_statements = true \ No newline at end of file diff --git a/Date-Group/Models/Binder/Configuration.cs b/Date-Group/Models/Binder/Configuration.cs index 1c2ca9f..3ee612c 100644 --- a/Date-Group/Models/Binder/Configuration.cs +++ b/Date-Group/Models/Binder/Configuration.cs @@ -1,6 +1,5 @@ using Microsoft.Extensions.Configuration; using Phares.Shared; -using System.ComponentModel.DataAnnotations; using System.Text.Json; namespace View_by_Distance.Date.Group.Models.Binder; @@ -10,13 +9,13 @@ public class Configuration #nullable disable - [Display(Name = "By Create Date Shortcut"), Required] public bool? ByCreateDateShortcut { get; set; } - [Display(Name = "By Date"), Required] public bool? ByDay { get; set; } - [Display(Name = "By Hash"), Required] public bool? ByHash { get; set; } - [Display(Name = "By Season"), Required] public bool? BySeason { get; set; } - [Display(Name = "By Week"), Required] public bool? ByWeek { get; set; } - [Display(Name = "Ignore Subdirectories for Rename"), Required] public bool? KeepFullPath { get; set; } - [Display(Name = "Property Configuration"), Required] public Property.Models.Configuration PropertyConfiguration { get; set; } + 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 @@ -29,20 +28,13 @@ public class Configuration private static Models.Configuration Get(Configuration? configuration) { Models.Configuration result; - if (configuration is null) - throw new NullReferenceException(nameof(configuration)); - 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)); - if (configuration.BySeason is null) - throw new NullReferenceException(nameof(configuration.BySeason)); - if (configuration.ByWeek is null) - throw new NullReferenceException(nameof(configuration.ByWeek)); - if (configuration.KeepFullPath is null) - throw new NullReferenceException(nameof(configuration.KeepFullPath)); + if (configuration is null) throw new NullReferenceException(nameof(configuration)); + 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)); + if (configuration.BySeason is null) throw new NullReferenceException(nameof(configuration.BySeason)); + if (configuration.ByWeek is null) throw new NullReferenceException(nameof(configuration.ByWeek)); + if (configuration.KeepFullPath is null) throw new NullReferenceException(nameof(configuration.KeepFullPath)); result = new( configuration.PropertyConfiguration, configuration.ByCreateDateShortcut.Value, @@ -68,8 +60,7 @@ public class Configuration configuration = configurationSection.Get(); } result = Get(configuration); - if (configuration is null) - throw new NullReferenceException(nameof(configuration)); + if (configuration is null) throw new NullReferenceException(nameof(configuration)); return result; } diff --git a/Delete-By-Relative/Models/AppSettings.cs b/Delete-By-Relative/Models/AppSettings.cs index 1c4eabc..c5960c3 100644 --- a/Delete-By-Relative/Models/AppSettings.cs +++ b/Delete-By-Relative/Models/AppSettings.cs @@ -3,29 +3,23 @@ using System.Text.Json.Serialization; namespace View_by_Distance.Delete.By.Relative.Models; -public class AppSettings +public record AppSettings(string Company, + string CompareRootDirectory, + int MaxDegreeOfParallelism, + string OutputExtension, + string WorkingDirectoryName) { - public string Company { init; get; } - public string CompareRootDirectory { init; get; } - public int MaxDegreeOfParallelism { init; get; } - public string OutputExtension { init; get; } - public string WorkingDirectoryName { init; get; } - - [JsonConstructor] - public AppSettings(string company, string compareRootDirectory, int maxDegreeOfParallelism, string outputExtension, string workingDirectoryName) - { - Company = company; - CompareRootDirectory = compareRootDirectory; - MaxDegreeOfParallelism = maxDegreeOfParallelism; - OutputExtension = outputExtension; - WorkingDirectoryName = workingDirectoryName; - } - public override string ToString() { - string result = JsonSerializer.Serialize(this, new JsonSerializerOptions() { WriteIndented = true }); + string result = JsonSerializer.Serialize(this, AppSettingsSourceGenerationContext.Default.AppSettings); return result; } +} + +[JsonSourceGenerationOptions(WriteIndented = true)] +[JsonSerializable(typeof(AppSettings))] +internal partial class AppSettingsSourceGenerationContext : JsonSerializerContext +{ } \ No newline at end of file diff --git a/Drag-Drop-Explorer/Models/AppSettings.cs b/Drag-Drop-Explorer/Models/AppSettings.cs index e7114a7..b9df620 100644 --- a/Drag-Drop-Explorer/Models/AppSettings.cs +++ b/Drag-Drop-Explorer/Models/AppSettings.cs @@ -3,25 +3,21 @@ using System.Text.Json.Serialization; namespace View_by_Distance.Drag_Drop_Explorer.Models; -public class AppSettings +public record AppSettings(string Company, + int MaxDegreeOfParallelism, + string WorkingDirectoryName) { - public string Company { init; get; } - public int MaxDegreeOfParallelism { init; get; } - public string WorkingDirectoryName { init; get; } - - [JsonConstructor] - public AppSettings(string company, int maxDegreeOfParallelism, string workingDirectoryName) - { - Company = company; - MaxDegreeOfParallelism = maxDegreeOfParallelism; - WorkingDirectoryName = workingDirectoryName; - } - public override string ToString() { - string result = JsonSerializer.Serialize(this, new JsonSerializerOptions() { WriteIndented = true }); + string result = JsonSerializer.Serialize(this, AppSettingsSourceGenerationContext.Default.AppSettings); return result; } +} + +[JsonSourceGenerationOptions(WriteIndented = true)] +[JsonSerializable(typeof(AppSettings))] +internal partial class AppSettingsSourceGenerationContext : JsonSerializerContext +{ } \ No newline at end of file diff --git a/Drag-Drop-Search/Models/AppSettings.cs b/Drag-Drop-Search/Models/AppSettings.cs index 881cc93..92f7566 100644 --- a/Drag-Drop-Search/Models/AppSettings.cs +++ b/Drag-Drop-Search/Models/AppSettings.cs @@ -3,25 +3,21 @@ using System.Text.Json.Serialization; namespace View_by_Distance.Drag_Drop.Models; -public class AppSettings +public record AppSettings(string Company, + int MaxDegreeOfParallelism, + string WorkingDirectoryName) { - public string Company { init; get; } - public int MaxDegreeOfParallelism { init; get; } - public string WorkingDirectoryName { init; get; } - - [JsonConstructor] - public AppSettings(string company, int maxDegreeOfParallelism, string workingDirectoryName) - { - Company = company; - MaxDegreeOfParallelism = maxDegreeOfParallelism; - WorkingDirectoryName = workingDirectoryName; - } - public override string ToString() { - string result = JsonSerializer.Serialize(this, new JsonSerializerOptions() { WriteIndented = true }); + string result = JsonSerializer.Serialize(this, AppSettingsSourceGenerationContext.Default.AppSettings); return result; } +} + +[JsonSourceGenerationOptions(WriteIndented = true)] +[JsonSerializable(typeof(AppSettings))] +internal partial class AppSettingsSourceGenerationContext : JsonSerializerContext +{ } \ No newline at end of file diff --git a/Drag-Drop-Search/Models/Binder/.editorconfig b/Drag-Drop-Search/Models/Binder/.editorconfig new file mode 100644 index 0000000..1c444cd --- /dev/null +++ b/Drag-Drop-Search/Models/Binder/.editorconfig @@ -0,0 +1,2 @@ +[*.cs] +csharp_preserve_single_line_statements = true \ No newline at end of file diff --git a/Drag-Drop-Search/Models/Binder/Configuration.cs b/Drag-Drop-Search/Models/Binder/Configuration.cs index d9ecf18..cd3ee94 100644 --- a/Drag-Drop-Search/Models/Binder/Configuration.cs +++ b/Drag-Drop-Search/Models/Binder/Configuration.cs @@ -1,6 +1,5 @@ using Microsoft.Extensions.Configuration; using Phares.Shared; -using System.ComponentModel.DataAnnotations; using System.Text.Json; namespace View_by_Distance.Drag_Drop.Models.Binder; @@ -10,45 +9,45 @@ public class Configuration #nullable disable - [Display(Name = "Check D Face and Up Dates"), Required] public bool? CheckDFaceAndUpWriteDates { get; set; } - [Display(Name = "Check Json For Distance Results"), Required] public bool? CheckJsonForDistanceResults { get; set; } - [Display(Name = "CrossDirectory Max Items In Distance Collection"), Required] public int? CrossDirectoryMaxItemsInDistanceCollection { get; set; } - [Display(Name = "Distance Factor"), Required] public int? DistanceFactor { get; set; } - [Display(Name = "Force Face Last Write Time to Creation Time"), Required] public bool? ForceFaceLastWriteTimeToCreationTime { get; set; } - [Display(Name = "Force Metadata Last Write Time to Creation Time"), Required] public bool? ForceMetadataLastWriteTimeToCreationTime { get; set; } - [Display(Name = "Force Resize Last Write Time to Creation Time"), Required] public bool? ForceResizeLastWriteTimeToCreationTime { get; set; } - [Display(Name = "Ignore Extensions"), Required] public string[] IgnoreExtensions { get; set; } - [Display(Name = "Julie Phares Copy Birthdays"), Required] public string[] JLinks { get; set; } - [Display(Name = "Load Or Create Then Save Distance Results"), Required] public string[] LoadOrCreateThenSaveDistanceResultsForOutputResolutions { get; set; } - [Display(Name = "Load Or Create Then Save Image Faces Results"), Required] public string[] LoadOrCreateThenSaveImageFacesResultsForOutputResolutions { get; set; } - [Display(Name = "Mixed Year Relative Paths"), Required] public string[] MixedYearRelativePaths { get; set; } - [Display(Name = "Model Directory"), Required] public string ModelDirectory { get; set; } - [Display(Name = "Model Name"), Required] public string ModelName { get; set; } - [Display(Name = "Number Jitters"), Required] public int? NumberOfJitters { get; set; } - [Display(Name = "Number of Times To Up Sample"), Required] public int? NumberOfTimesToUpsample { get; set; } - [Display(Name = "Output Extension"), Required] public string OutputExtension { get; set; } - [Display(Name = "Output Quality"), Required] public int? OutputQuality { get; set; } - [Display(Name = "Output Resolutions"), Required] public string[] OutputResolutions { get; set; } - [Display(Name = "Override For Face Images"), Required] public bool? OverrideForFaceImages { get; set; } - [Display(Name = "Override For Face Landmark Images"), Required] public bool? OverrideForFaceLandmarkImages { get; set; } - [Display(Name = "Override For Resize Images"), Required] public bool? OverrideForResizeImages { get; set; } - [Display(Name = "Person Birthday Format"), Required] public string PersonBirthdayFormat { get; set; } - [Display(Name = "Predictor Model Name"), Required] public string PredictorModelName { get; set; } - [Display(Name = "Properties Changed For Distance"), Required] public bool? PropertiesChangedForDistance { get; set; } - [Display(Name = "Properties Changed For Faces"), Required] public bool? PropertiesChangedForFaces { get; set; } - [Display(Name = "Properties Changed For Index"), Required] public bool? PropertiesChangedForIndex { get; set; } - [Display(Name = "Properties Changed For Metadata"), Required] public bool? PropertiesChangedForMetadata { get; set; } - [Display(Name = "Properties Changed For Resize"), Required] public bool? PropertiesChangedForResize { get; set; } - [Display(Name = "Property Configuration"), Required] public Property.Models.Configuration PropertyConfiguration { get; set; } - [Display(Name = "Reverse"), Required] public bool? Reverse { get; set; } - [Display(Name = "Save Face Landmark For Output Resolutions"), Required] public string[] SaveFaceLandmarkForOutputResolutions { get; set; } - [Display(Name = "Save Full Year Of Random Files"), Required] public bool? SaveFullYearOfRandomFiles { get; set; } - [Display(Name = "Save Resized Images by Person Key Formatted"), Required] public string[] SaveFilteredOriginalImagesFromJLinksForOutputResolutions { get; set; } - [Display(Name = "Save Shortcuts"), Required] public string[] SaveShortcutsForOutputResolutions { get; set; } - [Display(Name = "Save Resized Subfiles"), Required] public bool? SaveResizedSubfiles { get; set; } - [Display(Name = "Skip Search"), Required] public bool? SkipSearch { get; set; } - [Display(Name = "Test Distance Results"), Required] public bool? TestDistanceResults { get; set; } - [Display(Name = "Valid Resolutions"), Required] public string[] ValidResolutions { get; set; } + public bool? CheckDFaceAndUpWriteDates { get; set; } + public bool? CheckJsonForDistanceResults { get; set; } + public int? CrossDirectoryMaxItemsInDistanceCollection { get; set; } + public int? DistanceFactor { get; set; } + 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 int? NumberOfJitters { get; set; } + public int? NumberOfTimesToUpsample { get; set; } + public string OutputExtension { get; set; } + public int? OutputQuality { 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 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 bool? Reverse { get; set; } + public string[] SaveFaceLandmarkForOutputResolutions { get; set; } + public bool? SaveFullYearOfRandomFiles { 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 @@ -61,69 +60,40 @@ public class Configuration private static Models.Configuration Get(Configuration? configuration) { Models.Configuration result; - if (configuration is null) - throw new NullReferenceException(nameof(configuration)); - 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)); - if (configuration.DistanceFactor is null) - throw new NullReferenceException(nameof(configuration.DistanceFactor)); - 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.IgnoreExtensions is null) - throw new NullReferenceException(nameof(configuration.IgnoreExtensions)); + if (configuration is null) throw new NullReferenceException(nameof(configuration)); + 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)); + if (configuration.DistanceFactor is null) throw new NullReferenceException(nameof(configuration.DistanceFactor)); + 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.IgnoreExtensions is null) throw new NullReferenceException(nameof(configuration.IgnoreExtensions)); configuration.LoadOrCreateThenSaveDistanceResultsForOutputResolutions ??= Array.Empty(); configuration.LoadOrCreateThenSaveImageFacesResultsForOutputResolutions ??= Array.Empty(); - if (configuration.MixedYearRelativePaths is null) - throw new NullReferenceException(nameof(configuration.MixedYearRelativePaths)); - if (configuration.NumberOfJitters is null) - throw new NullReferenceException(nameof(configuration.NumberOfJitters)); - if (configuration.NumberOfTimesToUpsample is null) - throw new NullReferenceException(nameof(configuration.NumberOfTimesToUpsample)); - 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.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)); - if (configuration.PropertiesChangedForMetadata is null) - throw new NullReferenceException(nameof(configuration.PropertiesChangedForMetadata)); - if (configuration.PropertiesChangedForResize is null) - throw new NullReferenceException(nameof(configuration.PropertiesChangedForResize)); - if (configuration.Reverse is null) - throw new NullReferenceException(nameof(configuration.Reverse)); + if (configuration.MixedYearRelativePaths is null) throw new NullReferenceException(nameof(configuration.MixedYearRelativePaths)); + if (configuration.NumberOfJitters is null) throw new NullReferenceException(nameof(configuration.NumberOfJitters)); + if (configuration.NumberOfTimesToUpsample is null) throw new NullReferenceException(nameof(configuration.NumberOfTimesToUpsample)); + 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.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)); + if (configuration.PropertiesChangedForMetadata is null) throw new NullReferenceException(nameof(configuration.PropertiesChangedForMetadata)); + if (configuration.PropertiesChangedForResize is null) throw new NullReferenceException(nameof(configuration.PropertiesChangedForResize)); + if (configuration.Reverse is null) throw new NullReferenceException(nameof(configuration.Reverse)); configuration.SaveFaceLandmarkForOutputResolutions ??= Array.Empty(); - if (configuration.SaveFullYearOfRandomFiles is null) - throw new NullReferenceException(nameof(configuration.SaveFullYearOfRandomFiles)); + if (configuration.SaveFullYearOfRandomFiles is null) throw new NullReferenceException(nameof(configuration.SaveFullYearOfRandomFiles)); configuration.SaveFilteredOriginalImagesFromJLinksForOutputResolutions ??= Array.Empty(); - if (configuration.SaveResizedSubfiles is null) - throw new NullReferenceException(nameof(configuration.SaveResizedSubfiles)); + if (configuration.SaveResizedSubfiles is null) throw new NullReferenceException(nameof(configuration.SaveResizedSubfiles)); configuration.SaveShortcutsForOutputResolutions ??= Array.Empty(); - if (configuration.SkipSearch is null) - throw new NullReferenceException(nameof(configuration.SkipSearch)); - if (configuration.TestDistanceResults is null) - throw new NullReferenceException(nameof(configuration.TestDistanceResults)); - if (configuration.ValidResolutions is null) - throw new NullReferenceException(nameof(configuration.ValidResolutions)); + if (configuration.SkipSearch is null) throw new NullReferenceException(nameof(configuration.SkipSearch)); + if (configuration.TestDistanceResults is null) throw new NullReferenceException(nameof(configuration.TestDistanceResults)); + if (configuration.ValidResolutions is null) throw new NullReferenceException(nameof(configuration.ValidResolutions)); result = new(configuration.PropertyConfiguration, configuration.CheckDFaceAndUpWriteDates.Value, configuration.CheckJsonForDistanceResults.Value, diff --git a/Drag-Drop-Set-Property-Item/DragDropSetPropertyItem.cs b/Drag-Drop-Set-Property-Item/DragDropSetPropertyItem.cs index 13f97f6..158cc67 100644 --- a/Drag-Drop-Set-Property-Item/DragDropSetPropertyItem.cs +++ b/Drag-Drop-Set-Property-Item/DragDropSetPropertyItem.cs @@ -59,6 +59,7 @@ public partial class DragDropSetPropertyItem : Form Log.Logger = loggerConfiguration.CreateLogger(); logger = Log.ForContext(); Property.Models.Configuration propertyConfiguration = Property.Models.Binder.Configuration.Get(isEnvironment, configurationRoot); + Property.Models.Configuration.Verify(propertyConfiguration, requireExist: false); _PropertyConfiguration = propertyConfiguration; logger.Information("Complete"); _Logger = logger; @@ -169,7 +170,7 @@ public partial class DragDropSetPropertyItem : Form { if (record.PropertyItemType is not null && record.PropertyItemType.Value != type) throw new NotSupportedException(); - if ((record.DateTimeOriginal is null || !string.IsNullOrEmpty(record.Value) || record.Value == setTo) && !_AppSettings.IgnoreRulesKeyWords.Contains(setTo)) + if ((record.DateTimeOriginal is null || !string.IsNullOrEmpty(record.Value) || record.Value == setTo) && !_PropertyConfiguration.IgnoreRulesKeyWords.Contains(setTo)) continue; checkFile = $"{record.FileHolder.FullName}.exif"; propertyItem = Property.Models.Stateless.IProperty.GetPropertyItem(constructorInfo, tagId, type, setTo); diff --git a/Drag-Drop-Set-Property-Item/Models/AppSettings.cs b/Drag-Drop-Set-Property-Item/Models/AppSettings.cs index bcf392f..b6606e3 100644 --- a/Drag-Drop-Set-Property-Item/Models/AppSettings.cs +++ b/Drag-Drop-Set-Property-Item/Models/AppSettings.cs @@ -3,7 +3,6 @@ using System.Text.Json; namespace View_by_Distance.Drag.Drop.Set.Item.Models; public record AppSettings(string Company, - string[] IgnoreRulesKeyWords, int MaxDegreeOfParallelism, string[] ValidKeyWords, string WorkingDirectoryName) diff --git a/Drag-Drop-Set-Property-Item/Models/Binder/.editorconfig b/Drag-Drop-Set-Property-Item/Models/Binder/.editorconfig new file mode 100644 index 0000000..1c444cd --- /dev/null +++ b/Drag-Drop-Set-Property-Item/Models/Binder/.editorconfig @@ -0,0 +1,2 @@ +[*.cs] +csharp_preserve_single_line_statements = true \ No newline at end of file diff --git a/Drag-Drop-Set-Property-Item/Models/Binder/AppSettings.cs b/Drag-Drop-Set-Property-Item/Models/Binder/AppSettings.cs index 188d65f..1ba9c25 100644 --- a/Drag-Drop-Set-Property-Item/Models/Binder/AppSettings.cs +++ b/Drag-Drop-Set-Property-Item/Models/Binder/AppSettings.cs @@ -7,7 +7,6 @@ public class AppSettings { public string? Company { get; set; } - public string[]? IgnoreRulesKeyWords { get; set; } public int? MaxDegreeOfParallelism { get; set; } public string[]? ValidKeyWords { get; set; } public string? WorkingDirectoryName { get; set; } @@ -21,19 +20,12 @@ public class AppSettings private static Models.AppSettings Get(AppSettings? appSettings) { Models.AppSettings result; - if (appSettings?.Company is null) - throw new NullReferenceException(nameof(appSettings.Company)); - if (appSettings?.IgnoreRulesKeyWords is null) - throw new NullReferenceException(nameof(appSettings.IgnoreRulesKeyWords)); - if (appSettings?.MaxDegreeOfParallelism is null) - throw new NullReferenceException(nameof(appSettings.MaxDegreeOfParallelism)); - if (appSettings?.ValidKeyWords is null) - throw new NullReferenceException(nameof(appSettings.ValidKeyWords)); - if (appSettings?.WorkingDirectoryName is null) - throw new NullReferenceException(nameof(appSettings.WorkingDirectoryName)); + if (appSettings?.Company is null) throw new NullReferenceException(nameof(appSettings.Company)); + if (appSettings?.MaxDegreeOfParallelism is null) throw new NullReferenceException(nameof(appSettings.MaxDegreeOfParallelism)); + if (appSettings?.ValidKeyWords is null) throw new NullReferenceException(nameof(appSettings.ValidKeyWords)); + if (appSettings?.WorkingDirectoryName is null) throw new NullReferenceException(nameof(appSettings.WorkingDirectoryName)); result = new( appSettings.Company, - appSettings.IgnoreRulesKeyWords, appSettings.MaxDegreeOfParallelism.Value, appSettings.ValidKeyWords, appSettings.WorkingDirectoryName diff --git a/Duplicate-Search/Models/AppSettings.cs b/Duplicate-Search/Models/AppSettings.cs index 16a287b..f7217de 100644 --- a/Duplicate-Search/Models/AppSettings.cs +++ b/Duplicate-Search/Models/AppSettings.cs @@ -3,31 +3,24 @@ using System.Text.Json.Serialization; namespace View_by_Distance.Duplicate.Search.Models; -public class AppSettings +public record AppSettings(string Company, + bool IndexOnly, + int MaxDegreeOfParallelism, + string OutputExtension, + bool Reverse, + string WorkingDirectoryName) { - public string Company { init; get; } - public bool IndexOnly { init; get; } - public int MaxDegreeOfParallelism { init; get; } - public string OutputExtension { init; get; } - public bool Reverse { init; get; } - public string WorkingDirectoryName { init; get; } - - [JsonConstructor] - public AppSettings(string company, bool indexOnly, int maxDegreeOfParallelism, string outputExtension, bool reverse, string workingDirectoryName) - { - Company = company; - IndexOnly = indexOnly; - MaxDegreeOfParallelism = maxDegreeOfParallelism; - OutputExtension = outputExtension; - Reverse = reverse; - WorkingDirectoryName = workingDirectoryName; - } - public override string ToString() { - string result = JsonSerializer.Serialize(this, new JsonSerializerOptions() { WriteIndented = true }); + string result = JsonSerializer.Serialize(this, AppSettingsSourceGenerationContext.Default.AppSettings); return result; } +} + +[JsonSourceGenerationOptions(WriteIndented = true)] +[JsonSerializable(typeof(AppSettings))] +internal partial class AppSettingsSourceGenerationContext : JsonSerializerContext +{ } \ No newline at end of file diff --git a/Instance/DlibDotNet.cs b/Instance/DlibDotNet.cs index 6bd28dd..1ddfd4f 100644 --- a/Instance/DlibDotNet.cs +++ b/Instance/DlibDotNet.cs @@ -933,7 +933,6 @@ public partial class DlibDotNet Shared.Models.Property? property; List parseExceptions = new(); List> subFileTuples = new(); - List> metadataCollection; string[] changesFrom = new string[] { nameof(A_Property) }; FileHolder resizedFileHolder = _Resize.GetResizedFileHolder(cResultsFullGroupDirectory, item, outputResolutionHasNumber); ReadOnlyCollection> locationContainers = mapLogic.GetLocationContainers(item); @@ -966,7 +965,7 @@ public partial class DlibDotNet subFileTuples.Add(new Tuple(nameof(A_Property), item.SourceDirectoryFileHolder.LastWriteTime.Value)); else subFileTuples.Add(new Tuple(nameof(A_Property), new FileInfo(item.SourceDirectoryFileHolder.FullName).LastWriteTime)); - int sortOrderOnlyLengthIndex = IDirectory.GetSortOrderOnlyLengthIndex(); + int sortOrderOnlyLengthIndex = IDirectory.GetSortOrderOnlyLengthIndex(_Configuration.PropertyConfiguration.Offset); bool nameWithoutExtensionIsIdFormat = Shared.Models.Stateless.Methods.IProperty.NameWithoutExtensionIsIdFormat(item.ImageFileHolder); bool nameWithoutExtensionIsPaddedIdFormat = IDirectory.NameWithoutExtensionIsPaddedIdFormat(item.ImageFileHolder, sortOrderOnlyLengthIndex); if (nameWithoutExtensionIsIdFormat && item.ImageFileHolder.NameWithoutExtension != item.Property.Id.ToString()) @@ -985,10 +984,32 @@ public partial class DlibDotNet item.SetResizedFileHolder(_Resize.FileNameExtension, resizedFileHolder); MappingFromItem mappingFromItem = IMappingFromItem.GetMappingFromItem(containerDateTimes, item, resizedFileHolder); Map.Models.Stateless.Methods.IMapLogic.SetCreationTimeMaybeMoveToDecade(_Configuration.PropertyConfiguration, _Configuration.MoveToDecade && _Configuration.LocationContainerDistanceTolerance is null, mappingFromItem, locationContainers); - (int metadataGroups, metadataCollection) = metadata.GetMetadataCollection(subFileTuples, parseExceptions, changesFrom, mappingFromItem); + ReadOnlyDictionary metadataExtractorDirectories = metadata.GetMetadataCollection(subFileTuples, parseExceptions, changesFrom, mappingFromItem); if (_AppSettings.MaxDegreeOfParallelism < 2) ticks = LogDelta(ticks, nameof(B_Metadata.GetMetadataCollection)); - Dictionary outputResolutionToResize = _Resize.GetResizeKeyValuePairs(_Configuration.PropertyConfiguration, cResultsFullGroupDirectory, subFileTuples, parseExceptions, metadataCollection, item.Property, mappingFromItem); + if (_AppSettings.Places.Count > 0) + { + float latitude; + float longitude; + double? distance; + MetadataExtractor.GeoLocation? geoLocation = Metadata.Models.Stateless.Methods.IMetadata.GeoLocation(metadataExtractorDirectories); + foreach (Place place in _AppSettings.Places) + { + if (geoLocation is null) + continue; + latitude = Math.Abs(place.Latitude.Degrees) + (place.Latitude.Minutes / 60) + (place.Latitude.Seconds / 3600); + if (place.Latitude.Degrees < 0) + latitude *= -1; + longitude = Math.Abs(place.Longitude.Degrees) + (place.Longitude.Minutes / 60) + (place.Longitude.Seconds / 3600); + if (place.Longitude.Degrees < 0) + longitude *= -1; + distance = geoLocation is null ? null : Metadata.Models.Stateless.Methods.IMetadata.GetDistance(latitude, longitude, geoLocation.Latitude, geoLocation.Longitude); + if (distance is null or > 3) + continue; + distance += 1; + } + } + Dictionary outputResolutionToResize = _Resize.GetResizeKeyValuePairs(_Configuration.PropertyConfiguration, cResultsFullGroupDirectory, subFileTuples, parseExceptions, item.Property, mappingFromItem); if (_AppSettings.MaxDegreeOfParallelism < 2) ticks = LogDelta(ticks, nameof(C_Resize.GetResizeKeyValuePairs)); if (_Configuration.SaveResizedSubfiles) diff --git a/Instance/Models/AppSettings.cs b/Instance/Models/AppSettings.cs index c39cbfd..f23368d 100644 --- a/Instance/Models/AppSettings.cs +++ b/Instance/Models/AppSettings.cs @@ -1,3 +1,4 @@ +using System.Collections.ObjectModel; using System.Text.Json; using System.Text.Json.Serialization; @@ -5,6 +6,7 @@ namespace View_by_Distance.Instance.Models; public record AppSettings(string Company, int MaxDegreeOfParallelism, + ReadOnlyCollection Places, string WorkingDirectoryName) { diff --git a/Instance/Models/Binder/AppSettings.cs b/Instance/Models/Binder/AppSettings.cs index b418c20..8a21406 100644 --- a/Instance/Models/Binder/AppSettings.cs +++ b/Instance/Models/Binder/AppSettings.cs @@ -1,4 +1,5 @@ using Microsoft.Extensions.Configuration; +using System.Collections.ObjectModel; using System.Text.Json; using System.Text.Json.Serialization; @@ -9,6 +10,7 @@ public class AppSettings public string? Company { get; set; } public int? MaxDegreeOfParallelism { get; set; } + public string[]? Places { get; set; } public string? WorkingDirectoryName { get; set; } public override string ToString() @@ -22,10 +24,13 @@ public class AppSettings Models.AppSettings result; if (appSettings?.Company is null) throw new NullReferenceException(nameof(appSettings.Company)); if (appSettings?.MaxDegreeOfParallelism is null) throw new NullReferenceException(nameof(appSettings.MaxDegreeOfParallelism)); + // if (appSettings?.Places is null) throw new NullReferenceException(nameof(appSettings.Places)); if (appSettings?.WorkingDirectoryName is null) throw new NullReferenceException(nameof(appSettings.WorkingDirectoryName)); + ReadOnlyCollection places = Place.GetPlaces(appSettings.Places); result = new( appSettings.Company, appSettings.MaxDegreeOfParallelism.Value, + places, appSettings.WorkingDirectoryName ); return result; diff --git a/Instance/Models/Binder/DegreesMinutesSeconds.cs b/Instance/Models/Binder/DegreesMinutesSeconds.cs new file mode 100644 index 0000000..f98a8d3 --- /dev/null +++ b/Instance/Models/Binder/DegreesMinutesSeconds.cs @@ -0,0 +1,25 @@ +using System.Text.Json; +using System.Text.Json.Serialization; + +namespace View_by_Distance.Instance.Models.Binder; + +public class DegreesMinutesSeconds +{ + + public float? Degrees { get; set; } + public float? Minutes { get; set; } + public float? Seconds { get; set; } + + public override string ToString() + { + string result = JsonSerializer.Serialize(this, BinderDegreesMinutesSecondsSourceGenerationContext.Default.DegreesMinutesSeconds); + return result; + } + +} + +[JsonSourceGenerationOptions(WriteIndented = true)] +[JsonSerializable(typeof(DegreesMinutesSeconds))] +internal partial class BinderDegreesMinutesSecondsSourceGenerationContext : JsonSerializerContext +{ +} \ No newline at end of file diff --git a/Instance/Models/Binder/Place.cs b/Instance/Models/Binder/Place.cs new file mode 100644 index 0000000..8daaf76 --- /dev/null +++ b/Instance/Models/Binder/Place.cs @@ -0,0 +1,66 @@ +using System.Collections.ObjectModel; +using System.Text.Json; +using System.Text.Json.Serialization; + +namespace View_by_Distance.Instance.Models.Binder; + +public class Place +{ + + public string? Title { get; set; } + public DegreesMinutesSeconds? Latitude { get; set; } + public DegreesMinutesSeconds? Longitude { get; set; } + + public override string ToString() + { + string result = JsonSerializer.Serialize(this, BinderPlaceSourceGenerationContext.Default.Place); + return result; + } + + private static Models.Place Get(Place? Place) + { + Models.Place result; + Models.DegreesMinutesSeconds latitude; + Models.DegreesMinutesSeconds longitude; + if (Place is null) throw new NullReferenceException(nameof(Place)); + if (Place.Title is null) throw new NullReferenceException(nameof(Place.Title)); + if (Place.Latitude is null) throw new NullReferenceException(nameof(Place.Latitude)); + if (Place.Latitude.Degrees is null) throw new NullReferenceException(nameof(Place.Latitude.Degrees)); + if (Place.Latitude.Minutes is null) throw new NullReferenceException(nameof(Place.Latitude.Minutes)); + if (Place.Latitude.Seconds is null) throw new NullReferenceException(nameof(Place.Latitude.Seconds)); + if (Place.Longitude is null) throw new NullReferenceException(nameof(Place.Longitude)); + latitude = new(Place.Latitude.Degrees.Value, Place.Latitude.Minutes.Value, Place.Latitude.Seconds.Value); + if (Place.Longitude.Degrees is null) throw new NullReferenceException(nameof(Place.Longitude.Degrees)); + if (Place.Longitude.Minutes is null) throw new NullReferenceException(nameof(Place.Longitude.Minutes)); + if (Place.Longitude.Seconds is null) throw new NullReferenceException(nameof(Place.Longitude.Seconds)); + longitude = new(Place.Longitude.Degrees.Value, Place.Longitude.Minutes.Value, Place.Longitude.Seconds.Value); + result = new( + Place.Title, + latitude, + longitude + ); + return result; + } + + internal static ReadOnlyCollection GetPlaces(string[]? places) + { + List results = new(); + if (places is not null) + { + Place? place; + foreach (string jsonElement in places) + { + place = JsonSerializer.Deserialize(jsonElement, BinderPlaceSourceGenerationContext.Default.Place); + results.Add(Get(place)); + } + } + return new(results); + } + +} + +[JsonSourceGenerationOptions(WriteIndented = true)] +[JsonSerializable(typeof(Place))] +internal partial class BinderPlaceSourceGenerationContext : JsonSerializerContext +{ +} \ No newline at end of file diff --git a/Instance/Models/DegreesMinutesSeconds.cs b/Instance/Models/DegreesMinutesSeconds.cs new file mode 100644 index 0000000..69fc208 --- /dev/null +++ b/Instance/Models/DegreesMinutesSeconds.cs @@ -0,0 +1,23 @@ +using System.Text.Json; +using System.Text.Json.Serialization; + +namespace View_by_Distance.Instance.Models; + +public record DegreesMinutesSeconds(float Degrees, + float Minutes, + float Seconds) +{ + + public override string ToString() + { + string result = JsonSerializer.Serialize(this, DegreesMinutesSecondsSourceGenerationContext.Default.DegreesMinutesSeconds); + return result; + } + +} + +[JsonSourceGenerationOptions(WriteIndented = true)] +[JsonSerializable(typeof(DegreesMinutesSeconds))] +internal partial class DegreesMinutesSecondsSourceGenerationContext : JsonSerializerContext +{ +} \ No newline at end of file diff --git a/Instance/Models/Place.cs b/Instance/Models/Place.cs new file mode 100644 index 0000000..2bdd295 --- /dev/null +++ b/Instance/Models/Place.cs @@ -0,0 +1,23 @@ +using System.Text.Json; +using System.Text.Json.Serialization; + +namespace View_by_Distance.Instance.Models; + +public record Place(string Title, + DegreesMinutesSeconds Latitude, + DegreesMinutesSeconds Longitude) +{ + + public override string ToString() + { + string result = JsonSerializer.Serialize(this, PlaceSourceGenerationContext.Default.Place); + return result; + } + +} + +[JsonSourceGenerationOptions(WriteIndented = true)] +[JsonSerializable(typeof(Place))] +internal partial class PlaceSourceGenerationContext : JsonSerializerContext +{ +} \ No newline at end of file diff --git a/Map/Models/MapLogic.cs b/Map/Models/MapLogic.cs index 3d549ff..bdf29ca 100644 --- a/Map/Models/MapLogic.cs +++ b/Map/Models/MapLogic.cs @@ -1343,14 +1343,14 @@ public partial class MapLogic : Shared.Models.Methods.IMapLogic string? directoryName; List distinctFilteredIds = IContainer.GetFilteredDistinctIds(propertyConfiguration, containers); LookForAbandoned(propertyConfiguration, distinctFilteredIds); - Stateless.LookForAbandonedLogic.LookForAbandoned(bResultsFullGroupDirectory, distinctFilteredIds); + Stateless.LookForAbandonedLogic.LookForAbandoned(propertyConfiguration, bResultsFullGroupDirectory, distinctFilteredIds); directories = Directory.GetDirectories(cResultsFullGroupDirectory, "*", SearchOption.TopDirectoryOnly); foreach (string directory in directories) { directoryName = Path.GetFileName(directory); if (string.IsNullOrEmpty(directoryName) || directoryName.Length != 2 && directoryName.Length != 4) continue; - Stateless.LookForAbandonedLogic.LookForAbandoned(distinctFilteredIds, directory, directoryName); + Stateless.LookForAbandonedLogic.LookForAbandoned(propertyConfiguration, distinctFilteredIds, directory, directoryName); } directories = Directory.GetDirectories(dResultsFullGroupDirectory, "*", SearchOption.TopDirectoryOnly); foreach (string directory in directories) @@ -1358,7 +1358,7 @@ public partial class MapLogic : Shared.Models.Methods.IMapLogic directoryName = Path.GetFileName(directory); if (string.IsNullOrEmpty(directoryName) || directoryName.Length != 2 && directoryName.Length != 4) continue; - Stateless.LookForAbandonedLogic.LookForAbandoned(distinctFilteredIds, directory, directoryName); + Stateless.LookForAbandonedLogic.LookForAbandoned(propertyConfiguration, distinctFilteredIds, directory, directoryName); } directories = Directory.GetDirectories(d2ResultsFullGroupDirectory, "*", SearchOption.TopDirectoryOnly); foreach (string directory in directories) @@ -1366,7 +1366,7 @@ public partial class MapLogic : Shared.Models.Methods.IMapLogic directoryName = Path.GetFileName(directory); if (string.IsNullOrEmpty(directoryName) || directoryName.Length != 2 && directoryName.Length != 4) continue; - Stateless.LookForAbandonedLogic.LookForAbandoned(distinctFilteredIds, directory, directoryName); + Stateless.LookForAbandonedLogic.LookForAbandoned(propertyConfiguration, distinctFilteredIds, directory, directoryName); } } diff --git a/Map/Models/Stateless/LookForAbandonedLogic.cs b/Map/Models/Stateless/LookForAbandonedLogic.cs index fa588cd..da59b16 100644 --- a/Map/Models/Stateless/LookForAbandonedLogic.cs +++ b/Map/Models/Stateless/LookForAbandonedLogic.cs @@ -3,15 +3,15 @@ using View_by_Distance.Shared.Models.Stateless.Methods; namespace View_by_Distance.Map.Models.Stateless; internal abstract class LookForAbandonedLogic -{ +{ - internal static void LookForAbandoned(List distinctFilteredIds, string directory, string directoryName) + internal static void LookForAbandoned(Property.Models.Configuration propertyConfiguration, List distinctFilteredIds, string directory, string directoryName) { string fileNameWithoutExtension; bool nameWithoutExtensionIsIdFormat; List renameCollection = new(); bool nameWithoutExtensionIsPaddedIdFormat; - int sortOrderOnlyLengthIndex = IDirectory.GetSortOrderOnlyLengthIndex(); + int sortOrderOnlyLengthIndex = IDirectory.GetSortOrderOnlyLengthIndex(propertyConfiguration.Offset); string[] distinctFilteredIdsValues = distinctFilteredIds.Select(l => l.ToString()).ToArray(); string[] files = Directory.GetFiles(directory, "*", SearchOption.AllDirectories); foreach (string file in files) @@ -36,7 +36,7 @@ internal abstract class LookForAbandonedLogic } } - internal static void LookForAbandoned(string bResultsFullGroupDirectory, List distinctFilteredIds) + internal static void LookForAbandoned(Property.Models.Configuration propertyConfiguration, string bResultsFullGroupDirectory, List distinctFilteredIds) { string[] directories = Directory.GetDirectories(bResultsFullGroupDirectory, "*", SearchOption.TopDirectoryOnly); foreach (string directory in directories) @@ -44,7 +44,7 @@ internal abstract class LookForAbandonedLogic string? directoryName = Path.GetFileName(directory); if (string.IsNullOrEmpty(directoryName) || (directoryName.Length != 2 && directoryName.Length != 4)) continue; - LookForAbandoned(distinctFilteredIds, directory, directoryName); + LookForAbandoned(propertyConfiguration, distinctFilteredIds, directory, directoryName); } } diff --git a/Metadata-Query/Models/Binder/.editorconfig b/Metadata-Query/Models/Binder/.editorconfig new file mode 100644 index 0000000..1c444cd --- /dev/null +++ b/Metadata-Query/Models/Binder/.editorconfig @@ -0,0 +1,2 @@ +[*.cs] +csharp_preserve_single_line_statements = true \ No newline at end of file diff --git a/Metadata-Query/Models/Binder/Configuration.cs b/Metadata-Query/Models/Binder/Configuration.cs index b79616e..fc47217 100644 --- a/Metadata-Query/Models/Binder/Configuration.cs +++ b/Metadata-Query/Models/Binder/Configuration.cs @@ -1,6 +1,5 @@ using Microsoft.Extensions.Configuration; using Phares.Shared; -using System.ComponentModel.DataAnnotations; using System.Text.Json; namespace View_by_Distance.Metadata.Query.Models.Binder; @@ -10,9 +9,9 @@ public class Configuration #nullable disable - [Display(Name = "Ignore Extensions"), Required] public string[] IgnoreExtensions { get; set; } - [Display(Name = "Property Configuration"), Required] public Property.Models.Configuration PropertyConfiguration { get; set; } - [Display(Name = "Person Birthday Format"), Required] public string PersonBirthdayFormat { get; set; } + public string[] IgnoreExtensions { get; set; } + public Property.Models.Configuration PropertyConfiguration { get; set; } + public string PersonBirthdayFormat { get; set; } #nullable restore @@ -25,12 +24,9 @@ public class Configuration 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 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)); result = new( configuration.IgnoreExtensions, configuration.PersonBirthdayFormat, diff --git a/Metadata/Models/B_Metadata.cs b/Metadata/Models/B_Metadata.cs index 4794290..0fe2ead 100644 --- a/Metadata/Models/B_Metadata.cs +++ b/Metadata/Models/B_Metadata.cs @@ -2,13 +2,11 @@ using MetadataExtractor; using MetadataExtractor.Formats.Avi; using MetadataExtractor.Formats.Exif; using MetadataExtractor.Formats.QuickTime; -using System.Diagnostics; +using System.Collections.ObjectModel; using System.Text.Json; -using View_by_Distance.Metadata.Models.Stateless; using View_by_Distance.Shared.Models; using View_by_Distance.Shared.Models.Methods; using View_by_Distance.Shared.Models.Properties; -using View_by_Distance.Shared.Models.Stateless; namespace View_by_Distance.Metadata.Models; @@ -51,54 +49,10 @@ public class B_Metadata : IMetadata return result; } - private Dictionary>> GetMetadataCollection(string subFile) + public ReadOnlyDictionary GetMetadataCollection(List> subFileTuples, List parseExceptions, string[] changesFrom, MappingFromItem mappingFromItem) { - Dictionary>> results = new(); - if (_Log is null) - throw new NullReferenceException(nameof(_Log)); - try - { - object? @object; - string? tagDescription; - List tagNames = new(); - int type = (int)IExif.Tags.Orientation; - string key = nameof(IExif.Tags.Orientation); - IReadOnlyList directories = ImageMetadataReader.ReadMetadata(subFile); - foreach (MetadataExtractor.Directory directory in directories) - { - if (!results.ContainsKey(directory.Name)) - results.Add(directory.Name, new()); - foreach (Tag tag in directory.Tags) - { - tagNames.Add(tag.Name); - if (string.IsNullOrEmpty(tag.Description)) - continue; - results[directory.Name].Add(new KeyValuePair(string.Concat(tag.Type, '\t', tag.Name), tag.Description)); - } - if (tagNames.Contains(key) && !results.ContainsKey(key)) - { - @object = directory.GetObject(type); - if (@object is null) - continue; - tagDescription = @object.ToString(); - if (string.IsNullOrEmpty(tagDescription)) - continue; - results.Add(key, new() { new(string.Concat(type, '\t', key), tagDescription) }); - } - } - } - catch (Exception) - { - _Log.Info(string.Concat(new StackFrame().GetMethod()?.Name, " <", subFile, ">")); - } - return results; - } - - public (int, List>) GetMetadataCollection(List> subFileTuples, List parseExceptions, string[] changesFrom, MappingFromItem mappingFromItem) - { - List> results = new(); + Dictionary? results = null; string json = string.Empty; - Dictionary>>? dictionary; List dateTimes = (from l in subFileTuples where changesFrom.Contains(l.Item1) select l.Item2).ToList(); (_, int directoryIndex) = Shared.Models.Stateless.Methods.IPath.GetDirectoryNameAndIndex(_PropertyConfiguration.ResultAllInOneSubdirectoryLength, mappingFromItem.ImageFileHolder.Name); FileInfo fileInfo = new(Path.Combine(_FileGroups[_PropertyConfiguration.ResultSingleton][directoryIndex], $"{mappingFromItem.ImageFileHolder.NameWithoutExtension}{mappingFromItem.ImageFileHolder.ExtensionLowered}.json")); @@ -113,33 +67,34 @@ public class B_Metadata : IMetadata fileInfo.Refresh(); } if (_PropertiesChangedForMetadata) - dictionary = new(); + results = null; else if (!fileInfo.Exists) - dictionary = new(); + results = null; else if (!fileInfo.FullName.EndsWith(".json") && !fileInfo.FullName.EndsWith(".old")) throw new ArgumentException("must be a *.json file"); else if (dateTimes.Any() && dateTimes.Max() > fileInfo.LastWriteTime) - dictionary = new(); + results = null; else { json = File.ReadAllText(fileInfo.FullName); try { - dictionary = JsonSerializer.Deserialize>>>(json); - if (dictionary is null) + results = Stateless.Methods.Metadata.Deserialize(json); + if (results is null) throw new Exception(); subFileTuples.Add(new Tuple(nameof(B_Metadata), fileInfo.LastWriteTime)); } catch (Exception) { - dictionary = new(); + results = null; parseExceptions.Add(nameof(B_Metadata)); } } - if (dictionary is null || !dictionary.Any()) + if (results is null || results.Count == 0) { - dictionary = GetMetadataCollection(mappingFromItem.ImageFileHolder.FullName); - json = JsonSerializer.Serialize(dictionary, _WriteIndentedJsonSerializerOptions); + IReadOnlyList directories = ImageMetadataReader.ReadMetadata(mappingFromItem.ImageFileHolder.FullName); + results = Stateless.Methods.Metadata.Covert(directories); + json = JsonSerializer.Serialize(results, DictionaryStringMetadataExtractorDirectorySourceGenerationContext.Default.DictionaryStringMetadataExtractorDirectory); bool updateDateWhenMatches = dateTimes.Any() && fileInfo.Exists && dateTimes.Max() > fileInfo.LastWriteTime; DateTime? dateTime = !updateDateWhenMatches ? null : dateTimes.Max(); if (Shared.Models.Stateless.Methods.IPath.WriteAllText(fileInfo.FullName, json, updateDateWhenMatches, compareBeforeWrite: true, updateToWhenMatches: dateTime)) @@ -154,12 +109,7 @@ public class B_Metadata : IMetadata } } } - foreach (KeyValuePair>> keyValuePair in dictionary) - { - foreach (KeyValuePair keyValue in keyValuePair.Value) - results.Add(new(string.Concat(keyValuePair.Key, '\t', keyValue.Key), keyValue.Value)); - } - return new(dictionary.Count, results); + return new(results); } (DateTime?, DateTime?[]) IMetadata.GetDateTimes(FileHolder fileHolder, IReadOnlyList directories) diff --git a/Metadata/Models/MetadataExtractorDirectory.cs b/Metadata/Models/MetadataExtractorDirectory.cs new file mode 100644 index 0000000..89ee468 --- /dev/null +++ b/Metadata/Models/MetadataExtractorDirectory.cs @@ -0,0 +1,43 @@ +using System.Collections.ObjectModel; +using System.Text.Json; +using System.Text.Json.Serialization; + +namespace View_by_Distance.Metadata.Models; + +public record MetadataExtractorDirectory(string Name, + bool HasError, + ReadOnlyCollection Errors, + ReadOnlyDictionary Tags) +{ + + public override string ToString() + { + string result = JsonSerializer.Serialize(this, MetadataExtractorDirectorySourceGenerationContext.Default.MetadataExtractorDirectory); + return result; + } + +} + +[JsonSourceGenerationOptions(WriteIndented = true)] +[JsonSerializable(typeof(MetadataExtractorDirectory))] +public partial class MetadataExtractorDirectorySourceGenerationContext : JsonSerializerContext +{ +} + +[JsonSourceGenerationOptions(WriteIndented = true)] +[JsonSerializable(typeof(List))] +public partial class MetadataExtractorDirectoryCollectionSourceGenerationContext : JsonSerializerContext +{ +} + +[JsonSourceGenerationOptions(WriteIndented = true)] +[JsonSerializable(typeof(Dictionary))] +public partial class DictionaryStringMetadataExtractorDirectorySourceGenerationContext : JsonSerializerContext +{ +} + +[JsonSourceGenerationOptions(WriteIndented = true)] +[JsonSerializable(typeof(ReadOnlyDictionary))] +public partial class ReadOnlyDictionaryStringMetadataExtractorDirectorySourceGenerationContext : JsonSerializerContext +{ +} \ No newline at end of file diff --git a/Metadata/Models/MetadataExtractorTag.cs b/Metadata/Models/MetadataExtractorTag.cs new file mode 100644 index 0000000..150cbbc --- /dev/null +++ b/Metadata/Models/MetadataExtractorTag.cs @@ -0,0 +1,43 @@ +using System.Collections.ObjectModel; +using System.Text.Json; +using System.Text.Json.Serialization; + +namespace View_by_Distance.Metadata.Models; + +public record MetadataExtractorTag(int Type, + string? Description, + bool HasName, + string Name) +{ + + public override string ToString() + { + string result = JsonSerializer.Serialize(this, MetadataExtractorTagSourceGenerationContext.Default.MetadataExtractorTag); + return result; + } + +} + +[JsonSourceGenerationOptions(WriteIndented = true)] +[JsonSerializable(typeof(MetadataExtractorTag))] +public partial class MetadataExtractorTagSourceGenerationContext : JsonSerializerContext +{ +} + +[JsonSourceGenerationOptions(WriteIndented = true)] +[JsonSerializable(typeof(List))] +public partial class MetadataExtractorTagCollectionSourceGenerationContext : JsonSerializerContext +{ +} + +[JsonSourceGenerationOptions(WriteIndented = true)] +[JsonSerializable(typeof(Dictionary))] +public partial class DictionaryStringMetadataExtractorTagSourceGenerationContext : JsonSerializerContext +{ +} + +[JsonSourceGenerationOptions(WriteIndented = true)] +[JsonSerializable(typeof(ReadOnlyDictionary))] +public partial class ReadOnlyDictionaryStringMetadataExtractorTagSourceGenerationContext : JsonSerializerContext +{ +} \ No newline at end of file diff --git a/Metadata/Models/Record.cs b/Metadata/Models/Record.cs new file mode 100644 index 0000000..d300537 --- /dev/null +++ b/Metadata/Models/Record.cs @@ -0,0 +1,24 @@ +using System.Text.Json; +using System.Text.Json.Serialization; + +namespace View_by_Distance.Metadata.Models.Stateless.Methods; + +internal record Record(string Name, + bool HasError, + List Errors, + Dictionary Tags) +{ + + public override string ToString() + { + string result = JsonSerializer.Serialize(this, RecordSourceGenerationContext.Default.Record); + return result; + } + +} + +[JsonSourceGenerationOptions(WriteIndented = true)] +[JsonSerializable(typeof(Record))] +internal partial class RecordSourceGenerationContext : JsonSerializerContext +{ +} \ No newline at end of file diff --git a/Metadata/Models/Stateless/Methods/IMetadata.cs b/Metadata/Models/Stateless/Methods/IMetadata.cs index c521d23..bcef368 100644 --- a/Metadata/Models/Stateless/Methods/IMetadata.cs +++ b/Metadata/Models/Stateless/Methods/IMetadata.cs @@ -1,8 +1,24 @@ +using MetadataExtractor; +using System.Collections.ObjectModel; + namespace View_by_Distance.Metadata.Models.Stateless.Methods; public interface IMetadata { + enum DistanceUnit + { + Miles, + NauticalMiles, + Kilometers, + Meters + } + + ReadOnlyDictionary TestStatic_Covert(IReadOnlyList directories) => + Covert(directories); + static ReadOnlyDictionary Covert(IReadOnlyList directories) => + new(Metadata.Covert(directories)); + string? TestStatic_GetModel(IReadOnlyList directories) => GetModel(directories); static string? GetModel(IReadOnlyList directories) => @@ -18,9 +34,19 @@ public interface IMetadata static string? GetOutputResolution(IReadOnlyList directories) => Metadata.GetOutputResolution(directories); - int TestStatic_GetOrientation(List> metadataCollection) => - GetOrientation(metadataCollection); - static int GetOrientation(List> metadataCollection) => - Metadata.GetOrientation(metadataCollection); + GeoLocation? TestStatic_GeoLocation(IReadOnlyList directories) => + GeoLocation(directories); + static GeoLocation? GeoLocation(IReadOnlyList directories) => + Metadata.GeoLocation(directories); + + GeoLocation? TestStatic_GeoLocation(ReadOnlyDictionary metadataExtractorDirectories) => + GeoLocation(metadataExtractorDirectories); + static GeoLocation? GeoLocation(ReadOnlyDictionary metadataExtractorDirectories) => + Metadata.GeoLocation(metadataExtractorDirectories); + + double? TestStatic_GetDistance(double originLatitude, double originLongitude, double destinationLatitude, double destinationLongitude, int decimalPlaces = 1, DistanceUnit distanceUnit = DistanceUnit.Miles) => + GetDistance(originLatitude, originLongitude, destinationLatitude, destinationLongitude, decimalPlaces, distanceUnit); + static double? GetDistance(double originLatitude, double originLongitude, double destinationLatitude, double destinationLongitude, int decimalPlaces = 1, DistanceUnit distanceUnit = DistanceUnit.Miles) => + Metadata.GetDistance(originLatitude, originLongitude, destinationLatitude, destinationLongitude, decimalPlaces, distanceUnit); } \ No newline at end of file diff --git a/Metadata/Models/Stateless/Methods/Metadata.cs b/Metadata/Models/Stateless/Methods/Metadata.cs index 23416fe..e44baa6 100644 --- a/Metadata/Models/Stateless/Methods/Metadata.cs +++ b/Metadata/Models/Stateless/Methods/Metadata.cs @@ -1,12 +1,55 @@ using MetadataExtractor; using MetadataExtractor.Formats.Exif; -using View_by_Distance.Shared.Models.Stateless; +using System.Collections.ObjectModel; +using System.Text.Json; +using static View_by_Distance.Metadata.Models.Stateless.Methods.IMetadata; namespace View_by_Distance.Metadata.Models.Stateless.Methods; -internal class Metadata +internal partial class Metadata { + internal static Dictionary Covert(IReadOnlyList directories) + { + Dictionary results = new(); + MetadataExtractorTag metadataExtractorTag; + MetadataExtractorDirectory? metadataExtractorDirectory; + Dictionary metadataExtractorTags; + foreach (MetadataExtractor.Directory directory in directories) + { + metadataExtractorTags = new(); + if (results.TryGetValue(directory.Name, out metadataExtractorDirectory)) + continue; + foreach (Tag tag in directory.Tags) + { + metadataExtractorTag = new(tag.Type, tag.Description, tag.HasName, tag.Name); + metadataExtractorTags.Add(tag.Type, metadataExtractorTag); + } + metadataExtractorDirectory = new(directory.Name, directory.HasError, new(directory.Errors.ToArray()), new(metadataExtractorTags)); + results.Add(directory.Name, metadataExtractorDirectory); + } + return results; + } + + internal static Dictionary Deserialize(string json) + { + Dictionary results = new(); + Record? record; + MetadataExtractorDirectory metadataExtractorDirectory; + Dictionary? keyValuePairs = JsonSerializer.Deserialize>(json); + if (keyValuePairs is null) + throw new NullReferenceException(nameof(keyValuePairs)); + foreach (KeyValuePair keyValuePair in keyValuePairs) + { + record = JsonSerializer.Deserialize(keyValuePair.Value.ToString(), RecordSourceGenerationContext.Default.Record); + if (record is null) + throw new NullReferenceException(nameof(record)); + metadataExtractorDirectory = new(record.Name, record.HasError, new(record.Errors), new(record.Tags)); + results.Add(record.Name, metadataExtractorDirectory); + } + return results; + } + internal static string? GetFaceEncoding(IReadOnlyList directories) { string? result; @@ -62,15 +105,124 @@ internal class Metadata return result; } - internal static int GetOrientation(List> metadataCollection) + internal static GeoLocation? GeoLocation(IReadOnlyList directories) { - int result; - const string orientation = nameof(IExif.Tags.Orientation); - List orientations = (from l in metadataCollection where l.Key.Contains(orientation) select l.Value).ToList(); - if (!orientations.Any()) - result = 0; - else if (!int.TryParse(orientations[0], out result)) - result = 0; + GeoLocation? result; + GpsDirectory? gpsDirectory = directories.OfType().FirstOrDefault(); + if (gpsDirectory is null) + result = null; + else + result = gpsDirectory.GetGeoLocation(); + return result; + } + + private static bool CoordinateValidatorValidate(double latitude, double longitude) + { + if (latitude is < (-90) or > 90) + return false; + if (longitude is < (-180) or > 180) + return false; + + return true; + } + + private static double GetRadius(DistanceUnit distanceUnit) + { + return distanceUnit switch + { + DistanceUnit.Kilometers => 6371.0, // EarthRadiusInKilometers; + DistanceUnit.Meters => 6371000.0, // EarthRadiusInMeters; + DistanceUnit.NauticalMiles => 3440.0, // EarthRadiusInNauticalMiles; + DistanceUnit.Miles => 3959.0, // EarthRadiusInMiles; + _ => throw new NotSupportedException() + }; + } + + private static double ToRadian(double d) => + d * (Math.PI / 180); + + private static double DiffRadian(double val1, double val2) => + ToRadian(val2) - ToRadian(val1); + + internal static double GetDistance(double originLatitude, double originLongitude, double destinationLatitude, double destinationLongitude, int decimalPlaces = 1, DistanceUnit distanceUnit = DistanceUnit.Miles) + { + if (!CoordinateValidatorValidate(originLatitude, originLongitude)) + throw new ArgumentException("Invalid origin coordinates supplied."); + if (!CoordinateValidatorValidate(destinationLatitude, destinationLongitude)) + throw new ArgumentException("Invalid destination coordinates supplied."); + double radius = GetRadius(distanceUnit); + return Math.Round( + radius * 2 * + Math.Asin(Math.Min(1, + Math.Sqrt( + Math.Pow(Math.Sin(DiffRadian(originLatitude, destinationLatitude) / 2.0), 2.0) + + Math.Cos(ToRadian(originLatitude)) * Math.Cos(ToRadian(destinationLatitude)) * + Math.Pow(Math.Sin(DiffRadian(originLongitude, destinationLongitude) / 2.0), + 2.0)))), decimalPlaces); + } + + private static double ParseValueFromDmsString(string value) + { + double result; + if (string.IsNullOrEmpty(value)) + return double.MinValue; + + double secondsValue; + string[] degrees = value.Split('°'); + if (degrees.Length != 2) + return double.MinValue; + if (!double.TryParse(degrees[0], out double degreesValue)) + return double.MinValue; + + string[] minutes = degrees[1].Split('\''); + if (minutes.Length != 2) + return double.MinValue; + if (!double.TryParse(minutes[0], out double minutesValue)) + return double.MinValue; + + string[] seconds = minutes[1].Split('"'); + if (seconds.Length != 2) + secondsValue = 0; + else + { + if (!double.TryParse(seconds[0], out secondsValue)) + return double.MinValue; + } + result = Math.Abs(degreesValue) + (minutesValue / 60) + (secondsValue / 3600); + + if (degreesValue < 0) + result *= -1; + + return result; + } + + internal static GeoLocation? GeoLocation(ReadOnlyDictionary metadataExtractorDirectories) + { + GeoLocation? result; + if (!metadataExtractorDirectories.TryGetValue("GPS", out MetadataExtractorDirectory? metadataExtractorDirectory)) + result = null; + else + { + MetadataExtractorTag? metadataExtractorTag; + if (!metadataExtractorDirectory.Tags.TryGetValue((int)Shared.Models.Stateless.IExif.Tags.GPSLatitude, out metadataExtractorTag) || string.IsNullOrEmpty(metadataExtractorTag.Description)) + result = null; + else + { + string latitudeDMS = metadataExtractorTag.Description; + double latitude = ParseValueFromDmsString(latitudeDMS); + if (!metadataExtractorDirectory.Tags.TryGetValue((int)Shared.Models.Stateless.IExif.Tags.GPSLongitude, out metadataExtractorTag) || string.IsNullOrEmpty(metadataExtractorTag.Description)) + result = null; + else + { + string longitudeDMS = metadataExtractorTag.Description; + double longitude = ParseValueFromDmsString(longitudeDMS); + result = new(latitude, longitude); + string dms = result.ToDmsString(); + if ($"{latitudeDMS}, {longitudeDMS}" != dms) + result = null; + } + } + } return result; } diff --git a/Mirror-Length/Models/Binder/.editorconfig b/Mirror-Length/Models/Binder/.editorconfig new file mode 100644 index 0000000..1c444cd --- /dev/null +++ b/Mirror-Length/Models/Binder/.editorconfig @@ -0,0 +1,2 @@ +[*.cs] +csharp_preserve_single_line_statements = true \ No newline at end of file diff --git a/Mirror-Length/Models/Binder/Configuration.cs b/Mirror-Length/Models/Binder/Configuration.cs index 34d6b69..2cc0080 100644 --- a/Mirror-Length/Models/Binder/Configuration.cs +++ b/Mirror-Length/Models/Binder/Configuration.cs @@ -1,6 +1,5 @@ using Microsoft.Extensions.Configuration; using Phares.Shared; -using System.ComponentModel.DataAnnotations; using System.Text.Json; namespace View_by_Distance.Mirror.Length.Models.Binder; @@ -10,9 +9,9 @@ public class Configuration #nullable disable - [Display(Name = "Ignore Extensions"), Required] public string[] IgnoreExtensions { get; set; } - [Display(Name = "Property Configuration"), Required] public Property.Models.Configuration PropertyConfiguration { get; set; } - [Display(Name = "Person Birthday Format"), Required] public string PersonBirthdayFormat { get; set; } + public string[] IgnoreExtensions { get; set; } + public Property.Models.Configuration PropertyConfiguration { get; set; } + public string PersonBirthdayFormat { get; set; } #nullable restore @@ -25,12 +24,9 @@ public class Configuration 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 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)); result = new( configuration.IgnoreExtensions, configuration.PersonBirthdayFormat, diff --git a/Move-By-Id/Models/AppSettings.cs b/Move-By-Id/Models/AppSettings.cs index 8b05e92..d8e4a41 100644 --- a/Move-By-Id/Models/AppSettings.cs +++ b/Move-By-Id/Models/AppSettings.cs @@ -3,36 +3,24 @@ using System.Text.Json.Serialization; namespace View_by_Distance.Move.By.Id.Models; -public class AppSettings +public record AppSettings(string Company, + string MoveTo, + string ComparePathsFile, + int MaxDegreeOfParallelism, + int MaxMinutesDelta, + string WorkingDirectoryName) { - public string Company { init; get; } - public string MoveTo { init; get; } - public string ComparePathsFile { init; get; } - public int MaxDegreeOfParallelism { init; get; } - public int MaxMinutesDelta { init; get; } - public string WorkingDirectoryName { init; get; } - - [JsonConstructor] - public AppSettings(string company, - string moveTo, - string comparePathsFile, - int maxDegreeOfParallelism, - int maxMinutesDelta, - string workingDirectoryName) - { - Company = company; - MoveTo = moveTo; - ComparePathsFile = comparePathsFile; - MaxDegreeOfParallelism = maxDegreeOfParallelism; - MaxMinutesDelta = maxMinutesDelta; - WorkingDirectoryName = workingDirectoryName; - } - public override string ToString() { - string result = JsonSerializer.Serialize(this, new JsonSerializerOptions() { WriteIndented = true }); + string result = JsonSerializer.Serialize(this, AppSettingsSourceGenerationContext.Default.AppSettings); return result; } +} + +[JsonSourceGenerationOptions(WriteIndented = true)] +[JsonSerializable(typeof(AppSettings))] +internal partial class AppSettingsSourceGenerationContext : JsonSerializerContext +{ } \ No newline at end of file diff --git a/Move-By-Id/Models/Binder/.editorconfig b/Move-By-Id/Models/Binder/.editorconfig new file mode 100644 index 0000000..1c444cd --- /dev/null +++ b/Move-By-Id/Models/Binder/.editorconfig @@ -0,0 +1,2 @@ +[*.cs] +csharp_preserve_single_line_statements = true \ No newline at end of file diff --git a/Move-By-Id/Models/Binder/Configuration.cs b/Move-By-Id/Models/Binder/Configuration.cs index 5813a16..0e0f992 100644 --- a/Move-By-Id/Models/Binder/Configuration.cs +++ b/Move-By-Id/Models/Binder/Configuration.cs @@ -1,6 +1,5 @@ using Microsoft.Extensions.Configuration; using Phares.Shared; -using System.ComponentModel.DataAnnotations; using System.Text.Json; namespace View_by_Distance.Move.By.Id.Models.Binder; @@ -10,9 +9,9 @@ public class Configuration #nullable disable - [Display(Name = "Ignore Extensions"), Required] public string[] IgnoreExtensions { get; set; } - [Display(Name = "Property Configuration"), Required] public Property.Models.Configuration PropertyConfiguration { get; set; } - [Display(Name = "Person Birthday Format"), Required] public string PersonBirthdayFormat { get; set; } + public string[] IgnoreExtensions { get; set; } + public Property.Models.Configuration PropertyConfiguration { get; set; } + public string PersonBirthdayFormat { get; set; } #nullable restore @@ -25,12 +24,9 @@ public class Configuration 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 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)); result = new( configuration.IgnoreExtensions, configuration.PersonBirthdayFormat, diff --git a/Move-By-Id/Move-By-Id.csproj b/Move-By-Id/Move-By-Id.csproj index 68162a5..0be2614 100644 --- a/Move-By-Id/Move-By-Id.csproj +++ b/Move-By-Id/Move-By-Id.csproj @@ -49,12 +49,4 @@ - - - Always - - - Always - - \ No newline at end of file diff --git a/Move-By-Id/MoveById.cs b/Move-By-Id/MoveById.cs index b0ca637..606dcb7 100644 --- a/Move-By-Id/MoveById.cs +++ b/Move-By-Id/MoveById.cs @@ -40,6 +40,7 @@ public class MoveById if (comparePathRoot is null || comparePathRoot == propertyConfiguration.RootDirectory) throw new Exception("Nested isn't allowed!"); log.Information(propertyConfiguration.RootDirectory); + Property.Models.Configuration.Verify(propertyConfiguration, requireExist: false); Verify(); string json = File.ReadAllText(appSettings.ComparePathsFile); MatchNginx[]? matchNginxCollection = System.Text.Json.JsonSerializer.Deserialize(json); @@ -112,7 +113,7 @@ public class MoveById ASCIIEncoding asciiEncoding = new(); bool nameWithoutExtensionIsIdFormat; bool nameWithoutExtensionIsPaddedIdFormat; - int sortOrderOnlyLengthIndex = IDirectory.GetSortOrderOnlyLengthIndex(); + int sortOrderOnlyLengthIndex = IDirectory.GetSortOrderOnlyLengthIndex(_PropertyConfiguration.Offset); foreach (string file in allFiles) { progressBar.Tick(); diff --git a/Move-By-Id/Program.cs b/Move-By-Id/Program.cs index e4d3994..f44c417 100644 --- a/Move-By-Id/Program.cs +++ b/Move-By-Id/Program.cs @@ -19,8 +19,6 @@ public class Program IsEnvironment isEnvironment = new(processesCount: null, nullASPNetCoreEnvironmentIsDevelopment: debuggerWasAttachedAtLineZero, nullASPNetCoreEnvironmentIsProduction: !debuggerWasAttachedAtLineZero); IConfigurationBuilder configurationBuilder = new ConfigurationBuilder() .AddEnvironmentVariables() - .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true) - .AddJsonFile(isEnvironment.AppSettingsFileName, optional: false, reloadOnChange: true) .AddUserSecrets(); IConfigurationRoot configurationRoot = configurationBuilder.Build(); AppSettings appSettings = Models.Binder.AppSettings.Get(configurationRoot); diff --git a/Move-By-Id/appsettings.Development.json b/Move-By-Id/appsettings.Development.json deleted file mode 100644 index ad9619a..0000000 --- a/Move-By-Id/appsettings.Development.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "Logging": { - "LogLevel": { - "Log4netProvider": "Debug" - } - }, - "Serilog": { - "MinimumLevel": "Debug" - } -} \ No newline at end of file diff --git a/Move-By-Id/appsettings.json b/Move-By-Id/appsettings.json deleted file mode 100644 index 01d0ff8..0000000 --- a/Move-By-Id/appsettings.json +++ /dev/null @@ -1,98 +0,0 @@ -{ - "ComparePathsFile": "", - "Company": "Mike Phares", - "MoveTo": "", - "Linux": {}, - "Logging": { - "LogLevel": { - "Default": "Information", - "Microsoft": "Warning", - "Log4netProvider": "Debug", - "Microsoft.Hosting.Lifetime": "Information" - } - }, - "MaxDegreeOfParallelism": 6, - "MaxMinutesDelta": 2, - "Serilog": { - "Using": [ - "Serilog.Sinks.Console", - "Serilog.Sinks.File" - ], - "MinimumLevel": "Information", - "WriteTo": [ - { - "Name": "Debug", - "Args": { - "outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz} [{Level}] ({SourceContext}.{MethodName}) ({InstanceId}) ({RemoteIpAddress}) {Message}{NewLine}{Exception}" - } - }, - { - "Name": "Console", - "Args": { - "outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz} [{Level}] ({SourceContext}.{MethodName}) ({InstanceId}) ({RemoteIpAddress}) {Message}{NewLine}{Exception}" - } - }, - { - "Name": "File", - "Args": { - "path": "%workingDirectory% - Log/log-.txt", - "outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz} [{Level}] ({SourceContext}.{MethodName}) ({InstanceId}) ({RemoteIpAddress}) {Message}{NewLine}{Exception}", - "rollingInterval": "Hour" - } - } - ], - "Enrich": [ - "FromLogContext", - "WithMachineName", - "WithThreadId" - ], - "Properties": { - "Application": "Sample" - } - }, - "WorkingDirectoryName": "PharesApps", - "Windows": { - "Configuration": { - "DateGroup": "dd514b88", - "DiffPropertyDirectory": "", - "FileNameDirectorySeparator": ".Z.", - "ForcePropertyLastWriteTimeToCreationTime": false, - "MaxImagesInDirectoryForTopLevelFirstPass": 10, - "OutputExtension": ".jpg", - "Pattern": "[^ABCDEFGHIJKLMNOPQRSTUVWXYZbcdfghjklmnpqrstvwxyz0-9]", - "PersonBirthdayFormat": "yyyy-MM-dd_HH", - "PopulatePropertyId": true, - "PropertiesChangedForProperty": false, - "ResultAllInOne": "_ _ _", - "ResultAllInOneSubdirectoryLength": 2, - "ResultCollection": "[]", - "ResultContent": "()", - "ResultSingleton": "{}", - "RootDirectory": "C:/Tmp/Phares/Compare/Images-dd514b88", - "IgnoreExtensions": [ - ".gif", - ".GIF", - ".nef", - ".NEF", - ".pdf", - ".PDF" - ], - "ValidImageFormatExtensions": [ - ".bmp", - ".BMP", - ".gif", - ".GIF", - ".jpeg", - ".JPEG", - ".jpg", - ".JPG", - ".png", - ".PNG", - ".tiff", - ".TIFF", - ".tif", - ".TIF" - ] - } - } -} \ No newline at end of file diff --git a/Offset-Date-Time-Original/Models/Binder/.editorconfig b/Offset-Date-Time-Original/Models/Binder/.editorconfig new file mode 100644 index 0000000..1c444cd --- /dev/null +++ b/Offset-Date-Time-Original/Models/Binder/.editorconfig @@ -0,0 +1,2 @@ +[*.cs] +csharp_preserve_single_line_statements = true \ No newline at end of file diff --git a/Offset-Date-Time-Original/Models/Binder/Configuration.cs b/Offset-Date-Time-Original/Models/Binder/Configuration.cs index fa1bca2..0181e88 100644 --- a/Offset-Date-Time-Original/Models/Binder/Configuration.cs +++ b/Offset-Date-Time-Original/Models/Binder/Configuration.cs @@ -1,6 +1,5 @@ using Microsoft.Extensions.Configuration; using Phares.Shared; -using System.ComponentModel.DataAnnotations; using System.Text.Json; namespace View_by_Distance.Offset.Date.Time.Original.Models.Binder; @@ -10,9 +9,9 @@ public class Configuration #nullable disable - [Display(Name = "Ignore Extensions"), Required] public string[] IgnoreExtensions { get; set; } - [Display(Name = "Property Configuration"), Required] public Property.Models.Configuration PropertyConfiguration { get; set; } - [Display(Name = "Person Birthday Format"), Required] public string PersonBirthdayFormat { get; set; } + public string[] IgnoreExtensions { get; set; } + public Property.Models.Configuration PropertyConfiguration { get; set; } + public string PersonBirthdayFormat { get; set; } #nullable restore @@ -25,12 +24,9 @@ public class Configuration 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 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)); result = new( configuration.IgnoreExtensions, configuration.PersonBirthdayFormat, diff --git a/PrepareForOld/Models/AppSettings.cs b/PrepareForOld/Models/AppSettings.cs index ea6049a..62b0560 100644 --- a/PrepareForOld/Models/AppSettings.cs +++ b/PrepareForOld/Models/AppSettings.cs @@ -3,25 +3,21 @@ using System.Text.Json.Serialization; namespace View_by_Distance.PrepareForOld.Models; -public class AppSettings +public record AppSettings(string Company, + int MaxDegreeOfParallelism, + string WorkingDirectoryName) { - public string Company { init; get; } - public int MaxDegreeOfParallelism { init; get; } - public string WorkingDirectoryName { init; get; } - - [JsonConstructor] - public AppSettings(string company, int maxDegreeOfParallelism, string workingDirectoryName) - { - Company = company; - MaxDegreeOfParallelism = maxDegreeOfParallelism; - WorkingDirectoryName = workingDirectoryName; - } - public override string ToString() { - string result = JsonSerializer.Serialize(this, new JsonSerializerOptions() { WriteIndented = true }); + string result = JsonSerializer.Serialize(this, AppSettingsSourceGenerationContext.Default.AppSettings); return result; } +} + +[JsonSourceGenerationOptions(WriteIndented = true)] +[JsonSerializable(typeof(AppSettings))] +internal partial class AppSettingsSourceGenerationContext : JsonSerializerContext +{ } \ No newline at end of file diff --git a/PrepareForOld/Models/Binder/.editorconfig b/PrepareForOld/Models/Binder/.editorconfig new file mode 100644 index 0000000..1c444cd --- /dev/null +++ b/PrepareForOld/Models/Binder/.editorconfig @@ -0,0 +1,2 @@ +[*.cs] +csharp_preserve_single_line_statements = true \ No newline at end of file diff --git a/PrepareForOld/Models/Binder/Configuration.cs b/PrepareForOld/Models/Binder/Configuration.cs index 2734f28..18ae21a 100644 --- a/PrepareForOld/Models/Binder/Configuration.cs +++ b/PrepareForOld/Models/Binder/Configuration.cs @@ -1,4 +1,3 @@ -using System.ComponentModel.DataAnnotations; using System.Text.Json; namespace View_by_Distance.PrepareForOld.Models.Binder; @@ -8,8 +7,8 @@ public class Configuration #nullable disable - [Display(Name = "Property Configuration"), Required] public Property.Models.Configuration PropertyConfiguration { get; set; } - [Display(Name = "Spelling"), Required] public string[] Spelling { get; set; } + public Property.Models.Configuration PropertyConfiguration { get; set; } + public string[] Spelling { get; set; } #nullable restore diff --git a/PrepareForOld/Models/Stateless/Configuration.cs b/PrepareForOld/Models/Stateless/Configuration.cs index c7d4a64..9919aec 100644 --- a/PrepareForOld/Models/Stateless/Configuration.cs +++ b/PrepareForOld/Models/Stateless/Configuration.cs @@ -16,8 +16,7 @@ public abstract class Configuration Binder.Configuration? configuration = configurationSection.Get(); string json = JsonSerializer.Serialize(configuration, new JsonSerializerOptions() { WriteIndented = true }); result = JsonSerializer.Deserialize(json); - if (result is null) - throw new Exception(json); + if (result is null) throw new Exception(json); string jsonThis = result.ToString(); if (jsonThis != json) { @@ -30,11 +29,10 @@ public abstract class Configuration check = i; break; } - if (check is null) - throw new Exception(); + if (check is null) throw new Exception(); string a = json[..check.Value].Split(',')[^1]; string b = json[check.Value..].Split(',')[0]; - throw new Exception($"{a}{b}"); +throw new Exception($"{a}{b}"); } return result; } diff --git a/Property/Models/Binder/Configuration.cs b/Property/Models/Binder/Configuration.cs index 2228fb3..2b3f7ac 100644 --- a/Property/Models/Binder/Configuration.cs +++ b/Property/Models/Binder/Configuration.cs @@ -11,10 +11,12 @@ public class Configuration public string? FileNameDirectorySeparator { get; set; } public bool? ForcePropertyLastWriteTimeToCreationTime { get; set; } public string[]? IgnoreExtensions { get; set; } + public string[]? IgnoreRulesKeyWords { get; set; } public int? MaxImagesInDirectoryForTopLevelFirstPass { get; set; } public string? ModelName { init; get; } public int? NumberOfJitters { init; get; } public int? NumberOfTimesToUpsample { init; get; } + public int? Offset { init; get; } public string? Pattern { get; set; } public string? PersonBirthdayFormat { get; set; } public bool? PopulatePropertyId { get; set; } @@ -43,11 +45,13 @@ public class Configuration if (configuration.DateGroup is null) throw new NullReferenceException(nameof(configuration.DateGroup)); if (configuration.FileNameDirectorySeparator is null) throw new NullReferenceException(nameof(configuration.FileNameDirectorySeparator)); if (configuration.ForcePropertyLastWriteTimeToCreationTime is null) throw new NullReferenceException(nameof(configuration.ForcePropertyLastWriteTimeToCreationTime)); - // if (configuration.IgnoreExtensions is null) throw new NullReferenceException(nameof(configuration.IgnoreExtensions)); + if (configuration.IgnoreExtensions is null) throw new NullReferenceException(nameof(configuration.IgnoreExtensions)); + if (configuration.IgnoreRulesKeyWords is null) throw new NullReferenceException(nameof(configuration.IgnoreRulesKeyWords)); if (configuration.MaxImagesInDirectoryForTopLevelFirstPass is null) throw new NullReferenceException(nameof(configuration.MaxImagesInDirectoryForTopLevelFirstPass)); // 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.Offset is null) throw new NullReferenceException(nameof(configuration.Offset));; if (configuration.Pattern is null) throw new NullReferenceException(nameof(configuration.Pattern)); if (configuration.PersonBirthdayFormat is null) throw new NullReferenceException(nameof(configuration.PersonBirthdayFormat)); if (configuration.PopulatePropertyId is null) throw new NullReferenceException(nameof(configuration.PopulatePropertyId)); @@ -60,16 +64,18 @@ public class Configuration if (configuration.ResultContent is null) throw new NullReferenceException(nameof(configuration.ResultContent)); if (configuration.ResultSingleton is null) throw new NullReferenceException(nameof(configuration.ResultSingleton)); if (configuration.RootDirectory is null) throw new NullReferenceException(nameof(configuration.RootDirectory)); - // if (configuration.ValidImageFormatExtensions is null) throw new NullReferenceException(nameof(configuration.ValidImageFormatExtensions)); + if (configuration.ValidImageFormatExtensions is null) throw new NullReferenceException(nameof(configuration.ValidImageFormatExtensions)); // if (configuration.VerifyToSeason is null) throw new NullReferenceException(nameof(configuration.VerifyToSeason)); result = new(configuration.DateGroup, configuration.FileNameDirectorySeparator, configuration.ForcePropertyLastWriteTimeToCreationTime.Value, - configuration.IgnoreExtensions ?? Array.Empty(), + configuration.IgnoreExtensions, + configuration.IgnoreRulesKeyWords, configuration.MaxImagesInDirectoryForTopLevelFirstPass.Value, configuration.ModelName, configuration.NumberOfJitters, configuration.NumberOfTimesToUpsample, + configuration.Offset.Value, configuration.Pattern, configuration.PersonBirthdayFormat, configuration.PopulatePropertyId.Value, @@ -82,7 +88,7 @@ public class Configuration configuration.ResultContent, configuration.ResultSingleton, Path.GetFullPath(configuration.RootDirectory), - configuration.ValidImageFormatExtensions ?? Array.Empty(), + configuration.ValidImageFormatExtensions, configuration.VerifyToSeason ?? Array.Empty()); return result; } diff --git a/Property/Models/Configuration.cs b/Property/Models/Configuration.cs index d95cec5..13b575c 100644 --- a/Property/Models/Configuration.cs +++ b/Property/Models/Configuration.cs @@ -14,10 +14,12 @@ public class Configuration : Shared.Models.Properties.IPropertyConfiguration public string FileNameDirectorySeparator { init; get; } public bool ForcePropertyLastWriteTimeToCreationTime { init; get; } public string[] IgnoreExtensions { init; get; } + public string[] IgnoreRulesKeyWords { init; get; } public int MaxImagesInDirectoryForTopLevelFirstPass { init; get; } public string? ModelName { init; get; } public int? NumberOfJitters { init; get; } public int? NumberOfTimesToUpsample { init; get; } + public int Offset { init; get; } public string Pattern { init; get; } public string PersonBirthdayFormat { init; get; } public bool PopulatePropertyId { init; get; } @@ -36,10 +38,12 @@ public class Configuration : Shared.Models.Properties.IPropertyConfiguration string fileNameDirectorySeparator, bool forcePropertyLastWriteTimeToCreationTime, string[] ignoreExtensions, + string[] ignoreRulesKeyWords, int maxImagesInDirectoryForTopLevelFirstPass, string? modelName, int? numberOfJitters, int? numberOfTimesToUpsample, + int offset, string pattern, string personBirthdayFormat, bool populatePropertyId, @@ -59,10 +63,12 @@ public class Configuration : Shared.Models.Properties.IPropertyConfiguration FileNameDirectorySeparator = fileNameDirectorySeparator; ForcePropertyLastWriteTimeToCreationTime = forcePropertyLastWriteTimeToCreationTime; IgnoreExtensions = ignoreExtensions; + IgnoreRulesKeyWords = ignoreRulesKeyWords; MaxImagesInDirectoryForTopLevelFirstPass = maxImagesInDirectoryForTopLevelFirstPass; ModelName = modelName; NumberOfJitters = numberOfJitters; NumberOfTimesToUpsample = numberOfTimesToUpsample; + Offset = offset; Pattern = pattern; PersonBirthdayFormat = personBirthdayFormat; PredictorModelName = predictorModelName; @@ -89,26 +95,17 @@ public class Configuration : Shared.Models.Properties.IPropertyConfiguration public static void Verify(Configuration propertyConfiguration, bool requireExist) { - if (propertyConfiguration is null) - throw new NullReferenceException(nameof(propertyConfiguration)); - if (propertyConfiguration.IgnoreExtensions is null || propertyConfiguration.IgnoreExtensions.Length == 0) - throw new NullReferenceException(nameof(propertyConfiguration.IgnoreExtensions)); - if (propertyConfiguration.PropertyContentCollectionFiles is null) - throw new NullReferenceException(nameof(propertyConfiguration.PropertyContentCollectionFiles)); - if (propertyConfiguration.ValidImageFormatExtensions is null || propertyConfiguration.ValidImageFormatExtensions.Length == 0) - throw new NullReferenceException(nameof(propertyConfiguration.ValidImageFormatExtensions)); - if (propertyConfiguration is null) - throw new NullReferenceException(nameof(propertyConfiguration)); - if (string.IsNullOrEmpty(propertyConfiguration.DateGroup)) - throw new NullReferenceException(nameof(propertyConfiguration.DateGroup)); - if (string.IsNullOrEmpty(propertyConfiguration.FileNameDirectorySeparator)) - throw new NullReferenceException(nameof(propertyConfiguration.FileNameDirectorySeparator)); - if (string.IsNullOrEmpty(propertyConfiguration.Pattern)) - throw new NullReferenceException(nameof(propertyConfiguration.Pattern)); - if (string.IsNullOrEmpty(propertyConfiguration.RootDirectory) || (requireExist && !Directory.Exists(propertyConfiguration.RootDirectory))) - throw new NullReferenceException(nameof(propertyConfiguration.RootDirectory)); - if (propertyConfiguration.RootDirectory != Path.GetFullPath(propertyConfiguration.RootDirectory)) - throw new Exception(); + if (propertyConfiguration is null) throw new NullReferenceException(nameof(propertyConfiguration)); + if (propertyConfiguration.IgnoreExtensions is null || propertyConfiguration.IgnoreExtensions.Length == 0) throw new NullReferenceException(nameof(propertyConfiguration.IgnoreExtensions)); + if (propertyConfiguration.IgnoreRulesKeyWords is null || propertyConfiguration.IgnoreRulesKeyWords.Length == 0) throw new NullReferenceException(nameof(propertyConfiguration.IgnoreRulesKeyWords)); + if (propertyConfiguration.PropertyContentCollectionFiles is null) throw new NullReferenceException(nameof(propertyConfiguration.PropertyContentCollectionFiles)); + if (propertyConfiguration.ValidImageFormatExtensions is null || propertyConfiguration.ValidImageFormatExtensions.Length == 0) throw new NullReferenceException(nameof(propertyConfiguration.ValidImageFormatExtensions)); + if (propertyConfiguration is null) throw new NullReferenceException(nameof(propertyConfiguration)); + if (string.IsNullOrEmpty(propertyConfiguration.DateGroup)) throw new NullReferenceException(nameof(propertyConfiguration.DateGroup)); + if (string.IsNullOrEmpty(propertyConfiguration.FileNameDirectorySeparator)) throw new NullReferenceException(nameof(propertyConfiguration.FileNameDirectorySeparator)); + if (string.IsNullOrEmpty(propertyConfiguration.Pattern)) throw new NullReferenceException(nameof(propertyConfiguration.Pattern)); + if (string.IsNullOrEmpty(propertyConfiguration.RootDirectory) || (requireExist && !Directory.Exists(propertyConfiguration.RootDirectory))) throw new NullReferenceException(nameof(propertyConfiguration.RootDirectory)); + if (propertyConfiguration.RootDirectory != Path.GetFullPath(propertyConfiguration.RootDirectory)) throw new Exception(); } } \ No newline at end of file diff --git a/Property/Models/Stateless/Property.cs b/Property/Models/Stateless/Property.cs index 5c19956..491c003 100644 --- a/Property/Models/Stateless/Property.cs +++ b/Property/Models/Stateless/Property.cs @@ -214,10 +214,10 @@ internal class Property DateTime?[] dateTimes; string dateTimeFormat; DateTime checkDateTime; + int? orientation = null; DateTime? dateTime = null; string[]? keywords = null; PropertyItem? propertyItem; - string? orientation = null; DateTime? gpsDateStamp = null; List dateTimesByLogic; DateTime? dateTimeOriginal = null; @@ -312,28 +312,19 @@ internal class Property { propertyItem = image.GetPropertyItem((int)IExif.Tags.Make); if (propertyItem?.Value is not null) - { - value = asciiEncoding.GetString(propertyItem.Value, 0, propertyItem.Len - 1); - make = value; - } + make = asciiEncoding.GetString(propertyItem.Value, 0, propertyItem.Len - 1); } if (image.PropertyIdList.Contains((int)IExif.Tags.Model)) { propertyItem = image.GetPropertyItem((int)IExif.Tags.Model); if (propertyItem?.Value is not null) - { - value = asciiEncoding.GetString(propertyItem.Value, 0, propertyItem.Len - 1); - model = value; - } + model = asciiEncoding.GetString(propertyItem.Value, 0, propertyItem.Len - 1); } if (image.PropertyIdList.Contains((int)IExif.Tags.Orientation)) { propertyItem = image.GetPropertyItem((int)IExif.Tags.Orientation); if (propertyItem?.Value is not null) - { - value = BitConverter.ToInt16(propertyItem.Value, 0).ToString(); - orientation = value; - } + orientation = BitConverter.ToInt16(propertyItem.Value, 0); } if (image.PropertyIdList.Contains((int)IExif.Tags.XPKeywords)) { @@ -381,9 +372,9 @@ internal class Property if (fileHolder.LastWriteTime is null && property?.LastWriteTime is null) throw new NullReferenceException(nameof(fileHolder.LastWriteTime)); if (fileHolder.CreationTime is not null && fileHolder.LastWriteTime is not null) - result = new(fileHolder.CreationTime.Value, dateTime, dateTimeDigitized, dateTimeFromName, dateTimeOriginalByLogic, fileLength, gpsDateStamp, height, id, keywords, fileHolder.LastWriteTime.Value, make, model, orientation, width); + result = new(fileHolder.CreationTime.Value, dateTime, dateTimeDigitized, dateTimeFromName, dateTimeOriginalByLogic, fileLength, gpsDateStamp, height, id, keywords, fileHolder.LastWriteTime.Value, make, model, orientation?.ToString(), width); else if (property is not null) - result = new(property.CreationTime, dateTime, dateTimeDigitized, dateTimeFromName, dateTimeOriginalByLogic, fileLength, gpsDateStamp, height, id, keywords, property.LastWriteTime, make, model, orientation, width); + result = new(property.CreationTime, dateTime, dateTimeDigitized, dateTimeFromName, dateTimeOriginalByLogic, fileLength, gpsDateStamp, height, id, keywords, property.LastWriteTime, make, model, orientation?.ToString(), width); else throw new NullReferenceException(nameof(property)); return (message, dateTimesByLogic.ToArray(), result); diff --git a/Rename/Models/Binder/.editorconfig b/Rename/Models/Binder/.editorconfig new file mode 100644 index 0000000..1c444cd --- /dev/null +++ b/Rename/Models/Binder/.editorconfig @@ -0,0 +1,2 @@ +[*.cs] +csharp_preserve_single_line_statements = true \ No newline at end of file diff --git a/Rename/Models/Binder/AppSettings.cs b/Rename/Models/Binder/AppSettings.cs index d58e07d..e90405c 100644 --- a/Rename/Models/Binder/AppSettings.cs +++ b/Rename/Models/Binder/AppSettings.cs @@ -24,20 +24,13 @@ public class AppSettings private static Models.AppSettings Get(AppSettings? appSettings) { Models.AppSettings result; - if (appSettings?.Company is null) - throw new NullReferenceException(nameof(appSettings.Company)); - if (appSettings?.DefaultUnknownDirectoryName is null) - throw new NullReferenceException(nameof(appSettings.DefaultUnknownDirectoryName)); - if (appSettings?.ForceIdName is null) - throw new NullReferenceException(nameof(appSettings.ForceIdName)); - if (appSettings?.MaxDegreeOfParallelism is null) - throw new NullReferenceException(nameof(appSettings.MaxDegreeOfParallelism)); - if (appSettings?.MaxMinutesDelta is null) - throw new NullReferenceException(nameof(appSettings.MaxMinutesDelta)); - if (appSettings?.RenameUndo is null) - throw new NullReferenceException(nameof(appSettings.RenameUndo)); - if (appSettings?.WorkingDirectoryName is null) - throw new NullReferenceException(nameof(appSettings.WorkingDirectoryName)); + if (appSettings?.Company is null) throw new NullReferenceException(nameof(appSettings.Company)); + if (appSettings?.DefaultUnknownDirectoryName is null) throw new NullReferenceException(nameof(appSettings.DefaultUnknownDirectoryName)); + if (appSettings?.ForceIdName is null) throw new NullReferenceException(nameof(appSettings.ForceIdName)); + if (appSettings?.MaxDegreeOfParallelism is null) throw new NullReferenceException(nameof(appSettings.MaxDegreeOfParallelism)); + if (appSettings?.MaxMinutesDelta is null) throw new NullReferenceException(nameof(appSettings.MaxMinutesDelta)); + if (appSettings?.RenameUndo is null) throw new NullReferenceException(nameof(appSettings.RenameUndo)); + if (appSettings?.WorkingDirectoryName is null) throw new NullReferenceException(nameof(appSettings.WorkingDirectoryName)); result = new( appSettings.Company, appSettings.DefaultUnknownDirectoryName, diff --git a/Rename/Models/Binder/Configuration.cs b/Rename/Models/Binder/Configuration.cs index e510e8a..4566570 100644 --- a/Rename/Models/Binder/Configuration.cs +++ b/Rename/Models/Binder/Configuration.cs @@ -1,6 +1,5 @@ using Microsoft.Extensions.Configuration; using Phares.Shared; -using System.ComponentModel.DataAnnotations; using System.Text.Json; namespace View_by_Distance.Rename.Models.Binder; @@ -10,9 +9,9 @@ public class Configuration #nullable disable - [Display(Name = "Ignore Extensions"), Required] public string[] IgnoreExtensions { get; set; } - [Display(Name = "Property Configuration"), Required] public Property.Models.Configuration PropertyConfiguration { get; set; } - [Display(Name = "Person Birthday Format"), Required] public string PersonBirthdayFormat { get; set; } + public string[] IgnoreExtensions { get; set; } + public Property.Models.Configuration PropertyConfiguration { get; set; } + public string PersonBirthdayFormat { get; set; } #nullable restore @@ -25,12 +24,9 @@ public class Configuration 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 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)); result = new( configuration.IgnoreExtensions, configuration.PersonBirthdayFormat, diff --git a/Rename/Models/Configuration.cs b/Rename/Models/Configuration.cs index 94072b0..1ea6068 100644 --- a/Rename/Models/Configuration.cs +++ b/Rename/Models/Configuration.cs @@ -1,32 +1,6 @@ -using System.Text.Json; -using System.Text.Json.Serialization; namespace View_by_Distance.Rename.Models; -public class Configuration -{ - - protected Property.Models.Configuration _PropertyConfiguration; - public string[] IgnoreExtensions { init; get; } - public string PersonBirthdayFormat { init; get; } - - public Property.Models.Configuration PropertyConfiguration => _PropertyConfiguration; - - [JsonConstructor] - public Configuration( - string[] ignoreExtensions, - string personBirthdayFormat, - Property.Models.Configuration propertyConfiguration) - { - IgnoreExtensions = ignoreExtensions; - PersonBirthdayFormat = personBirthdayFormat; - _PropertyConfiguration = propertyConfiguration; - } - - public override string ToString() - { - string result = JsonSerializer.Serialize(this, new JsonSerializerOptions() { WriteIndented = true }); - return result; - } - -} \ No newline at end of file +public record Configuration(string[] IgnoreExtensions, + string PersonBirthdayFormat, + Property.Models.Configuration PropertyConfiguration); \ No newline at end of file diff --git a/Rename/Rename.cs b/Rename/Rename.cs index e91b1b0..fd0d7f6 100644 --- a/Rename/Rename.cs +++ b/Rename/Rename.cs @@ -47,6 +47,7 @@ public class Rename _PropertyConfiguration = propertyConfiguration; _Configuration = configuration; log.Information(propertyConfiguration.RootDirectory); + Property.Models.Configuration.Verify(propertyConfiguration, requireExist: false); Verify(); List lines = RenameFilesInDirectories(log); if (lines.Any()) @@ -81,7 +82,6 @@ public class Rename ProgressBar progressBar; List records = new(); const string fileSearchFilter = "*"; - int offset = IDirectory.GetOffset(); const bool useCeilingAverage = false; const string directorySearchFilter = "*"; List distinctDirectories = new(); @@ -115,12 +115,12 @@ public class Rename progressBar = new(files.Length, message, options); nefPresentCheck = files.Any(l => l.EndsWith(".NEF")); if (!nefPresentCheck) - records.AddRange(GetRecords(metadata, offset + records.Count, progressBar, files)); + records.AddRange(GetRecords(metadata, _PropertyConfiguration.Offset + records.Count, progressBar, files)); else { if (!nefPresent) nefPresent = true; - records.AddRange(GetRecords(metadata, offset + records.Count, progressBar, (from l in files where l.EndsWith(".JPG") select l).ToArray())); + records.AddRange(GetRecords(metadata, _PropertyConfiguration.Offset + records.Count, progressBar, (from l in files where l.EndsWith(".JPG") select l).ToArray())); } } progressBar.Dispose(); @@ -226,7 +226,7 @@ public class Rename bool nameWithoutExtensionIsIdFormat; bool nameWithoutExtensionIsPaddedIdFormat; IReadOnlyList directories; - int sortOrderOnlyLengthIndex = IDirectory.GetSortOrderOnlyLengthIndex(); + int sortOrderOnlyLengthIndex = IDirectory.GetSortOrderOnlyLengthIndex(_PropertyConfiguration.Offset); for (int i = 0; i < files.Length; i++) { progressBar.Tick(); diff --git a/Resize/Models/_C_Resize.cs b/Resize/Models/_C_Resize.cs index e81befd..bd35bec 100644 --- a/Resize/Models/_C_Resize.cs +++ b/Resize/Models/_C_Resize.cs @@ -364,21 +364,17 @@ public class C_Resize return results.ToArray(); } - private Dictionary GetImageResizes(Shared.Models.Property property, List> metadataCollection) + private Dictionary GetImageResizes(Shared.Models.Property property) { Dictionary results = new(); int[] desired; int checkWidth; - int orientation; int checkHeight; int desiredWidth; int desiredHeight; + int orientation = property.Orientation is null || string.IsNullOrEmpty(property.Orientation) || !int.TryParse(property.Orientation, out int propertyOrientation) ? 0 : propertyOrientation; if (property is null || property.Width is null || property.Height is null) - throw new Exception(); - if (!string.IsNullOrEmpty(property.Orientation) && int.TryParse(property.Orientation, out int propertyOrientation)) - orientation = propertyOrientation; - else - orientation = Metadata.Models.Stateless.Methods.IMetadata.GetOrientation(metadataCollection); + throw new NotSupportedException(); checkWidth = property.Width.Value; checkHeight = property.Height.Value; if (!_ValidResolutions.Contains(_Original)) @@ -438,7 +434,7 @@ public class C_Resize public FileHolder GetResizedFileHolder(string cResultsFullGroupDirectory, Item item, bool outputResolutionHasNumber, int id) => GetResizedFileHolder(cResultsFullGroupDirectory, item, outputResolutionHasNumber, $"{id}{item.ImageFileHolder.ExtensionLowered}"); - public Dictionary GetResizeKeyValuePairs(Configuration configuration, string cResultsFullGroupDirectory, List> subFileTuples, List parseExceptions, List> metadataCollection, Shared.Models.Property property, MappingFromItem mappingFromItem) + public Dictionary GetResizeKeyValuePairs(Configuration configuration, string cResultsFullGroupDirectory, List> subFileTuples, List parseExceptions, Shared.Models.Property property, MappingFromItem mappingFromItem) { Dictionary? results; string json; @@ -482,7 +478,7 @@ public class C_Resize } if (results is null) { - results = GetImageResizes(property, metadataCollection); + results = GetImageResizes(property); json = JsonSerializer.Serialize(results, _WriteIndentedJsonSerializerOptions); bool updateDateWhenMatches = dateTimes.Any() && fileInfo.Exists && dateTimes.Max() > fileInfo.LastWriteTime; DateTime? dateTime = !updateDateWhenMatches ? null : dateTimes.Max(); diff --git a/Set-Created-Date/Models/AppSettings.cs b/Set-Created-Date/Models/AppSettings.cs index 2bb9297..ab2b290 100644 --- a/Set-Created-Date/Models/AppSettings.cs +++ b/Set-Created-Date/Models/AppSettings.cs @@ -3,30 +3,22 @@ using System.Text.Json.Serialization; namespace View_by_Distance.Set.Created.Date.Models; -public class AppSettings +public record AppSettings(string Company, + string CopyTo, + int MaxDegreeOfParallelism, + string WorkingDirectoryName) { - public string Company { init; get; } - public string CopyTo { init; get; } - public int MaxDegreeOfParallelism { init; get; } - public string WorkingDirectoryName { init; get; } - - [JsonConstructor] - public AppSettings(string company, - string copyTo, - int maxDegreeOfParallelism, - string workingDirectoryName) - { - Company = company; - CopyTo = copyTo; - MaxDegreeOfParallelism = maxDegreeOfParallelism; - WorkingDirectoryName = workingDirectoryName; - } - public override string ToString() { - string result = JsonSerializer.Serialize(this, new JsonSerializerOptions() { WriteIndented = true }); + string result = JsonSerializer.Serialize(this, AppSettingsSourceGenerationContext.Default.AppSettings); return result; } +} + +[JsonSourceGenerationOptions(WriteIndented = true)] +[JsonSerializable(typeof(AppSettings))] +internal partial class AppSettingsSourceGenerationContext : JsonSerializerContext +{ } \ No newline at end of file diff --git a/Set-Created-Date/Models/Binder/.editorconfig b/Set-Created-Date/Models/Binder/.editorconfig new file mode 100644 index 0000000..1c444cd --- /dev/null +++ b/Set-Created-Date/Models/Binder/.editorconfig @@ -0,0 +1,2 @@ +[*.cs] +csharp_preserve_single_line_statements = true \ No newline at end of file diff --git a/Set-Created-Date/Models/Binder/Configuration.cs b/Set-Created-Date/Models/Binder/Configuration.cs index 42cadd7..603eea1 100644 --- a/Set-Created-Date/Models/Binder/Configuration.cs +++ b/Set-Created-Date/Models/Binder/Configuration.cs @@ -1,6 +1,5 @@ using Microsoft.Extensions.Configuration; using Phares.Shared; -using System.ComponentModel.DataAnnotations; using System.Text.Json; namespace View_by_Distance.Set.Created.Date.Models.Binder; @@ -10,9 +9,9 @@ public class Configuration #nullable disable - [Display(Name = "Ignore Extensions"), Required] public string[] IgnoreExtensions { get; set; } - [Display(Name = "Property Configuration"), Required] public Property.Models.Configuration PropertyConfiguration { get; set; } - [Display(Name = "Person Birthday Format"), Required] public string PersonBirthdayFormat { get; set; } + public string[] IgnoreExtensions { get; set; } + public Property.Models.Configuration PropertyConfiguration { get; set; } + public string PersonBirthdayFormat { get; set; } #nullable restore @@ -25,12 +24,9 @@ public class Configuration 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 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)); result = new( configuration.IgnoreExtensions, configuration.PersonBirthdayFormat, diff --git a/Shared/.kanbn/index.md b/Shared/.kanbn/index.md index 30336e7..ad8aaa8 100644 --- a/Shared/.kanbn/index.md +++ b/Shared/.kanbn/index.md @@ -1,7 +1,7 @@ --- -type: "Kanban" -created: "2023-08-23T22:44:24.920Z" -updated: "2023-09-30T02:39:33.671Z" +type: Kanban +created: '2023-08-23T22:44:24.920Z' +updated: '2023-09-30T02:39:33.671Z' startedColumns: - 'In Progress' completedColumns: @@ -42,9 +42,11 @@ taskTemplate: '^+^_${overdue ? ''^R'' : ''''}${name}^: ${relations ? (''\n^-^/^g - [verify-camera-model-still-works](tasks/verify-camera-model-still-works.md) - [run-limiting-on-days](tasks/run-limiting-on-days.md) - [merge-kristy-files](tasks/merge-kristy-files.md) +- [limit-amazon-sync](tasks/limit-amazon-sync.md) ## Done +- [sftp-sync](tasks/sftp-sync.md) - [eof-error](tasks/eof-error.md) - [shrink-percent](tasks/shrink-percent.md) - [setup-photo-prism-again-in-wsl-docker](tasks/setup-photo-prism-again-in-wsl-docker.md) diff --git a/Shared/.kanbn/tasks/limit-amazon-sync.md b/Shared/.kanbn/tasks/limit-amazon-sync.md new file mode 100644 index 0000000..bb281c9 --- /dev/null +++ b/Shared/.kanbn/tasks/limit-amazon-sync.md @@ -0,0 +1,14 @@ +--- +created: 2023-10-14T22:34:13.711Z +updated: 2023-10-15T08:07:29.699Z +assigned: "" +progress: 0 +tags: [] +started: 2023-10-14T00:00:00.000Z +--- + +# Limit Amazon Sync + +Don't sync using ValidKeyWordsToIgnoreInRandom + +https://github.com/trevorhobenshield/amazon_photos#installation diff --git a/Shared/.kanbn/tasks/sftp-sync.md b/Shared/.kanbn/tasks/sftp-sync.md new file mode 100644 index 0000000..67403d4 --- /dev/null +++ b/Shared/.kanbn/tasks/sftp-sync.md @@ -0,0 +1,11 @@ +--- +created: 2023-10-14T22:29:10.180Z +updated: 2023-10-14T22:29:16.518Z +assigned: "" +progress: 0 +tags: [] +started: 2023-10-14T22:29:10.181Z +completed: 2023-10-14T22:29:16.518Z +--- + +# SFTP Sync diff --git a/Shared/Models/Properties/IPropertyConfiguration.cs b/Shared/Models/Properties/IPropertyConfiguration.cs index 7b1f2c1..7280890 100644 --- a/Shared/Models/Properties/IPropertyConfiguration.cs +++ b/Shared/Models/Properties/IPropertyConfiguration.cs @@ -5,6 +5,7 @@ public interface IPropertyConfiguration public string DateGroup { init; get; } public string[] IgnoreExtensions { init; get; } + public string[] IgnoreRulesKeyWords { init; get; } public string PersonBirthdayFormat { init; get; } public bool PropertiesChangedForProperty { init; get; } public string[] PropertyContentCollectionFiles { init; get; } @@ -17,6 +18,7 @@ public interface IPropertyConfiguration public string? ModelName { get; } public int? NumberOfJitters { get; } public int? NumberOfTimesToUpsample { get; } + public int Offset { init; get; } public string? PredictorModelName { get; } public string RootDirectory { get; } diff --git a/Shared/Models/Relation.cs b/Shared/Models/Relation.cs index 2d6b1b5..e8ef6d0 100644 --- a/Shared/Models/Relation.cs +++ b/Shared/Models/Relation.cs @@ -11,4 +11,4 @@ public record Relation(int DistancePermyriad, string File) return result; } -} +} \ No newline at end of file diff --git a/Shared/Models/RelationContainer.cs b/Shared/Models/RelationContainer.cs index c30e45d..ab8d897 100644 --- a/Shared/Models/RelationContainer.cs +++ b/Shared/Models/RelationContainer.cs @@ -12,4 +12,4 @@ public record RelationContainer(FileHolder FileHolder, ReadOnlyCollection - 1000000; - - int TestStatic_GetSortOrderOnlyLengthIndex() => - GetSortOrderOnlyLengthIndex(); - static int GetSortOrderOnlyLengthIndex() => - GetOffset().ToString().Length + 3; + short TestStatic_GetSortOrderOnlyLengthIndex(int offset) => + GetSortOrderOnlyLengthIndex(offset); + static short GetSortOrderOnlyLengthIndex(int offset) => + (short)(offset.ToString().Length + 3); char TestStatic_GetDirectory(string fileName) => GetDirectory(fileName); @@ -84,14 +81,14 @@ public interface IDirectory static List CopyOrMove(List<(Models.FileHolder, string?, string)> toDoCollection, bool move, bool moveBack, Action? tick) => XDirectory.CopyOrMove(toDoCollection, move, moveBack, tick); - (bool, int?) TestStatic_GetId(int sortOrderOnlyLengthIndex, Models.FileHolder fileHolder) => + (bool, int?) TestStatic_GetId(short sortOrderOnlyLengthIndex, Models.FileHolder fileHolder) => GetId(sortOrderOnlyLengthIndex, fileHolder); - static (bool, int?) GetId(int sortOrderOnlyLengthIndex, Models.FileHolder fileHolder) => + static (bool, int?) GetId(short sortOrderOnlyLengthIndex, Models.FileHolder fileHolder) => XDirectory.GetId(sortOrderOnlyLengthIndex, fileHolder); - (bool, int?) TestStatic_GetId(Models.FileHolder fileHolder) => - GetId(fileHolder); - static (bool, int?) GetId(Models.FileHolder fileHolder) => - XDirectory.GetId(GetSortOrderOnlyLengthIndex(), fileHolder); + (bool, int?) TestStatic_GetId(int offset, Models.FileHolder fileHolder) => + GetId(offset, fileHolder); + static (bool, int?) GetId(int offset, Models.FileHolder fileHolder) => + XDirectory.GetId(GetSortOrderOnlyLengthIndex(offset), fileHolder); } \ No newline at end of file diff --git a/Shared/Models/Stateless/Methods/XDirectory.cs b/Shared/Models/Stateless/Methods/XDirectory.cs index 2c91fa6..7d0d3e8 100644 --- a/Shared/Models/Stateless/Methods/XDirectory.cs +++ b/Shared/Models/Stateless/Methods/XDirectory.cs @@ -281,7 +281,7 @@ internal abstract partial class XDirectory } } - internal static (bool, int?) GetId(int sortOrderOnlyLengthIndex, Models.FileHolder fileHolder) + internal static (bool, int?) GetId(short sortOrderOnlyLengthIndex, Models.FileHolder fileHolder) { int? id; short? multiplier; @@ -319,13 +319,13 @@ internal abstract partial class XDirectory return (nameWithoutExtensionIsIdFormat, id); } - private static SortedRecord[] GetSortedRecords(List filesCollection) + private static SortedRecord[] GetSortedRecords(int offset, List filesCollection) { List results = new(); int? id; Models.FileHolder fileHolder; bool nameWithoutExtensionIsIdFormat; - int sortOrderOnlyLengthIndex = IDirectory.GetSortOrderOnlyLengthIndex(); + short sortOrderOnlyLengthIndex = IDirectory.GetSortOrderOnlyLengthIndex(offset); foreach (string[] files in filesCollection) { foreach (string file in files) @@ -357,10 +357,9 @@ internal abstract partial class XDirectory Models.FileHolder fileHolder; List distinctIds = new(); List distinct = new(); - int offset = IDirectory.GetOffset(); List distinctDirectories = new(); int intMinValueLength = int.MinValue.ToString().Length; - SortedRecord[] sortedRecords = GetSortedRecords(filesCollection); + SortedRecord[] sortedRecords = GetSortedRecords(propertyConfiguration.Offset, filesCollection); string? alternateResultAllInOne = !propertyConfiguration.ResultAllInOne.Contains(' ') ? null : propertyConfiguration.ResultAllInOne.Replace(' ', '-'); for (int i = 0; i < sortedRecords.Length; i++) { @@ -390,7 +389,7 @@ internal abstract partial class XDirectory } if (ifCanUseId && sortedRecord.NameWithoutExtensionIsIdFormat && sortedRecord.Id is not null && fileHolder.DirectoryName is not null) { - paddedId = IDirectory.GetPaddedId(intMinValueLength, offset + i, sortedRecord.Id.Value); + paddedId = IDirectory.GetPaddedId(intMinValueLength, propertyConfiguration.Offset + i, sortedRecord.Id.Value); paddedIdFile = Path.Combine(fileHolder.DirectoryName, $"{paddedId}{fileHolder.ExtensionLowered}"); if (!File.Exists(paddedIdFile)) { @@ -462,9 +461,9 @@ internal abstract partial class XDirectory foreach ((Models.FileHolder fileHolder, string? alternateFile, string to) in toDoCollection) { tick?.Invoke(); - if (alternateFile is not null) - _ = XPath.WriteAllText(alternateFile, fileHolder.FullName, updateDateWhenMatches: false, compareBeforeWrite: true, updateToWhenMatches: null); fileInfo = new(to); + if (!fileInfo.Exists && alternateFile is not null) + _ = XPath.WriteAllText(alternateFile, fileHolder.FullName, updateDateWhenMatches: false, compareBeforeWrite: true, updateToWhenMatches: null); if (fileInfo.Exists) { if (fileHolder.Length != fileInfo.Length || fileHolder.LastWriteTime != fileInfo.LastWriteTime) diff --git a/Shared/Models/Stateless/Methods/XPath.cs b/Shared/Models/Stateless/Methods/XPath.cs index a5aead1..7d2b13a 100644 --- a/Shared/Models/Stateless/Methods/XPath.cs +++ b/Shared/Models/Stateless/Methods/XPath.cs @@ -286,8 +286,9 @@ internal abstract class XPath internal static Dictionary GetKeyValuePairs(IPropertyConfiguration propertyConfiguration, string? resultsFullGroupDirectory, string[]? directories) { Dictionary results = new(); - int converted = int.Parse($"1{new string('0', propertyConfiguration.ResultAllInOneSubdirectoryLength)}"); + string directory; string checkDirectory; + int converted = int.Parse($"1{new string('0', propertyConfiguration.ResultAllInOneSubdirectoryLength)}"); int plusOne = converted + 1; List collection = new(); if (directories is not null) @@ -308,10 +309,11 @@ internal abstract class XPath } else { + directory = Path.Combine(resultsFullGroupDirectory, key, propertyConfiguration.ResultAllInOne); if (i == converted) - checkDirectory = Path.GetFullPath(Path.Combine(resultsFullGroupDirectory, key, propertyConfiguration.ResultAllInOne, new('-', propertyConfiguration.ResultAllInOneSubdirectoryLength))); + checkDirectory = Path.GetFullPath(Path.Combine(directory, new('-', propertyConfiguration.ResultAllInOneSubdirectoryLength))); else - checkDirectory = Path.GetFullPath(Path.Combine(resultsFullGroupDirectory, key, propertyConfiguration.ResultAllInOne, i.ToString().PadLeft(propertyConfiguration.ResultAllInOneSubdirectoryLength, '0'))); + checkDirectory = Path.GetFullPath(Path.Combine(directory, i.ToString().PadLeft(propertyConfiguration.ResultAllInOneSubdirectoryLength, '0'))); } if (!Directory.Exists(checkDirectory)) _ = Directory.CreateDirectory(checkDirectory); diff --git a/Tests/UnitTestResize.cs b/Tests/UnitTestResize.cs index f98b742..62298e9 100644 --- a/Tests/UnitTestResize.cs +++ b/Tests/UnitTestResize.cs @@ -2,9 +2,11 @@ using Microsoft.Extensions.Configuration; using Microsoft.VisualStudio.TestTools.UnitTesting; using Phares.Shared; using Serilog; +using System.Collections.ObjectModel; using System.Diagnostics; using System.Drawing.Imaging; using System.Reflection; +using System.Text.Json; using View_by_Distance.Metadata.Models; using View_by_Distance.Property.Models; using View_by_Distance.Resize.Models; @@ -53,6 +55,7 @@ public class UnitTestResize logger = Log.ForContext(); propertyConfiguration = Property.Models.Binder.Configuration.Get(isEnvironment, configurationRoot); configuration = Models.Binder.Configuration.Get(isEnvironment, configurationRoot, propertyConfiguration); + Property.Models.Configuration.Verify(propertyConfiguration, requireExist: false); logger.Information("Complete"); _Logger = logger; _AppSettings = appSettings; @@ -132,8 +135,10 @@ public class UnitTestResize throw new NullReferenceException(nameof(_PropertyConfiguration.NumberOfJitters)); if (_PropertyConfiguration.NumberOfTimesToUpsample is null) throw new NullReferenceException(nameof(_PropertyConfiguration.NumberOfTimesToUpsample)); - string sourceFileName = "100000507001158650387.jpg"; - string sourceDirectoryName = "Facebook/2023.2 Summer Facebook"; + // string sourceFileName = "100000507001158650387.jpg"; + // string sourceDirectoryName = "Facebook/2023.2 Summer Facebook"; + string sourceFileName = "105131603001106320328.jpg"; + string sourceDirectoryName = "Mike iCloud Have Date Taken 2022 !9"; Item item; bool reverse = false; FileHolder resizedFileHolder; @@ -142,7 +147,6 @@ public class UnitTestResize const bool isValidImageFormatExtension = true; List> subFileTuples = new(); string[] alternateFileLines = Array.Empty(); - List> metadataCollection; int length = _PropertyConfiguration.RootDirectory.Length; string[] changesFrom = new string[] { nameof(A_Property) }; string outputResolution = _Configuration.OutputResolutions[0]; @@ -165,7 +169,7 @@ public class UnitTestResize FileHolder sourceDirectoryFileHolder = new(".json"); string sourceDirectory = Path.GetFullPath(Path.Combine(_PropertyConfiguration.RootDirectory, sourceDirectoryName)); FileHolder fileHolder = new(Path.Combine(sourceDirectory, sourceFileName)); - (_, int? id) = IDirectory.GetId(fileHolder); + (_, int? id) = IDirectory.GetId(_PropertyConfiguration.Offset, fileHolder); Assert.IsNotNull(id); string relativePath = IPath.GetRelativePath(fileHolder.FullName, length); string propertyLogicSourceDirectory = Path.GetFullPath(Path.Combine(aPropertySingletonDirectory, sourceDirectoryName)); @@ -186,12 +190,16 @@ public class UnitTestResize resizedFileHolder = resize.GetResizedFileHolder(cResultsFullGroupDirectory, item, outputResolutionHasNumber, id.Value); item.SetResizedFileHolder(resize.FileNameExtension, resizedFileHolder); MappingFromItem mappingFromItem = IMappingFromItem.GetMappingFromItem(item); - (int _, metadataCollection) = metadata.GetMetadataCollection(subFileTuples, parseExceptions, changesFrom, mappingFromItem); - Dictionary outputResolutionToResize = resize.GetResizeKeyValuePairs(_PropertyConfiguration, cResultsFullGroupDirectory, subFileTuples, parseExceptions, metadataCollection, item.Property, mappingFromItem); + Dictionary outputResolutionToResize = resize.GetResizeKeyValuePairs(_PropertyConfiguration, cResultsFullGroupDirectory, subFileTuples, parseExceptions, item.Property, mappingFromItem); Assert.IsNotNull(mappingFromItem.ResizedFileHolder); resize.SaveResizedSubfile(_PropertyConfiguration, outputResolution, cResultsFullGroupDirectory, subFileTuples, item, item.Property, mappingFromItem, outputResolutionToResize); string blurHash = blurHasher.Encode(resizedFileHolder); Assert.IsNotNull(blurHash); + ReadOnlyDictionary metadataExtractorDirectories = metadata.GetMetadataCollection(subFileTuples, parseExceptions, changesFrom, mappingFromItem); + string json = JsonSerializer.Serialize(metadataExtractorDirectories, ReadOnlyDictionaryStringMetadataExtractorDirectorySourceGenerationContext.Default.ReadOnlyDictionaryStringMetadataExtractorDirectory); + File.WriteAllText("../../../.json", json); + MetadataExtractor.GeoLocation? geoLocation = Metadata.Models.Stateless.Methods.IMetadata.GeoLocation(metadataExtractorDirectories); + double? distance = geoLocation is null ? null : Metadata.Models.Stateless.Methods.IMetadata.GetDistance(1, 1, geoLocation.Latitude, geoLocation.Longitude); NonThrowTryCatch(); } diff --git a/TestsWithFaceRecognitionDotNet/UnitTestFace.cs b/TestsWithFaceRecognitionDotNet/UnitTestFace.cs index 60c4c6b..a0fee3f 100644 --- a/TestsWithFaceRecognitionDotNet/UnitTestFace.cs +++ b/TestsWithFaceRecognitionDotNet/UnitTestFace.cs @@ -2,9 +2,11 @@ using Microsoft.Extensions.Configuration; using Microsoft.VisualStudio.TestTools.UnitTesting; using Phares.Shared; using Serilog; +using System.Collections.ObjectModel; using System.Diagnostics; using System.Drawing.Imaging; using System.Reflection; +using System.Text.Json; using View_by_Distance.FaceRecognitionDotNet; using View_by_Distance.Metadata.Models; using View_by_Distance.Property.Models; @@ -55,6 +57,7 @@ public class UnitTestFace logger = Log.ForContext(); propertyConfiguration = Property.Models.Binder.Configuration.Get(isEnvironment, configurationRoot); configuration = Models.Binder.Configuration.Get(isEnvironment, configurationRoot, propertyConfiguration); + Property.Models.Configuration.Verify(propertyConfiguration, requireExist: false); logger.Information("Complete"); _Logger = logger; _AppSettings = appSettings; @@ -217,7 +220,6 @@ public class UnitTestFace const bool isValidImageFormatExtension = true; List> subFileTuples = new(); string[] alternateFileLines = Array.Empty(); - List> metadataCollection; int length = _PropertyConfiguration.RootDirectory.Length; string[] changesFrom = new string[] { nameof(A_Property) }; string outputResolution = _Configuration.OutputResolutions[0]; @@ -240,7 +242,7 @@ public class UnitTestFace FileHolder sourceDirectoryFileHolder = new(".json"); string sourceDirectory = Path.GetFullPath(Path.Combine(_PropertyConfiguration.RootDirectory, sourceDirectoryName)); FileHolder fileHolder = new(Path.Combine(sourceDirectory, sourceFileName)); - (_, int? id) = IDirectory.GetId(fileHolder); + (_, int? id) = IDirectory.GetId(_PropertyConfiguration.Offset, fileHolder); Assert.IsNotNull(id); string relativePath = IPath.GetRelativePath(fileHolder.FullName, length); string propertyLogicSourceDirectory = Path.GetFullPath(Path.Combine(aPropertySingletonDirectory, sourceDirectoryName)); @@ -261,12 +263,15 @@ public class UnitTestFace resizedFileHolder = resize.GetResizedFileHolder(cResultsFullGroupDirectory, item, outputResolutionHasNumber, id.Value); item.SetResizedFileHolder(resize.FileNameExtension, resizedFileHolder); MappingFromItem mappingFromItem = IMappingFromItem.GetMappingFromItem(item); - (int _, metadataCollection) = metadata.GetMetadataCollection(subFileTuples, parseExceptions, changesFrom, mappingFromItem); - Dictionary outputResolutionToResize = resize.GetResizeKeyValuePairs(_PropertyConfiguration, cResultsFullGroupDirectory, subFileTuples, parseExceptions, metadataCollection, item.Property, mappingFromItem); + IReadOnlyList directories = MetadataExtractor.ImageMetadataReader.ReadMetadata(resizedFileHolder.FullName); + Dictionary outputResolutionToResize = resize.GetResizeKeyValuePairs(_PropertyConfiguration, cResultsFullGroupDirectory, subFileTuples, parseExceptions, item.Property, mappingFromItem); Assert.IsNotNull(mappingFromItem.ResizedFileHolder); resize.SaveResizedSubfile(_PropertyConfiguration, outputResolution, cResultsFullGroupDirectory, subFileTuples, item, item.Property, mappingFromItem, outputResolutionToResize); string blurHash = blurHasher.Encode(resizedFileHolder); Assert.IsNotNull(blurHash); + ReadOnlyDictionary? metadataExtractorDirectories = metadata.GetMetadataCollection(subFileTuples, parseExceptions, changesFrom, mappingFromItem); + string json = JsonSerializer.Serialize(metadataExtractorDirectories, ReadOnlyDictionaryStringMetadataExtractorDirectorySourceGenerationContext.Default.ReadOnlyDictionaryStringMetadataExtractorDirectory); + File.WriteAllText("../../../.json", json); Image image = FaceRecognition.LoadImageFile(mappingFromItem.ResizedFileHolder.FullName); Assert.IsNotNull(image); (Model model, PredictorModel predictorModel, ModelParameter modelParameter) = GetModel(_Configuration);