Compare commits
10 Commits
ec22446643
...
dca487deb3
Author | SHA1 | Date | |
---|---|---|---|
dca487deb3 | |||
7f8b09e66c | |||
9a772f8dcc | |||
99e3f29720 | |||
bf2d6849b3 | |||
c9dbce3b57 | |||
1200780eee | |||
4081a73b9d | |||
cfe43360fc | |||
13848a4cb7 |
@ -82,28 +82,60 @@ csharp_style_var_elsewhere = false:warning
|
|||||||
csharp_style_var_for_built_in_types = false:warning
|
csharp_style_var_for_built_in_types = false:warning
|
||||||
csharp_style_var_when_type_is_apparent = false:warning
|
csharp_style_var_when_type_is_apparent = false:warning
|
||||||
csharp_using_directive_placement = outside_namespace
|
csharp_using_directive_placement = outside_namespace
|
||||||
|
dotnet_analyzer_diagnostic.category-Design.severity = error
|
||||||
|
dotnet_analyzer_diagnostic.category-Documentation.severity = error
|
||||||
|
dotnet_analyzer_diagnostic.category-Globalization.severity = none
|
||||||
|
dotnet_analyzer_diagnostic.category-Interoperability.severity = error
|
||||||
|
dotnet_analyzer_diagnostic.category-Maintainability.severity = error
|
||||||
|
dotnet_analyzer_diagnostic.category-Naming.severity = none
|
||||||
|
dotnet_analyzer_diagnostic.category-Performance.severity = none
|
||||||
|
dotnet_analyzer_diagnostic.category-Reliability.severity = error
|
||||||
|
dotnet_analyzer_diagnostic.category-Security.severity = error
|
||||||
|
dotnet_analyzer_diagnostic.category-SingleFile.severity = error
|
||||||
|
dotnet_analyzer_diagnostic.category-Style.severity = error
|
||||||
|
dotnet_analyzer_diagnostic.category-Usage.severity = error
|
||||||
dotnet_code_quality_unused_parameters = all
|
dotnet_code_quality_unused_parameters = all
|
||||||
dotnet_code_quality_unused_parameters = non_public # IDE0060: Remove unused parameter
|
dotnet_code_quality_unused_parameters = non_public # IDE0060: Remove unused parameter
|
||||||
dotnet_code_quality.CAXXXX.api_surface = private, internal
|
dotnet_code_quality.CAXXXX.api_surface = private, internal
|
||||||
|
dotnet_diagnostic.CA1001.severity = none # CA1001: Types that own disposable fields should be disposable
|
||||||
|
dotnet_diagnostic.CA1051.severity = none # CA1051: Do not declare visible instance fields
|
||||||
|
dotnet_diagnostic.CA1511.severity = warning # CA1511: Use 'ArgumentException.ThrowIfNullOrEmpty' instead of explicitly throwing a new exception instance
|
||||||
|
dotnet_diagnostic.CA1511.severity = warning # CA1511: Use 'ArgumentException.ThrowIfNullOrEmpty' instead of explicitly throwing a new exception instance
|
||||||
|
dotnet_diagnostic.CA1513.severity = warning # Use 'ObjectDisposedException.ThrowIf' instead of explicitly throwing a new exception instance
|
||||||
|
dotnet_diagnostic.CA1816.severity = none # CA1816: Call GC.SuppressFinalize correctly
|
||||||
dotnet_diagnostic.CA1825.severity = warning # CA1823: Avoid zero-length array allocations
|
dotnet_diagnostic.CA1825.severity = warning # CA1823: Avoid zero-length array allocations
|
||||||
dotnet_diagnostic.CA1829.severity = warning # CA1829: Use Length/Count property instead of Count() when available
|
dotnet_diagnostic.CA1829.severity = warning # CA1829: Use Length/Count property instead of Count() when available
|
||||||
dotnet_diagnostic.CA1834.severity = warning # CA1834: Consider using 'StringBuilder.Append(char)' when applicable
|
dotnet_diagnostic.CA1834.severity = warning # CA1834: Consider using 'StringBuilder.Append(char)' when applicable
|
||||||
dotnet_diagnostic.CA1860.severity = error # CA1860: Prefer comparing 'Count' to 0 rather than using 'Any()', both for clarity and for performance
|
dotnet_diagnostic.CA1854.severity = warning # CA1854: Prefer a 'TryGetValue' call over a Dictionary indexer access guarded by a 'ContainsKey' check to avoid double lookup
|
||||||
|
dotnet_diagnostic.CA1860.severity = warning # CA1860: Prefer comparing 'Count' to 0 rather than using 'Any()', both for clarity and for performance
|
||||||
|
dotnet_diagnostic.CA1861.severity = none # CA1861: Prefer 'static readonly' fields over constant array arguments
|
||||||
|
dotnet_diagnostic.CA1862.severity = warning # CA1862: Prefer using 'string.Equals(string, StringComparison)' to perform a case-insensitive comparison, but keep in mind that this might cause subtle changes in behavior, so make sure to conduct thorough testing after applying the suggestion, or if culturally sensitive comparison is not required, consider using 'StringComparison.OrdinalIgnoreCase'
|
||||||
|
dotnet_diagnostic.CA1866.severity = none # CA1866: Use 'string.EndsWith(char)' instead of 'string.EndsWith(string)' when you have a string with a single char
|
||||||
dotnet_diagnostic.CA1869.severity = none # CA1869: Avoid creating a new 'JsonSerializerOptions' instance for every serialization operation. Cache and reuse instances instead.
|
dotnet_diagnostic.CA1869.severity = none # CA1869: Avoid creating a new 'JsonSerializerOptions' instance for every serialization operation. Cache and reuse instances instead.
|
||||||
|
dotnet_diagnostic.CA2201.severity = none # CA2201: Exception type System.NullReferenceException is reserved by the runtime
|
||||||
dotnet_diagnostic.CA2254.severity = none # CA2254: The logging message template should not vary between calls to 'LoggerExtensions.LogInformation(ILogger, string?, params object?[])'
|
dotnet_diagnostic.CA2254.severity = none # CA2254: The logging message template should not vary between calls to 'LoggerExtensions.LogInformation(ILogger, string?, params object?[])'
|
||||||
dotnet_diagnostic.IDE0001.severity = warning # IDE0001: Simplify name
|
dotnet_diagnostic.IDE0001.severity = warning # IDE0001: Simplify name
|
||||||
dotnet_diagnostic.IDE0002.severity = warning # Simplify (member access) - System.Version.Equals("1", "2"); Version.Equals("1", "2");
|
dotnet_diagnostic.IDE0002.severity = warning # Simplify (member access) - System.Version.Equals("1", "2"); Version.Equals("1", "2");
|
||||||
dotnet_diagnostic.IDE0004.severity = warning # IDE0004: Cast is redundant.
|
dotnet_diagnostic.IDE0004.severity = warning # IDE0004: Cast is redundant.
|
||||||
dotnet_diagnostic.IDE0005.severity = warning # Using directive is unnecessary
|
dotnet_diagnostic.IDE0005.severity = warning # Using directive is unnecessary
|
||||||
dotnet_diagnostic.IDE0028.severity = error # IDE0028: Collection initialization can be simplified
|
dotnet_diagnostic.IDE0010.severity = none # Add missing cases to switch statement (IDE0010)
|
||||||
|
dotnet_diagnostic.IDE0028.severity = warning # IDE0028: Collection initialization can be simplified
|
||||||
dotnet_diagnostic.IDE0031.severity = warning # Use null propagation (IDE0031)
|
dotnet_diagnostic.IDE0031.severity = warning # Use null propagation (IDE0031)
|
||||||
dotnet_diagnostic.IDE0047.severity = warning # IDE0047: Parentheses can be removed
|
dotnet_diagnostic.IDE0047.severity = warning # IDE0047: Parentheses can be removed
|
||||||
|
dotnet_diagnostic.IDE0048.severity = none # Parentheses preferences (IDE0047 and IDE0048)
|
||||||
dotnet_diagnostic.IDE0049.severity = warning # Use language keywords instead of framework type names for type references (IDE0049)
|
dotnet_diagnostic.IDE0049.severity = warning # Use language keywords instead of framework type names for type references (IDE0049)
|
||||||
|
dotnet_diagnostic.IDE0051.severity = error # Private member '' is unused [, ]
|
||||||
|
dotnet_diagnostic.IDE0058.severity = warning # IDE0058: Expression value is never used
|
||||||
dotnet_diagnostic.IDE0060.severity = warning # IDE0060: Remove unused parameter
|
dotnet_diagnostic.IDE0060.severity = warning # IDE0060: Remove unused parameter
|
||||||
|
dotnet_diagnostic.IDE0074.severity = warning # IDE0074: Use compound assignment
|
||||||
|
dotnet_diagnostic.IDE0130.severity = none # Namespace does not match folder structure (IDE0130)
|
||||||
|
dotnet_diagnostic.IDE0200.severity = warning # IDE0200: Lambda expression can be removed [Map]
|
||||||
|
dotnet_diagnostic.IDE0230.severity = warning # IDE0230: Use UTF-8 string literal
|
||||||
dotnet_diagnostic.IDE0290.severity = none # Use primary constructor [Distance]csharp(IDE0290)
|
dotnet_diagnostic.IDE0290.severity = none # Use primary constructor [Distance]csharp(IDE0290)
|
||||||
dotnet_diagnostic.IDE0300.severity = error # IDE0300: Collection initialization can be simplified
|
dotnet_diagnostic.IDE0300.severity = warning # IDE0300: Collection initialization can be simplified
|
||||||
dotnet_diagnostic.IDE0301.severity = error #IDE0301: Collection initialization can be simplified
|
dotnet_diagnostic.IDE0301.severity = warning #IDE0301: Collection initialization can be simplified
|
||||||
dotnet_diagnostic.IDE0305.severity = none # IDE0305: Collection initialization can be simplified
|
dotnet_diagnostic.IDE0305.severity = none # IDE0305: Collection initialization can be simplified
|
||||||
|
dotnet_diagnostic.JSON002.severity = warning # JSON002: Probable JSON string detected
|
||||||
dotnet_naming_rule.abstract_method_should_be_pascal_case.severity = warning
|
dotnet_naming_rule.abstract_method_should_be_pascal_case.severity = warning
|
||||||
dotnet_naming_rule.abstract_method_should_be_pascal_case.style = pascal_case
|
dotnet_naming_rule.abstract_method_should_be_pascal_case.style = pascal_case
|
||||||
dotnet_naming_rule.abstract_method_should_be_pascal_case.symbols = abstract_method
|
dotnet_naming_rule.abstract_method_should_be_pascal_case.symbols = abstract_method
|
||||||
|
2
.gitignore
vendored
2
.gitignore
vendored
@ -468,3 +468,5 @@ globalStorage/
|
|||||||
[Ll]ib/
|
[Ll]ib/
|
||||||
|
|
||||||
Shared/.kanbn
|
Shared/.kanbn
|
||||||
|
|
||||||
|
.Immich/immich-assets.json
|
||||||
|
3
.vscode/mklink.md
vendored
3
.vscode/mklink.md
vendored
@ -7,8 +7,9 @@ updated: "2023-10-20T03:57:15.006Z"
|
|||||||
# mklink
|
# mklink
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
|
mklink /J "D:\1-Images-A\Images-4083e56a-Results\A2)People\4083e56a\{}\!" "D:\1-Images-A\Images-4083e56a-Results\E)Distance\4083e56a\{}\!"
|
||||||
```
|
```
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
mklink /J "D:\1-Images-A\Images-4083e56a-Results\A2)People\4083e56a\{}\!" "D:\1-Images-A\Images-4083e56a-Results\E)Distance\4083e56a\{}\!"
|
mklink /J "L:\Git\View-by-Distance-MKLink-Console\.Immich" "D:\1-Images-A\Images-c9dbce3b-Results\F)Immich\c9dbce3b\{}"
|
||||||
```
|
```
|
||||||
|
6
.vscode/settings.json
vendored
6
.vscode/settings.json
vendored
@ -20,10 +20,9 @@
|
|||||||
"Hasher",
|
"Hasher",
|
||||||
"Hmmss",
|
"Hmmss",
|
||||||
"Hmmssfff",
|
"Hmmssfff",
|
||||||
|
"Immich",
|
||||||
"jfif",
|
"jfif",
|
||||||
"JOSN",
|
"JOSN",
|
||||||
"Makernote",
|
|
||||||
"Makernotes",
|
|
||||||
"mmod",
|
"mmod",
|
||||||
"Nicéphore",
|
"Nicéphore",
|
||||||
"Niépce",
|
"Niépce",
|
||||||
@ -33,14 +32,15 @@
|
|||||||
"permyriad",
|
"permyriad",
|
||||||
"Phares",
|
"Phares",
|
||||||
"Phgtv",
|
"Phgtv",
|
||||||
"photoshop",
|
|
||||||
"RDHC",
|
"RDHC",
|
||||||
"Rects",
|
"Rects",
|
||||||
"resnet",
|
"resnet",
|
||||||
|
"Rijndael",
|
||||||
"Serilog",
|
"Serilog",
|
||||||
"Subfile",
|
"Subfile",
|
||||||
"Subfiles",
|
"Subfiles",
|
||||||
"Syncthing",
|
"Syncthing",
|
||||||
|
"Thumbhash",
|
||||||
"Unmanaged",
|
"Unmanaged",
|
||||||
"Upsample",
|
"Upsample",
|
||||||
"Vericruz"
|
"Vericruz"
|
||||||
|
10
.vscode/tasks.json
vendored
10
.vscode/tasks.json
vendored
@ -42,6 +42,16 @@
|
|||||||
],
|
],
|
||||||
"problemMatcher": "$msCompile"
|
"problemMatcher": "$msCompile"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"label": "Format-Whitespaces",
|
||||||
|
"command": "dotnet",
|
||||||
|
"type": "process",
|
||||||
|
"args": [
|
||||||
|
"format",
|
||||||
|
"whitespace"
|
||||||
|
],
|
||||||
|
"problemMatcher": "$msCompile"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"label": "build",
|
"label": "build",
|
||||||
"command": "dotnet",
|
"command": "dotnet",
|
||||||
|
@ -20,6 +20,23 @@ public class AppSettings
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void PreVerify(IConfigurationRoot configurationRoot, AppSettings? appSettings)
|
||||||
|
{
|
||||||
|
if (appSettings?.Company is null)
|
||||||
|
{
|
||||||
|
List<string> paths = [];
|
||||||
|
foreach (IConfigurationProvider configurationProvider in configurationRoot.Providers)
|
||||||
|
{
|
||||||
|
if (configurationProvider is not Microsoft.Extensions.Configuration.Json.JsonConfigurationProvider jsonConfigurationProvider)
|
||||||
|
continue;
|
||||||
|
if (jsonConfigurationProvider.Source.FileProvider is not Microsoft.Extensions.FileProviders.PhysicalFileProvider physicalFileProvider)
|
||||||
|
continue;
|
||||||
|
paths.Add(physicalFileProvider.Root);
|
||||||
|
}
|
||||||
|
throw new NotSupportedException($"Not found!{Environment.NewLine}{string.Join(Environment.NewLine, paths.Distinct())}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private static Models.AppSettings Get(AppSettings? appSettings)
|
private static Models.AppSettings Get(AppSettings? appSettings)
|
||||||
{
|
{
|
||||||
Models.AppSettings result;
|
Models.AppSettings result;
|
||||||
@ -36,7 +53,10 @@ public class AppSettings
|
|||||||
public static Models.AppSettings Get(IConfigurationRoot configurationRoot)
|
public static Models.AppSettings Get(IConfigurationRoot configurationRoot)
|
||||||
{
|
{
|
||||||
Models.AppSettings result;
|
Models.AppSettings result;
|
||||||
|
#pragma warning disable IL3050, IL2026
|
||||||
AppSettings? appSettings = configurationRoot.Get<AppSettings>();
|
AppSettings? appSettings = configurationRoot.Get<AppSettings>();
|
||||||
|
#pragma warning restore IL3050, IL2026
|
||||||
|
PreVerify(configurationRoot, appSettings);
|
||||||
result = Get(appSettings);
|
result = Get(appSettings);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,6 @@ namespace View_by_Distance.Compare.Models.Binder;
|
|||||||
public class Configuration
|
public class Configuration
|
||||||
{
|
{
|
||||||
|
|
||||||
#nullable disable
|
|
||||||
public string DiffPropertyDirectory { get; set; }
|
public string DiffPropertyDirectory { get; set; }
|
||||||
public Property.Models.Configuration PropertyConfiguration { get; set; }
|
public Property.Models.Configuration PropertyConfiguration { get; set; }
|
||||||
public string[] Rename { get; set; }
|
public string[] Rename { get; set; }
|
||||||
@ -13,8 +12,6 @@ public class Configuration
|
|||||||
public string[] RenameC { get; set; }
|
public string[] RenameC { get; set; }
|
||||||
public string[] Spelling { get; set; }
|
public string[] Spelling { get; set; }
|
||||||
|
|
||||||
#nullable restore
|
|
||||||
|
|
||||||
public override string ToString()
|
public override string ToString()
|
||||||
{
|
{
|
||||||
string result = JsonSerializer.Serialize(this, new JsonSerializerOptions() { WriteIndented = true });
|
string result = JsonSerializer.Serialize(this, new JsonSerializerOptions() { WriteIndented = true });
|
||||||
|
@ -21,6 +21,23 @@ public class AppSettings
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void PreVerify(IConfigurationRoot configurationRoot, AppSettings? appSettings)
|
||||||
|
{
|
||||||
|
if (appSettings?.Company is null)
|
||||||
|
{
|
||||||
|
List<string> paths = [];
|
||||||
|
foreach (IConfigurationProvider configurationProvider in configurationRoot.Providers)
|
||||||
|
{
|
||||||
|
if (configurationProvider is not Microsoft.Extensions.Configuration.Json.JsonConfigurationProvider jsonConfigurationProvider)
|
||||||
|
continue;
|
||||||
|
if (jsonConfigurationProvider.Source.FileProvider is not Microsoft.Extensions.FileProviders.PhysicalFileProvider physicalFileProvider)
|
||||||
|
continue;
|
||||||
|
paths.Add(physicalFileProvider.Root);
|
||||||
|
}
|
||||||
|
throw new NotSupportedException($"Not found!{Environment.NewLine}{string.Join(Environment.NewLine, paths.Distinct())}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private static Models.AppSettings Get(AppSettings? appSettings)
|
private static Models.AppSettings Get(AppSettings? appSettings)
|
||||||
{
|
{
|
||||||
Models.AppSettings result;
|
Models.AppSettings result;
|
||||||
@ -56,6 +73,7 @@ public class AppSettings
|
|||||||
#pragma warning disable IL3050, IL2026
|
#pragma warning disable IL3050, IL2026
|
||||||
AppSettings? appSettings = configurationRoot.Get<AppSettings>();
|
AppSettings? appSettings = configurationRoot.Get<AppSettings>();
|
||||||
#pragma warning restore IL3050, IL2026
|
#pragma warning restore IL3050, IL2026
|
||||||
|
PreVerify(configurationRoot, appSettings);
|
||||||
result = Get(appSettings);
|
result = Get(appSettings);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -7,13 +7,9 @@ namespace View_by_Distance.Copy.Distinct.Models.Binder;
|
|||||||
public class Configuration
|
public class Configuration
|
||||||
{
|
{
|
||||||
|
|
||||||
#nullable disable
|
public string[]? IgnoreExtensions { get; set; }
|
||||||
|
public Property.Models.Configuration? PropertyConfiguration { get; set; }
|
||||||
public string[] IgnoreExtensions { get; set; }
|
public string? PersonBirthdayFormat { get; set; }
|
||||||
public Property.Models.Configuration PropertyConfiguration { get; set; }
|
|
||||||
public string PersonBirthdayFormat { get; set; }
|
|
||||||
|
|
||||||
#nullable restore
|
|
||||||
|
|
||||||
public override string ToString()
|
public override string ToString()
|
||||||
{
|
{
|
||||||
@ -21,12 +17,30 @@ public class Configuration
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void PreVerify(IConfigurationRoot configurationRoot, Configuration? configuration)
|
||||||
|
{
|
||||||
|
if (configuration?.IgnoreExtensions is null)
|
||||||
|
{
|
||||||
|
List<string> paths = [];
|
||||||
|
foreach (IConfigurationProvider configurationProvider in configurationRoot.Providers)
|
||||||
|
{
|
||||||
|
if (configurationProvider is not Microsoft.Extensions.Configuration.Json.JsonConfigurationProvider jsonConfigurationProvider)
|
||||||
|
continue;
|
||||||
|
if (jsonConfigurationProvider.Source.FileProvider is not Microsoft.Extensions.FileProviders.PhysicalFileProvider physicalFileProvider)
|
||||||
|
continue;
|
||||||
|
paths.Add(physicalFileProvider.Root);
|
||||||
|
}
|
||||||
|
throw new NotSupportedException($"Not found!{Environment.NewLine}{string.Join(Environment.NewLine, paths.Distinct())}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private static Models.Configuration Get(Configuration? configuration)
|
private static Models.Configuration Get(Configuration? configuration)
|
||||||
{
|
{
|
||||||
Models.Configuration result;
|
Models.Configuration result;
|
||||||
if (configuration is null) throw new NullReferenceException(nameof(configuration));
|
if (configuration is null) throw new NullReferenceException(nameof(configuration));
|
||||||
if (configuration.IgnoreExtensions is null) throw new NullReferenceException(nameof(configuration.IgnoreExtensions));
|
if (configuration.IgnoreExtensions is null) throw new NullReferenceException(nameof(configuration.IgnoreExtensions));
|
||||||
if (configuration.PersonBirthdayFormat is null) throw new NullReferenceException(nameof(configuration.PersonBirthdayFormat));
|
if (configuration.PersonBirthdayFormat is null) throw new NullReferenceException(nameof(configuration.PersonBirthdayFormat));
|
||||||
|
if (configuration.PropertyConfiguration is null) throw new NullReferenceException(nameof(configuration.PropertyConfiguration));
|
||||||
result = new(
|
result = new(
|
||||||
configuration.IgnoreExtensions,
|
configuration.IgnoreExtensions,
|
||||||
configuration.PersonBirthdayFormat,
|
configuration.PersonBirthdayFormat,
|
||||||
@ -39,14 +53,19 @@ public class Configuration
|
|||||||
Models.Configuration result;
|
Models.Configuration result;
|
||||||
Configuration? configuration;
|
Configuration? configuration;
|
||||||
if (isEnvironment is null)
|
if (isEnvironment is null)
|
||||||
|
#pragma warning disable IL3050, IL2026
|
||||||
configuration = configurationRoot.Get<Configuration>();
|
configuration = configurationRoot.Get<Configuration>();
|
||||||
|
#pragma warning restore IL3050, IL2026
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
string environmentName = IsEnvironment.GetEnvironmentName(isEnvironment);
|
string environmentName = IsEnvironment.GetEnvironmentName(isEnvironment);
|
||||||
string section = string.Concat(environmentName, ":", nameof(Configuration));
|
string section = string.Concat(environmentName, ":", nameof(Configuration));
|
||||||
IConfigurationSection configurationSection = configurationRoot.GetSection(section);
|
IConfigurationSection configurationSection = configurationRoot.GetSection(section);
|
||||||
|
#pragma warning disable IL3050, IL2026
|
||||||
configuration = configurationSection.Get<Configuration>();
|
configuration = configurationSection.Get<Configuration>();
|
||||||
|
#pragma warning restore IL3050, IL2026
|
||||||
}
|
}
|
||||||
|
PreVerify(configurationRoot, configuration);
|
||||||
result = Get(configuration);
|
result = Get(configuration);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -193,15 +193,11 @@ public class DateGroup
|
|||||||
if (item.Property is not null)
|
if (item.Property is not null)
|
||||||
dateTimes = item.Property.GetDateTimes();
|
dateTimes = item.Property.GetDateTimes();
|
||||||
else
|
else
|
||||||
{
|
dateTimes = [new(item.FilePath.LastWriteTicks)];
|
||||||
if (item.ImageFileHolder.LastWriteTime is null)
|
|
||||||
throw new Exception();
|
|
||||||
dateTimes = [item.ImageFileHolder.LastWriteTime.Value];
|
|
||||||
}
|
|
||||||
if (item.Property is not null && item.Property.DateTimeOriginal is not null)
|
if (item.Property is not null && item.Property.DateTimeOriginal is not null)
|
||||||
dateTime = item.Property.DateTimeOriginal.Value;
|
dateTime = item.Property.DateTimeOriginal.Value;
|
||||||
else if (item.ImageFileHolder.LastWriteTime is not null && item.Property is null)
|
else if (item.Property is null)
|
||||||
dateTime = item.ImageFileHolder.LastWriteTime.Value;
|
dateTime = new(item.FilePath.LastWriteTicks);
|
||||||
else
|
else
|
||||||
dateTime = Shared.Models.Stateless.Methods.IProperty.GetMinimumDateTime(item.Property);
|
dateTime = Shared.Models.Stateless.Methods.IProperty.GetMinimumDateTime(item.Property);
|
||||||
day = dateTime.ToString("MM-dd");
|
day = dateTime.ToString("MM-dd");
|
||||||
@ -213,7 +209,7 @@ public class DateGroup
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
(isWrongYear, _) = Shared.Models.Stateless.Methods.IProperty.IsWrongYear(item.ImageFileHolder, item.Property.DateTimeOriginal, dateTimes);
|
(isWrongYear, _) = Shared.Models.Stateless.Methods.IProperty.IsWrongYear(item.FilePath, item.Property.DateTimeOriginal, dateTimes);
|
||||||
if (isWrongYear is null)
|
if (isWrongYear is null)
|
||||||
flag = '#';
|
flag = '#';
|
||||||
else if (isWrongYear.Value)
|
else if (isWrongYear.Value)
|
||||||
@ -283,18 +279,16 @@ public class DateGroup
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!_Configuration.ByHash || item.Property?.Id is null)
|
if (!_Configuration.ByHash || item.Property?.Id is null)
|
||||||
fileName = item.ImageFileHolder.Name;
|
fileName = item.FilePath.Name;
|
||||||
else
|
else
|
||||||
fileName = $"{item.Property.Id.Value}{item.ImageFileHolder.ExtensionLowered}";
|
fileName = $"{item.Property.Id.Value}{item.FilePath.ExtensionLowered}";
|
||||||
destinationCollection.Add(destinationDirectory);
|
destinationCollection.Add(destinationDirectory);
|
||||||
destinationCollection.AddRange(directoryNames);
|
destinationCollection.AddRange(directoryNames);
|
||||||
destinationCollection.Add(fileName);
|
destinationCollection.Add(fileName);
|
||||||
if (item.ImageFileHolder.LastWriteTime is null)
|
if (item.Property is null)
|
||||||
continue;
|
results.Add(new(item, item.FilePath.LastWriteTicks, dateTime.Ticks, destinationCollection.ToArray()));
|
||||||
if (item.Property is not null)
|
|
||||||
results.Add(new(item, item.Property.LastWriteTime.Ticks, dateTime.Ticks, destinationCollection.ToArray()));
|
|
||||||
else
|
else
|
||||||
results.Add(new(item, item.ImageFileHolder.LastWriteTime.Value.Ticks, dateTime.Ticks, destinationCollection.ToArray()));
|
results.Add(new(item, item.Property.LastWriteTime.Ticks, dateTime.Ticks, destinationCollection.ToArray()));
|
||||||
}
|
}
|
||||||
return results;
|
return results;
|
||||||
}
|
}
|
||||||
@ -313,7 +307,7 @@ public class DateGroup
|
|||||||
List<Item> results = [];
|
List<Item> results = [];
|
||||||
foreach (Item item in container.Items)
|
foreach (Item item in container.Items)
|
||||||
{
|
{
|
||||||
if (item.ImageFileHolder is not null)
|
if (item.FilePath is not null)
|
||||||
results.Add(item);
|
results.Add(item);
|
||||||
}
|
}
|
||||||
return results.ToArray();
|
return results.ToArray();
|
||||||
@ -422,13 +416,13 @@ public class DateGroup
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
File.Move(item.ImageFileHolder.FullName, fullFileName);
|
File.Move(item.FilePath.FullName, fullFileName);
|
||||||
moved += 1;
|
moved += 1;
|
||||||
if (hasDuplicate)
|
if (hasDuplicate)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
windowsShortcut = new() { Path = item.ImageFileHolder.DirectoryName, Description = item.ImageFileHolder.Name };
|
windowsShortcut = new() { Path = item.FilePath.DirectoryName, Description = item.FilePath.Name };
|
||||||
windowsShortcut.Save(string.Concat(fullFileName, ".lnk"));
|
windowsShortcut.Save(string.Concat(fullFileName, ".lnk"));
|
||||||
windowsShortcut.Dispose();
|
windowsShortcut.Dispose();
|
||||||
}
|
}
|
||||||
@ -447,11 +441,11 @@ public class DateGroup
|
|||||||
foreach ((Item item, long lastWriteTimeTicks, long minimumDateTimeTicks, string[] destination) in fileMoveCollectionAll)
|
foreach ((Item item, long lastWriteTimeTicks, long minimumDateTimeTicks, string[] destination) in fileMoveCollectionAll)
|
||||||
{
|
{
|
||||||
fullFileName = Path.Combine(destination);
|
fullFileName = Path.Combine(destination);
|
||||||
if (File.Exists(item.ImageFileHolder.FullName))
|
if (File.Exists(item.FilePath.FullName))
|
||||||
continue;
|
continue;
|
||||||
if (!File.Exists(fullFileName))
|
if (!File.Exists(fullFileName))
|
||||||
continue;
|
continue;
|
||||||
File.Move(fullFileName, item.ImageFileHolder.FullName);
|
File.Move(fullFileName, item.FilePath.FullName);
|
||||||
moved += 1;
|
moved += 1;
|
||||||
}
|
}
|
||||||
_Logger?.LogInformation($"Done moving back {moved} file(s)");
|
_Logger?.LogInformation($"Done moving back {moved} file(s)");
|
||||||
@ -493,8 +487,8 @@ public class DateGroup
|
|||||||
relativePathDirectory = Path.GetDirectoryName(item.RelativePath);
|
relativePathDirectory = Path.GetDirectoryName(item.RelativePath);
|
||||||
if (string.IsNullOrEmpty(relativePathDirectory))
|
if (string.IsNullOrEmpty(relativePathDirectory))
|
||||||
continue;
|
continue;
|
||||||
if (item.ImageFileHolder.LastWriteTime is not null && item.Property is null)
|
if (item.Property is null)
|
||||||
dateTime = item.ImageFileHolder.LastWriteTime.Value;
|
dateTime = new(item.FilePath.LastWriteTicks);
|
||||||
else if (item.Property is not null && item.Property.DateTimeOriginal is not null)
|
else if (item.Property is not null && item.Property.DateTimeOriginal is not null)
|
||||||
dateTime = item.Property.DateTimeOriginal.Value;
|
dateTime = item.Property.DateTimeOriginal.Value;
|
||||||
else
|
else
|
||||||
|
@ -20,6 +20,23 @@ public class AppSettings
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void PreVerify(IConfigurationRoot configurationRoot, AppSettings? appSettings)
|
||||||
|
{
|
||||||
|
if (appSettings?.Company is null)
|
||||||
|
{
|
||||||
|
List<string> paths = [];
|
||||||
|
foreach (IConfigurationProvider configurationProvider in configurationRoot.Providers)
|
||||||
|
{
|
||||||
|
if (configurationProvider is not Microsoft.Extensions.Configuration.Json.JsonConfigurationProvider jsonConfigurationProvider)
|
||||||
|
continue;
|
||||||
|
if (jsonConfigurationProvider.Source.FileProvider is not Microsoft.Extensions.FileProviders.PhysicalFileProvider physicalFileProvider)
|
||||||
|
continue;
|
||||||
|
paths.Add(physicalFileProvider.Root);
|
||||||
|
}
|
||||||
|
throw new NotSupportedException($"Not found!{Environment.NewLine}{string.Join(Environment.NewLine, paths.Distinct())}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private static Models.AppSettings Get(AppSettings? appSettings)
|
private static Models.AppSettings Get(AppSettings? appSettings)
|
||||||
{
|
{
|
||||||
Models.AppSettings result;
|
Models.AppSettings result;
|
||||||
@ -36,7 +53,10 @@ public class AppSettings
|
|||||||
public static Models.AppSettings Get(IConfigurationRoot configurationRoot)
|
public static Models.AppSettings Get(IConfigurationRoot configurationRoot)
|
||||||
{
|
{
|
||||||
Models.AppSettings result;
|
Models.AppSettings result;
|
||||||
|
#pragma warning disable IL3050, IL2026
|
||||||
AppSettings? appSettings = configurationRoot.Get<AppSettings>();
|
AppSettings? appSettings = configurationRoot.Get<AppSettings>();
|
||||||
|
#pragma warning restore IL3050, IL2026
|
||||||
|
PreVerify(configurationRoot, appSettings);
|
||||||
result = Get(appSettings);
|
result = Get(appSettings);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -7,17 +7,13 @@ namespace View_by_Distance.Date.Group.Models.Binder;
|
|||||||
public class Configuration
|
public class Configuration
|
||||||
{
|
{
|
||||||
|
|
||||||
#nullable disable
|
|
||||||
|
|
||||||
public bool? ByCreateDateShortcut { get; set; }
|
public bool? ByCreateDateShortcut { get; set; }
|
||||||
public bool? ByDay { get; set; }
|
public bool? ByDay { get; set; }
|
||||||
public bool? ByHash { get; set; }
|
public bool? ByHash { get; set; }
|
||||||
public bool? BySeason { get; set; }
|
public bool? BySeason { get; set; }
|
||||||
public bool? ByWeek { get; set; }
|
public bool? ByWeek { get; set; }
|
||||||
public bool? KeepFullPath { get; set; }
|
public bool? KeepFullPath { get; set; }
|
||||||
public Property.Models.Configuration PropertyConfiguration { get; set; }
|
public Property.Models.Configuration? PropertyConfiguration { get; set; }
|
||||||
|
|
||||||
#nullable restore
|
|
||||||
|
|
||||||
public override string ToString()
|
public override string ToString()
|
||||||
{
|
{
|
||||||
@ -25,10 +21,28 @@ public class Configuration
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void PreVerify(IConfigurationRoot configurationRoot, Configuration? configuration)
|
||||||
|
{
|
||||||
|
if (configuration?.ByCreateDateShortcut is null)
|
||||||
|
{
|
||||||
|
List<string> paths = [];
|
||||||
|
foreach (IConfigurationProvider configurationProvider in configurationRoot.Providers)
|
||||||
|
{
|
||||||
|
if (configurationProvider is not Microsoft.Extensions.Configuration.Json.JsonConfigurationProvider jsonConfigurationProvider)
|
||||||
|
continue;
|
||||||
|
if (jsonConfigurationProvider.Source.FileProvider is not Microsoft.Extensions.FileProviders.PhysicalFileProvider physicalFileProvider)
|
||||||
|
continue;
|
||||||
|
paths.Add(physicalFileProvider.Root);
|
||||||
|
}
|
||||||
|
throw new NotSupportedException($"Not found!{Environment.NewLine}{string.Join(Environment.NewLine, paths.Distinct())}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private static Models.Configuration Get(Configuration? configuration)
|
private static Models.Configuration Get(Configuration? configuration)
|
||||||
{
|
{
|
||||||
Models.Configuration result;
|
Models.Configuration result;
|
||||||
if (configuration is null) throw new NullReferenceException(nameof(configuration));
|
if (configuration is null) throw new NullReferenceException(nameof(configuration));
|
||||||
|
if (configuration.PropertyConfiguration is null) throw new NullReferenceException(nameof(configuration.PropertyConfiguration));
|
||||||
if (configuration.ByCreateDateShortcut is null) throw new NullReferenceException(nameof(configuration.ByCreateDateShortcut));
|
if (configuration.ByCreateDateShortcut is null) throw new NullReferenceException(nameof(configuration.ByCreateDateShortcut));
|
||||||
if (configuration.ByDay is null) throw new NullReferenceException(nameof(configuration.ByDay));
|
if (configuration.ByDay is null) throw new NullReferenceException(nameof(configuration.ByDay));
|
||||||
if (configuration.ByHash is null) throw new NullReferenceException(nameof(configuration.ByHash));
|
if (configuration.ByHash is null) throw new NullReferenceException(nameof(configuration.ByHash));
|
||||||
@ -51,16 +65,20 @@ public class Configuration
|
|||||||
Models.Configuration result;
|
Models.Configuration result;
|
||||||
Configuration? configuration;
|
Configuration? configuration;
|
||||||
if (isEnvironment is null)
|
if (isEnvironment is null)
|
||||||
|
#pragma warning disable IL3050, IL2026
|
||||||
configuration = configurationRoot.Get<Configuration>();
|
configuration = configurationRoot.Get<Configuration>();
|
||||||
|
#pragma warning restore IL3050, IL2026
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
string environmentName = IsEnvironment.GetEnvironmentName(isEnvironment);
|
string environmentName = IsEnvironment.GetEnvironmentName(isEnvironment);
|
||||||
string section = string.Concat(environmentName, ":", nameof(Configuration));
|
string section = string.Concat(environmentName, ":", nameof(Configuration));
|
||||||
IConfigurationSection configurationSection = configurationRoot.GetSection(section);
|
IConfigurationSection configurationSection = configurationRoot.GetSection(section);
|
||||||
|
#pragma warning disable IL3050, IL2026
|
||||||
configuration = configurationSection.Get<Configuration>();
|
configuration = configurationSection.Get<Configuration>();
|
||||||
|
#pragma warning restore IL3050, IL2026
|
||||||
}
|
}
|
||||||
|
PreVerify(configurationRoot, configuration);
|
||||||
result = Get(configuration);
|
result = Get(configuration);
|
||||||
if (configuration is null) throw new NullReferenceException(nameof(configuration));
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -27,6 +27,23 @@ public class AppSettings
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void PreVerify(IConfigurationRoot configurationRoot, AppSettings? appSettings)
|
||||||
|
{
|
||||||
|
if (appSettings?.Company is null)
|
||||||
|
{
|
||||||
|
List<string> paths = [];
|
||||||
|
foreach (IConfigurationProvider configurationProvider in configurationRoot.Providers)
|
||||||
|
{
|
||||||
|
if (configurationProvider is not Microsoft.Extensions.Configuration.Json.JsonConfigurationProvider jsonConfigurationProvider)
|
||||||
|
continue;
|
||||||
|
if (jsonConfigurationProvider.Source.FileProvider is not Microsoft.Extensions.FileProviders.PhysicalFileProvider physicalFileProvider)
|
||||||
|
continue;
|
||||||
|
paths.Add(physicalFileProvider.Root);
|
||||||
|
}
|
||||||
|
throw new NotSupportedException($"Not found!{Environment.NewLine}{string.Join(Environment.NewLine, paths.Distinct())}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private static Models.AppSettings Get(AppSettings? appSettings)
|
private static Models.AppSettings Get(AppSettings? appSettings)
|
||||||
{
|
{
|
||||||
Models.AppSettings result;
|
Models.AppSettings result;
|
||||||
@ -58,7 +75,10 @@ public class AppSettings
|
|||||||
public static Models.AppSettings Get(IConfigurationRoot configurationRoot)
|
public static Models.AppSettings Get(IConfigurationRoot configurationRoot)
|
||||||
{
|
{
|
||||||
Models.AppSettings result;
|
Models.AppSettings result;
|
||||||
|
#pragma warning disable IL3050, IL2026
|
||||||
AppSettings? appSettings = configurationRoot.Get<AppSettings>();
|
AppSettings? appSettings = configurationRoot.Get<AppSettings>();
|
||||||
|
#pragma warning restore IL3050, IL2026
|
||||||
|
PreVerify(configurationRoot, appSettings);
|
||||||
result = Get(appSettings);
|
result = Get(appSettings);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -22,6 +22,23 @@ public class AppSettings
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void PreVerify(IConfigurationRoot configurationRoot, AppSettings? appSettings)
|
||||||
|
{
|
||||||
|
if (appSettings?.Company is null)
|
||||||
|
{
|
||||||
|
List<string> paths = [];
|
||||||
|
foreach (IConfigurationProvider configurationProvider in configurationRoot.Providers)
|
||||||
|
{
|
||||||
|
if (configurationProvider is not Microsoft.Extensions.Configuration.Json.JsonConfigurationProvider jsonConfigurationProvider)
|
||||||
|
continue;
|
||||||
|
if (jsonConfigurationProvider.Source.FileProvider is not Microsoft.Extensions.FileProviders.PhysicalFileProvider physicalFileProvider)
|
||||||
|
continue;
|
||||||
|
paths.Add(physicalFileProvider.Root);
|
||||||
|
}
|
||||||
|
throw new NotSupportedException($"Not found!{Environment.NewLine}{string.Join(Environment.NewLine, paths.Distinct())}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private static Models.AppSettings Get(AppSettings? appSettings)
|
private static Models.AppSettings Get(AppSettings? appSettings)
|
||||||
{
|
{
|
||||||
Models.AppSettings result;
|
Models.AppSettings result;
|
||||||
@ -40,7 +57,10 @@ public class AppSettings
|
|||||||
public static Models.AppSettings Get(IConfigurationRoot configurationRoot)
|
public static Models.AppSettings Get(IConfigurationRoot configurationRoot)
|
||||||
{
|
{
|
||||||
Models.AppSettings result;
|
Models.AppSettings result;
|
||||||
|
#pragma warning disable IL3050, IL2026
|
||||||
AppSettings? appSettings = configurationRoot.Get<AppSettings>();
|
AppSettings? appSettings = configurationRoot.Get<AppSettings>();
|
||||||
|
#pragma warning restore IL3050, IL2026
|
||||||
|
PreVerify(configurationRoot, appSettings);
|
||||||
result = Get(appSettings);
|
result = Get(appSettings);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -14,6 +14,7 @@ public class DistanceLimits : IDistanceLimits
|
|||||||
public double FaceDistancePermyriad { init; get; }
|
public double FaceDistancePermyriad { init; get; }
|
||||||
public int SortingMaximumPerFaceShouldBeHigh { init; get; }
|
public int SortingMaximumPerFaceShouldBeHigh { init; get; }
|
||||||
public bool RangeDaysDeltaTargetLessThenUpper { init; get; }
|
public bool RangeDaysDeltaTargetLessThenUpper { init; get; }
|
||||||
|
public double RangeDistanceToleranceUpperLimit { init; get; }
|
||||||
|
|
||||||
public DistanceLimits(int faceAreaPermyriad,
|
public DistanceLimits(int faceAreaPermyriad,
|
||||||
int faceConfidencePercent,
|
int faceConfidencePercent,
|
||||||
@ -25,6 +26,7 @@ public class DistanceLimits : IDistanceLimits
|
|||||||
int sortingMaximumPerFaceShouldBeHigh,
|
int sortingMaximumPerFaceShouldBeHigh,
|
||||||
int? useFiltersCounter = null)
|
int? useFiltersCounter = null)
|
||||||
{
|
{
|
||||||
|
RangeDistanceToleranceUpperLimit = rangeDistanceTolerance[2];
|
||||||
SortingMaximumPerFaceShouldBeHigh = sortingMaximumPerFaceShouldBeHigh;
|
SortingMaximumPerFaceShouldBeHigh = sortingMaximumPerFaceShouldBeHigh;
|
||||||
RangeDaysDeltaTargetLessThenUpper = rangeDaysDeltaTolerance[1] > rangeDaysDeltaTolerance[2];
|
RangeDaysDeltaTargetLessThenUpper = rangeDaysDeltaTolerance[1] > rangeDaysDeltaTolerance[2];
|
||||||
if (useFiltersCounter is null)
|
if (useFiltersCounter is null)
|
||||||
|
@ -1,10 +1,13 @@
|
|||||||
using ShellProgressBar;
|
using ShellProgressBar;
|
||||||
using System.Collections.ObjectModel;
|
using System.Collections.ObjectModel;
|
||||||
|
using System.Data;
|
||||||
using System.Text.Json;
|
using System.Text.Json;
|
||||||
using View_by_Distance.FaceRecognitionDotNet;
|
using View_by_Distance.FaceRecognitionDotNet;
|
||||||
|
using View_by_Distance.Map.Models;
|
||||||
using View_by_Distance.Property.Models.Stateless;
|
using View_by_Distance.Property.Models.Stateless;
|
||||||
using View_by_Distance.Shared.Models;
|
using View_by_Distance.Shared.Models;
|
||||||
using View_by_Distance.Shared.Models.Methods;
|
using View_by_Distance.Shared.Models.Methods;
|
||||||
|
using View_by_Distance.Shared.Models.Stateless.Methods;
|
||||||
|
|
||||||
namespace View_by_Distance.Distance.Models;
|
namespace View_by_Distance.Distance.Models;
|
||||||
|
|
||||||
@ -50,6 +53,7 @@ public partial class E_Distance : IDistance
|
|||||||
private FaceDistanceContainer[] GetFaceDistanceContainers(MappingFromItem mappingFromItem, List<Face> intersectFaces)
|
private FaceDistanceContainer[] GetFaceDistanceContainers(MappingFromItem mappingFromItem, List<Face> intersectFaces)
|
||||||
{
|
{
|
||||||
FaceDistanceContainer[] results;
|
FaceDistanceContainer[] results;
|
||||||
|
DateTime dateTime;
|
||||||
int wholePercentages;
|
int wholePercentages;
|
||||||
int confidencePercent;
|
int confidencePercent;
|
||||||
FaceDistance faceDistance;
|
FaceDistance faceDistance;
|
||||||
@ -61,14 +65,15 @@ public partial class E_Distance : IDistance
|
|||||||
throw new NotSupportedException();
|
throw new NotSupportedException();
|
||||||
if (face.Mapping?.MappingFromFilterPost is null)
|
if (face.Mapping?.MappingFromFilterPost is null)
|
||||||
throw new NotSupportedException();
|
throw new NotSupportedException();
|
||||||
|
dateTime = mappingFromItem.GetDateTimeOriginalThenMinimumDateTime();
|
||||||
confidencePercent = Shared.Models.Stateless.Methods.ILocation.GetConfidencePercent(_FaceConfidencePercent, face.Location.Confidence);
|
confidencePercent = Shared.Models.Stateless.Methods.ILocation.GetConfidencePercent(_FaceConfidencePercent, face.Location.Confidence);
|
||||||
wholePercentages = Shared.Models.Stateless.Methods.ILocation.GetWholePercentages(face.Location, Shared.Models.Stateless.ILocation.Digits, face.OutputResolution);
|
wholePercentages = Shared.Models.Stateless.Methods.ILocation.GetWholePercentages(face.Location, Shared.Models.Stateless.ILocation.Digits, face.OutputResolution);
|
||||||
if (face.FaceDistance?.Encoding is not null && face.FaceDistance.Encoding is FaceRecognitionDotNet.FaceEncoding faceEncoding)
|
if (face.FaceDistance?.Encoding is not null && face.FaceDistance.Encoding is FaceRecognitionDotNet.FaceEncoding faceEncoding)
|
||||||
faceDistance = new(confidencePercent, mappingFromItem.GetDateTimeOriginalThenMinimumDateTime(), faceEncoding, face.Mapping?.MappingFromFilterPost, mappingFromItem.Id, mappingFromItem.IsWrongYear, wholePercentages);
|
faceDistance = new(confidencePercent, dateTime, faceEncoding, face.Mapping?.MappingFromFilterPost, mappingFromItem.Id, mappingFromItem.IsWrongYear, wholePercentages);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
faceEncoding = FaceRecognition.LoadFaceEncoding(face.FaceEncoding.RawEncoding);
|
faceEncoding = FaceRecognition.LoadFaceEncoding(face.FaceEncoding.RawEncoding);
|
||||||
faceDistance = new(confidencePercent, mappingFromItem.GetDateTimeOriginalThenMinimumDateTime(), faceEncoding, face.Mapping?.MappingFromFilterPost, mappingFromItem.Id, mappingFromItem.IsWrongYear, wholePercentages);
|
faceDistance = new(confidencePercent, dateTime, faceEncoding, face.Mapping?.MappingFromFilterPost, mappingFromItem.Id, mappingFromItem.IsWrongYear, wholePercentages);
|
||||||
lock (intersectFaces)
|
lock (intersectFaces)
|
||||||
face.SetFaceDistance(faceDistance);
|
face.SetFaceDistance(faceDistance);
|
||||||
}
|
}
|
||||||
@ -91,7 +96,7 @@ public partial class E_Distance : IDistance
|
|||||||
return new(faceDistanceEncodings);
|
return new(faceDistanceEncodings);
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<(Face Face, double? Length)> GetValues(MappingFromItem mappingFromItem, List<Face> intersectFaces, Shared.Models.FaceEncoding modelsFaceEncoding)
|
private List<(Face Face, double? Length)> GetValues(IDistanceLimits distanceLimits, MappingFromItem mappingFromItem, List<Face> intersectFaces, Shared.Models.FaceEncoding modelsFaceEncoding)
|
||||||
{
|
{
|
||||||
List<(Face Face, double? Length)> results = [];
|
List<(Face Face, double? Length)> results = [];
|
||||||
Face face;
|
Face face;
|
||||||
@ -112,6 +117,8 @@ public partial class E_Distance : IDistance
|
|||||||
{
|
{
|
||||||
face = intersectFaces[i];
|
face = intersectFaces[i];
|
||||||
faceDistanceLength = faceDistanceLengths[i];
|
faceDistanceLength = faceDistanceLengths[i];
|
||||||
|
if (faceDistanceLength.Length is null || faceDistanceLength.Length > distanceLimits.RangeDistanceToleranceUpperLimit)
|
||||||
|
continue;
|
||||||
if (faceDistanceLength.Length is null)
|
if (faceDistanceLength.Length is null)
|
||||||
throw new NotSupportedException();
|
throw new NotSupportedException();
|
||||||
results.Add(new(face, faceDistanceLength.Length.Value));
|
results.Add(new(face, faceDistanceLength.Length.Value));
|
||||||
@ -119,10 +126,10 @@ public partial class E_Distance : IDistance
|
|||||||
return results;
|
return results;
|
||||||
}
|
}
|
||||||
|
|
||||||
private (Face, double?)[] GetClosestFaceByDistanceIgnoringTolerance(MappingFromItem mappingFromItem, List<Face> intersectFaces, Shared.Models.FaceEncoding modelsFaceEncoding)
|
private (Face, double?)[] GetClosestFaceByDistanceIgnoringTolerance(IDistanceLimits distanceLimits, MappingFromItem mappingFromItem, List<Face> intersectFaces, Shared.Models.FaceEncoding modelsFaceEncoding)
|
||||||
{
|
{
|
||||||
(Face, double?)[] results;
|
(Face, double?)[] results;
|
||||||
List<(Face Face, double? Length)> collection = GetValues(mappingFromItem, intersectFaces, modelsFaceEncoding);
|
List<(Face Face, double? Length)> collection = GetValues(distanceLimits, mappingFromItem, intersectFaces, modelsFaceEncoding);
|
||||||
results = (from l in collection where l.Length < _RangeDistanceToleranceAverage orderby l.Length select l).Take(1).ToArray();
|
results = (from l in collection where l.Length < _RangeDistanceToleranceAverage orderby l.Length select l).Take(1).ToArray();
|
||||||
if (results.Length > 0)
|
if (results.Length > 0)
|
||||||
{
|
{
|
||||||
@ -132,11 +139,11 @@ public partial class E_Distance : IDistance
|
|||||||
return results;
|
return results;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static List<(Face, double?)> GetMatchingFacesByFaceEncoding(Face[] filteredFaces, string? json)
|
private static List<(Face, double?)> GetMatchingFacesByFaceEncoding(List<Face> faces, string? json)
|
||||||
{
|
{
|
||||||
List<(Face, double?)> results = [];
|
List<(Face, double?)> results = [];
|
||||||
string check;
|
string check;
|
||||||
foreach (Face face in filteredFaces)
|
foreach (Face face in faces)
|
||||||
{
|
{
|
||||||
if (json is null || face.FaceEncoding is null)
|
if (json is null || face.FaceEncoding is null)
|
||||||
continue;
|
continue;
|
||||||
@ -165,8 +172,8 @@ public partial class E_Distance : IDistance
|
|||||||
mappedFaceDirectory = Path.GetDirectoryName(file);
|
mappedFaceDirectory = Path.GetDirectoryName(file);
|
||||||
if (mappedFaceDirectory is null)
|
if (mappedFaceDirectory is null)
|
||||||
throw new NotSupportedException();
|
throw new NotSupportedException();
|
||||||
deterministicHashCodeKey = Shared.Models.Stateless.Methods.IMapping.GetDeterministicHashCodeKey(filePath, face.Location, Shared.Models.Stateless.ILocation.Digits, face.OutputResolution);
|
deterministicHashCodeKey = IMapping.GetDeterministicHashCodeKey(filePath, face.Location, Shared.Models.Stateless.ILocation.Digits, face.OutputResolution);
|
||||||
checkFile = Path.Combine(mappedFaceDirectory, $"{deterministicHashCodeKey}{mappingFromItem.ImageFileHolder.ExtensionLowered}{facesFileNameExtension}");
|
checkFile = Path.Combine(mappedFaceDirectory, $"{deterministicHashCodeKey}{mappingFromItem.FilePath.ExtensionLowered}{facesFileNameExtension}");
|
||||||
if (checkFile == file)
|
if (checkFile == file)
|
||||||
continue;
|
continue;
|
||||||
result = new FileInfo(checkFile);
|
result = new FileInfo(checkFile);
|
||||||
@ -201,17 +208,14 @@ public partial class E_Distance : IDistance
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void LookForMatchFacesAndPossiblyRename(string facesFileNameExtension, FilePath filePath, MappingFromItem mappingFromItem, List<Face> faces, ReadOnlyCollection<LocationContainer> locationContainers)
|
public void LookForMatchFacesAndPossiblyRename(bool overrideForFaceImages, IDistanceLimits distanceLimits, IFaceD dFace, FilePath filePath, MappingFromItem mappingFromItem, ExifDirectory exifDirectory, List<Face> faces, ReadOnlyCollection<LocationContainer> locationContainers)
|
||||||
{
|
{
|
||||||
string? json;
|
string? json;
|
||||||
string[] matches;
|
string[] matches;
|
||||||
FileInfo? fileInfo;
|
FileInfo? fileInfo;
|
||||||
List<Face> intersectFaces;
|
List<Face> intersectFaces;
|
||||||
List<(Face, double?)> checkFaces = [];
|
|
||||||
Shared.Models.FaceEncoding? modelsFaceEncoding;
|
Shared.Models.FaceEncoding? modelsFaceEncoding;
|
||||||
Face[] filteredFaces = (from l in faces where l.FaceEncoding is not null && l.Location is not null && l.OutputResolution is not null select l).ToArray();
|
List<(Face Face, double? Distance)> checkFaces = [];
|
||||||
if (filteredFaces.Length != faces.Count)
|
|
||||||
checkFaces.Clear();
|
|
||||||
foreach (LocationContainer locationContainer in locationContainers)
|
foreach (LocationContainer locationContainer in locationContainers)
|
||||||
{
|
{
|
||||||
if (_Renamed.Contains(locationContainer.FilePath.FullName))
|
if (_Renamed.Contains(locationContainer.FilePath.FullName))
|
||||||
@ -232,8 +236,8 @@ public partial class E_Distance : IDistance
|
|||||||
MoveUnableToMatch(locationContainer.FilePath);
|
MoveUnableToMatch(locationContainer.FilePath);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (filteredFaces.Length > 0)
|
if (faces.Count > 0)
|
||||||
checkFaces.AddRange(GetMatchingFacesByFaceEncoding(filteredFaces, json));
|
checkFaces.AddRange(GetMatchingFacesByFaceEncoding(faces, json));
|
||||||
if (checkFaces.Count == 1)
|
if (checkFaces.Count == 1)
|
||||||
_Debug.Add(0);
|
_Debug.Add(0);
|
||||||
if (checkFaces.Count != 1 && !string.IsNullOrEmpty(json))
|
if (checkFaces.Count != 1 && !string.IsNullOrEmpty(json))
|
||||||
@ -242,11 +246,11 @@ public partial class E_Distance : IDistance
|
|||||||
modelsFaceEncoding = JsonSerializer.Deserialize<Shared.Models.FaceEncoding>(json);
|
modelsFaceEncoding = JsonSerializer.Deserialize<Shared.Models.FaceEncoding>(json);
|
||||||
if (modelsFaceEncoding is null)
|
if (modelsFaceEncoding is null)
|
||||||
throw new NotSupportedException();
|
throw new NotSupportedException();
|
||||||
if (filteredFaces.Length > 0)
|
if (faces.Count > 0)
|
||||||
{
|
{
|
||||||
intersectFaces = Shared.Models.Stateless.Methods.ILocation.FilterByIntersect(filteredFaces, _RectangleIntersectMinimum, locationContainer.WholePercentages);
|
intersectFaces = Shared.Models.Stateless.Methods.ILocation.FilterByIntersect(faces, _RectangleIntersectMinimum, locationContainer.WholePercentages);
|
||||||
if (intersectFaces.Count > 0)
|
if (intersectFaces.Count > 0)
|
||||||
checkFaces.AddRange(GetClosestFaceByDistanceIgnoringTolerance(mappingFromItem, intersectFaces, modelsFaceEncoding));
|
checkFaces.AddRange(GetClosestFaceByDistanceIgnoringTolerance(distanceLimits, mappingFromItem, intersectFaces, modelsFaceEncoding));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (checkFaces.Count == 0)
|
if (checkFaces.Count == 0)
|
||||||
@ -261,7 +265,7 @@ public partial class E_Distance : IDistance
|
|||||||
MoveUnableToMatch(locationContainer.FilePath);
|
MoveUnableToMatch(locationContainer.FilePath);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
fileInfo = CheckFileThenGetFileInfo(facesFileNameExtension, filePath, mappingFromItem, locationContainer.FilePath.FullName, checkFaces);
|
fileInfo = CheckFileThenGetFileInfo(dFace.FileNameExtension, filePath, mappingFromItem, locationContainer.FilePath.FullName, checkFaces);
|
||||||
if (fileInfo is not null)
|
if (fileInfo is not null)
|
||||||
{
|
{
|
||||||
if (_DistanceRenameToMatch && fileInfo is not null)
|
if (_DistanceRenameToMatch && fileInfo is not null)
|
||||||
@ -275,6 +279,15 @@ public partial class E_Distance : IDistance
|
|||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
if (overrideForFaceImages)
|
||||||
|
{
|
||||||
|
json = Metadata.Models.Stateless.Methods.IMetadata.GetOutputResolution(locationContainer.ExifDirectory);
|
||||||
|
if (json is null || !json.Contains(nameof(DateTime)))
|
||||||
|
{
|
||||||
|
if (checkFaces.Count == 1)
|
||||||
|
dFace.ReSaveFace(exifDirectory, locationContainer.FilePath, checkFaces[0].Face, mappedFile: true);
|
||||||
|
}
|
||||||
|
}
|
||||||
if (_AllMappedFaceFileNames.Contains(locationContainer.FilePath.Name))
|
if (_AllMappedFaceFileNames.Contains(locationContainer.FilePath.Name))
|
||||||
{
|
{
|
||||||
lock (_AllMappedFaceFiles)
|
lock (_AllMappedFaceFiles)
|
||||||
@ -322,10 +335,88 @@ public partial class E_Distance : IDistance
|
|||||||
File.WriteAllLines(eDistanceContentFileName, results);
|
File.WriteAllLines(eDistanceContentFileName, results);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void PreFilterSetFaceDistances(int maxDegreeOfParallelism, long ticks, ReadOnlyCollection<Face> distinctFilteredFaces)
|
public static ReadOnlyDictionary<int, ReadOnlyDictionary<int, LocationContainer>> GetMappedWithEncoding(ReadOnlyDictionary<int, ReadOnlyDictionary<int, LocationContainer>> mapped)
|
||||||
|
{
|
||||||
|
Dictionary<int, ReadOnlyDictionary<int, LocationContainer>> results = [];
|
||||||
|
string? json;
|
||||||
|
LocationContainer? locationContainer;
|
||||||
|
Shared.Models.FaceEncoding? faceEncoding;
|
||||||
|
FaceRecognitionDotNet.FaceEncoding? encoding;
|
||||||
|
Dictionary<int, LocationContainer> keyValuePairs;
|
||||||
|
foreach (KeyValuePair<int, ReadOnlyDictionary<int, LocationContainer>> keyValuePair in mapped)
|
||||||
|
{
|
||||||
|
keyValuePairs = [];
|
||||||
|
foreach (KeyValuePair<int, LocationContainer> keyValue in keyValuePair.Value)
|
||||||
|
{
|
||||||
|
json = Metadata.Models.Stateless.Methods.IMetadata.GetFaceEncoding(keyValue.Value.ExifDirectory);
|
||||||
|
faceEncoding = json is null ? null : JsonSerializer.Deserialize<Shared.Models.FaceEncoding>(json);
|
||||||
|
if (faceEncoding is null)
|
||||||
|
continue;
|
||||||
|
encoding = FaceRecognition.LoadFaceEncoding(faceEncoding.RawEncoding);
|
||||||
|
locationContainer = LocationContainer.Get(keyValue.Value, encoding, keepExifDirectory: false);
|
||||||
|
keyValuePairs.Add(keyValue.Key, locationContainer);
|
||||||
|
}
|
||||||
|
results.Add(keyValuePair.Key, new(keyValuePairs));
|
||||||
|
}
|
||||||
|
return new(results);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static List<LocationContainer> GetPreFilterLocationContainer(int maxDegreeOfParallelism, Configuration configuration, string focusDirectory, string focusModel, int? skipPersonWithMoreThen, long ticks, MapLogic mapLogic, long[] jLinkResolvedPersonKeys, ReadOnlyDictionary<int, ReadOnlyDictionary<int, LocationContainer>> mapped, List<LocationContainer> available)
|
||||||
|
{
|
||||||
|
List<LocationContainer> results = [];
|
||||||
|
string? json;
|
||||||
|
string? model;
|
||||||
|
bool? canReMap;
|
||||||
|
bool? isFocusPerson;
|
||||||
|
bool? inSkipCollection;
|
||||||
|
Shared.Models.FaceEncoding? faceEncoding;
|
||||||
|
FaceRecognitionDotNet.FaceEncoding? encoding;
|
||||||
|
ReadOnlyDictionary<int, LocationContainer>? keyValuePairs;
|
||||||
|
ReadOnlyDictionary<int, ReadOnlyCollection<PersonContainer>>? wholePercentagesToPersonContainers;
|
||||||
|
foreach (LocationContainer locationContainer in available)
|
||||||
|
{
|
||||||
|
if (mapped.TryGetValue(locationContainer.Id, out keyValuePairs))
|
||||||
|
{
|
||||||
|
if (keyValuePairs.ContainsKey(locationContainer.WholePercentages))
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (locationContainer.ExifDirectory is null || locationContainer.FaceFile is null)
|
||||||
|
continue;
|
||||||
|
inSkipCollection = mapLogic.InSkipCollection(locationContainer.Id, locationContainer.WholePercentages);
|
||||||
|
if (inSkipCollection is not null && inSkipCollection.Value)
|
||||||
|
continue;
|
||||||
|
wholePercentagesToPersonContainers = mapLogic.GetWholePercentagesToPersonContainers(locationContainer.Id);
|
||||||
|
canReMap = Map.Models.Stateless.Methods.IMapLogic.CanReMap(jLinkResolvedPersonKeys, wholePercentagesToPersonContainers, locationContainer.WholePercentages);
|
||||||
|
if (canReMap is not null && !canReMap.Value)
|
||||||
|
continue;
|
||||||
|
isFocusPerson = mapLogic.IsFocusPerson(skipPersonWithMoreThen, jLinkResolvedPersonKeys, wholePercentagesToPersonContainers, locationContainer.WholePercentages);
|
||||||
|
if (isFocusPerson is not null && !isFocusPerson.Value)
|
||||||
|
continue;
|
||||||
|
if (!string.IsNullOrEmpty(focusModel))
|
||||||
|
{
|
||||||
|
model = Metadata.Models.Stateless.Methods.IMetadata.GetModel(locationContainer.ExifDirectory);
|
||||||
|
if (string.IsNullOrEmpty(model) || !model.Contains(focusModel))
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (!string.IsNullOrEmpty(focusDirectory))
|
||||||
|
{
|
||||||
|
if (!locationContainer.FilePath.DirectoryName.Contains(focusDirectory))
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
json = Metadata.Models.Stateless.Methods.IMetadata.GetFaceEncoding(locationContainer.ExifDirectory);
|
||||||
|
faceEncoding = json is null ? null : JsonSerializer.Deserialize<Shared.Models.FaceEncoding>(json);
|
||||||
|
if (faceEncoding is null)
|
||||||
|
continue;
|
||||||
|
encoding = FaceRecognition.LoadFaceEncoding(faceEncoding.RawEncoding);
|
||||||
|
results.Add(LocationContainer.Get(locationContainer, encoding, keepExifDirectory: false));
|
||||||
|
}
|
||||||
|
return results;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void PreFilterSetFaceDistances(int maxDegreeOfParallelism, Configuration configuration, long ticks, ReadOnlyCollection<Face> distinctValidImageFaces)
|
||||||
{
|
{
|
||||||
List<Face> faces = [];
|
List<Face> faces = [];
|
||||||
foreach (Face face in distinctFilteredFaces)
|
foreach (Face face in distinctValidImageFaces)
|
||||||
{
|
{
|
||||||
if (face.Mapping?.MappingFromFilterPre is null)
|
if (face.Mapping?.MappingFromFilterPre is null)
|
||||||
throw new NotSupportedException();
|
throw new NotSupportedException();
|
||||||
@ -335,7 +426,10 @@ public partial class E_Distance : IDistance
|
|||||||
continue;
|
continue;
|
||||||
if (face.Mapping.MappingFromFilterPre.IsFocusRelativePath is not null && !face.Mapping.MappingFromFilterPre.IsFocusRelativePath.Value)
|
if (face.Mapping.MappingFromFilterPre.IsFocusRelativePath is not null && !face.Mapping.MappingFromFilterPre.IsFocusRelativePath.Value)
|
||||||
continue;
|
continue;
|
||||||
if (face.FaceEncoding is not null && face.FaceDistance?.Encoding is not null && face.FaceDistance.Encoding is FaceRecognitionDotNet.FaceEncoding _)
|
if (!configuration.ReMap && face.Mapping.MappingFromPerson is not null)
|
||||||
|
continue;
|
||||||
|
if (!configuration.ReMap && face.FaceEncoding is not null && face.FaceDistance?.Encoding is not null && face.FaceDistance.Encoding is FaceRecognitionDotNet.FaceEncoding)
|
||||||
|
// throw new NotSupportedException($"{face.FaceEncoding} should not be null!");
|
||||||
continue;
|
continue;
|
||||||
faces.Add(face);
|
faces.Add(face);
|
||||||
}
|
}
|
||||||
@ -352,18 +446,19 @@ public partial class E_Distance : IDistance
|
|||||||
throw new NotSupportedException();
|
throw new NotSupportedException();
|
||||||
progressBar.Tick();
|
progressBar.Tick();
|
||||||
faceEncoding = FaceRecognition.LoadFaceEncoding(face.FaceEncoding.RawEncoding);
|
faceEncoding = FaceRecognition.LoadFaceEncoding(face.FaceEncoding.RawEncoding);
|
||||||
FaceDistance faceDistance = new(face.Mapping.MappingFromLocation.ConfidencePercent, face.Mapping.MappingFromItem.GetDateTimeOriginalThenMinimumDateTime(), faceEncoding, face.Mapping.MappingFromFilterPost, face.Mapping.MappingFromItem.Id, face.Mapping.MappingFromItem.IsWrongYear, face.Mapping.MappingFromLocation.WholePercentages);
|
DateTime dateTime = face.Mapping.MappingFromItem.GetDateTimeOriginalThenMinimumDateTime();
|
||||||
|
FaceDistance faceDistance = new(face.Mapping.MappingFromLocation.ConfidencePercent, dateTime, faceEncoding, face.Mapping.MappingFromFilterPost, face.Mapping.MappingFromItem.Id, face.Mapping.MappingFromItem.IsWrongYear, face.Mapping.MappingFromLocation.WholePercentages);
|
||||||
lock (face)
|
lock (face)
|
||||||
face.SetFaceDistance(faceDistance);
|
face.SetFaceDistance(faceDistance);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private static List<SortingContainer> GetSortingContainers(Map.Models.Configuration mapConfiguration, IDistanceLimits distanceLimits, Face face, FaceDistance faceDistanceEncoding, List<Sorting> sortingCollection)
|
private static List<SortingContainer> GetSortingContainers(Configuration mapConfiguration, IDistanceLimits distanceLimits, Face face, FaceDistance faceDistanceEncoding, List<Sorting> sortingCollection)
|
||||||
{
|
{
|
||||||
List<SortingContainer> results = [];
|
List<SortingContainer> results = [];
|
||||||
SortingContainer sortingContainer;
|
|
||||||
int days = 0, distance = 0;
|
int days = 0, distance = 0;
|
||||||
Sorting[] collection = Shared.Models.Stateless.Methods.ISorting.Sort(sortingCollection);
|
SortingContainer sortingContainer;
|
||||||
|
Sorting[] collection = ISorting.Sort(sortingCollection);
|
||||||
foreach (Sorting sorting in collection)
|
foreach (Sorting sorting in collection)
|
||||||
{
|
{
|
||||||
if (face.Mapping?.MappingFromLocation is null || faceDistanceEncoding.WholePercentages is null)
|
if (face.Mapping?.MappingFromLocation is null || faceDistanceEncoding.WholePercentages is null)
|
||||||
@ -389,7 +484,7 @@ public partial class E_Distance : IDistance
|
|||||||
return results;
|
return results;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static List<Sorting> GetSortingCollection(Map.Models.MapLogic mapLogic, ReadOnlyCollection<FaceDistance> faceDistanceEncodings, int i, Face face, FaceDistance faceDistanceEncoding)
|
private static List<Sorting> GetSortingCollection(MapLogic mapLogic, ReadOnlyCollection<FaceDistance> faceDistanceEncodings, int i, Face face, FaceDistance faceDistanceEncoding)
|
||||||
{
|
{
|
||||||
List<Sorting> results;
|
List<Sorting> results;
|
||||||
List<FaceDistance> faceDistanceLengths = FaceRecognition.FaceDistances(faceDistanceEncodings, faceDistanceEncoding);
|
List<FaceDistance> faceDistanceLengths = FaceRecognition.FaceDistances(faceDistanceEncodings, faceDistanceEncoding);
|
||||||
@ -397,19 +492,21 @@ public partial class E_Distance : IDistance
|
|||||||
return results;
|
return results;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ReadOnlyCollection<FaceDistanceContainer> GetFaceDistanceContainers(ReadOnlyCollection<Face> distinctFilteredFaces)
|
public static ReadOnlyCollection<FaceDistanceContainer> GetFaceDistanceContainers(ReadOnlyCollection<Face> distinctValidImageFaces)
|
||||||
{
|
{
|
||||||
ReadOnlyCollection<FaceDistanceContainer> results;
|
ReadOnlyCollection<FaceDistanceContainer> results;
|
||||||
|
DateTime dateTime;
|
||||||
FaceDistance faceDistance;
|
FaceDistance faceDistance;
|
||||||
FaceDistanceContainer faceDistanceContainer;
|
FaceDistanceContainer faceDistanceContainer;
|
||||||
List<FaceDistanceContainer> collection = [];
|
List<FaceDistanceContainer> collection = [];
|
||||||
foreach (Face face in distinctFilteredFaces)
|
foreach (Face face in distinctValidImageFaces)
|
||||||
{
|
{
|
||||||
if (face.Mapping?.MappingFromLocation is null)
|
if (face.Mapping?.MappingFromLocation is null)
|
||||||
throw new NotSupportedException();
|
throw new NotSupportedException();
|
||||||
if (face.FaceDistance?.Encoding is not FaceRecognitionDotNet.FaceEncoding faceEncoding)
|
if (face.FaceDistance?.Encoding is not FaceRecognitionDotNet.FaceEncoding faceEncoding)
|
||||||
continue;
|
continue;
|
||||||
faceDistance = new(face.Mapping.MappingFromLocation.ConfidencePercent, face.Mapping.MappingFromItem.GetDateTimeOriginalThenMinimumDateTime(), faceEncoding, face.Mapping.MappingFromFilterPost, face.Mapping.MappingFromItem.Id, face.Mapping.MappingFromItem.IsWrongYear, face.Mapping.MappingFromLocation.WholePercentages);
|
dateTime = face.Mapping.MappingFromItem.GetDateTimeOriginalThenMinimumDateTime();
|
||||||
|
faceDistance = new(face.Mapping.MappingFromLocation.ConfidencePercent, dateTime, faceEncoding, face.Mapping.MappingFromFilterPost, face.Mapping.MappingFromItem.Id, face.Mapping.MappingFromItem.IsWrongYear, face.Mapping.MappingFromLocation.WholePercentages);
|
||||||
faceDistanceContainer = new(face, faceDistance);
|
faceDistanceContainer = new(face, faceDistance);
|
||||||
collection.Add(faceDistanceContainer);
|
collection.Add(faceDistanceContainer);
|
||||||
}
|
}
|
||||||
@ -417,7 +514,23 @@ public partial class E_Distance : IDistance
|
|||||||
return results;
|
return results;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static FaceDistanceContainer[] FilteredPostLoadFaceDistanceContainers(Map.Models.MapLogic mapLogic, ReadOnlyCollection<FaceDistanceContainer> faceDistanceContainers, long? skipOlderThan, DistanceLimits distanceLimits)
|
public static List<LocationContainer> GetPostFilterLocationContainer(MapLogic mapLogic, List<LocationContainer> preFiltered, DistanceLimits distanceLimits)
|
||||||
|
{
|
||||||
|
List<LocationContainer> results = [];
|
||||||
|
foreach (LocationContainer locationContainer in preFiltered)
|
||||||
|
{
|
||||||
|
if (locationContainer.FaceFile is null)
|
||||||
|
continue;
|
||||||
|
if (locationContainer.FaceFile.AreaPermyriad < distanceLimits.FaceAreaPermyriad)
|
||||||
|
continue;
|
||||||
|
if (locationContainer.FaceFile.ConfidencePercent < distanceLimits.FaceConfidencePercent)
|
||||||
|
continue;
|
||||||
|
results.Add(locationContainer);
|
||||||
|
}
|
||||||
|
return results;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static FaceDistanceContainer[] FilteredPostLoadFaceDistanceContainers(MapLogic mapLogic, ReadOnlyCollection<FaceDistanceContainer> faceDistanceContainers, long? skipOlderThan, DistanceLimits distanceLimits)
|
||||||
{
|
{
|
||||||
List<FaceDistanceContainer> results = [];
|
List<FaceDistanceContainer> results = [];
|
||||||
foreach (FaceDistanceContainer faceDistanceContainer in faceDistanceContainers)
|
foreach (FaceDistanceContainer faceDistanceContainer in faceDistanceContainers)
|
||||||
@ -431,7 +544,8 @@ public partial class E_Distance : IDistance
|
|||||||
if (faceDistanceContainer.Face.Mapping.MappingFromLocation.AreaPermyriad < distanceLimits.FaceAreaPermyriad)
|
if (faceDistanceContainer.Face.Mapping.MappingFromLocation.AreaPermyriad < distanceLimits.FaceAreaPermyriad)
|
||||||
continue;
|
continue;
|
||||||
if (faceDistanceContainer.Face.Mapping.MappingFromFilterPre.InSkipCollection is not null && faceDistanceContainer.Face.Mapping.MappingFromFilterPre.InSkipCollection.Value)
|
if (faceDistanceContainer.Face.Mapping.MappingFromFilterPre.InSkipCollection is not null && faceDistanceContainer.Face.Mapping.MappingFromFilterPre.InSkipCollection.Value)
|
||||||
throw new NotSupportedException(nameof(PreFilterSetFaceDistances));
|
// throw new NotSupportedException(nameof(PreFilterSetFaceDistances));
|
||||||
|
continue;
|
||||||
if (faceDistanceContainer.Face.Mapping.MappingFromFilterPre.IsFocusModel is not null && !faceDistanceContainer.Face.Mapping.MappingFromFilterPre.IsFocusModel.Value)
|
if (faceDistanceContainer.Face.Mapping.MappingFromFilterPre.IsFocusModel is not null && !faceDistanceContainer.Face.Mapping.MappingFromFilterPre.IsFocusModel.Value)
|
||||||
continue;
|
continue;
|
||||||
if (faceDistanceContainer.Face.Mapping.MappingFromFilterPre.IsFocusRelativePath is not null && !faceDistanceContainer.Face.Mapping.MappingFromFilterPre.IsFocusRelativePath.Value)
|
if (faceDistanceContainer.Face.Mapping.MappingFromFilterPre.IsFocusRelativePath is not null && !faceDistanceContainer.Face.Mapping.MappingFromFilterPre.IsFocusRelativePath.Value)
|
||||||
@ -445,7 +559,46 @@ public partial class E_Distance : IDistance
|
|||||||
return results.ToArray();
|
return results.ToArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ReadOnlyCollection<SortingContainer> SetFaceMappingSortingCollectionThenGetSortedSortingContainers(int maxDegreeOfParallelism, Map.Models.Configuration mapConfiguration, long ticks, Map.Models.MapLogic mapLogic, IDistanceLimits distanceLimits, ReadOnlyCollection<FaceDistance> faceDistanceEncodings, FaceDistanceContainer[] filteredFaceDistanceContainers)
|
private static ReadOnlyCollection<LocationContainer> GetReadOnlyLocationContainer(ReadOnlyDictionary<int, ReadOnlyDictionary<int, LocationContainer>> mappedWithEncoding, List<LocationContainer> postFiltered)
|
||||||
|
{
|
||||||
|
List<LocationContainer> results = [];
|
||||||
|
foreach (LocationContainer locationContainer in postFiltered)
|
||||||
|
results.Add(locationContainer);
|
||||||
|
foreach (KeyValuePair<int, ReadOnlyDictionary<int, LocationContainer>> keyValuePair in mappedWithEncoding)
|
||||||
|
{
|
||||||
|
foreach (KeyValuePair<int, LocationContainer> keyValue in keyValuePair.Value)
|
||||||
|
results.Add(keyValue.Value);
|
||||||
|
}
|
||||||
|
return new(results);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ReadOnlyCollection<LocationContainer> GetMatrixLocationContainers(IDlibDotNet dlibDotNet, Configuration mapConfiguration, long ticks, MapLogic mapLogic, ReadOnlyDictionary<int, ReadOnlyDictionary<int, LocationContainer>> mappedWithEncoding, List<LocationContainer> preFiltered, DistanceLimits distanceLimits, List<LocationContainer> postFiltered)
|
||||||
|
{
|
||||||
|
List<LocationContainer> results = [];
|
||||||
|
ReadOnlyCollection<LocationContainer> locationContainers;
|
||||||
|
ReadOnlyCollection<LocationContainer> readOnlyLocationContainers = GetReadOnlyLocationContainer(mappedWithEncoding, postFiltered);
|
||||||
|
foreach (LocationContainer locationContainer in postFiltered)
|
||||||
|
{
|
||||||
|
dlibDotNet.Tick();
|
||||||
|
locationContainers = FaceRecognition.GetLocationContainers(mapConfiguration.FaceDistancePermyriad, readOnlyLocationContainers, locationContainer);
|
||||||
|
foreach (LocationContainer item in locationContainers)
|
||||||
|
{
|
||||||
|
if (item.LengthPermyriad is null)
|
||||||
|
continue;
|
||||||
|
if (item.LengthPermyriad > distanceLimits.FaceDistancePermyriad)
|
||||||
|
break;
|
||||||
|
if (!mapConfiguration.SaveSortingWithoutPerson && item.PersonKey is null)
|
||||||
|
continue;
|
||||||
|
if (item.Id == locationContainer.Id && item.WholePercentages == locationContainer.WholePercentages)
|
||||||
|
continue;
|
||||||
|
results.Add(item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
LocationContainer[] array = results.OrderBy(l => l.LengthPermyriad).ToArray();
|
||||||
|
return new(array);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ReadOnlyCollection<SortingContainer> SetFaceMappingSortingCollectionThenGetSortedSortingContainers(int maxDegreeOfParallelism, Configuration mapConfiguration, long ticks, MapLogic mapLogic, IDistanceLimits distanceLimits, ReadOnlyCollection<FaceDistance> faceDistanceEncodings, FaceDistanceContainer[] filteredFaceDistanceContainers)
|
||||||
{
|
{
|
||||||
List<SortingContainer> results = [];
|
List<SortingContainer> results = [];
|
||||||
int totalSeconds = (int)Math.Floor(new TimeSpan(DateTime.Now.Ticks - ticks).TotalSeconds);
|
int totalSeconds = (int)Math.Floor(new TimeSpan(DateTime.Now.Ticks - ticks).TotalSeconds);
|
||||||
@ -469,13 +622,13 @@ public partial class E_Distance : IDistance
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
if (distanceLimits is not null && distanceLimits.RangeDaysDeltaTargetLessThenUpper)
|
if (distanceLimits is not null && distanceLimits.RangeDaysDeltaTargetLessThenUpper)
|
||||||
results = Shared.Models.Stateless.Methods.ISortingContainer.Sort(results);
|
results = ISortingContainer.Sort(results);
|
||||||
else
|
else
|
||||||
results = Shared.Models.Stateless.Methods.ISortingContainer.SortUsingDaysDelta(results);
|
results = ISortingContainer.SortUsingDaysDelta(results);
|
||||||
return new(results);
|
return new(results);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static ReadOnlyCollection<RelationContainer> GetRelationCollections(int faceDistancePermyriad, int locationContainerDistanceTake, float distanceTolerance, List<Record> records)
|
private static ReadOnlyCollection<RelationContainer> GetRelationCollections(IDistanceLimits distanceLimits, int faceDistancePermyriad, int locationContainerDistanceTake, float distanceTolerance, List<Record> records)
|
||||||
{
|
{
|
||||||
List<RelationContainer> results = [];
|
List<RelationContainer> results = [];
|
||||||
string fileName;
|
string fileName;
|
||||||
@ -495,6 +648,7 @@ public partial class E_Distance : IDistance
|
|||||||
foreach (Record record in records)
|
foreach (Record record in records)
|
||||||
{
|
{
|
||||||
mappedRelations = [];
|
mappedRelations = [];
|
||||||
|
FaceDistance faceDistanceLength;
|
||||||
fileHolder = Shared.Models.Stateless.Methods.IFileHolder.Get(record.FilePath.FullName);
|
fileHolder = Shared.Models.Stateless.Methods.IFileHolder.Get(record.FilePath.FullName);
|
||||||
if (files.Count > 1)
|
if (files.Count > 1)
|
||||||
{
|
{
|
||||||
@ -507,10 +661,12 @@ public partial class E_Distance : IDistance
|
|||||||
fileName = Path.GetFileName(files[i]);
|
fileName = Path.GetFileName(files[i]);
|
||||||
if (fileName == fileHolder.Name)
|
if (fileName == fileHolder.Name)
|
||||||
continue;
|
continue;
|
||||||
FaceDistance faceDistance = faceDistanceLengths[i];
|
faceDistanceLength = faceDistanceLengths[i];
|
||||||
if (faceDistance.Length is null || faceDistance.Length.Value > distanceTolerance)
|
if (faceDistanceLength.Length is null || faceDistanceLength.Length > distanceLimits.RangeDistanceToleranceUpperLimit)
|
||||||
continue;
|
continue;
|
||||||
distancePermyriad = (int)(faceDistance.Length.Value * faceDistancePermyriad);
|
if (faceDistanceLength.Length is null || faceDistanceLength.Length.Value > distanceTolerance)
|
||||||
|
continue;
|
||||||
|
distancePermyriad = (int)(faceDistanceLength.Length.Value * faceDistancePermyriad);
|
||||||
mappedRelations.Add(new(distancePermyriad, files[i]));
|
mappedRelations.Add(new(distancePermyriad, files[i]));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -520,7 +676,7 @@ public partial class E_Distance : IDistance
|
|||||||
return new(results);
|
return new(results);
|
||||||
}
|
}
|
||||||
|
|
||||||
ReadOnlyCollection<RelationContainer> IDistance.GetRelationContainers(int faceDistancePermyriad, int locationContainerDistanceTake, float locationContainerDistanceTolerance, ReadOnlyCollection<LocationContainer> locationContainers)
|
ReadOnlyCollection<RelationContainer> IDistance.GetRelationContainers(IDistanceLimits distanceLimits, int faceDistancePermyriad, int locationContainerDistanceTake, float locationContainerDistanceTolerance, ReadOnlyCollection<LocationContainer> locationContainers)
|
||||||
{
|
{
|
||||||
ReadOnlyCollection<RelationContainer> result;
|
ReadOnlyCollection<RelationContainer> result;
|
||||||
string? json;
|
string? json;
|
||||||
@ -538,7 +694,7 @@ public partial class E_Distance : IDistance
|
|||||||
faceRecognitionDotNetFaceEncoding = FaceRecognition.LoadFaceEncoding(modelsFaceEncoding.RawEncoding);
|
faceRecognitionDotNetFaceEncoding = FaceRecognition.LoadFaceEncoding(modelsFaceEncoding.RawEncoding);
|
||||||
records.Add(new(locationContainer.FilePath, faceRecognitionDotNetFaceEncoding));
|
records.Add(new(locationContainer.FilePath, faceRecognitionDotNetFaceEncoding));
|
||||||
}
|
}
|
||||||
result = GetRelationCollections(faceDistancePermyriad, locationContainerDistanceTake, locationContainerDistanceTolerance, records);
|
result = GetRelationCollections(distanceLimits, faceDistancePermyriad, locationContainerDistanceTake, locationContainerDistanceTolerance, records);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -59,7 +59,7 @@ public partial class DragDropExplorer : Form
|
|||||||
Controls.Add(_FirstTextBox);
|
Controls.Add(_FirstTextBox);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Form1_Load(object? sender, EventArgs e)
|
private void Form1_Load(object? sender, EventArgs e)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@ -81,7 +81,7 @@ public partial class DragDropExplorer : Form
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
void TextBox_LostFocus(object? sender, EventArgs e)
|
private void TextBox_LostFocus(object? sender, EventArgs e)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@ -99,7 +99,7 @@ public partial class DragDropExplorer : Form
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Form1_DragEnter(object? sender, DragEventArgs e)
|
private void Form1_DragEnter(object? sender, DragEventArgs e)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@ -112,7 +112,7 @@ public partial class DragDropExplorer : Form
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Form1_DragDrop(object? sender, DragEventArgs e)
|
private void Form1_DragDrop(object? sender, DragEventArgs e)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
@ -20,6 +20,23 @@ public class AppSettings
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void PreVerify(IConfigurationRoot configurationRoot, AppSettings? appSettings)
|
||||||
|
{
|
||||||
|
if (appSettings?.Company is null)
|
||||||
|
{
|
||||||
|
List<string> paths = [];
|
||||||
|
foreach (IConfigurationProvider configurationProvider in configurationRoot.Providers)
|
||||||
|
{
|
||||||
|
if (configurationProvider is not Microsoft.Extensions.Configuration.Json.JsonConfigurationProvider jsonConfigurationProvider)
|
||||||
|
continue;
|
||||||
|
if (jsonConfigurationProvider.Source.FileProvider is not Microsoft.Extensions.FileProviders.PhysicalFileProvider physicalFileProvider)
|
||||||
|
continue;
|
||||||
|
paths.Add(physicalFileProvider.Root);
|
||||||
|
}
|
||||||
|
throw new NotSupportedException($"Not found!{Environment.NewLine}{string.Join(Environment.NewLine, paths.Distinct())}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private static Models.AppSettings Get(AppSettings? appSettings)
|
private static Models.AppSettings Get(AppSettings? appSettings)
|
||||||
{
|
{
|
||||||
Models.AppSettings result;
|
Models.AppSettings result;
|
||||||
@ -36,7 +53,10 @@ public class AppSettings
|
|||||||
public static Models.AppSettings Get(IConfigurationRoot configurationRoot)
|
public static Models.AppSettings Get(IConfigurationRoot configurationRoot)
|
||||||
{
|
{
|
||||||
Models.AppSettings result;
|
Models.AppSettings result;
|
||||||
|
#pragma warning disable IL3050, IL2026
|
||||||
AppSettings? appSettings = configurationRoot.Get<AppSettings>();
|
AppSettings? appSettings = configurationRoot.Get<AppSettings>();
|
||||||
|
#pragma warning restore IL3050, IL2026
|
||||||
|
PreVerify(configurationRoot, appSettings);
|
||||||
result = Get(appSettings);
|
result = Get(appSettings);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -6,7 +6,7 @@ public class Program
|
|||||||
/// The main entry point for the application.
|
/// The main entry point for the application.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[STAThread]
|
[STAThread]
|
||||||
static void Main()
|
private static void Main()
|
||||||
{
|
{
|
||||||
ApplicationConfiguration.Initialize();
|
ApplicationConfiguration.Initialize();
|
||||||
Application.Run(new DragDropExplorer());
|
Application.Run(new DragDropExplorer());
|
||||||
|
@ -16,6 +16,23 @@ public class AppSettings
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void PreVerify(IConfigurationRoot configurationRoot, AppSettings? appSettings)
|
||||||
|
{
|
||||||
|
if (appSettings?.Company is null)
|
||||||
|
{
|
||||||
|
List<string> paths = [];
|
||||||
|
foreach (IConfigurationProvider configurationProvider in configurationRoot.Providers)
|
||||||
|
{
|
||||||
|
if (configurationProvider is not Microsoft.Extensions.Configuration.Json.JsonConfigurationProvider jsonConfigurationProvider)
|
||||||
|
continue;
|
||||||
|
if (jsonConfigurationProvider.Source.FileProvider is not Microsoft.Extensions.FileProviders.PhysicalFileProvider physicalFileProvider)
|
||||||
|
continue;
|
||||||
|
paths.Add(physicalFileProvider.Root);
|
||||||
|
}
|
||||||
|
throw new NotSupportedException($"Not found!{Environment.NewLine}{string.Join(Environment.NewLine, paths.Distinct())}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private static Models.AppSettings Get(AppSettings? appSettings)
|
private static Models.AppSettings Get(AppSettings? appSettings)
|
||||||
{
|
{
|
||||||
Models.AppSettings result;
|
Models.AppSettings result;
|
||||||
@ -36,7 +53,10 @@ public class AppSettings
|
|||||||
public static Models.AppSettings Get(IConfigurationRoot configurationRoot)
|
public static Models.AppSettings Get(IConfigurationRoot configurationRoot)
|
||||||
{
|
{
|
||||||
Models.AppSettings result;
|
Models.AppSettings result;
|
||||||
|
#pragma warning disable IL3050, IL2026
|
||||||
AppSettings? appSettings = configurationRoot.Get<AppSettings>();
|
AppSettings? appSettings = configurationRoot.Get<AppSettings>();
|
||||||
|
#pragma warning restore IL3050, IL2026
|
||||||
|
PreVerify(configurationRoot, appSettings);
|
||||||
result = Get(appSettings);
|
result = Get(appSettings);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -6,7 +6,7 @@ public class Program
|
|||||||
/// The main entry point for the application.
|
/// The main entry point for the application.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[STAThread]
|
[STAThread]
|
||||||
static void Main()
|
private static void Main()
|
||||||
{
|
{
|
||||||
ApplicationConfiguration.Initialize();
|
ApplicationConfiguration.Initialize();
|
||||||
Application.Run(new DragDropMove());
|
Application.Run(new DragDropMove());
|
||||||
|
@ -64,7 +64,7 @@ public partial class DragDropSearch : Form
|
|||||||
Controls.Add(_TextBox);
|
Controls.Add(_TextBox);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Form1_Load(object? sender, EventArgs e)
|
private void Form1_Load(object? sender, EventArgs e)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@ -79,7 +79,7 @@ public partial class DragDropSearch : Form
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void TextBox_LostFocus(object? sender, EventArgs e)
|
private void TextBox_LostFocus(object? sender, EventArgs e)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@ -92,7 +92,7 @@ public partial class DragDropSearch : Form
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Form1_DragEnter(object? sender, DragEventArgs e)
|
private void Form1_DragEnter(object? sender, DragEventArgs e)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@ -105,7 +105,7 @@ public partial class DragDropSearch : Form
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void LoadData()
|
private void LoadData()
|
||||||
{
|
{
|
||||||
Container[] containers;
|
Container[] containers;
|
||||||
string aPropertySingletonDirectory = Property.Models.Stateless.IResult.GetResultsDateGroupDirectory(_Configuration.PropertyConfiguration, nameof(A_Property), "{}");
|
string aPropertySingletonDirectory = Property.Models.Stateless.IResult.GetResultsDateGroupDirectory(_Configuration.PropertyConfiguration, nameof(A_Property), "{}");
|
||||||
@ -160,15 +160,15 @@ public partial class DragDropSearch : Form
|
|||||||
LoadData();
|
LoadData();
|
||||||
if (int.TryParse(segments[0], out int id) && _IdToItem.TryGetValue(id, out Item? item))
|
if (int.TryParse(segments[0], out int id) && _IdToItem.TryGetValue(id, out Item? item))
|
||||||
{
|
{
|
||||||
Text = item.ImageFileHolder.Name;
|
Text = item.FilePath.Name;
|
||||||
_TextBox.Text = item.ImageFileHolder.FullName;
|
_TextBox.Text = item.FilePath.FullName;
|
||||||
if (!string.IsNullOrEmpty(item.ImageFileHolder.DirectoryName))
|
if (!string.IsNullOrEmpty(item.FilePath.DirectoryName))
|
||||||
_ = Process.Start("explorer.exe", string.Concat("\"", item.ImageFileHolder.DirectoryName, "\""));
|
_ = Process.Start("explorer.exe", string.Concat("\"", item.FilePath.DirectoryName, "\""));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Form1_DragDrop(object? sender, DragEventArgs e)
|
private void Form1_DragDrop(object? sender, DragEventArgs e)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
@ -20,6 +20,23 @@ public class AppSettings
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void PreVerify(IConfigurationRoot configurationRoot, AppSettings? appSettings)
|
||||||
|
{
|
||||||
|
if (appSettings?.Company is null)
|
||||||
|
{
|
||||||
|
List<string> paths = [];
|
||||||
|
foreach (IConfigurationProvider configurationProvider in configurationRoot.Providers)
|
||||||
|
{
|
||||||
|
if (configurationProvider is not Microsoft.Extensions.Configuration.Json.JsonConfigurationProvider jsonConfigurationProvider)
|
||||||
|
continue;
|
||||||
|
if (jsonConfigurationProvider.Source.FileProvider is not Microsoft.Extensions.FileProviders.PhysicalFileProvider physicalFileProvider)
|
||||||
|
continue;
|
||||||
|
paths.Add(physicalFileProvider.Root);
|
||||||
|
}
|
||||||
|
throw new NotSupportedException($"Not found!{Environment.NewLine}{string.Join(Environment.NewLine, paths.Distinct())}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private static Models.AppSettings Get(AppSettings? appSettings)
|
private static Models.AppSettings Get(AppSettings? appSettings)
|
||||||
{
|
{
|
||||||
Models.AppSettings result;
|
Models.AppSettings result;
|
||||||
@ -36,7 +53,10 @@ public class AppSettings
|
|||||||
public static Models.AppSettings Get(IConfigurationRoot configurationRoot)
|
public static Models.AppSettings Get(IConfigurationRoot configurationRoot)
|
||||||
{
|
{
|
||||||
Models.AppSettings result;
|
Models.AppSettings result;
|
||||||
|
#pragma warning disable IL3050, IL2026
|
||||||
AppSettings? appSettings = configurationRoot.Get<AppSettings>();
|
AppSettings? appSettings = configurationRoot.Get<AppSettings>();
|
||||||
|
#pragma warning restore IL3050, IL2026
|
||||||
|
PreVerify(configurationRoot, appSettings);
|
||||||
result = Get(appSettings);
|
result = Get(appSettings);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -7,8 +7,6 @@ namespace View_by_Distance.Drag_Drop.Models.Binder;
|
|||||||
public class Configuration
|
public class Configuration
|
||||||
{
|
{
|
||||||
|
|
||||||
#nullable disable
|
|
||||||
|
|
||||||
public bool? CheckDFaceAndUpWriteDates { get; set; }
|
public bool? CheckDFaceAndUpWriteDates { get; set; }
|
||||||
public bool? CheckJsonForDistanceResults { get; set; }
|
public bool? CheckJsonForDistanceResults { get; set; }
|
||||||
public int? CrossDirectoryMaxItemsInDistanceCollection { get; set; }
|
public int? CrossDirectoryMaxItemsInDistanceCollection { get; set; }
|
||||||
@ -16,40 +14,38 @@ public class Configuration
|
|||||||
public bool? ForceFaceLastWriteTimeToCreationTime { get; set; }
|
public bool? ForceFaceLastWriteTimeToCreationTime { get; set; }
|
||||||
public bool? ForceMetadataLastWriteTimeToCreationTime { get; set; }
|
public bool? ForceMetadataLastWriteTimeToCreationTime { get; set; }
|
||||||
public bool? ForceResizeLastWriteTimeToCreationTime { get; set; }
|
public bool? ForceResizeLastWriteTimeToCreationTime { get; set; }
|
||||||
public string[] IgnoreExtensions { get; set; }
|
public string[]? IgnoreExtensions { get; set; }
|
||||||
public string[] JLinks { get; set; }
|
public string[]? JLinks { get; set; }
|
||||||
public string[] LoadOrCreateThenSaveDistanceResultsForOutputResolutions { get; set; }
|
public string[]? LoadOrCreateThenSaveDistanceResultsForOutputResolutions { get; set; }
|
||||||
public string[] LoadOrCreateThenSaveImageFacesResultsForOutputResolutions { get; set; }
|
public string[]? LoadOrCreateThenSaveImageFacesResultsForOutputResolutions { get; set; }
|
||||||
public string[] MixedYearRelativePaths { get; set; }
|
public string[]? MixedYearRelativePaths { get; set; }
|
||||||
public string ModelDirectory { get; set; }
|
public string? ModelDirectory { get; set; }
|
||||||
public string ModelName { get; set; }
|
public string? ModelName { get; set; }
|
||||||
public int? NumberOfJitters { get; set; }
|
public int? NumberOfJitters { get; set; }
|
||||||
public int? NumberOfTimesToUpsample { get; set; }
|
public int? NumberOfTimesToUpsample { get; set; }
|
||||||
public string OutputExtension { get; set; }
|
public string? OutputExtension { get; set; }
|
||||||
public int? OutputQuality { get; set; }
|
public int? OutputQuality { get; set; }
|
||||||
public string[] OutputResolutions { get; set; }
|
public string[]? OutputResolutions { get; set; }
|
||||||
public bool? OverrideForFaceImages { get; set; }
|
public bool? OverrideForFaceImages { get; set; }
|
||||||
public bool? OverrideForFaceLandmarkImages { get; set; }
|
public bool? OverrideForFaceLandmarkImages { get; set; }
|
||||||
public bool? OverrideForResizeImages { get; set; }
|
public bool? OverrideForResizeImages { get; set; }
|
||||||
public string PersonBirthdayFormat { get; set; }
|
public string? PersonBirthdayFormat { get; set; }
|
||||||
public string PredictorModelName { get; set; }
|
public string? PredictorModelName { get; set; }
|
||||||
public bool? PropertiesChangedForDistance { get; set; }
|
public bool? PropertiesChangedForDistance { get; set; }
|
||||||
public bool? PropertiesChangedForFaces { get; set; }
|
public bool? PropertiesChangedForFaces { get; set; }
|
||||||
public bool? PropertiesChangedForIndex { get; set; }
|
public bool? PropertiesChangedForIndex { get; set; }
|
||||||
public bool? PropertiesChangedForMetadata { get; set; }
|
public bool? PropertiesChangedForMetadata { get; set; }
|
||||||
public bool? PropertiesChangedForResize { get; set; }
|
public bool? PropertiesChangedForResize { get; set; }
|
||||||
public Property.Models.Configuration PropertyConfiguration { get; set; }
|
public Property.Models.Configuration? PropertyConfiguration { get; set; }
|
||||||
public bool? Reverse { get; set; }
|
public bool? Reverse { get; set; }
|
||||||
public string[] SaveFaceLandmarkForOutputResolutions { get; set; }
|
public string[]? SaveFaceLandmarkForOutputResolutions { get; set; }
|
||||||
public bool? SaveFullYearOfRandomFiles { get; set; }
|
public bool? SaveFullYearOfRandomFiles { get; set; }
|
||||||
public string[] SaveFilteredOriginalImagesFromJLinksForOutputResolutions { get; set; }
|
public string[]? SaveFilteredOriginalImagesFromJLinksForOutputResolutions { get; set; }
|
||||||
public string[] SaveShortcutsForOutputResolutions { get; set; }
|
public string[]? SaveShortcutsForOutputResolutions { get; set; }
|
||||||
public bool? SaveResizedSubfiles { get; set; }
|
public bool? SaveResizedSubfiles { get; set; }
|
||||||
public bool? SkipSearch { get; set; }
|
public bool? SkipSearch { get; set; }
|
||||||
public bool? TestDistanceResults { get; set; }
|
public bool? TestDistanceResults { get; set; }
|
||||||
public string[] ValidResolutions { get; set; }
|
public string[]? ValidResolutions { get; set; }
|
||||||
|
|
||||||
#nullable restore
|
|
||||||
|
|
||||||
public override string ToString()
|
public override string ToString()
|
||||||
{
|
{
|
||||||
@ -57,10 +53,28 @@ public class Configuration
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void PreVerify(IConfigurationRoot configurationRoot, Configuration? configuration)
|
||||||
|
{
|
||||||
|
if (configuration?.CheckDFaceAndUpWriteDates is null)
|
||||||
|
{
|
||||||
|
List<string> paths = [];
|
||||||
|
foreach (IConfigurationProvider configurationProvider in configurationRoot.Providers)
|
||||||
|
{
|
||||||
|
if (configurationProvider is not Microsoft.Extensions.Configuration.Json.JsonConfigurationProvider jsonConfigurationProvider)
|
||||||
|
continue;
|
||||||
|
if (jsonConfigurationProvider.Source.FileProvider is not Microsoft.Extensions.FileProviders.PhysicalFileProvider physicalFileProvider)
|
||||||
|
continue;
|
||||||
|
paths.Add(physicalFileProvider.Root);
|
||||||
|
}
|
||||||
|
throw new NotSupportedException($"Not found!{Environment.NewLine}{string.Join(Environment.NewLine, paths.Distinct())}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private static Models.Configuration Get(Configuration? configuration)
|
private static Models.Configuration Get(Configuration? configuration)
|
||||||
{
|
{
|
||||||
Models.Configuration result;
|
Models.Configuration result;
|
||||||
if (configuration is null) throw new NullReferenceException(nameof(configuration));
|
if (configuration is null) throw new NullReferenceException(nameof(configuration));
|
||||||
|
if (configuration.PropertyConfiguration is null) throw new NullReferenceException(nameof(configuration.PropertyConfiguration));
|
||||||
if (configuration.CheckDFaceAndUpWriteDates is null) throw new NullReferenceException(nameof(configuration.CheckDFaceAndUpWriteDates));
|
if (configuration.CheckDFaceAndUpWriteDates is null) throw new NullReferenceException(nameof(configuration.CheckDFaceAndUpWriteDates));
|
||||||
if (configuration.CheckJsonForDistanceResults is null) throw new NullReferenceException(nameof(configuration.CheckJsonForDistanceResults));
|
if (configuration.CheckJsonForDistanceResults is null) throw new NullReferenceException(nameof(configuration.CheckJsonForDistanceResults));
|
||||||
if (configuration.CrossDirectoryMaxItemsInDistanceCollection is null) throw new NullReferenceException(nameof(configuration.CrossDirectoryMaxItemsInDistanceCollection));
|
if (configuration.CrossDirectoryMaxItemsInDistanceCollection is null) throw new NullReferenceException(nameof(configuration.CrossDirectoryMaxItemsInDistanceCollection));
|
||||||
@ -68,18 +82,23 @@ public class Configuration
|
|||||||
if (configuration.ForceFaceLastWriteTimeToCreationTime is null) throw new NullReferenceException(nameof(configuration.ForceFaceLastWriteTimeToCreationTime));
|
if (configuration.ForceFaceLastWriteTimeToCreationTime is null) throw new NullReferenceException(nameof(configuration.ForceFaceLastWriteTimeToCreationTime));
|
||||||
if (configuration.ForceMetadataLastWriteTimeToCreationTime is null) throw new NullReferenceException(nameof(configuration.ForceMetadataLastWriteTimeToCreationTime));
|
if (configuration.ForceMetadataLastWriteTimeToCreationTime is null) throw new NullReferenceException(nameof(configuration.ForceMetadataLastWriteTimeToCreationTime));
|
||||||
if (configuration.ForceResizeLastWriteTimeToCreationTime is null) throw new NullReferenceException(nameof(configuration.ForceResizeLastWriteTimeToCreationTime));
|
if (configuration.ForceResizeLastWriteTimeToCreationTime is null) throw new NullReferenceException(nameof(configuration.ForceResizeLastWriteTimeToCreationTime));
|
||||||
|
if (configuration.JLinks is null) throw new NullReferenceException(nameof(configuration.JLinks));
|
||||||
if (configuration.IgnoreExtensions is null) throw new NullReferenceException(nameof(configuration.IgnoreExtensions));
|
if (configuration.IgnoreExtensions is null) throw new NullReferenceException(nameof(configuration.IgnoreExtensions));
|
||||||
configuration.LoadOrCreateThenSaveDistanceResultsForOutputResolutions ??= [];
|
configuration.LoadOrCreateThenSaveDistanceResultsForOutputResolutions ??= [];
|
||||||
configuration.LoadOrCreateThenSaveImageFacesResultsForOutputResolutions ??= [];
|
configuration.LoadOrCreateThenSaveImageFacesResultsForOutputResolutions ??= [];
|
||||||
if (configuration.MixedYearRelativePaths is null) throw new NullReferenceException(nameof(configuration.MixedYearRelativePaths));
|
if (configuration.MixedYearRelativePaths is null) throw new NullReferenceException(nameof(configuration.MixedYearRelativePaths));
|
||||||
|
if (configuration.ModelDirectory is null) throw new NullReferenceException(nameof(configuration.ModelDirectory));
|
||||||
|
if (configuration.ModelName is null) throw new NullReferenceException(nameof(configuration.ModelName));
|
||||||
if (configuration.NumberOfJitters is null) throw new NullReferenceException(nameof(configuration.NumberOfJitters));
|
if (configuration.NumberOfJitters is null) throw new NullReferenceException(nameof(configuration.NumberOfJitters));
|
||||||
if (configuration.NumberOfTimesToUpsample is null) throw new NullReferenceException(nameof(configuration.NumberOfTimesToUpsample));
|
if (configuration.NumberOfTimesToUpsample is null) throw new NullReferenceException(nameof(configuration.NumberOfTimesToUpsample));
|
||||||
|
if (configuration.OutputExtension is null) throw new NullReferenceException(nameof(configuration.OutputExtension));
|
||||||
if (configuration.OutputQuality is null) throw new NullReferenceException(nameof(configuration.OutputQuality));
|
if (configuration.OutputQuality is null) throw new NullReferenceException(nameof(configuration.OutputQuality));
|
||||||
if (configuration.OutputResolutions is null) throw new NullReferenceException(nameof(configuration.OutputResolutions));
|
if (configuration.OutputResolutions is null) throw new NullReferenceException(nameof(configuration.OutputResolutions));
|
||||||
if (configuration.OverrideForFaceImages is null) throw new NullReferenceException(nameof(configuration.OverrideForFaceImages));
|
if (configuration.OverrideForFaceImages is null) throw new NullReferenceException(nameof(configuration.OverrideForFaceImages));
|
||||||
if (configuration.OverrideForFaceLandmarkImages is null) throw new NullReferenceException(nameof(configuration.OverrideForFaceLandmarkImages));
|
if (configuration.OverrideForFaceLandmarkImages is null) throw new NullReferenceException(nameof(configuration.OverrideForFaceLandmarkImages));
|
||||||
if (configuration.OverrideForResizeImages is null) throw new NullReferenceException(nameof(configuration.OverrideForResizeImages));
|
if (configuration.OverrideForResizeImages is null) throw new NullReferenceException(nameof(configuration.OverrideForResizeImages));
|
||||||
if (configuration.PersonBirthdayFormat is null) throw new NullReferenceException(nameof(configuration.PersonBirthdayFormat));
|
if (configuration.PersonBirthdayFormat is null) throw new NullReferenceException(nameof(configuration.PersonBirthdayFormat));
|
||||||
|
if (configuration.PredictorModelName is null) throw new NullReferenceException(nameof(configuration.PredictorModelName));
|
||||||
if (configuration.PropertiesChangedForDistance is null) throw new NullReferenceException(nameof(configuration.PropertiesChangedForDistance));
|
if (configuration.PropertiesChangedForDistance is null) throw new NullReferenceException(nameof(configuration.PropertiesChangedForDistance));
|
||||||
if (configuration.PropertiesChangedForFaces is null) throw new NullReferenceException(nameof(configuration.PropertiesChangedForFaces));
|
if (configuration.PropertiesChangedForFaces is null) throw new NullReferenceException(nameof(configuration.PropertiesChangedForFaces));
|
||||||
if (configuration.PropertiesChangedForIndex is null) throw new NullReferenceException(nameof(configuration.PropertiesChangedForIndex));
|
if (configuration.PropertiesChangedForIndex is null) throw new NullReferenceException(nameof(configuration.PropertiesChangedForIndex));
|
||||||
@ -141,14 +160,19 @@ public class Configuration
|
|||||||
Models.Configuration result;
|
Models.Configuration result;
|
||||||
Configuration? configuration;
|
Configuration? configuration;
|
||||||
if (isEnvironment is null)
|
if (isEnvironment is null)
|
||||||
|
#pragma warning disable IL3050, IL2026
|
||||||
configuration = configurationRoot.Get<Configuration>();
|
configuration = configurationRoot.Get<Configuration>();
|
||||||
|
#pragma warning restore IL3050, IL2026
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
string environmentName = IsEnvironment.GetEnvironmentName(isEnvironment);
|
string environmentName = IsEnvironment.GetEnvironmentName(isEnvironment);
|
||||||
string section = string.Concat(environmentName, ":", nameof(Configuration));
|
string section = string.Concat(environmentName, ":", nameof(Configuration));
|
||||||
IConfigurationSection configurationSection = configurationRoot.GetSection(section);
|
IConfigurationSection configurationSection = configurationRoot.GetSection(section);
|
||||||
|
#pragma warning disable IL3050, IL2026
|
||||||
configuration = configurationSection.Get<Configuration>();
|
configuration = configurationSection.Get<Configuration>();
|
||||||
|
#pragma warning restore IL3050, IL2026
|
||||||
}
|
}
|
||||||
|
PreVerify(configurationRoot, configuration);
|
||||||
result = Get(configuration);
|
result = Get(configuration);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -8,7 +8,7 @@ public class Program
|
|||||||
/// The main entry point for the application.
|
/// The main entry point for the application.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[STAThread]
|
[STAThread]
|
||||||
static void Main()
|
private static void Main()
|
||||||
{
|
{
|
||||||
ApplicationConfiguration.Initialize();
|
ApplicationConfiguration.Initialize();
|
||||||
Application.Run(new DragDropSearch());
|
Application.Run(new DragDropSearch());
|
||||||
@ -19,9 +19,8 @@ public class Program
|
|||||||
List<Item> results = [];
|
List<Item> results = [];
|
||||||
foreach (Item item in container.Items)
|
foreach (Item item in container.Items)
|
||||||
{
|
{
|
||||||
if (item.ImageFileHolder is not null
|
if (item.IsValidImageFormatExtension
|
||||||
&& item.IsValidImageFormatExtension
|
&& !configuration.IgnoreExtensions.Contains(item.FilePath.ExtensionLowered))
|
||||||
&& !configuration.IgnoreExtensions.Contains(item.ImageFileHolder.ExtensionLowered))
|
|
||||||
results.Add(item);
|
results.Add(item);
|
||||||
}
|
}
|
||||||
return results.ToArray();
|
return results.ToArray();
|
||||||
|
@ -116,7 +116,7 @@ public partial class DragDropSetPropertyItem : Form
|
|||||||
fileHolder = IFileHolder.Get(file);
|
fileHolder = IFileHolder.Get(file);
|
||||||
isValidImageFormatExtension = _PropertyConfiguration.ValidImageFormatExtensions.Contains(fileHolder.ExtensionLowered);
|
isValidImageFormatExtension = _PropertyConfiguration.ValidImageFormatExtensions.Contains(fileHolder.ExtensionLowered);
|
||||||
isIgnoreExtension = isValidImageFormatExtension && _PropertyConfiguration.IgnoreExtensions.Contains(fileHolder.ExtensionLowered);
|
isIgnoreExtension = isValidImageFormatExtension && _PropertyConfiguration.IgnoreExtensions.Contains(fileHolder.ExtensionLowered);
|
||||||
(dateTimeOriginal, _, id, message) = Property.Models.Stateless.IProperty.Get(_PropertyConfiguration.PopulatePropertyId, fileHolder, isIgnoreExtension, isValidImageFormatExtension, asciiEncoding);
|
(dateTimeOriginal, _, id, message) = Property.Models.Stateless.IProperty.Get(_PropertyConfiguration, _PropertyConfiguration.PopulatePropertyId, fileHolder, isIgnoreExtension, isValidImageFormatExtension, asciiEncoding);
|
||||||
if (message is not null)
|
if (message is not null)
|
||||||
throw new Exception(message);
|
throw new Exception(message);
|
||||||
if (id is null)
|
if (id is null)
|
||||||
@ -165,7 +165,7 @@ public partial class DragDropSetPropertyItem : Form
|
|||||||
bitmap.SetPropertyItem(propertyItem);
|
bitmap.SetPropertyItem(propertyItem);
|
||||||
bitmap.Save(checkFile);
|
bitmap.Save(checkFile);
|
||||||
bitmap.Dispose();
|
bitmap.Dispose();
|
||||||
(_, _, id, message) = Property.Models.Stateless.IProperty.Get(_PropertyConfiguration.PopulatePropertyId, record.FileHolder, record.IsIgnoreExtension, record.IsValidImageFormatExtension, asciiEncoding);
|
(_, _, id, message) = Property.Models.Stateless.IProperty.Get(_PropertyConfiguration, _PropertyConfiguration.PopulatePropertyId, record.FileHolder, record.IsIgnoreExtension, record.IsValidImageFormatExtension, asciiEncoding);
|
||||||
if (id is null || id.Value != record.Id)
|
if (id is null || id.Value != record.Id)
|
||||||
throw new NotSupportedException();
|
throw new NotSupportedException();
|
||||||
File.Delete(record.FileHolder.FullName);
|
File.Delete(record.FileHolder.FullName);
|
||||||
|
@ -17,6 +17,23 @@ public class AppSettings
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void PreVerify(IConfigurationRoot configurationRoot, AppSettings? appSettings)
|
||||||
|
{
|
||||||
|
if (appSettings?.Company is null)
|
||||||
|
{
|
||||||
|
List<string> paths = [];
|
||||||
|
foreach (IConfigurationProvider configurationProvider in configurationRoot.Providers)
|
||||||
|
{
|
||||||
|
if (configurationProvider is not Microsoft.Extensions.Configuration.Json.JsonConfigurationProvider jsonConfigurationProvider)
|
||||||
|
continue;
|
||||||
|
if (jsonConfigurationProvider.Source.FileProvider is not Microsoft.Extensions.FileProviders.PhysicalFileProvider physicalFileProvider)
|
||||||
|
continue;
|
||||||
|
paths.Add(physicalFileProvider.Root);
|
||||||
|
}
|
||||||
|
throw new NotSupportedException($"Not found!{Environment.NewLine}{string.Join(Environment.NewLine, paths.Distinct())}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private static Models.AppSettings Get(AppSettings? appSettings)
|
private static Models.AppSettings Get(AppSettings? appSettings)
|
||||||
{
|
{
|
||||||
Models.AppSettings result;
|
Models.AppSettings result;
|
||||||
@ -36,7 +53,10 @@ public class AppSettings
|
|||||||
public static Models.AppSettings Get(IConfigurationRoot configurationRoot)
|
public static Models.AppSettings Get(IConfigurationRoot configurationRoot)
|
||||||
{
|
{
|
||||||
Models.AppSettings result;
|
Models.AppSettings result;
|
||||||
|
#pragma warning disable IL3050, IL2026
|
||||||
AppSettings? appSettings = configurationRoot.Get<AppSettings>();
|
AppSettings? appSettings = configurationRoot.Get<AppSettings>();
|
||||||
|
#pragma warning restore IL3050, IL2026
|
||||||
|
PreVerify(configurationRoot, appSettings);
|
||||||
result = Get(appSettings);
|
result = Get(appSettings);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -6,7 +6,7 @@ public class Program
|
|||||||
/// The main entry point for the application.
|
/// The main entry point for the application.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[STAThread]
|
[STAThread]
|
||||||
static void Main()
|
private static void Main()
|
||||||
{
|
{
|
||||||
ApplicationConfiguration.Initialize();
|
ApplicationConfiguration.Initialize();
|
||||||
Application.Run(new DragDropSetPropertyItem());
|
Application.Run(new DragDropSetPropertyItem());
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using Phares.Shared;
|
using Phares.Shared;
|
||||||
using ShellProgressBar;
|
using ShellProgressBar;
|
||||||
|
using System.Collections.ObjectModel;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Text.Json;
|
using System.Text.Json;
|
||||||
using View_by_Distance.Duplicate.Search.Models;
|
using View_by_Distance.Duplicate.Search.Models;
|
||||||
@ -29,9 +30,9 @@ public class DuplicateSearch
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
Configuration.Verify(configuration, requireExist: false);
|
Configuration.Verify(configuration, requireExist: false);
|
||||||
|
Container[] containers = GetContainers(ticks, configuration);
|
||||||
string argZero = args.Count > 0 ? Path.GetFullPath(args[0]) : Path.GetFullPath(configuration.RootDirectory);
|
string argZero = args.Count > 0 ? Path.GetFullPath(args[0]) : Path.GetFullPath(configuration.RootDirectory);
|
||||||
bool argZeroIsConfigurationRootDirectory = configuration.RootDirectory == argZero;
|
bool argZeroIsConfigurationRootDirectory = configuration.RootDirectory == argZero;
|
||||||
Container[] containers = GetContainers(appSettings, ticks, argZero, configuration, argZeroIsConfigurationRootDirectory);
|
|
||||||
string destinationRoot = Property.Models.Stateless.IResult.GetResultsGroupDirectory(configuration, "Z) Moved");
|
string destinationRoot = Property.Models.Stateless.IResult.GetResultsGroupDirectory(configuration, "Z) Moved");
|
||||||
List<int> preloadIds = GetPreloadIds(destinationRoot);
|
List<int> preloadIds = GetPreloadIds(destinationRoot);
|
||||||
Dictionary<int, List<MappingFromItem?>> idToCollection = GetIdToCollection(argZero, configuration, argZeroIsConfigurationRootDirectory, containers, destinationRoot, preloadIds);
|
Dictionary<int, List<MappingFromItem?>> idToCollection = GetIdToCollection(argZero, configuration, argZeroIsConfigurationRootDirectory, containers, destinationRoot, preloadIds);
|
||||||
@ -60,10 +61,10 @@ public class DuplicateSearch
|
|||||||
File.WriteAllText(Path.Combine(alongSideDirectory, $"{directoryName}-{ticks}.json"), json);
|
File.WriteAllText(Path.Combine(alongSideDirectory, $"{directoryName}-{ticks}.json"), json);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void Move(ILogger<Program>? logger, long ticks, string destinationRoot, List<(FileHolder ImageFileHolder, string Destination)> collection)
|
private static void Move(ILogger<Program>? logger, long ticks, string destinationRoot, List<(FilePath FilePath, string Destination)> collection)
|
||||||
{
|
{
|
||||||
StringBuilder stringBuilder = new();
|
StringBuilder stringBuilder = new();
|
||||||
foreach ((FileHolder fileHolder, string destination) in collection)
|
foreach ((FilePath fileHolder, string destination) in collection)
|
||||||
{
|
{
|
||||||
_ = stringBuilder.AppendLine(fileHolder.FullName);
|
_ = stringBuilder.AppendLine(fileHolder.FullName);
|
||||||
_ = stringBuilder.AppendLine(destination);
|
_ = stringBuilder.AppendLine(destination);
|
||||||
@ -77,12 +78,12 @@ public class DuplicateSearch
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
logger?.LogInformation(". . .");
|
logger?.LogInformation(". . .");
|
||||||
foreach ((FileHolder fileHolder, string destination) in collection)
|
foreach ((FilePath filePath, string destination) in collection)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{ File.Move(fileHolder.FullName, destination); }
|
{ File.Move(filePath.FullName, destination); }
|
||||||
catch (Exception exception)
|
catch (Exception exception)
|
||||||
{ logger?.LogError(exception, $"Failed to move <{fileHolder.FullName}>"); }
|
{ logger?.LogError(exception, $"Failed to move <{filePath.FullName}>"); }
|
||||||
}
|
}
|
||||||
logger?.LogInformation($"{collection.Count} file(s) moved");
|
logger?.LogInformation($"{collection.Count} file(s) moved");
|
||||||
for (int y = 0; y < int.MaxValue; y++)
|
for (int y = 0; y < int.MaxValue; y++)
|
||||||
@ -91,14 +92,14 @@ public class DuplicateSearch
|
|||||||
if (System.Console.ReadKey().Key != ConsoleKey.Y)
|
if (System.Console.ReadKey().Key != ConsoleKey.Y)
|
||||||
continue;
|
continue;
|
||||||
logger?.LogInformation(". . .");
|
logger?.LogInformation(". . .");
|
||||||
foreach ((FileHolder fileHolder, string destination) in collection)
|
foreach ((FilePath filePath, string destination) in collection)
|
||||||
{
|
{
|
||||||
if (!File.Exists(destination))
|
if (!File.Exists(destination))
|
||||||
continue;
|
continue;
|
||||||
if (File.Exists(fileHolder.FullName))
|
if (File.Exists(filePath.FullName))
|
||||||
continue;
|
continue;
|
||||||
try
|
try
|
||||||
{ File.Move(destination, fileHolder.FullName); }
|
{ File.Move(destination, filePath.FullName); }
|
||||||
catch (Exception exception)
|
catch (Exception exception)
|
||||||
{ logger?.LogError(exception, $"Failed to move <{destination}>"); }
|
{ logger?.LogError(exception, $"Failed to move <{destination}>"); }
|
||||||
}
|
}
|
||||||
@ -119,12 +120,12 @@ public class DuplicateSearch
|
|||||||
if (System.Console.ReadKey().Key != ConsoleKey.Y)
|
if (System.Console.ReadKey().Key != ConsoleKey.Y)
|
||||||
continue;
|
continue;
|
||||||
logger?.LogInformation(". . .");
|
logger?.LogInformation(". . .");
|
||||||
List<(FileHolder ImageFileHolder, string Destination)> collection = GetCollectionAndCreateDirectories(idToCollection);
|
List<(FilePath FilePath, string Destination)> collection = GetCollectionAndCreateDirectories(idToCollection);
|
||||||
Move(logger, ticks, destinationRoot, collection);
|
Move(logger, ticks, destinationRoot, collection);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Container[] GetContainers(AppSettings appSettings, long ticks, string argZero, Configuration configuration, bool argZeroIsConfigurationRootDirectory)
|
private static Container[] GetContainers(long ticks, Configuration configuration)
|
||||||
{
|
{
|
||||||
int f;
|
int f;
|
||||||
Container[] containers;
|
Container[] containers;
|
||||||
@ -145,11 +146,11 @@ public class DuplicateSearch
|
|||||||
Dictionary<int, List<MappingFromItem?>> results = [];
|
Dictionary<int, List<MappingFromItem?>> results = [];
|
||||||
string directory;
|
string directory;
|
||||||
const int zero = 0;
|
const int zero = 0;
|
||||||
Item[] filteredItems;
|
|
||||||
FileHolder resizedFileHolder;
|
FileHolder resizedFileHolder;
|
||||||
DateTime[] containerDateTimes;
|
DateTime[] containerDateTimes;
|
||||||
MappingFromItem? mappingFromItem;
|
MappingFromItem? mappingFromItem;
|
||||||
List<MappingFromItem?>? collection;
|
List<MappingFromItem?>? collection;
|
||||||
|
ReadOnlyCollection<Item> validImageItems;
|
||||||
const string duplicates = "-Duplicate(s)";
|
const string duplicates = "-Duplicate(s)";
|
||||||
if (containers.Length != 0)
|
if (containers.Length != 0)
|
||||||
{
|
{
|
||||||
@ -162,15 +163,15 @@ public class DuplicateSearch
|
|||||||
continue;
|
continue;
|
||||||
if (!argZeroIsConfigurationRootDirectory && !container.SourceDirectory.StartsWith(argZero))
|
if (!argZeroIsConfigurationRootDirectory && !container.SourceDirectory.StartsWith(argZero))
|
||||||
continue;
|
continue;
|
||||||
filteredItems = Shared.Models.Stateless.Methods.IContainer.GetFilterItems(configuration, container);
|
validImageItems = Shared.Models.Stateless.Methods.IContainer.GetValidImageItems(configuration, container);
|
||||||
if (filteredItems.Length == 0)
|
if (validImageItems.Count == 0)
|
||||||
continue;
|
continue;
|
||||||
containerDateTimes = Shared.Models.Stateless.Methods.IContainer.GetContainerDateTimes(filteredItems);
|
containerDateTimes = Shared.Models.Stateless.Methods.IContainer.GetContainerDateTimes(validImageItems);
|
||||||
foreach (Item item in filteredItems)
|
foreach (Item item in validImageItems)
|
||||||
{
|
{
|
||||||
if (item.Property?.Id is null)
|
if (item.Property?.Id is null)
|
||||||
{
|
{
|
||||||
if (int.TryParse(item.ImageFileHolder.NameWithoutExtension, out int id))
|
if (int.TryParse(item.FilePath.NameWithoutExtension, out int id))
|
||||||
continue;
|
continue;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -188,7 +189,7 @@ public class DuplicateSearch
|
|||||||
if (mappingFromItem is not null)
|
if (mappingFromItem is not null)
|
||||||
{
|
{
|
||||||
resizedFileHolder = Shared.Models.Stateless.Methods.IFileHolder.Get(mappingFromItem.ResizedFileHolder.FullName.Replace($"0{duplicates}", $"1{duplicates}"));
|
resizedFileHolder = Shared.Models.Stateless.Methods.IFileHolder.Get(mappingFromItem.ResizedFileHolder.FullName.Replace($"0{duplicates}", $"1{duplicates}"));
|
||||||
collection[0] = new(mappingFromItem.ContainerDateTimes, item.Property.DateTimeDigitized, item.Property.DateTimeOriginal, mappingFromItem.Id, mappingFromItem.ImageFileHolder, mappingFromItem.IsWrongYear, item.Property.Keywords ?? [], mappingFromItem.MinimumDateTime, item.Property.Model, mappingFromItem.RelativePath, resizedFileHolder);
|
collection[0] = new(mappingFromItem.ContainerDateTimes, item.Property.DateTimeDigitized, item.Property.DateTimeOriginal, mappingFromItem.Id, mappingFromItem.FilePath, mappingFromItem.IsWrongYear, item.Property.Keywords ?? [], mappingFromItem.MinimumDateTime, item.Property.Model, mappingFromItem.RelativePath, resizedFileHolder);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
resizedFileHolder = Shared.Models.Stateless.Methods.IFileHolder.Get(string.Concat(Path.Combine(destinationRoot, directory), item.RelativePath));
|
resizedFileHolder = Shared.Models.Stateless.Methods.IFileHolder.Get(string.Concat(Path.Combine(destinationRoot, directory), item.RelativePath));
|
||||||
@ -199,9 +200,9 @@ public class DuplicateSearch
|
|||||||
return results;
|
return results;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static List<(FileHolder ImageFileHolder, string Destination)> GetCollectionAndCreateDirectories(Dictionary<int, List<MappingFromItem?>> idToCollection)
|
private static List<(FilePath FilePath, string Destination)> GetCollectionAndCreateDirectories(Dictionary<int, List<MappingFromItem?>> idToCollection)
|
||||||
{
|
{
|
||||||
List<(FileHolder ImageFileHolder, string Destination)> results = [];
|
List<(FilePath FilePath, string Destination)> results = [];
|
||||||
List<string> collection = [];
|
List<string> collection = [];
|
||||||
foreach (KeyValuePair<int, List<MappingFromItem?>> keyValuePair in idToCollection)
|
foreach (KeyValuePair<int, List<MappingFromItem?>> keyValuePair in idToCollection)
|
||||||
{
|
{
|
||||||
@ -209,10 +210,10 @@ public class DuplicateSearch
|
|||||||
{
|
{
|
||||||
if (mappingFromItem?.ResizedFileHolder.DirectoryName is null)
|
if (mappingFromItem?.ResizedFileHolder.DirectoryName is null)
|
||||||
continue;
|
continue;
|
||||||
if (!mappingFromItem.ImageFileHolder.Exists || mappingFromItem.ResizedFileHolder.Exists)
|
if (mappingFromItem.ResizedFileHolder.Exists)
|
||||||
continue;
|
continue;
|
||||||
collection.Add(mappingFromItem.ResizedFileHolder.DirectoryName);
|
collection.Add(mappingFromItem.ResizedFileHolder.DirectoryName);
|
||||||
results.Add(new(mappingFromItem.ImageFileHolder, mappingFromItem.ResizedFileHolder.FullName));
|
results.Add(new(mappingFromItem.FilePath, mappingFromItem.ResizedFileHolder.FullName));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
foreach (string directory in collection.Distinct())
|
foreach (string directory in collection.Distinct())
|
||||||
|
@ -23,6 +23,23 @@ public class AppSettings
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void PreVerify(IConfigurationRoot configurationRoot, AppSettings? appSettings)
|
||||||
|
{
|
||||||
|
if (appSettings?.Company is null)
|
||||||
|
{
|
||||||
|
List<string> paths = [];
|
||||||
|
foreach (IConfigurationProvider configurationProvider in configurationRoot.Providers)
|
||||||
|
{
|
||||||
|
if (configurationProvider is not Microsoft.Extensions.Configuration.Json.JsonConfigurationProvider jsonConfigurationProvider)
|
||||||
|
continue;
|
||||||
|
if (jsonConfigurationProvider.Source.FileProvider is not Microsoft.Extensions.FileProviders.PhysicalFileProvider physicalFileProvider)
|
||||||
|
continue;
|
||||||
|
paths.Add(physicalFileProvider.Root);
|
||||||
|
}
|
||||||
|
throw new NotSupportedException($"Not found!{Environment.NewLine}{string.Join(Environment.NewLine, paths.Distinct())}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private static Models.AppSettings Get(AppSettings? appSettings)
|
private static Models.AppSettings Get(AppSettings? appSettings)
|
||||||
{
|
{
|
||||||
Models.AppSettings result;
|
Models.AppSettings result;
|
||||||
@ -46,7 +63,10 @@ public class AppSettings
|
|||||||
public static Models.AppSettings Get(IConfigurationRoot configurationRoot)
|
public static Models.AppSettings Get(IConfigurationRoot configurationRoot)
|
||||||
{
|
{
|
||||||
Models.AppSettings result;
|
Models.AppSettings result;
|
||||||
|
#pragma warning disable IL3050, IL2026
|
||||||
AppSettings? appSettings = configurationRoot.Get<AppSettings>();
|
AppSettings? appSettings = configurationRoot.Get<AppSettings>();
|
||||||
|
#pragma warning restore IL3050, IL2026
|
||||||
|
PreVerify(configurationRoot, appSettings);
|
||||||
result = Get(appSettings);
|
result = Get(appSettings);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -6,19 +6,20 @@ using System.Text.Json;
|
|||||||
using System.Text.Json.Serialization;
|
using System.Text.Json.Serialization;
|
||||||
using View_by_Distance.FaceRecognitionDotNet;
|
using View_by_Distance.FaceRecognitionDotNet;
|
||||||
using View_by_Distance.Metadata.Models;
|
using View_by_Distance.Metadata.Models;
|
||||||
|
using View_by_Distance.Metadata.Models.Stateless.Methods;
|
||||||
using View_by_Distance.Property.Models;
|
using View_by_Distance.Property.Models;
|
||||||
using View_by_Distance.Property.Models.Stateless;
|
|
||||||
using View_by_Distance.Resize.Models;
|
using View_by_Distance.Resize.Models;
|
||||||
using View_by_Distance.Shared.Models;
|
using View_by_Distance.Shared.Models;
|
||||||
using View_by_Distance.Shared.Models.Properties;
|
using View_by_Distance.Shared.Models.Properties;
|
||||||
using View_by_Distance.Shared.Models.Stateless;
|
using View_by_Distance.Shared.Models.Stateless;
|
||||||
|
using View_by_Distance.Shared.Models.Stateless.Methods;
|
||||||
|
|
||||||
namespace View_by_Distance.Face.Models;
|
namespace View_by_Distance.Face.Models;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
// List<D_Faces>
|
// List<D_Faces>
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class D_Face
|
public class D_Face : IFaceD
|
||||||
{
|
{
|
||||||
|
|
||||||
protected readonly string _FileNameExtension;
|
protected readonly string _FileNameExtension;
|
||||||
@ -149,51 +150,66 @@ public class D_Face
|
|||||||
|
|
||||||
#pragma warning disable CA1416
|
#pragma warning disable CA1416
|
||||||
|
|
||||||
private void SaveFaces(FileHolder resizedFileHolder, List<(Shared.Models.Face, FileInfo?, string, bool)> collection)
|
private void SaveFaces(FileHolder resizedFileHolder, ExifDirectory exifDirectory, List<(Shared.Models.Face, FileHolder?, string, bool)> collection)
|
||||||
{
|
{
|
||||||
int width;
|
int width;
|
||||||
int height;
|
int height;
|
||||||
Bitmap bitmap;
|
Bitmap bitmap;
|
||||||
short type = 2;
|
short type = 2;
|
||||||
|
FaceFile faceFile;
|
||||||
Graphics graphics;
|
Graphics graphics;
|
||||||
Location? location;
|
Location? location;
|
||||||
Rectangle rectangle;
|
Rectangle rectangle;
|
||||||
string locationJson;
|
string faceFileJson;
|
||||||
string faceEncodingJson;
|
string faceEncodingJson;
|
||||||
PropertyItem? propertyItem;
|
PropertyItem? propertyItem;
|
||||||
string outputResolutionJson;
|
string? maker = IMetadata.GetMaker(exifDirectory);
|
||||||
|
string? model = IMetadata.GetModel(exifDirectory);
|
||||||
using Bitmap source = new(resizedFileHolder.FullName);
|
using Bitmap source = new(resizedFileHolder.FullName);
|
||||||
int artist = MetadataExtractor.Formats.Exif.ExifDirectoryBase.TagArtist;
|
MetadataExtractor.GeoLocation? geoLocation = IMetadata.GeoLocation(exifDirectory);
|
||||||
int fileSource = MetadataExtractor.Formats.Exif.ExifDirectoryBase.TagFileSource;
|
const int artist = MetadataExtractor.Formats.Exif.ExifDirectoryBase.TagArtist; // 315
|
||||||
int userComment = MetadataExtractor.Formats.Exif.ExifDirectoryBase.TagUserComment;
|
const int userComment = MetadataExtractor.Formats.Exif.ExifDirectoryBase.TagUserComment;
|
||||||
foreach ((Shared.Models.Face face, FileInfo? fileInfo, string fileName, bool save) in collection)
|
foreach ((Shared.Models.Face face, FileHolder? fileHolder, string fileName, bool save) in collection)
|
||||||
{
|
{
|
||||||
if (!save)
|
if (!save)
|
||||||
continue;
|
continue;
|
||||||
if (fileInfo is null)
|
if (fileHolder is null)
|
||||||
continue;
|
continue;
|
||||||
if (face.FaceEncoding is null || face?.Location is null || face?.OutputResolution is null)
|
if (face.FaceEncoding is null || face?.Location is null || face?.OutputResolution is null)
|
||||||
continue;
|
continue;
|
||||||
|
if (_OverrideForFaceImages && fileHolder.Exists)
|
||||||
|
{
|
||||||
|
IFaceD dFace = this;
|
||||||
|
FilePath filePath = FilePath.Get(_PropertyConfiguration, fileHolder, index: null);
|
||||||
|
dFace.ReSaveFace(exifDirectory, filePath, face, mappedFile: false);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
location = Shared.Models.Stateless.Methods.ILocation.GetLocation(face.Location, Shared.Models.Stateless.ILocation.Digits, Shared.Models.Stateless.ILocation.Factor, source.Height, source.Width, collection.Count);
|
location = Shared.Models.Stateless.Methods.ILocation.GetLocation(face.Location, Shared.Models.Stateless.ILocation.Digits, Shared.Models.Stateless.ILocation.Factor, source.Height, source.Width, collection.Count);
|
||||||
if (location is null)
|
if (location is null)
|
||||||
continue;
|
continue;
|
||||||
width = location.Right - location.Left;
|
width = location.Right - location.Left;
|
||||||
height = location.Bottom - location.Top;
|
height = location.Bottom - location.Top;
|
||||||
locationJson = JsonSerializer.Serialize(face.Location);
|
|
||||||
faceEncodingJson = JsonSerializer.Serialize(face.FaceEncoding);
|
faceEncodingJson = JsonSerializer.Serialize(face.FaceEncoding);
|
||||||
outputResolutionJson = JsonSerializer.Serialize(face.OutputResolution);
|
|
||||||
rectangle = new Rectangle(location.Left, location.Top, width, height);
|
rectangle = new Rectangle(location.Left, location.Top, width, height);
|
||||||
|
faceFile = new(face.Mapping?.MappingFromLocation?.AreaPermyriad,
|
||||||
|
face.Mapping?.MappingFromLocation?.ConfidencePercent,
|
||||||
|
face.DateTime,
|
||||||
|
geoLocation?.ToDmsString(),
|
||||||
|
face.FaceParts,
|
||||||
|
face.Location,
|
||||||
|
maker,
|
||||||
|
model,
|
||||||
|
face.OutputResolution);
|
||||||
|
faceFileJson = JsonSerializer.Serialize(faceFile, FaceFileGenerationContext.Default.FaceFile);
|
||||||
using (bitmap = new(width, height))
|
using (bitmap = new(width, height))
|
||||||
{
|
{
|
||||||
using (graphics = Graphics.FromImage(bitmap))
|
using (graphics = Graphics.FromImage(bitmap))
|
||||||
graphics.DrawImage(source, new Rectangle(0, 0, width, height), rectangle, GraphicsUnit.Pixel);
|
graphics.DrawImage(source, new Rectangle(0, 0, width, height), rectangle, GraphicsUnit.Pixel);
|
||||||
propertyItem = IProperty.GetPropertyItem(_ConstructorInfo, fileSource, type, locationJson);
|
propertyItem = Property.Models.Stateless.IProperty.GetPropertyItem(_ConstructorInfo, artist, type, faceFileJson);
|
||||||
bitmap.SetPropertyItem(propertyItem);
|
bitmap.SetPropertyItem(propertyItem);
|
||||||
propertyItem = IProperty.GetPropertyItem(_ConstructorInfo, artist, type, outputResolutionJson);
|
propertyItem = Property.Models.Stateless.IProperty.GetPropertyItem(_ConstructorInfo, userComment, type, faceEncodingJson);
|
||||||
bitmap.SetPropertyItem(propertyItem);
|
bitmap.SetPropertyItem(propertyItem);
|
||||||
propertyItem = IProperty.GetPropertyItem(_ConstructorInfo, userComment, type, faceEncodingJson);
|
bitmap.Save(fileHolder.FullName, _ImageCodecInfo, _EncoderParameters);
|
||||||
bitmap.SetPropertyItem(propertyItem);
|
|
||||||
bitmap.Save(fileInfo.FullName, _ImageCodecInfo, _EncoderParameters);
|
|
||||||
}
|
}
|
||||||
if (File.Exists(fileName))
|
if (File.Exists(fileName))
|
||||||
File.Delete(fileName);
|
File.Delete(fileName);
|
||||||
@ -213,7 +229,7 @@ public class D_Face
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<Shared.Models.Face> GetFaces(string outputResolution, Shared.Models.Property property, MappingFromItem mappingFromItem, Dictionary<string, int[]> outputResolutionToResize, List<Location>? locations)
|
private List<Shared.Models.Face> GetFaces(string outputResolution, Shared.Models.Property property, MappingFromItem mappingFromItem, Dictionary<string, int[]> outputResolutionToResize, List<Location> locations)
|
||||||
{
|
{
|
||||||
if (_PropertyConfiguration.NumberOfJitters is null)
|
if (_PropertyConfiguration.NumberOfJitters is null)
|
||||||
throw new NullReferenceException(nameof(_PropertyConfiguration.NumberOfJitters));
|
throw new NullReferenceException(nameof(_PropertyConfiguration.NumberOfJitters));
|
||||||
@ -260,73 +276,17 @@ public class D_Face
|
|||||||
|
|
||||||
#pragma warning restore CA1416
|
#pragma warning restore CA1416
|
||||||
|
|
||||||
private static List<LocationContainer> GetLocationContainers(string outputResolution, ReadOnlyCollection<LocationContainer> locationContainers, Dictionary<string, int[]> outputResolutionToResize, List<Shared.Models.Face> faces)
|
public List<Shared.Models.Face> GetFaces(string outputResolution, string dResultsFullGroupDirectory, FilePath filePath, List<Tuple<string, DateTime>> subFileTuples, List<string> parseExceptions, Shared.Models.Property property, MappingFromItem mappingFromItem, Dictionary<string, int[]> outputResolutionToResize, List<MappingFromPhotoPrism>? mappingFromPhotoPrismCollection)
|
||||||
{
|
|
||||||
List<LocationContainer> results = [];
|
|
||||||
string? json;
|
|
||||||
Location? location;
|
|
||||||
Rectangle? rectangle;
|
|
||||||
List<int> skip = [];
|
|
||||||
OutputResolution? outputResolutionCheck = null;
|
|
||||||
(int outputResolutionWidth, int outputResolutionHeight, int outputResolutionOrientation) = Resize.Models.Stateless.Methods.IResize.Get(outputResolution, outputResolutionToResize);
|
|
||||||
foreach (Shared.Models.Face face in faces)
|
|
||||||
{
|
|
||||||
if (face.Location is null || face.OutputResolution is null)
|
|
||||||
continue;
|
|
||||||
skip.Add(Shared.Models.Stateless.Methods.ILocation.GetWholePercentages(face.Location, Shared.Models.Stateless.ILocation.Digits, face.OutputResolution));
|
|
||||||
}
|
|
||||||
foreach (LocationContainer locationContainer in locationContainers)
|
|
||||||
{
|
|
||||||
if (locationContainer.ExifDirectory is null)
|
|
||||||
continue;
|
|
||||||
if (skip.Contains(locationContainer.WholePercentages))
|
|
||||||
continue;
|
|
||||||
foreach (Shared.Models.Face face in faces)
|
|
||||||
{
|
|
||||||
if (face.Location is not null && face.OutputResolution is not null)
|
|
||||||
continue;
|
|
||||||
json = Metadata.Models.Stateless.Methods.IMetadata.GetOutputResolution(locationContainer.ExifDirectory);
|
|
||||||
if (json is null)
|
|
||||||
continue;
|
|
||||||
outputResolutionCheck = JsonSerializer.Deserialize<OutputResolution>(json);
|
|
||||||
if (outputResolutionCheck is null || outputResolutionCheck.Width != outputResolutionWidth || outputResolutionCheck.Height != outputResolutionHeight)
|
|
||||||
continue;
|
|
||||||
rectangle = Shared.Models.Stateless.Methods.ILocation.GetRectangle(Shared.Models.Stateless.ILocation.Digits, outputResolutionCheck, locationContainer.WholePercentages);
|
|
||||||
if (rectangle is null)
|
|
||||||
continue;
|
|
||||||
location = Shared.Models.Stateless.Methods.ILocation.GetLocation(outputResolutionHeight, rectangle.Value, outputResolutionWidth);
|
|
||||||
if (location is null)
|
|
||||||
continue;
|
|
||||||
if (!results.Any(l => l.WholePercentages == locationContainer.WholePercentages))
|
|
||||||
results.Add(new(locationContainer.CreationDateOnly,
|
|
||||||
locationContainer.ExifDirectory,
|
|
||||||
locationContainer.DirectoryNumber,
|
|
||||||
locationContainer.DisplayDirectoryName,
|
|
||||||
locationContainer.FilePath,
|
|
||||||
locationContainer.FromDistanceContent,
|
|
||||||
locationContainer.Id,
|
|
||||||
location,
|
|
||||||
locationContainer.PersonKey,
|
|
||||||
rectangle.Value,
|
|
||||||
locationContainer.WholePercentages));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (results.Count > 0)
|
|
||||||
outputResolutionCheck = null;
|
|
||||||
return results;
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<Shared.Models.Face> GetFaces(string outputResolution, string dResultsFullGroupDirectory, FilePath filePath, List<Tuple<string, DateTime>> subFileTuples, List<string> parseExceptions, Shared.Models.Property property, MappingFromItem mappingFromItem, Dictionary<string, int[]> outputResolutionToResize, ReadOnlyCollection<LocationContainer>? locationContainers, List<MappingFromPhotoPrism>? mappingFromPhotoPrismCollection)
|
|
||||||
{
|
{
|
||||||
List<Shared.Models.Face>? results;
|
List<Shared.Models.Face>? results;
|
||||||
if (string.IsNullOrEmpty(dResultsFullGroupDirectory))
|
if (string.IsNullOrEmpty(dResultsFullGroupDirectory))
|
||||||
throw new NullReferenceException(nameof(dResultsFullGroupDirectory));
|
throw new NullReferenceException(nameof(dResultsFullGroupDirectory));
|
||||||
string? json;
|
string? json;
|
||||||
List<Location>? locations;
|
List<Location> locations;
|
||||||
string[] changesFrom = [nameof(A_Property), nameof(B_Metadata), nameof(C_Resize)];
|
string[] changesFrom = [nameof(A_Property), nameof(B_Metadata), nameof(C_Resize)];
|
||||||
List<DateTime> dateTimes = (from l in subFileTuples where changesFrom.Contains(l.Item1) select l.Item2).ToList();
|
List<DateTime> dateTimes = (from l in subFileTuples where changesFrom.Contains(l.Item1) select l.Item2).ToList();
|
||||||
(_, int directoryIndex) = Shared.Models.Stateless.Methods.IPath.GetDirectoryNameAndIndex(_PropertyConfiguration, filePath);
|
(_, int directoryIndex) = Shared.Models.Stateless.Methods.IPath.GetDirectoryNameAndIndex(_PropertyConfiguration, filePath);
|
||||||
FileInfo fileInfo = new(Path.Combine(_FileGroups[_PropertyConfiguration.ResultCollection][directoryIndex], $"{mappingFromItem.ImageFileHolder.NameWithoutExtension}{mappingFromItem.ImageFileHolder.ExtensionLowered}.json"));
|
FileInfo fileInfo = new(Path.Combine(_FileGroups[_PropertyConfiguration.ResultCollection][directoryIndex], $"{mappingFromItem.FilePath.NameWithoutExtension}{mappingFromItem.FilePath.ExtensionLowered}.json"));
|
||||||
if (_ForceFaceLastWriteTimeToCreationTime && !fileInfo.Exists && File.Exists(Path.ChangeExtension(fileInfo.FullName, ".delete")))
|
if (_ForceFaceLastWriteTimeToCreationTime && !fileInfo.Exists && File.Exists(Path.ChangeExtension(fileInfo.FullName, ".delete")))
|
||||||
{
|
{
|
||||||
File.Move(Path.ChangeExtension(fileInfo.FullName, ".delete"), fileInfo.FullName);
|
File.Move(Path.ChangeExtension(fileInfo.FullName, ".delete"), fileInfo.FullName);
|
||||||
@ -359,16 +319,11 @@ public class D_Face
|
|||||||
parseExceptions.Add(nameof(D_Face));
|
parseExceptions.Add(nameof(D_Face));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
List<LocationContainer> collection;
|
|
||||||
if (results is null || locationContainers is null)
|
|
||||||
collection = [];
|
|
||||||
else
|
|
||||||
collection = GetLocationContainers(outputResolution, locationContainers, outputResolutionToResize, results);
|
|
||||||
if (!_LoadPhotoPrismLocations || mappingFromPhotoPrismCollection is null || results is null)
|
if (!_LoadPhotoPrismLocations || mappingFromPhotoPrismCollection is null || results is null)
|
||||||
locations = (from l in collection where l is not null select l.Location).ToList();
|
locations = [];
|
||||||
else
|
else
|
||||||
locations = Shared.Models.Stateless.Methods.ILocation.GetLocations(collection, results, mappingFromPhotoPrismCollection, _RectangleIntersectMinimum);
|
locations = Shared.Models.Stateless.Methods.ILocation.GetLocations(results, mappingFromPhotoPrismCollection, _RectangleIntersectMinimum);
|
||||||
if (results is null || (locations is not null && locations.Count > 0))
|
if (results is null || locations.Count > 0)
|
||||||
{
|
{
|
||||||
results = GetFaces(outputResolution, property, mappingFromItem, outputResolutionToResize, locations);
|
results = GetFaces(outputResolution, property, mappingFromItem, outputResolutionToResize, locations);
|
||||||
if (results.Count == 0)
|
if (results.Count == 0)
|
||||||
@ -394,16 +349,17 @@ public class D_Face
|
|||||||
return results;
|
return results;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<(Shared.Models.Face, FileInfo?, string, bool)> SaveFaces(string f, string dResultsFullGroupDirectory, FilePath filePath, List<Tuple<string, DateTime>> subFileTuples, List<string> parseExceptions, MappingFromItem mappingFromItem, List<Shared.Models.Face> faces)
|
public List<(Shared.Models.Face, FileHolder?, string, bool)> SaveFaces(string f, string dResultsFullGroupDirectory, FilePath filePath, List<Tuple<string, DateTime>> subFileTuples, List<string> parseExceptions, MappingFromItem mappingFromItem, ExifDirectory exifDirectory, List<Shared.Models.Face> faces)
|
||||||
{
|
{
|
||||||
List<(Shared.Models.Face, FileInfo?, string, bool Save)> results = [];
|
List<(Shared.Models.Face, FileHolder?, string, bool Save)> results = [];
|
||||||
bool save;
|
bool save;
|
||||||
FileInfo fileInfo;
|
FileInfo fileInfo;
|
||||||
|
FileHolder fileHolder;
|
||||||
string deterministicHashCodeKey;
|
string deterministicHashCodeKey;
|
||||||
string[] changesFrom = [nameof(A_Property), nameof(B_Metadata), nameof(C_Resize)];
|
string[] changesFrom = [nameof(A_Property), nameof(B_Metadata), nameof(C_Resize)];
|
||||||
List<DateTime> dateTimes = (from l in subFileTuples where changesFrom.Contains(l.Item1) select l.Item2).ToList();
|
List<DateTime> dateTimes = (from l in subFileTuples where changesFrom.Contains(l.Item1) select l.Item2).ToList();
|
||||||
(_, int directoryIndex) = Shared.Models.Stateless.Methods.IPath.GetDirectoryNameAndIndex(_PropertyConfiguration, filePath);
|
(_, int directoryIndex) = Shared.Models.Stateless.Methods.IPath.GetDirectoryNameAndIndex(_PropertyConfiguration, filePath);
|
||||||
string directory = Path.Combine(_FileGroups[_PropertyConfiguration.ResultContent][directoryIndex], mappingFromItem.ImageFileHolder.NameWithoutExtension);
|
string directory = Path.Combine(_FileGroups[_PropertyConfiguration.ResultContent][directoryIndex], mappingFromItem.FilePath.NameWithoutExtension);
|
||||||
bool directoryExists = Directory.Exists(directory);
|
bool directoryExists = Directory.Exists(directory);
|
||||||
foreach (Shared.Models.Face face in faces)
|
foreach (Shared.Models.Face face in faces)
|
||||||
{
|
{
|
||||||
@ -414,24 +370,92 @@ public class D_Face
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
deterministicHashCodeKey = Shared.Models.Stateless.Methods.IMapping.GetDeterministicHashCodeKey(filePath, face.Location, Shared.Models.Stateless.ILocation.Digits, face.OutputResolution);
|
deterministicHashCodeKey = Shared.Models.Stateless.Methods.IMapping.GetDeterministicHashCodeKey(filePath, face.Location, Shared.Models.Stateless.ILocation.Digits, face.OutputResolution);
|
||||||
fileInfo = new FileInfo(Path.Combine(directory, $"{deterministicHashCodeKey}{mappingFromItem.ImageFileHolder.ExtensionLowered}{_FileNameExtension}"));
|
fileInfo = new FileInfo(Path.Combine(directory, $"{deterministicHashCodeKey}{mappingFromItem.FilePath.ExtensionLowered}{_FileNameExtension}"));
|
||||||
|
fileHolder = FileHolder.Get(fileInfo);
|
||||||
if (!directoryExists)
|
if (!directoryExists)
|
||||||
save = true;
|
save = true;
|
||||||
else if (_OverrideForFaceImages)
|
else if (_OverrideForFaceImages)
|
||||||
save = true;
|
save = true;
|
||||||
else if (!fileInfo.Exists)
|
else if (!fileHolder.Exists)
|
||||||
save = true;
|
save = true;
|
||||||
else if (_CheckDFaceAndUpWriteDates && dateTimes.Count > 0 && dateTimes.Max() > fileInfo.LastWriteTime)
|
else if (_CheckDFaceAndUpWriteDates && dateTimes.Count > 0 && dateTimes.Max() > fileInfo.LastWriteTime)
|
||||||
save = true;
|
save = true;
|
||||||
results.Add(new(face, fileInfo, Path.Combine(directory, $"{deterministicHashCodeKey}{mappingFromItem.ImageFileHolder.ExtensionLowered}{_HiddenFileNameExtension}"), save));
|
results.Add(new(face, fileHolder, Path.Combine(directory, $"{deterministicHashCodeKey}{mappingFromItem.FilePath.ExtensionLowered}{_HiddenFileNameExtension}"), save));
|
||||||
}
|
}
|
||||||
if (results.Any(l => l.Save))
|
if (results.Any(l => l.Save))
|
||||||
{
|
{
|
||||||
if (!directoryExists)
|
if (!directoryExists)
|
||||||
_ = Directory.CreateDirectory(directory);
|
_ = Directory.CreateDirectory(directory);
|
||||||
SaveFaces(mappingFromItem.ResizedFileHolder, results);
|
SaveFaces(mappingFromItem.ResizedFileHolder, exifDirectory, results);
|
||||||
}
|
}
|
||||||
return results;
|
return results;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#pragma warning disable CA1416
|
||||||
|
|
||||||
|
private static (string?, string?) Get(string? json)
|
||||||
|
{
|
||||||
|
string? model;
|
||||||
|
string? maker;
|
||||||
|
FaceFile? faceFile = json is null ? null : JsonSerializer.Deserialize(json, FaceFileGenerationContext.Default.FaceFile);
|
||||||
|
if (faceFile is null || faceFile.Location is null)
|
||||||
|
(maker, model) = (null, null);
|
||||||
|
else
|
||||||
|
(maker, model) = (faceFile.Maker, faceFile.Model);
|
||||||
|
return (maker, model);
|
||||||
|
}
|
||||||
|
|
||||||
|
void IFaceD.ReSaveFace(ExifDirectory exifDirectory, FilePath filePath, Shared.Models.Face face, bool mappedFile)
|
||||||
|
{
|
||||||
|
FileInfo fileInfo = new(filePath.FullName);
|
||||||
|
if (fileInfo.Exists)
|
||||||
|
{
|
||||||
|
string? json;
|
||||||
|
short type = 2;
|
||||||
|
string? model;
|
||||||
|
string? maker;
|
||||||
|
string checkFile = $"{filePath.FullName}.exif";
|
||||||
|
const int artist = MetadataExtractor.Formats.Exif.ExifDirectoryBase.TagArtist;
|
||||||
|
// const int author = MetadataExtractor.Formats.Exif.ExifDirectoryBase.TagWinAuthor; // 40093
|
||||||
|
if (mappedFile)
|
||||||
|
{
|
||||||
|
json = IMetadata.GetOutputResolution(exifDirectory);
|
||||||
|
if (json is not null && json.Contains(nameof(DateTime)))
|
||||||
|
return;
|
||||||
|
(maker, model) = Get(json);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
maker = IMetadata.GetMaker(exifDirectory);
|
||||||
|
model = IMetadata.GetModel(exifDirectory);
|
||||||
|
ExifDirectory? faceExifDirectory = IMetadata.GetExifDirectory(filePath);
|
||||||
|
json = IMetadata.GetOutputResolution(faceExifDirectory);
|
||||||
|
if (json is not null && json.Contains(nameof(DateTime)))
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
MetadataExtractor.GeoLocation? geoLocation = IMetadata.GeoLocation(exifDirectory);
|
||||||
|
FaceFile faceFile = new(face.Mapping?.MappingFromLocation?.AreaPermyriad,
|
||||||
|
face.Mapping?.MappingFromLocation?.ConfidencePercent,
|
||||||
|
face.DateTime,
|
||||||
|
geoLocation?.ToDmsString(),
|
||||||
|
face.FaceParts,
|
||||||
|
face.Location,
|
||||||
|
maker,
|
||||||
|
model,
|
||||||
|
face.OutputResolution);
|
||||||
|
string faceFileJson = JsonSerializer.Serialize(faceFile, FaceFileGenerationContext.Default.FaceFile);
|
||||||
|
ConstructorInfo? constructorInfo = typeof(PropertyItem).GetConstructor(BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Public, null, [], null) ?? throw new Exception();
|
||||||
|
PropertyItem? propertyItem = Property.Models.Stateless.IProperty.GetPropertyItem(constructorInfo, artist, type, faceFileJson);
|
||||||
|
Bitmap bitmap = new(fileInfo.FullName);
|
||||||
|
bitmap.SetPropertyItem(propertyItem);
|
||||||
|
bitmap.Save(checkFile);
|
||||||
|
bitmap.Dispose();
|
||||||
|
File.SetLastWriteTime(checkFile, fileInfo.LastWriteTime);
|
||||||
|
File.Delete(fileInfo.FullName);
|
||||||
|
File.Move(checkFile, fileInfo.FullName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma warning restore CA1416
|
||||||
|
|
||||||
}
|
}
|
@ -57,10 +57,10 @@ public class D2_FaceParts
|
|||||||
_FileGroups.Add(keyValuePair.Key, keyValuePair.Value);
|
_FileGroups.Add(keyValuePair.Key, keyValuePair.Value);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetAngleBracketCollection(Configuration configuration, string d2ResultsFullGroupDirectory, string sourceDirectory)
|
public void SetAngleBracketCollection(IPropertyConfiguration propertyConfiguration, string d2ResultsFullGroupDirectory, string sourceDirectory)
|
||||||
{
|
{
|
||||||
_AngleBracketCollection.Clear();
|
_AngleBracketCollection.Clear();
|
||||||
_AngleBracketCollection.AddRange(IResult.GetDirectoryInfoCollection(configuration,
|
_AngleBracketCollection.AddRange(IResult.GetDirectoryInfoCollection(propertyConfiguration,
|
||||||
sourceDirectory,
|
sourceDirectory,
|
||||||
d2ResultsFullGroupDirectory,
|
d2ResultsFullGroupDirectory,
|
||||||
contentDescription: "n gif file(s) for each face found",
|
contentDescription: "n gif file(s) for each face found",
|
||||||
@ -69,18 +69,18 @@ public class D2_FaceParts
|
|||||||
converted: true));
|
converted: true));
|
||||||
}
|
}
|
||||||
|
|
||||||
public string GetFacePartsDirectory(Configuration configuration, string dResultsFullGroupDirectory, Item item, bool includeNameWithoutExtension)
|
public string GetFacePartsDirectory(IPropertyConfiguration propertyConfiguration, string dResultsFullGroupDirectory, Item item, bool includeNameWithoutExtension)
|
||||||
{
|
{
|
||||||
string result;
|
string result;
|
||||||
bool angleBracketCollectionAny = _AngleBracketCollection.Count != 0;
|
bool angleBracketCollectionAny = _AngleBracketCollection.Count != 0;
|
||||||
if (!angleBracketCollectionAny)
|
if (!angleBracketCollectionAny)
|
||||||
{
|
{
|
||||||
if (item.ImageFileHolder.DirectoryName is null)
|
if (item.FilePath.DirectoryName is null)
|
||||||
throw new NullReferenceException(nameof(item.ImageFileHolder.DirectoryName));
|
throw new NullReferenceException(nameof(item.FilePath.DirectoryName));
|
||||||
SetAngleBracketCollection(configuration, dResultsFullGroupDirectory, item.ImageFileHolder.DirectoryName);
|
SetAngleBracketCollection(propertyConfiguration, dResultsFullGroupDirectory, item.FilePath.DirectoryName);
|
||||||
}
|
}
|
||||||
if (includeNameWithoutExtension)
|
if (includeNameWithoutExtension)
|
||||||
result = Path.Combine(_AngleBracketCollection[0].Replace("<>", _PropertyConfiguration.ResultContent), item.ImageFileHolder.NameWithoutExtension);
|
result = Path.Combine(_AngleBracketCollection[0].Replace("<>", _PropertyConfiguration.ResultContent), item.FilePath.NameWithoutExtension);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
result = _AngleBracketCollection[0].Replace("<>", $"[{_PropertyConfiguration.ResultContent}]");
|
result = _AngleBracketCollection[0].Replace("<>", $"[{_PropertyConfiguration.ResultContent}]");
|
||||||
@ -259,7 +259,7 @@ public class D2_FaceParts
|
|||||||
string[] changesFrom = [nameof(A_Property), nameof(B_Metadata), nameof(C_Resize), nameof(D_Face)];
|
string[] changesFrom = [nameof(A_Property), nameof(B_Metadata), nameof(C_Resize), nameof(D_Face)];
|
||||||
List<DateTime> dateTimes = (from l in subFileTuples where changesFrom.Contains(l.Item1) select l.Item2).ToList();
|
List<DateTime> dateTimes = (from l in subFileTuples where changesFrom.Contains(l.Item1) select l.Item2).ToList();
|
||||||
(_, int directoryIndex) = Shared.Models.Stateless.Methods.IPath.GetDirectoryNameAndIndex(_PropertyConfiguration, filePath);
|
(_, int directoryIndex) = Shared.Models.Stateless.Methods.IPath.GetDirectoryNameAndIndex(_PropertyConfiguration, filePath);
|
||||||
string directory = Path.Combine(_FileGroups[_PropertyConfiguration.ResultContent][directoryIndex], mappingFromItem.ImageFileHolder.NameWithoutExtension);
|
string directory = Path.Combine(_FileGroups[_PropertyConfiguration.ResultContent][directoryIndex], mappingFromItem.FilePath.NameWithoutExtension);
|
||||||
bool directoryExists = Directory.Exists(directory);
|
bool directoryExists = Directory.Exists(directory);
|
||||||
foreach (Shared.Models.Face face in faces)
|
foreach (Shared.Models.Face face in faces)
|
||||||
{
|
{
|
||||||
@ -269,10 +269,10 @@ public class D2_FaceParts
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
deterministicHashCodeKey = Shared.Models.Stateless.Methods.IMapping.GetDeterministicHashCodeKey(filePath, face.Location, Shared.Models.Stateless.ILocation.Digits, face.OutputResolution);
|
deterministicHashCodeKey = Shared.Models.Stateless.Methods.IMapping.GetDeterministicHashCodeKey(filePath, face.Location, Shared.Models.Stateless.ILocation.Digits, face.OutputResolution);
|
||||||
fileInfo = new FileInfo(Path.Combine(directory, $"{deterministicHashCodeKey}{mappingFromItem.ImageFileHolder.ExtensionLowered}{_FileNameExtension}"));
|
fileInfo = new FileInfo(Path.Combine(directory, $"{deterministicHashCodeKey}{mappingFromItem.FilePath.ExtensionLowered}{_FileNameExtension}"));
|
||||||
if (string.IsNullOrEmpty(fileInfo.DirectoryName))
|
if (string.IsNullOrEmpty(fileInfo.DirectoryName))
|
||||||
continue;
|
continue;
|
||||||
rotatedFileInfo = new FileInfo(Path.Combine(fileInfo.DirectoryName, $"{deterministicHashCodeKey} - R{mappingFromItem.ImageFileHolder.ExtensionLowered}{_FileNameExtension}"));
|
rotatedFileInfo = new FileInfo(Path.Combine(fileInfo.DirectoryName, $"{deterministicHashCodeKey} - R{mappingFromItem.FilePath.ExtensionLowered}{_FileNameExtension}"));
|
||||||
collection.Add(new(face, fileInfo.FullName, rotatedFileInfo.FullName));
|
collection.Add(new(face, fileInfo.FullName, rotatedFileInfo.FullName));
|
||||||
if (check)
|
if (check)
|
||||||
continue;
|
continue;
|
||||||
@ -302,12 +302,12 @@ public class D2_FaceParts
|
|||||||
|
|
||||||
#pragma warning disable CA1416
|
#pragma warning disable CA1416
|
||||||
|
|
||||||
private void SaveFaceLandmarkImage(MappingFromItem mappingFromItem, List<(Shared.Models.Face, FileInfo?, string, bool)> faceCollection, string fileName)
|
private void SaveFaceLandmarkImage(MappingFromItem mappingFromItem, List<(Shared.Models.Face, FileHolder?, string, bool)> faceCollection, string fileName)
|
||||||
{
|
{
|
||||||
Pen pen;
|
Pen pen;
|
||||||
using Image image = Image.FromFile(mappingFromItem.ResizedFileHolder.FullName);
|
using Image image = Image.FromFile(mappingFromItem.ResizedFileHolder.FullName);
|
||||||
using Graphics graphic = Graphics.FromImage(image);
|
using Graphics graphic = Graphics.FromImage(image);
|
||||||
foreach ((Shared.Models.Face face, FileInfo? fileInfo, string _, bool _) in faceCollection)
|
foreach ((Shared.Models.Face face, FileHolder? _, string _, bool _) in faceCollection)
|
||||||
{
|
{
|
||||||
if (face.FaceEncoding is null || face.Location is null || face.OutputResolution is null || face.FaceParts is null || face.FaceParts.Count == 0)
|
if (face.FaceEncoding is null || face.Location is null || face.OutputResolution is null || face.FaceParts is null || face.FaceParts.Count == 0)
|
||||||
continue;
|
continue;
|
||||||
@ -327,17 +327,17 @@ public class D2_FaceParts
|
|||||||
|
|
||||||
#pragma warning restore CA1416
|
#pragma warning restore CA1416
|
||||||
|
|
||||||
private static bool GetNotMapped(string facePartsCollectionDirectory, List<(Shared.Models.Face Face, FileInfo?, string, bool)> faceCollection)
|
private static bool GetNotMapped(string facePartsCollectionDirectory, List<(Shared.Models.Face Face, FileHolder?, string, bool)> faceCollection)
|
||||||
{
|
{
|
||||||
bool results = false;
|
bool results = false;
|
||||||
string checkFile;
|
string checkFile;
|
||||||
foreach ((Shared.Models.Face face, FileInfo? fileInfo, string _, bool _) in faceCollection)
|
foreach ((Shared.Models.Face face, FileHolder? fileHolder, string _, bool _) in faceCollection)
|
||||||
{
|
{
|
||||||
if (face.FaceEncoding is null || face.Location is null || face.OutputResolution is null)
|
if (face.FaceEncoding is null || face.Location is null || face.OutputResolution is null)
|
||||||
continue;
|
continue;
|
||||||
if (fileInfo is not null)
|
if (fileHolder is not null)
|
||||||
{
|
{
|
||||||
checkFile = Path.Combine(facePartsCollectionDirectory, fileInfo.Name);
|
checkFile = Path.Combine(facePartsCollectionDirectory, fileHolder.Name);
|
||||||
if (face.Mapping?.MappingFromPerson is not null)
|
if (face.Mapping?.MappingFromPerson is not null)
|
||||||
{
|
{
|
||||||
if (File.Exists(checkFile))
|
if (File.Exists(checkFile))
|
||||||
@ -353,17 +353,17 @@ public class D2_FaceParts
|
|||||||
if (!results)
|
if (!results)
|
||||||
results = true;
|
results = true;
|
||||||
if (!File.Exists(checkFile))
|
if (!File.Exists(checkFile))
|
||||||
File.Copy(fileInfo.FullName, checkFile);
|
File.Copy(fileHolder.FullName, checkFile);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return results;
|
return results;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void CopyFacesAndSaveFaceLandmarkImage(string facePartsCollectionDirectory, MappingFromItem mappingFromItem, List<(Shared.Models.Face Face, FileInfo?, string, bool)> faceCollection)
|
public void CopyFacesAndSaveFaceLandmarkImage(string facePartsCollectionDirectory, MappingFromItem mappingFromItem, List<(Shared.Models.Face Face, FileHolder?, string, bool)> faceCollection)
|
||||||
{
|
{
|
||||||
bool hasNotMapped = GetNotMapped(facePartsCollectionDirectory, faceCollection);
|
bool hasNotMapped = GetNotMapped(facePartsCollectionDirectory, faceCollection);
|
||||||
string fileName = Path.Combine(facePartsCollectionDirectory, $"{mappingFromItem.ImageFileHolder.Name}{_FileNameExtension}");
|
string fileName = Path.Combine(facePartsCollectionDirectory, $"{mappingFromItem.FilePath.Name}{_FileNameExtension}");
|
||||||
bool save = faceCollection.Any(l => l.Face.FaceEncoding is not null && l.Face.Location is not null && l.Face.OutputResolution is not null && l.Face.FaceParts is not null && l.Face.FaceParts.Count != 0);
|
bool save = faceCollection.Any(l => l.Face.FaceEncoding is not null && l.Face.Location is not null && l.Face.OutputResolution is not null && l.Face.FaceParts is not null && l.Face.FaceParts.Count != 0);
|
||||||
FileInfo fileInfo = new(fileName);
|
FileInfo fileInfo = new(fileName);
|
||||||
if (save && (!fileInfo.Exists || new TimeSpan(DateTime.Now.Ticks - fileInfo.LastWriteTime.Ticks).TotalDays > 10))
|
if (save && (!fileInfo.Exists || new TimeSpan(DateTime.Now.Ticks - fileInfo.LastWriteTime.Ticks).TotalDays > 10))
|
||||||
|
@ -26,16 +26,15 @@ public abstract class DisposableObject : IDisposable
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// If this object is disposed, then <see cref="ObjectDisposedException"/> is thrown.
|
/// If this object is disposed, then <see cref="ObjectDisposedException"/> is thrown.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public void ThrowIfDisposed()
|
public void ThrowIfDisposed() =>
|
||||||
{
|
ObjectDisposedException.ThrowIf(IsDisposed, this);
|
||||||
if (IsDisposed)
|
|
||||||
throw new ObjectDisposedException(GetType().FullName);
|
|
||||||
}
|
|
||||||
|
|
||||||
internal void ThrowIfDisposed(string objectName)
|
internal void ThrowIfDisposed(string objectName)
|
||||||
{
|
{
|
||||||
|
#pragma warning disable CA1513
|
||||||
if (IsDisposed)
|
if (IsDisposed)
|
||||||
throw new ObjectDisposedException(objectName);
|
throw new ObjectDisposedException(objectName);
|
||||||
|
#pragma warning restore CA1513
|
||||||
}
|
}
|
||||||
|
|
||||||
#region Overrides
|
#region Overrides
|
||||||
|
@ -167,7 +167,13 @@ public class FaceRecognition : DisposableObject
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ShapePredictor posePredictor = _PredictorModel switch { PredictorModel.Large => _PosePredictor68Point, PredictorModel.Small => _PosePredictor5Point, _ => throw new Exception() };
|
ShapePredictor posePredictor = _PredictorModel switch
|
||||||
|
{
|
||||||
|
PredictorModel.Large => _PosePredictor68Point,
|
||||||
|
PredictorModel.Small => _PosePredictor5Point,
|
||||||
|
PredictorModel.Custom => throw new NotImplementedException(),
|
||||||
|
_ => throw new Exception()
|
||||||
|
};
|
||||||
foreach (Location location in locations)
|
foreach (Location location in locations)
|
||||||
{
|
{
|
||||||
DlibDotNet.Rectangle rectangle = new(location.Left, location.Top, location.Right, location.Bottom);
|
DlibDotNet.Rectangle rectangle = new(location.Left, location.Top, location.Right, location.Bottom);
|
||||||
@ -197,7 +203,7 @@ public class FaceRecognition : DisposableObject
|
|||||||
return results;
|
return results;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<(Location, FaceEncoding?, Dictionary<FacePart, FacePoint[]>?)> GetCollection(Image image, List<Location>? locations, bool includeFaceEncoding, bool includeFaceParts)
|
public List<(Location, FaceEncoding?, Dictionary<FacePart, FacePoint[]>?)> GetCollection(Image image, List<Location> locations, bool includeFaceEncoding, bool includeFaceParts)
|
||||||
{
|
{
|
||||||
List<(Location, FaceEncoding?, Dictionary<FacePart, FacePoint[]>?)> results = [];
|
List<(Location, FaceEncoding?, Dictionary<FacePart, FacePoint[]>?)> results = [];
|
||||||
if (image is null)
|
if (image is null)
|
||||||
@ -206,9 +212,7 @@ public class FaceRecognition : DisposableObject
|
|||||||
ThrowIfDisposed();
|
ThrowIfDisposed();
|
||||||
if (_PredictorModel == PredictorModel.Custom)
|
if (_PredictorModel == PredictorModel.Custom)
|
||||||
throw new NotSupportedException("FaceRecognition.PredictorModel.Custom is not supported.");
|
throw new NotSupportedException("FaceRecognition.PredictorModel.Custom is not supported.");
|
||||||
if (locations is null)
|
if (locations.Count == 0)
|
||||||
locations = GetLocations(image);
|
|
||||||
else if (locations.Count == 0)
|
|
||||||
locations.AddRange(GetLocations(image));
|
locations.AddRange(GetLocations(image));
|
||||||
List<FullObjectDetection> fullObjectDetections = GetFullObjectDetections(image, locations);
|
List<FullObjectDetection> fullObjectDetections = GetFullObjectDetections(image, locations);
|
||||||
if (fullObjectDetections.Count != locations.Count)
|
if (fullObjectDetections.Count != locations.Count)
|
||||||
@ -408,22 +412,50 @@ public class FaceRecognition : DisposableObject
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static ReadOnlyCollection<LocationContainer> GetLocationContainers(int permyriad, ReadOnlyCollection<LocationContainer> readOnlyLocationContainers, LocationContainer locationContainer)
|
||||||
|
{
|
||||||
|
List<LocationContainer> results = [];
|
||||||
|
int lengthPermyriad;
|
||||||
|
if (readOnlyLocationContainers.Count != 0)
|
||||||
|
{
|
||||||
|
double length;
|
||||||
|
LocationContainer result;
|
||||||
|
if (locationContainer.Encoding is not FaceEncoding faceEncodingToCompare)
|
||||||
|
throw new NullReferenceException(nameof(locationContainer));
|
||||||
|
faceEncodingToCompare.ThrowIfDisposed();
|
||||||
|
foreach (LocationContainer item in readOnlyLocationContainers)
|
||||||
|
{
|
||||||
|
#pragma warning disable CA1513
|
||||||
|
if (item.Encoding is not FaceEncoding faceEncoding || faceEncoding.IsDisposed)
|
||||||
|
throw new ObjectDisposedException($"{nameof(item)} contains disposed object.");
|
||||||
|
#pragma warning restore CA1513
|
||||||
|
using (Matrix<double> diff = faceEncoding.Encoding - faceEncodingToCompare.Encoding)
|
||||||
|
length = DlibDotNet.Dlib.Length(diff);
|
||||||
|
lengthPermyriad = (int)(length * permyriad);
|
||||||
|
result = LocationContainer.Get(locationContainer, item, lengthPermyriad, keepExifDirectory: false, keepEncoding: false);
|
||||||
|
results.Add(result);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
LocationContainer[] array = results.OrderBy(l => l.LengthPermyriad).ToArray();
|
||||||
|
return new(array);
|
||||||
|
}
|
||||||
|
|
||||||
public static List<FaceDistance> FaceDistances(ReadOnlyCollection<FaceDistance> faceDistances, FaceDistance faceDistanceToCompare)
|
public static List<FaceDistance> FaceDistances(ReadOnlyCollection<FaceDistance> faceDistances, FaceDistance faceDistanceToCompare)
|
||||||
{
|
{
|
||||||
List<FaceDistance> results = [];
|
List<FaceDistance> results = [];
|
||||||
if (faceDistances is null)
|
|
||||||
throw new NullReferenceException(nameof(faceDistances));
|
|
||||||
if (faceDistances.Count != 0)
|
if (faceDistances.Count != 0)
|
||||||
{
|
{
|
||||||
double length;
|
double length;
|
||||||
FaceDistance result;
|
FaceDistance result;
|
||||||
if (faceDistanceToCompare is null || faceDistanceToCompare.Encoding is not FaceEncoding faceEncodingToCompare)
|
if (faceDistanceToCompare.Encoding is not FaceEncoding faceEncodingToCompare)
|
||||||
throw new NullReferenceException(nameof(faceDistanceToCompare));
|
throw new NullReferenceException(nameof(faceDistanceToCompare));
|
||||||
faceEncodingToCompare.ThrowIfDisposed();
|
faceEncodingToCompare.ThrowIfDisposed();
|
||||||
foreach (FaceDistance faceDistance in faceDistances)
|
foreach (FaceDistance faceDistance in faceDistances)
|
||||||
{
|
{
|
||||||
|
#pragma warning disable CA1513
|
||||||
if (faceDistance.Encoding is not FaceEncoding faceEncoding || faceEncoding.IsDisposed)
|
if (faceDistance.Encoding is not FaceEncoding faceEncoding || faceEncoding.IsDisposed)
|
||||||
throw new ObjectDisposedException($"{nameof(faceDistances)} contains disposed object.");
|
throw new ObjectDisposedException($"{nameof(faceDistances)} contains disposed object.");
|
||||||
|
#pragma warning restore CA1513
|
||||||
using (Matrix<double> diff = faceEncoding.Encoding - faceEncodingToCompare.Encoding)
|
using (Matrix<double> diff = faceEncoding.Encoding - faceEncodingToCompare.Encoding)
|
||||||
length = DlibDotNet.Dlib.Length(diff);
|
length = DlibDotNet.Dlib.Length(diff);
|
||||||
result = new(faceDistance, length);
|
result = new(faceDistance, length);
|
||||||
|
@ -22,23 +22,25 @@ using WindowsShortcutFactory;
|
|||||||
|
|
||||||
namespace View_by_Distance.Instance;
|
namespace View_by_Distance.Instance;
|
||||||
|
|
||||||
public partial class DlibDotNet
|
public partial class DlibDotNet : IDlibDotNet, IDisposable
|
||||||
{
|
{
|
||||||
|
|
||||||
[GeneratedRegex(@"[\\,\/,\:,\*,\?,\"",\<,\>,\|]")]
|
[GeneratedRegex(@"[\\,\/,\:,\*,\?,\"",\<,\>,\|]")]
|
||||||
private static partial Regex CameraRegex();
|
private static partial Regex CameraRegex();
|
||||||
|
|
||||||
private readonly D_Face _Faces;
|
private readonly D_Face _Faces;
|
||||||
|
private ProgressBar? _ProgressBar;
|
||||||
private readonly C_Resize _Resize;
|
private readonly C_Resize _Resize;
|
||||||
private readonly F_Random _Random;
|
private readonly F_Random _Random;
|
||||||
private readonly IConsole _Console;
|
private readonly IConsole _Console;
|
||||||
private readonly E_Distance _Distance;
|
private readonly E_Distance _Distance;
|
||||||
private readonly IBlurHasher _BlurHasher;
|
|
||||||
private readonly D2_FaceParts _FaceParts;
|
private readonly D2_FaceParts _FaceParts;
|
||||||
|
private readonly IBlurHasher _BlurHasher;
|
||||||
private readonly AppSettings _AppSettings;
|
private readonly AppSettings _AppSettings;
|
||||||
private readonly List<string> _Exceptions;
|
private readonly List<string> _Exceptions;
|
||||||
private readonly ILogger<Program>? _Logger;
|
private readonly ILogger<Program>? _Logger;
|
||||||
private readonly IsEnvironment _IsEnvironment;
|
private readonly IsEnvironment _IsEnvironment;
|
||||||
|
private readonly DistanceLimits _DistanceLimits;
|
||||||
private readonly bool _PropertyRootExistedBefore;
|
private readonly bool _PropertyRootExistedBefore;
|
||||||
private readonly Models.Configuration _Configuration;
|
private readonly Models.Configuration _Configuration;
|
||||||
private readonly bool _ArgZeroIsConfigurationRootDirectory;
|
private readonly bool _ArgZeroIsConfigurationRootDirectory;
|
||||||
@ -111,7 +113,8 @@ public partial class DlibDotNet
|
|||||||
(ImageCodecInfo imageCodecInfo, EncoderParameters encoderParameters, string filenameExtension) = C_Resize.GetGifLowQuality();
|
(ImageCodecInfo imageCodecInfo, EncoderParameters encoderParameters, string filenameExtension) = C_Resize.GetGifLowQuality();
|
||||||
_FaceParts = new D2_FaceParts(_Configuration.PropertyConfiguration, imageCodecInfo, encoderParameters, filenameExtension, configuration.CheckDFaceAndUpWriteDates, configuration.OverrideForFaceLandmarkImages);
|
_FaceParts = new D2_FaceParts(_Configuration.PropertyConfiguration, imageCodecInfo, encoderParameters, filenameExtension, configuration.CheckDFaceAndUpWriteDates, configuration.OverrideForFaceLandmarkImages);
|
||||||
}
|
}
|
||||||
_MapConfiguration = Get(configuration, _Faces.FileNameExtension, _Faces.HiddenFileNameExtension, _FaceParts.FileNameExtension);
|
_DistanceLimits = new(_Configuration.FaceAreaPermyriad, _Configuration.FaceConfidencePercent, _Configuration.FaceDistancePermyriad, _Configuration.RangeDaysDeltaTolerance, _Configuration.RangeDistanceTolerance, _Configuration.RangeFaceAreaPermyriadTolerance, _Configuration.RangeFaceConfidence, _Configuration.SortingMaximumPerFaceShouldBeHigh);
|
||||||
|
_MapConfiguration = Get(configuration, _DistanceLimits, _Faces.FileNameExtension, _Faces.HiddenFileNameExtension, _FaceParts.FileNameExtension);
|
||||||
_Distance = new(configuration.DistanceMoveUnableToMatch, configuration.DistanceRenameToMatch, configuration.FaceConfidencePercent, configuration.RangeDistanceTolerance, configuration.RectangleIntersectMinimums);
|
_Distance = new(configuration.DistanceMoveUnableToMatch, configuration.DistanceRenameToMatch, configuration.FaceConfidencePercent, configuration.RangeDistanceTolerance, configuration.RectangleIntersectMinimums);
|
||||||
if (_PropertyRootExistedBefore || !_ArgZeroIsConfigurationRootDirectory)
|
if (_PropertyRootExistedBefore || !_ArgZeroIsConfigurationRootDirectory)
|
||||||
personContainers = new(new List<PersonContainer>());
|
personContainers = new(new List<PersonContainer>());
|
||||||
@ -165,6 +168,15 @@ public partial class DlibDotNet
|
|||||||
_Logger?.LogInformation("First run completed. Run again if wanted");
|
_Logger?.LogInformation("First run completed. Run again if wanted");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void IDlibDotNet.Tick() =>
|
||||||
|
_ProgressBar?.Tick();
|
||||||
|
|
||||||
|
void IDisposable.Dispose()
|
||||||
|
{
|
||||||
|
_ProgressBar?.Dispose();
|
||||||
|
GC.SuppressFinalize(this);
|
||||||
|
}
|
||||||
|
|
||||||
private static void Verify(Models.Configuration configuration)
|
private static void Verify(Models.Configuration configuration)
|
||||||
{
|
{
|
||||||
if (configuration.RangeDaysDeltaTolerance.Length != 3)
|
if (configuration.RangeDaysDeltaTolerance.Length != 3)
|
||||||
@ -232,6 +244,12 @@ public partial class DlibDotNet
|
|||||||
throw new Exception("Configuration has to match interface!");
|
throw new Exception("Configuration has to match interface!");
|
||||||
if (configuration.LocationFactor != Shared.Models.Stateless.ILocation.Factor)
|
if (configuration.LocationFactor != Shared.Models.Stateless.ILocation.Factor)
|
||||||
throw new Exception("Configuration has to match interface!");
|
throw new Exception("Configuration has to match interface!");
|
||||||
|
if (configuration.SaveSortingWithoutPerson && configuration.JLinks.Length > 0)
|
||||||
|
throw new Exception("Configuration has SaveSortingWithoutPerson and JLinks!");
|
||||||
|
if (configuration.SaveSortingWithoutPerson && !string.IsNullOrEmpty(configuration.FocusModel))
|
||||||
|
throw new Exception("Configuration has SaveSortingWithoutPerson and FocusModel!");
|
||||||
|
if (configuration.SaveSortingWithoutPerson && !string.IsNullOrEmpty(configuration.FocusDirectory))
|
||||||
|
throw new Exception("Configuration has SaveSortingWithoutPerson and FocusDirectory!");
|
||||||
}
|
}
|
||||||
|
|
||||||
private ReadOnlyCollection<int> GetNotNineCollection(ReadOnlyCollection<string[]> filesCollection)
|
private ReadOnlyCollection<int> GetNotNineCollection(ReadOnlyCollection<string[]> filesCollection)
|
||||||
@ -255,6 +273,47 @@ public partial class DlibDotNet
|
|||||||
return new(results);
|
return new(results);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void DeleteContinueFiles(ReadOnlyCollection<PersonContainer> personContainers)
|
||||||
|
{
|
||||||
|
foreach (PersonContainer personContainer in personContainers)
|
||||||
|
{
|
||||||
|
foreach (FilePath filePath in personContainer.DisplayDirectoryAllFilePaths)
|
||||||
|
{
|
||||||
|
if (filePath.ExtensionLowered != ".continue")
|
||||||
|
continue;
|
||||||
|
File.Delete(filePath.FullName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void MapFaceFileLogic(long ticks, ReadOnlyCollection<PersonContainer> personContainers, MapLogic mapLogic, string? a2PeopleContentDirectory, string eDistanceContentDirectory, ProgressBarOptions options)
|
||||||
|
{
|
||||||
|
foreach (string outputResolution in _Configuration.OutputResolutions)
|
||||||
|
{
|
||||||
|
if (_Exceptions.Count != 0)
|
||||||
|
break;
|
||||||
|
if (!_Configuration.SaveResizedSubfiles)
|
||||||
|
continue;
|
||||||
|
if (!_ArgZeroIsConfigurationRootDirectory)
|
||||||
|
continue;
|
||||||
|
if (outputResolution != _Configuration.OutputResolutions[0])
|
||||||
|
continue;
|
||||||
|
if (_PropertyRootExistedBefore || a2PeopleContentDirectory is null)
|
||||||
|
break;
|
||||||
|
if (!_Configuration.SaveFaceDistancesForOutputResolutions.Contains(outputResolution))
|
||||||
|
continue;
|
||||||
|
if (!_Configuration.LoadOrCreateThenSaveDistanceResultsForOutputResolutions.Contains(outputResolution))
|
||||||
|
continue;
|
||||||
|
List<SaveContainer> saveContainers = GetSaveContainers(ticks, personContainers, a2PeopleContentDirectory, eDistanceContentDirectory, options, mapLogic, outputResolution);
|
||||||
|
if (saveContainers.Count > 0)
|
||||||
|
{
|
||||||
|
int updated = 0;
|
||||||
|
mapLogic.SaveContainers(updated, saveContainers);
|
||||||
|
throw new NotSupportedException("Done Restart! :)");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void Search(long ticks, ReadOnlyCollection<PersonContainer> personContainers, string argZero, string propertyRoot)
|
private void Search(long ticks, ReadOnlyCollection<PersonContainer> personContainers, string argZero, string propertyRoot)
|
||||||
{
|
{
|
||||||
int t;
|
int t;
|
||||||
@ -277,9 +336,8 @@ public partial class DlibDotNet
|
|||||||
ReadOnlyCollection<int>? notNineCollection = null;
|
ReadOnlyCollection<int>? notNineCollection = null;
|
||||||
ReadOnlyDictionary<long, List<int>> personKeyToIds;
|
ReadOnlyDictionary<long, List<int>> personKeyToIds;
|
||||||
ReadOnlyCollection<string[]>? filesCollection = null;
|
ReadOnlyCollection<string[]>? filesCollection = null;
|
||||||
bool runToDoCollectionFirst = GetRunToDoCollectionFirst(ticks);
|
|
||||||
Dictionary<int, List<MappingFromPhotoPrism>> fileNameToCollection;
|
|
||||||
(aResultsFullGroupDirectory, bResultsFullGroupDirectory) = GetResultsFullGroupDirectories();
|
(aResultsFullGroupDirectory, bResultsFullGroupDirectory) = GetResultsFullGroupDirectories();
|
||||||
|
bool runToDoCollectionFirst = GetRunToDoCollectionFirst(_Configuration.PropertyConfiguration, ticks);
|
||||||
ProgressBarOptions options = new() { ProgressCharacter = '─', ProgressBarOnBottom = true, DisableBottomPercentage = true };
|
ProgressBarOptions options = new() { ProgressCharacter = '─', ProgressBarOnBottom = true, DisableBottomPercentage = true };
|
||||||
Shared.Models.Stateless.Methods.IPath.ChangeDateForEmptyDirectories(_Configuration.PropertyConfiguration.RootDirectory, ticks);
|
Shared.Models.Stateless.Methods.IPath.ChangeDateForEmptyDirectories(_Configuration.PropertyConfiguration.RootDirectory, ticks);
|
||||||
a2PeopleContentDirectory = Property.Models.Stateless.IResult.GetResultsDateGroupDirectory(_Configuration.PropertyConfiguration, nameof(A2_People), "([])");
|
a2PeopleContentDirectory = Property.Models.Stateless.IResult.GetResultsDateGroupDirectory(_Configuration.PropertyConfiguration, nameof(A2_People), "([])");
|
||||||
@ -341,38 +399,40 @@ public partial class DlibDotNet
|
|||||||
if (filesCollectionRootDirectory is null || filesCollection is null)
|
if (filesCollectionRootDirectory is null || filesCollection is null)
|
||||||
throw new NullReferenceException(nameof(filesCollection));
|
throw new NullReferenceException(nameof(filesCollection));
|
||||||
message = $") Building Container(s) - {(int)Math.Floor(new TimeSpan(DateTime.Now.Ticks - ticks).TotalSeconds)} total second(s)";
|
message = $") Building Container(s) - {(int)Math.Floor(new TimeSpan(DateTime.Now.Ticks - ticks).TotalSeconds)} total second(s)";
|
||||||
using (ProgressBar progressBar = new(2, message, options))
|
string aPropertySingletonDirectory = Path.Combine(aResultsFullGroupDirectory, _Configuration.PropertyConfiguration.ResultSingleton);
|
||||||
{
|
if (!Directory.Exists(aPropertySingletonDirectory))
|
||||||
progressBar.Tick();
|
_ = Directory.CreateDirectory(aPropertySingletonDirectory);
|
||||||
string aPropertySingletonDirectory = Path.Combine(aResultsFullGroupDirectory, _Configuration.PropertyConfiguration.ResultSingleton);
|
_ProgressBar = new(short.MaxValue, message, options);
|
||||||
if (!Directory.Exists(aPropertySingletonDirectory))
|
(t, containers) = Shared.Models.Stateless.Methods.IContainer.GetContainers(this, _Configuration.PropertyConfiguration, aPropertySingletonDirectory, filesCollectionRootDirectory, filesCollection);
|
||||||
_ = Directory.CreateDirectory(aPropertySingletonDirectory);
|
_ProgressBar.Dispose();
|
||||||
(t, containers) = Shared.Models.Stateless.Methods.IContainer.GetContainers(_Configuration.PropertyConfiguration, aPropertySingletonDirectory, filesCollectionRootDirectory, filesCollection);
|
ReadOnlyCollection<Container> readOnlyContainers = new(containers);
|
||||||
progressBar.Tick();
|
SaveDistinctIds(_Configuration.PropertyConfiguration, bResultsFullGroupDirectory, readOnlyContainers);
|
||||||
}
|
|
||||||
fileNameToCollection = !Directory.Exists(fPhotoPrismSingletonDirectory) ? fileNameToCollection = [] : F_PhotoPrism.GetFileNameToCollection(fPhotoPrismSingletonDirectory);
|
|
||||||
B_Metadata metadata = new(_Configuration.PropertyConfiguration, _Configuration.ForceMetadataLastWriteTimeToCreationTime, _Configuration.PropertiesChangedForMetadata, bResultsFullGroupDirectory);
|
|
||||||
mapLogic ??= new(_AppSettings.MaxDegreeOfParallelism, _Configuration.PropertyConfiguration, _MapConfiguration, _Distance, personContainers, ticks, a2PeopleContentDirectory, a2PeopleSingletonDirectory, eDistanceContentDirectory);
|
mapLogic ??= new(_AppSettings.MaxDegreeOfParallelism, _Configuration.PropertyConfiguration, _MapConfiguration, _Distance, personContainers, ticks, a2PeopleContentDirectory, a2PeopleSingletonDirectory, eDistanceContentDirectory);
|
||||||
FullDoWork(argZero, propertyRoot, ticks, aResultsFullGroupDirectory, bResultsFullGroupDirectory, t, containers, propertyLogic, metadata, fileNameToCollection, mapLogic);
|
DeleteContinueFiles(personContainers);
|
||||||
ReadOnlyCollection<Item> distinctFilteredItems = Shared.Models.Stateless.Methods.IContainer.GetItems(_Configuration.PropertyConfiguration, new(containers), distinctItems: true, filterItems: true);
|
if (!runToDoCollectionFirst)
|
||||||
|
MapFaceFileLogic(ticks, personContainers, mapLogic, a2PeopleContentDirectory, eDistanceContentDirectory, options);
|
||||||
|
FullDoWork(argZero, propertyRoot, ticks, aResultsFullGroupDirectory, bResultsFullGroupDirectory, fPhotoPrismSingletonDirectory, t, readOnlyContainers, propertyLogic, mapLogic);
|
||||||
|
ReadOnlyCollection<Item> distinctValidImageItems = Shared.Models.Stateless.Methods.IContainer.GetValidImageItems(_Configuration.PropertyConfiguration, readOnlyContainers, distinctItems: true, filterItems: true);
|
||||||
if (_Configuration.LookForAbandoned)
|
if (_Configuration.LookForAbandoned)
|
||||||
{
|
{
|
||||||
string dResultsFullGroupDirectory;
|
string dResultsFullGroupDirectory;
|
||||||
string d2ResultsFullGroupDirectory;
|
string d2ResultsFullGroupDirectory;
|
||||||
foreach (string outputResolution in _Configuration.OutputResolutions)
|
foreach (string outputResolution in _Configuration.OutputResolutions)
|
||||||
{
|
{
|
||||||
|
_ProgressBar = new(5, nameof(mapLogic.LookForAbandoned), options);
|
||||||
(cResultsFullGroupDirectory, _, dResultsFullGroupDirectory, d2ResultsFullGroupDirectory) = GetResultsFullGroupDirectories(outputResolution);
|
(cResultsFullGroupDirectory, _, dResultsFullGroupDirectory, d2ResultsFullGroupDirectory) = GetResultsFullGroupDirectories(outputResolution);
|
||||||
mapLogic.LookForAbandoned(_Configuration.PropertyConfiguration, bResultsFullGroupDirectory, containers, cResultsFullGroupDirectory, dResultsFullGroupDirectory, d2ResultsFullGroupDirectory);
|
mapLogic.LookForAbandoned(this, _Configuration.PropertyConfiguration, bResultsFullGroupDirectory, readOnlyContainers, cResultsFullGroupDirectory, dResultsFullGroupDirectory, d2ResultsFullGroupDirectory);
|
||||||
|
_ProgressBar.Dispose();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_Distance.Clear();
|
_Distance.Clear();
|
||||||
ReadOnlyCollection<Shared.Models.Face> distinctFilteredFaces = Map.Models.Stateless.Methods.IMapLogic.GetFaces(distinctFilteredItems);
|
ReadOnlyCollection<Shared.Models.Face> distinctValidImageFaces = Map.Models.Stateless.Methods.IMapLogic.GetFaces(distinctValidImageItems);
|
||||||
ReadOnlyCollection<Mapping> distinctFilteredMappingCollection = GetMappings(_Configuration.PropertyConfiguration, eDistanceContentDirectory, containers, mapLogic, distinctItems: true);
|
ReadOnlyCollection<Mapping> distinctValidImageMappingCollection = GetMappings(_Configuration.PropertyConfiguration, eDistanceContentDirectory, readOnlyContainers, mapLogic, distinctItems: true);
|
||||||
if (runToDoCollectionFirst)
|
if (runToDoCollectionFirst)
|
||||||
{
|
{
|
||||||
if (!Directory.Exists(eDistanceContentDirectory))
|
if (!Directory.Exists(eDistanceContentDirectory))
|
||||||
_ = Directory.CreateDirectory(eDistanceContentDirectory);
|
_ = Directory.CreateDirectory(eDistanceContentDirectory);
|
||||||
string json = JsonSerializer.Serialize(distinctFilteredMappingCollection);
|
string json = JsonSerializer.Serialize(distinctValidImageMappingCollection);
|
||||||
File.WriteAllText(Path.Combine(eDistanceContentDirectory, $"{ticks}.json"), json);
|
File.WriteAllText(Path.Combine(eDistanceContentDirectory, $"{ticks}.json"), json);
|
||||||
}
|
}
|
||||||
foreach (string outputResolution in _Configuration.OutputResolutions)
|
foreach (string outputResolution in _Configuration.OutputResolutions)
|
||||||
@ -381,19 +441,19 @@ public partial class DlibDotNet
|
|||||||
break;
|
break;
|
||||||
personKeyToIds = mapLogic.GetPersonKeyToIds();
|
personKeyToIds = mapLogic.GetPersonKeyToIds();
|
||||||
if (_Configuration.SavePropertyShortcutsForOutputResolutions.Contains(outputResolution))
|
if (_Configuration.SavePropertyShortcutsForOutputResolutions.Contains(outputResolution))
|
||||||
SavePropertyShortcutsForOutputResolutions(eDistanceContentDirectory, distinctFilteredItems);
|
SavePropertyShortcutsForOutputResolutions(eDistanceContentDirectory, distinctValidImageItems);
|
||||||
if (!string.IsNullOrEmpty(a2PeopleContentDirectory) && _Configuration.SaveShortcutsForOutputResolutions.Contains(outputResolution))
|
if (!string.IsNullOrEmpty(a2PeopleContentDirectory) && _Configuration.SaveShortcutsForOutputResolutions.Contains(outputResolution))
|
||||||
mapLogic.SaveShortcutsForOutputResolutionsPreMapLogic(eDistanceContentDirectory, personKeyToIds, distinctFilteredMappingCollection);
|
mapLogic.SaveShortcutsForOutputResolutionsPreMapLogic(eDistanceContentDirectory, personKeyToIds, distinctValidImageMappingCollection);
|
||||||
if (!string.IsNullOrEmpty(a2PeopleContentDirectory) && _Configuration.JLinks.Where(l => !string.IsNullOrEmpty(l)).Any() && _Configuration.SaveFilteredOriginalImagesFromJLinksForOutputResolutions.Contains(outputResolution))
|
if (!string.IsNullOrEmpty(a2PeopleContentDirectory) && _Configuration.JLinks.Where(l => !string.IsNullOrEmpty(l)).Any() && _Configuration.SaveFilteredOriginalImagesFromJLinksForOutputResolutions.Contains(outputResolution))
|
||||||
mapLogic.SaveFilteredOriginalImagesFromJLinks(_Configuration.JLinks, personContainers, a2PeopleContentDirectory, personKeyToIds, distinctFilteredMappingCollection);
|
mapLogic.SaveFilteredOriginalImagesFromJLinks(_Configuration.JLinks, personContainers, a2PeopleContentDirectory, personKeyToIds, distinctValidImageMappingCollection);
|
||||||
if (_ArgZeroIsConfigurationRootDirectory
|
if (_ArgZeroIsConfigurationRootDirectory
|
||||||
&& _Configuration.SaveResizedSubfiles
|
&& _Configuration.SaveResizedSubfiles
|
||||||
&& outputResolution == _Configuration.OutputResolutions[0]
|
&& outputResolution == _Configuration.OutputResolutions[0]
|
||||||
&& _Configuration.LoadOrCreateThenSaveDistanceResultsForOutputResolutions.Contains(outputResolution)
|
&& _Configuration.LoadOrCreateThenSaveDistanceResultsForOutputResolutions.Contains(outputResolution)
|
||||||
&& _Exceptions.Count == 0)
|
&& _Exceptions.Count == 0)
|
||||||
MapLogic(ticks, new(containers), fPhotoPrismContentDirectory, mapLogic, outputResolution, new(personKeyToIds), distinctFilteredFaces, distinctFilteredMappingCollection);
|
MapLogic(ticks, readOnlyContainers, fPhotoPrismContentDirectory, mapLogic, outputResolution, new(personKeyToIds), distinctValidImageFaces, distinctValidImageMappingCollection);
|
||||||
if (runToDoCollectionFirst && _Configuration.SaveRandomForOutputResolutions.Contains(outputResolution) && personKeyToIds.Count > 0 && distinctFilteredMappingCollection.Count > 0)
|
if (runToDoCollectionFirst && _Configuration.SaveRandomForOutputResolutions.Contains(outputResolution) && personKeyToIds.Count > 0 && distinctValidImageMappingCollection.Count > 0)
|
||||||
_Random.Random(_Configuration.PropertyConfiguration, _Configuration.RadomUseBirthdayMinimum, _Configuration.ValidKeyWordsToIgnoreInRandom, outputResolution, personKeyToIds, notNineCollection, distinctFilteredMappingCollection);
|
_Random.Random(_Configuration.PropertyConfiguration, _Configuration.ImmichAssetsFile, _Configuration.RadomUseBirthdayMinimum, _Configuration.ValidKeyWordsToIgnoreInRandom, personKeyToIds, notNineCollection, distinctValidImageMappingCollection);
|
||||||
if (_IsEnvironment.Development)
|
if (_IsEnvironment.Development)
|
||||||
continue;
|
continue;
|
||||||
if (!_IsEnvironment.Development)
|
if (!_IsEnvironment.Development)
|
||||||
@ -411,47 +471,50 @@ public partial class DlibDotNet
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool GetRunToDoCollectionFirst(long ticks)
|
private bool GetRunToDoCollectionFirst(Property.Models.Configuration propertyConfiguration, long ticks)
|
||||||
{
|
{
|
||||||
bool result = false;
|
bool result = !IId.IsOffsetDeterministicHashCode(propertyConfiguration);
|
||||||
string[] directories;
|
if (!result)
|
||||||
directories = Directory.GetDirectories(_Configuration.PropertyConfiguration.RootDirectory, "*", SearchOption.TopDirectoryOnly);
|
|
||||||
if (directories.Length == 0)
|
|
||||||
result = true;
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
string seasonDirectory;
|
string[] directories;
|
||||||
DirectoryInfo directoryInfo;
|
directories = Directory.GetDirectories(_Configuration.PropertyConfiguration.RootDirectory, "*", SearchOption.TopDirectoryOnly);
|
||||||
DateTime dateTime = new(ticks);
|
if (directories.Length == 0)
|
||||||
string rootDirectory = _Configuration.PropertyConfiguration.RootDirectory;
|
result = true;
|
||||||
string eDistanceContentDirectory = Property.Models.Stateless.IResult.GetResultsDateGroupDirectory(_Configuration.PropertyConfiguration, nameof(E_Distance), _Configuration.PropertyConfiguration.ResultContent);
|
else
|
||||||
(int season, string seasonName) = Shared.Models.Stateless.Methods.IProperty.GetSeason(dateTime.DayOfYear);
|
|
||||||
FileSystemInfo fileSystemInfo = new DirectoryInfo(eDistanceContentDirectory);
|
|
||||||
string[] checkDirectories =
|
|
||||||
[
|
|
||||||
Path.Combine(rootDirectory, "Ancestry"),
|
|
||||||
Path.Combine(rootDirectory, "Facebook"),
|
|
||||||
Path.Combine(rootDirectory, "LinkedIn"),
|
|
||||||
rootDirectory,
|
|
||||||
];
|
|
||||||
foreach (string checkDirectory in checkDirectories)
|
|
||||||
{
|
{
|
||||||
if (checkDirectory == rootDirectory)
|
string seasonDirectory;
|
||||||
seasonDirectory = Path.Combine(checkDirectory, $"{dateTime.Year}.{season} {seasonName}");
|
DirectoryInfo directoryInfo;
|
||||||
else
|
DateTime dateTime = new(ticks);
|
||||||
seasonDirectory = Path.Combine(checkDirectory, $"{dateTime.Year}.{season} {seasonName} {Path.GetFileName(checkDirectory)}");
|
string rootDirectory = _Configuration.PropertyConfiguration.RootDirectory;
|
||||||
if (!Directory.Exists(seasonDirectory))
|
string eDistanceContentDirectory = Property.Models.Stateless.IResult.GetResultsDateGroupDirectory(_Configuration.PropertyConfiguration, nameof(E_Distance), _Configuration.PropertyConfiguration.ResultContent);
|
||||||
_ = Directory.CreateDirectory(seasonDirectory);
|
(int season, string seasonName) = Shared.Models.Stateless.Methods.IProperty.GetSeason(dateTime.DayOfYear);
|
||||||
if (result)
|
FileSystemInfo fileSystemInfo = new DirectoryInfo(eDistanceContentDirectory);
|
||||||
continue;
|
string[] checkDirectories =
|
||||||
directories = Directory.GetDirectories(checkDirectory, "*", SearchOption.TopDirectoryOnly);
|
[
|
||||||
foreach (string directory in directories)
|
Path.Combine(rootDirectory, "Ancestry"),
|
||||||
|
Path.Combine(rootDirectory, "Facebook"),
|
||||||
|
Path.Combine(rootDirectory, "LinkedIn"),
|
||||||
|
rootDirectory,
|
||||||
|
];
|
||||||
|
foreach (string checkDirectory in checkDirectories)
|
||||||
{
|
{
|
||||||
directoryInfo = new(directory);
|
if (checkDirectory == rootDirectory)
|
||||||
if (directoryInfo.LastWriteTime > fileSystemInfo.LastWriteTime)
|
seasonDirectory = Path.Combine(checkDirectory, $"{dateTime.Year}.{season} {seasonName}");
|
||||||
|
else
|
||||||
|
seasonDirectory = Path.Combine(checkDirectory, $"{dateTime.Year}.{season} {seasonName} {Path.GetFileName(checkDirectory)}");
|
||||||
|
if (!Directory.Exists(seasonDirectory))
|
||||||
|
_ = Directory.CreateDirectory(seasonDirectory);
|
||||||
|
if (result)
|
||||||
|
continue;
|
||||||
|
directories = Directory.GetDirectories(checkDirectory, "*", SearchOption.TopDirectoryOnly);
|
||||||
|
foreach (string directory in directories)
|
||||||
{
|
{
|
||||||
result = true;
|
directoryInfo = new(directory);
|
||||||
break;
|
if (directoryInfo.LastWriteTime > fileSystemInfo.LastWriteTime)
|
||||||
|
{
|
||||||
|
result = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -509,7 +572,7 @@ public partial class DlibDotNet
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void FullDoWork(string argZero, string propertyRoot, long ticks, string aResultsFullGroupDirectory, string bResultsFullGroupDirectory, int t, Container[] containers, A_Property propertyLogic, B_Metadata metadata, Dictionary<int, List<MappingFromPhotoPrism>> fileNameToCollection, MapLogic mapLogic)
|
private void FullDoWork(string argZero, string propertyRoot, long ticks, string aResultsFullGroupDirectory, string bResultsFullGroupDirectory, string fPhotoPrismSingletonDirectory, int t, ReadOnlyCollection<Container> readOnlyContainers, A_Property propertyLogic, MapLogic mapLogic)
|
||||||
{
|
{
|
||||||
int total;
|
int total;
|
||||||
int notMapped;
|
int notMapped;
|
||||||
@ -517,7 +580,6 @@ public partial class DlibDotNet
|
|||||||
bool exceptions;
|
bool exceptions;
|
||||||
int totalSeconds;
|
int totalSeconds;
|
||||||
Container container;
|
Container container;
|
||||||
Item[] filteredItems;
|
|
||||||
int totalNotMapped = 0;
|
int totalNotMapped = 0;
|
||||||
bool outputResolutionHasNumber;
|
bool outputResolutionHasNumber;
|
||||||
bool anyNullOrNoIsUniqueFileName;
|
bool anyNullOrNoIsUniqueFileName;
|
||||||
@ -525,33 +587,36 @@ public partial class DlibDotNet
|
|||||||
string dResultsFullGroupDirectory;
|
string dResultsFullGroupDirectory;
|
||||||
string c2ResultsFullGroupDirectory;
|
string c2ResultsFullGroupDirectory;
|
||||||
string d2ResultsFullGroupDirectory;
|
string d2ResultsFullGroupDirectory;
|
||||||
int containersLength = containers.Length;
|
ReadOnlyCollection<Item> filteredItems;
|
||||||
|
int containersLength = readOnlyContainers.Count;
|
||||||
List<Tuple<string, DateTime>> sourceDirectoryChanges = [];
|
List<Tuple<string, DateTime>> sourceDirectoryChanges = [];
|
||||||
int maxDegreeOfParallelism = _AppSettings.MaxDegreeOfParallelism;
|
int maxDegreeOfParallelism = _AppSettings.MaxDegreeOfParallelism;
|
||||||
|
Dictionary<int, List<MappingFromPhotoPrism>> fileNameToCollection = !Directory.Exists(fPhotoPrismSingletonDirectory) ? fileNameToCollection = [] : F_PhotoPrism.GetFileNameToCollection(fPhotoPrismSingletonDirectory);
|
||||||
string dResultsDateGroupDirectory = Property.Models.Stateless.IResult.GetResultsDateGroupDirectory(_Configuration.PropertyConfiguration, nameof(D_Face));
|
string dResultsDateGroupDirectory = Property.Models.Stateless.IResult.GetResultsDateGroupDirectory(_Configuration.PropertyConfiguration, nameof(D_Face));
|
||||||
|
B_Metadata metadata = new(_Configuration.PropertyConfiguration, _Configuration.ForceMetadataLastWriteTimeToCreationTime, _Configuration.PropertiesChangedForMetadata, bResultsFullGroupDirectory);
|
||||||
foreach (string outputResolution in _Configuration.OutputResolutions)
|
foreach (string outputResolution in _Configuration.OutputResolutions)
|
||||||
{
|
{
|
||||||
total = 0;
|
total = 0;
|
||||||
outputResolutionHasNumber = outputResolution.Any(l => char.IsNumber(l));
|
outputResolutionHasNumber = outputResolution.Any(char.IsNumber);
|
||||||
(cResultsFullGroupDirectory, c2ResultsFullGroupDirectory, dResultsFullGroupDirectory, d2ResultsFullGroupDirectory) = GetResultsFullGroupDirectories(outputResolution);
|
(cResultsFullGroupDirectory, c2ResultsFullGroupDirectory, dResultsFullGroupDirectory, d2ResultsFullGroupDirectory) = GetResultsFullGroupDirectories(outputResolution);
|
||||||
_Faces.Update(dResultsFullGroupDirectory);
|
_Faces.Update(dResultsFullGroupDirectory);
|
||||||
_Resize.Update(cResultsFullGroupDirectory);
|
_Resize.Update(cResultsFullGroupDirectory);
|
||||||
_FaceParts.Update(d2ResultsFullGroupDirectory);
|
_FaceParts.Update(d2ResultsFullGroupDirectory);
|
||||||
_BlurHasher.Update(c2ResultsFullGroupDirectory);
|
_BlurHasher.Update(c2ResultsFullGroupDirectory);
|
||||||
for (int i = 0; i < containers.Length; i++)
|
for (int i = 0; i < readOnlyContainers.Count; i++)
|
||||||
{
|
{
|
||||||
container = containers[i];
|
container = readOnlyContainers[i];
|
||||||
if (container.Items.Count == 0)
|
if (container.Items.Count == 0)
|
||||||
continue;
|
continue;
|
||||||
if (!_ArgZeroIsConfigurationRootDirectory && !container.SourceDirectory.StartsWith(argZero))
|
if (!_ArgZeroIsConfigurationRootDirectory && !container.SourceDirectory.StartsWith(argZero))
|
||||||
continue;
|
continue;
|
||||||
filteredItems = Shared.Models.Stateless.Methods.IContainer.GetFilterItems(_Configuration.PropertyConfiguration, container);
|
filteredItems = Shared.Models.Stateless.Methods.IContainer.GetValidImageItems(_Configuration.PropertyConfiguration, container);
|
||||||
if (filteredItems.Length == 0)
|
if (filteredItems.Count == 0)
|
||||||
continue;
|
continue;
|
||||||
sourceDirectoryChanges.Clear();
|
sourceDirectoryChanges.Clear();
|
||||||
anyNullOrNoIsUniqueFileName = filteredItems.Any(l => !l.IsUniqueFileName);
|
anyNullOrNoIsUniqueFileName = filteredItems.Any(l => !l.IsUniqueFileName);
|
||||||
totalSeconds = (int)Math.Floor(new TimeSpan(DateTime.Now.Ticks - ticks).TotalSeconds);
|
totalSeconds = (int)Math.Floor(new TimeSpan(DateTime.Now.Ticks - ticks).TotalSeconds);
|
||||||
message = $"{i + 1:000} [{filteredItems.Length:000}] / {containersLength:000} - {total} / {t} total - {totalSeconds} total second(s) - {outputResolution} - <{container.SourceDirectory}> - total not mapped {totalNotMapped:000000}";
|
message = $"{i + 1:000} [{filteredItems.Count:000}] / {containersLength:000} - {total} / {t} total - {totalSeconds} total second(s) - {outputResolution} - <{container.SourceDirectory}> - total not mapped {totalNotMapped:000000}";
|
||||||
propertyLogic.SetAngleBracketCollection(aResultsFullGroupDirectory, container.SourceDirectory, anyNullOrNoIsUniqueFileName);
|
propertyLogic.SetAngleBracketCollection(aResultsFullGroupDirectory, container.SourceDirectory, anyNullOrNoIsUniqueFileName);
|
||||||
if (outputResolutionHasNumber)
|
if (outputResolutionHasNumber)
|
||||||
_Resize.SetAngleBracketCollection(cResultsFullGroupDirectory, container.SourceDirectory);
|
_Resize.SetAngleBracketCollection(cResultsFullGroupDirectory, container.SourceDirectory);
|
||||||
@ -595,26 +660,54 @@ public partial class DlibDotNet
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private ReadOnlyCollection<Mapping> GetMappings(Property.Models.Configuration propertyConfiguration, string eDistanceContentDirectory, Container[] containers, MapLogic mapLogic, bool distinctItems)
|
private static void SaveDistinctIds(Property.Models.Configuration propertyConfiguration, string bResultsFullGroupDirectory, ReadOnlyCollection<Container> readOnlyContainers)
|
||||||
{
|
{
|
||||||
ReadOnlyCollection<Mapping> results;
|
string paddedId;
|
||||||
|
List<int> distinct = [];
|
||||||
|
List<Identifier> identifiers = [];
|
||||||
|
string bMetadataCollectionDirectory = Path.Combine(bResultsFullGroupDirectory, propertyConfiguration.ResultCollection);
|
||||||
|
if (!Directory.Exists(bMetadataCollectionDirectory))
|
||||||
|
_ = Directory.CreateDirectory(bMetadataCollectionDirectory);
|
||||||
|
foreach (Container container in readOnlyContainers)
|
||||||
|
{
|
||||||
|
if (container.Items.Count == 0)
|
||||||
|
continue;
|
||||||
|
foreach (Item item in container.Items)
|
||||||
|
{
|
||||||
|
if (item.Property?.Id is null)
|
||||||
|
continue;
|
||||||
|
if (item.Property.Id != item.FilePath.Id)
|
||||||
|
throw new NotSupportedException();
|
||||||
|
if (distinct.Contains(item.Property.Id.Value))
|
||||||
|
continue;
|
||||||
|
distinct.Add(item.Property.Id.Value);
|
||||||
|
paddedId = IId.GetPaddedId(propertyConfiguration, item.Property.Id.Value, item.FilePath.IsIgnore, index: null);
|
||||||
|
identifiers.Add(new(item.Property.Id.Value, paddedId));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
string json = JsonSerializer.Serialize(identifiers.OrderBy(l => l.PaddedId).ToArray(), IdentifierCollectionSourceGenerationContext.Default.IdentifierArray);
|
||||||
|
_ = Shared.Models.Stateless.Methods.IPath.WriteAllText(Path.Combine(bMetadataCollectionDirectory, ".json"), json, updateDateWhenMatches: false, compareBeforeWrite: true, updateToWhenMatches: null);
|
||||||
|
}
|
||||||
|
|
||||||
|
private ReadOnlyCollection<Mapping> GetMappings(Property.Models.Configuration propertyConfiguration, string eDistanceContentDirectory, ReadOnlyCollection<Container> readOnlyContainers, MapLogic mapLogic, bool distinctItems)
|
||||||
|
{
|
||||||
|
List<Mapping> results = [];
|
||||||
int count = 0;
|
int count = 0;
|
||||||
int notMapped;
|
int notMapped;
|
||||||
Mapping mapping;
|
Mapping mapping;
|
||||||
bool anyValidFaces;
|
bool anyValidFaces;
|
||||||
|
List<int> distinct = [];
|
||||||
string focusRelativePath;
|
string focusRelativePath;
|
||||||
bool? isFocusRelativePath;
|
bool? isFocusRelativePath;
|
||||||
List<int> distinct = [];
|
|
||||||
DateTime[] containerDateTimes;
|
DateTime[] containerDateTimes;
|
||||||
IEnumerable<Item> filteredItems;
|
|
||||||
MappingFromItem mappingFromItem;
|
MappingFromItem mappingFromItem;
|
||||||
List<Mapping> mappingCollection = [];
|
ReadOnlyCollection<Item> filteredItems;
|
||||||
foreach (Container container in containers)
|
foreach (Container container in readOnlyContainers)
|
||||||
{
|
{
|
||||||
if (container.Items.Count == 0)
|
if (container.Items.Count == 0)
|
||||||
continue;
|
continue;
|
||||||
filteredItems = Shared.Models.Stateless.Methods.IContainer.GetFilterItems(propertyConfiguration, container);
|
filteredItems = Shared.Models.Stateless.Methods.IContainer.GetValidImageItems(propertyConfiguration, container);
|
||||||
if (!filteredItems.Any())
|
if (filteredItems.Count == 0)
|
||||||
continue;
|
continue;
|
||||||
containerDateTimes = Shared.Models.Stateless.Methods.IContainer.GetContainerDateTimes(filteredItems);
|
containerDateTimes = Shared.Models.Stateless.Methods.IContainer.GetContainerDateTimes(filteredItems);
|
||||||
focusRelativePath = Path.GetFullPath(string.Concat(_Configuration.PropertyConfiguration.RootDirectory, _Configuration.FocusDirectory));
|
focusRelativePath = Path.GetFullPath(string.Concat(_Configuration.PropertyConfiguration.RootDirectory, _Configuration.FocusDirectory));
|
||||||
@ -635,24 +728,25 @@ public partial class DlibDotNet
|
|||||||
foreach (Shared.Models.Face face in item.Faces)
|
foreach (Shared.Models.Face face in item.Faces)
|
||||||
{
|
{
|
||||||
if (face.Mapping is null)
|
if (face.Mapping is null)
|
||||||
|
throw new NotSupportedException();
|
||||||
|
if (face.FaceEncoding is null || face.Location is null || face.OutputResolution is null)
|
||||||
continue;
|
continue;
|
||||||
anyValidFaces = true;
|
anyValidFaces = true;
|
||||||
mappingCollection.Add(face.Mapping);
|
results.Add(face.Mapping);
|
||||||
}
|
}
|
||||||
if (!anyValidFaces)
|
if (!anyValidFaces)
|
||||||
{
|
{
|
||||||
(mapping, notMapped) = GetMappingAndUpdateMappingFromPerson(mapLogic, item, isFocusRelativePath, mappingFromItem);
|
(mapping, notMapped) = GetMappingAndUpdateMappingFromPerson(mapLogic, item, isFocusRelativePath, mappingFromItem);
|
||||||
mappingCollection.Add(mapping);
|
results.Add(mapping);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (_Configuration.MoveToDecade && _Configuration.LocationContainerDistanceTolerance is null)
|
if (_Configuration.MoveToDecade && _Configuration.LocationContainerDistanceTolerance is null)
|
||||||
_ = Shared.Models.Stateless.Methods.IPath.DeleteEmptyDirectories(eDistanceContentDirectory);
|
_ = Shared.Models.Stateless.Methods.IPath.DeleteEmptyDirectories(eDistanceContentDirectory);
|
||||||
results = new((from l in mappingCollection orderby l.MappingFromItem.Id select l).ToArray());
|
return new(results);
|
||||||
return results;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void SavePropertyShortcutsForOutputResolutions(string eDistanceContentDirectory, ReadOnlyCollection<Item> distinctFilteredItems)
|
private static void SavePropertyShortcutsForOutputResolutions(string eDistanceContentDirectory, ReadOnlyCollection<Item> distinctValidImageItems)
|
||||||
{
|
{
|
||||||
#if VerifyItem
|
#if VerifyItem
|
||||||
bool found;
|
bool found;
|
||||||
@ -683,32 +777,32 @@ public partial class DlibDotNet
|
|||||||
List<string> distinct = [];
|
List<string> distinct = [];
|
||||||
WindowsShortcut windowsShortcut;
|
WindowsShortcut windowsShortcut;
|
||||||
List<(string, string, string)> collection = [];
|
List<(string, string, string)> collection = [];
|
||||||
foreach (Item item in distinctFilteredItems)
|
foreach (Item item in distinctValidImageItems)
|
||||||
{
|
{
|
||||||
if (item.Property?.Id is null || item.ImageFileHolder.LastWriteTime is null)
|
if (item.Property?.Id is null)
|
||||||
continue;
|
continue;
|
||||||
if (item.IsNotUniqueAndNeedsReview is null || !item.IsNotUniqueAndNeedsReview.Value)
|
if (item.IsNotUniqueAndNeedsReview is null || !item.IsNotUniqueAndNeedsReview.Value)
|
||||||
continue;
|
continue;
|
||||||
directory = Path.Combine($"{eDistanceContentDirectory[..^1]}{nameof(item.IsNotUniqueAndNeedsReview)})", item.ImageFileHolder.NameWithoutExtension);
|
directory = Path.Combine($"{eDistanceContentDirectory[..^1]}{nameof(item.IsNotUniqueAndNeedsReview)})", item.FilePath.NameWithoutExtension);
|
||||||
fileName = Path.Combine(directory, $"{item.ImageFileHolder.Length} {item.ImageFileHolder.LastWriteTime.Value.Ticks}.lnk");
|
fileName = Path.Combine(directory, $"{item.FilePath.Length} {item.FilePath.LastWriteTicks}.lnk");
|
||||||
collection.Add((item.ImageFileHolder.FullName, directory, fileName));
|
collection.Add((item.FilePath.FullName, directory, fileName));
|
||||||
if (distinct.Contains(directory))
|
if (distinct.Contains(directory))
|
||||||
continue;
|
continue;
|
||||||
distinct.Add(directory);
|
distinct.Add(directory);
|
||||||
}
|
}
|
||||||
foreach (Item item in distinctFilteredItems)
|
foreach (Item item in distinctValidImageItems)
|
||||||
{
|
{
|
||||||
if (item.Property?.Id is null || item.Property.DateTimeOriginal is null)
|
if (item.Property?.Id is null || item.Property.DateTimeOriginal is null)
|
||||||
continue;
|
continue;
|
||||||
dateTimes = item.Property.GetDateTimes();
|
dateTimes = item.Property.GetDateTimes();
|
||||||
(isWrongYear, _) = Shared.Models.Stateless.Methods.IProperty.IsWrongYear(item.ImageFileHolder, item.Property.DateTimeOriginal, dateTimes);
|
(isWrongYear, _) = Shared.Models.Stateless.Methods.IProperty.IsWrongYear(item.FilePath, item.Property.DateTimeOriginal, dateTimes);
|
||||||
if (isWrongYear is null || !isWrongYear.Value)
|
if (isWrongYear is null || !isWrongYear.Value)
|
||||||
continue;
|
continue;
|
||||||
// Remove-Item -LiteralPath "\\?\D:\Tmp\a\EX-Z70 "
|
// Remove-Item -LiteralPath "\\?\D:\Tmp\a\EX-Z70 "
|
||||||
model = string.IsNullOrEmpty(item.Property.Model) ? "Unknown" : CameraRegex().Replace(item.Property.Model.Trim(), "_");
|
model = string.IsNullOrEmpty(item.Property.Model) ? "Unknown" : CameraRegex().Replace(item.Property.Model.Trim(), "_");
|
||||||
directory = Path.Combine($"{eDistanceContentDirectory[..^1]}{nameof(Item)})", item.Property.DateTimeOriginal.Value.Year.ToString(), model);
|
directory = Path.Combine($"{eDistanceContentDirectory[..^1]}{nameof(Item)})", item.Property.DateTimeOriginal.Value.Year.ToString(), model);
|
||||||
fileName = item.IsNotUniqueAndNeedsReview is not null && item.IsNotUniqueAndNeedsReview.Value ? Path.Combine(directory, $"{item.ImageFileHolder.Name} {item.ImageFileHolder.Length}.lnk") : Path.Combine(directory, $"{item.ImageFileHolder.Name}.lnk");
|
fileName = item.IsNotUniqueAndNeedsReview is not null && item.IsNotUniqueAndNeedsReview.Value ? Path.Combine(directory, $"{item.FilePath.Name} {item.FilePath.Length}.lnk") : Path.Combine(directory, $"{item.FilePath.Name}.lnk");
|
||||||
collection.Add((item.ImageFileHolder.FullName, directory, fileName));
|
collection.Add((item.FilePath.FullName, directory, fileName));
|
||||||
if (distinct.Contains(directory))
|
if (distinct.Contains(directory))
|
||||||
continue;
|
continue;
|
||||||
distinct.Add(directory);
|
distinct.Add(directory);
|
||||||
@ -741,27 +835,78 @@ public partial class DlibDotNet
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void MapLogic(long ticks, ReadOnlyCollection<Container> containers, string fPhotoPrismContentDirectory, MapLogic mapLogic, string outputResolution, ReadOnlyDictionary<long, List<int>> personKeyToIds, ReadOnlyCollection<Shared.Models.Face> distinctFilteredFaces, ReadOnlyCollection<Mapping> distinctFilteredMappingCollection)
|
private ReadOnlyCollection<FilePath> GetFilePath(long ticks, string dFacesContentDirectory)
|
||||||
|
{
|
||||||
|
List<FilePath> results = [];
|
||||||
|
FilePath filePath;
|
||||||
|
FileHolder fileHolder;
|
||||||
|
string[] files = Directory.GetFiles(dFacesContentDirectory, $"*{_Faces.FileNameExtension}", SearchOption.AllDirectories);
|
||||||
|
long? skipOlderThan = _Configuration.SkipOlderThanDays is null ? null : new DateTime(ticks).AddDays(-_Configuration.SkipOlderThanDays.Value).Ticks;
|
||||||
|
foreach (string file in files)
|
||||||
|
{
|
||||||
|
fileHolder = Shared.Models.Stateless.Methods.IFileHolder.Get(file);
|
||||||
|
filePath = FilePath.Get(_Configuration.PropertyConfiguration, fileHolder, index: null);
|
||||||
|
if (filePath.Id is null)
|
||||||
|
continue;
|
||||||
|
if (skipOlderThan is not null && (fileHolder.LastWriteTime is null || fileHolder.LastWriteTime.Value.Ticks < skipOlderThan.Value))
|
||||||
|
continue;
|
||||||
|
results.Add(filePath);
|
||||||
|
}
|
||||||
|
return new(results);
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<SaveContainer> GetSaveContainers(long ticks, ReadOnlyCollection<PersonContainer> personContainers, string a2PeopleSingletonDirectory, string eDistanceContentDirectory, ProgressBarOptions options, MapLogic mapLogic, string outputResolution)
|
||||||
|
{
|
||||||
|
List<SaveContainer> results;
|
||||||
|
long[] jLinkResolvedPersonKeys = _JLinkResolvedDirectories.Select(l => l.PersonKey).ToArray();
|
||||||
|
(string cResultsFullGroupDirectory, string _, string dResultsFullGroupDirectory, string d2ResultsFullGroupDirectory) = GetResultsFullGroupDirectories(outputResolution);
|
||||||
|
string dFacesContentDirectory = Path.Combine(dResultsFullGroupDirectory, _Configuration.PropertyConfiguration.ResultContent);
|
||||||
|
ReadOnlyDictionary<int, ReadOnlyDictionary<int, LocationContainer>> mapped = Map.Models.Stateless.Methods.IMapLogic.GetMapped(_AppSettings.MaxDegreeOfParallelism, _Configuration.PropertyConfiguration, _MapConfiguration, ticks, personContainers, a2PeopleSingletonDirectory, eDistanceContentDirectory);
|
||||||
|
if (mapped.Count == 0 && !_Configuration.SaveSortingWithoutPerson)
|
||||||
|
throw new NotSupportedException($"Switch {nameof(_Configuration.SaveSortingWithoutPerson)}!");
|
||||||
|
ReadOnlyCollection<FilePath> filePaths = GetFilePath(ticks, dFacesContentDirectory);
|
||||||
|
List<LocationContainer> available = Map.Models.Stateless.Methods.IMapLogic.GetAvailable(_AppSettings.MaxDegreeOfParallelism, _Configuration.PropertyConfiguration, _MapConfiguration, _Faces, ticks, dFacesContentDirectory, filePaths);
|
||||||
|
if (!string.IsNullOrEmpty(_Configuration.FocusDirectory) && _Configuration.FocusDirectory.Length != 2)
|
||||||
|
throw new NotSupportedException($"{nameof(_Configuration.FocusDirectory)} currently only works with output directory! Example 00.");
|
||||||
|
ReadOnlyDictionary<int, ReadOnlyDictionary<int, LocationContainer>> mappedWithEncoding = E_Distance.GetMappedWithEncoding(mapped);
|
||||||
|
if (mappedWithEncoding.Count == 0 && !_Configuration.SaveSortingWithoutPerson)
|
||||||
|
throw new NotSupportedException($"Switch {nameof(_Configuration.SaveSortingWithoutPerson)}!");
|
||||||
|
List<LocationContainer> preFiltered = E_Distance.GetPreFilterLocationContainer(_AppSettings.MaxDegreeOfParallelism, _MapConfiguration, _Configuration.FocusDirectory, _Configuration.FocusModel, _Configuration.SkipPersonWithMoreThen, ticks, mapLogic, jLinkResolvedPersonKeys, mapped, available);
|
||||||
|
if (preFiltered.Count == 0)
|
||||||
|
throw new NotSupportedException("Done?");
|
||||||
|
DistanceLimits distanceLimits = new(_Configuration.FaceAreaPermyriad, _Configuration.FaceConfidencePercent, _Configuration.FaceDistancePermyriad, _Configuration.RangeDaysDeltaTolerance, _Configuration.RangeDistanceTolerance, _Configuration.RangeFaceAreaPermyriadTolerance, _Configuration.RangeFaceConfidence, _Configuration.SortingMaximumPerFaceShouldBeHigh);
|
||||||
|
List<LocationContainer> postFiltered = E_Distance.GetPostFilterLocationContainer(mapLogic, preFiltered, distanceLimits);
|
||||||
|
if (postFiltered.Count == 0)
|
||||||
|
throw new NotSupportedException("Done?");
|
||||||
|
string message = $") Building Matrix - {(int)Math.Floor(new TimeSpan(DateTime.Now.Ticks - ticks).TotalSeconds)} total second(s)";
|
||||||
|
_ProgressBar = new(postFiltered.Count, message, options);
|
||||||
|
ReadOnlyCollection<LocationContainer> matrix = E_Distance.GetMatrixLocationContainers(this, _MapConfiguration, ticks, mapLogic, mappedWithEncoding, preFiltered, distanceLimits, postFiltered);
|
||||||
|
_ProgressBar.Dispose();
|
||||||
|
results = mapLogic.GetSaveContainers(cResultsFullGroupDirectory, dResultsFullGroupDirectory, d2ResultsFullGroupDirectory, distanceLimits, matrix);
|
||||||
|
return results;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void MapLogic(long ticks, ReadOnlyCollection<Container> containers, string fPhotoPrismContentDirectory, MapLogic mapLogic, string outputResolution, ReadOnlyDictionary<long, List<int>> personKeyToIds, ReadOnlyCollection<Shared.Models.Face> distinctValidImageFaces, ReadOnlyCollection<Mapping> distinctValidImageMappingCollection)
|
||||||
{
|
{
|
||||||
(_, _, string dResultsFullGroupDirectory, string d2ResultsFullGroupDirectory) = GetResultsFullGroupDirectories(outputResolution);
|
(_, _, string dResultsFullGroupDirectory, string d2ResultsFullGroupDirectory) = GetResultsFullGroupDirectories(outputResolution);
|
||||||
string dFacesContentDirectory = Path.Combine(dResultsFullGroupDirectory, _Configuration.PropertyConfiguration.ResultContent);
|
string dFacesContentDirectory = Path.Combine(dResultsFullGroupDirectory, _Configuration.PropertyConfiguration.ResultContent);
|
||||||
string d2FacePartsContentDirectory = Path.Combine(d2ResultsFullGroupDirectory, _Configuration.PropertyConfiguration.ResultContent);
|
string d2FacePartsContentDirectory = Path.Combine(d2ResultsFullGroupDirectory, _Configuration.PropertyConfiguration.ResultContent);
|
||||||
string d2FacePartsContentCollectionDirectory = Path.Combine(d2ResultsFullGroupDirectory, "[()]");
|
string d2FacePartsContentCollectionDirectory = Path.Combine(d2ResultsFullGroupDirectory, "[()]");
|
||||||
if (distinctFilteredMappingCollection.Count > 0)
|
if (distinctValidImageMappingCollection.Count > 0)
|
||||||
{
|
{
|
||||||
Shared.Models.Stateless.Methods.IPath.ChangeDateForEmptyDirectories(d2FacePartsContentDirectory, ticks);
|
Shared.Models.Stateless.Methods.IPath.ChangeDateForEmptyDirectories(d2FacePartsContentDirectory, ticks);
|
||||||
if (Directory.Exists(d2FacePartsContentCollectionDirectory))
|
if (Directory.Exists(d2FacePartsContentCollectionDirectory))
|
||||||
Shared.Models.Stateless.Methods.IPath.MakeHiddenIfAllItemsAreHidden(d2FacePartsContentCollectionDirectory);
|
Shared.Models.Stateless.Methods.IPath.MakeHiddenIfAllItemsAreHidden(d2FacePartsContentCollectionDirectory);
|
||||||
}
|
}
|
||||||
if (Directory.Exists(fPhotoPrismContentDirectory))
|
if (Directory.Exists(fPhotoPrismContentDirectory))
|
||||||
F_PhotoPrism.WriteMatches(fPhotoPrismContentDirectory, _Configuration.PersonBirthdayFormat, _Configuration.RectangleIntersectMinimums, ticks, distinctFilteredFaces, mapLogic);
|
F_PhotoPrism.WriteMatches(fPhotoPrismContentDirectory, _Configuration.PersonBirthdayFormat, _Configuration.RectangleIntersectMinimums, ticks, distinctValidImageFaces, mapLogic);
|
||||||
if (_Configuration.SaveShortcutsForOutputResolutions.Contains(outputResolution))
|
if (_Configuration.SaveShortcutsForOutputResolutions.Contains(outputResolution))
|
||||||
mapLogic.SaveShortcutsForOutputResolutionsDuringMapLogic(containers, personKeyToIds, dFacesContentDirectory, distinctFilteredMappingCollection);
|
mapLogic.SaveShortcutsForOutputResolutionsDuringMapLogic(containers, personKeyToIds, dFacesContentDirectory, distinctValidImageMappingCollection);
|
||||||
ReadOnlyDictionary<int, ReadOnlyDictionary<int, Mapping>> idToWholePercentagesToMapping = Map.Models.Stateless.Methods.IMapLogic.GetIdToWholePercentagesToFace(distinctFilteredMappingCollection);
|
ReadOnlyDictionary<int, ReadOnlyDictionary<int, Mapping>> idToWholePercentagesToMapping = Map.Models.Stateless.Methods.IMapLogic.GetIdToWholePercentagesToFace(distinctValidImageMappingCollection);
|
||||||
if (_Configuration.SaveMappedForOutputResolutions.Contains(outputResolution))
|
if (_Configuration.SaveMappedForOutputResolutions.Contains(outputResolution))
|
||||||
mapLogic.SaveMapped(dFacesContentDirectory, d2FacePartsContentDirectory, d2FacePartsContentCollectionDirectory, personKeyToIds, distinctFilteredMappingCollection, idToWholePercentagesToMapping);
|
mapLogic.SaveMapped(dFacesContentDirectory, d2FacePartsContentDirectory, d2FacePartsContentCollectionDirectory, personKeyToIds, distinctValidImageMappingCollection, idToWholePercentagesToMapping);
|
||||||
if (_Configuration.SaveFaceDistancesForOutputResolutions.Contains(outputResolution))
|
if (_Configuration.SaveFaceDistancesForOutputResolutions.Contains(outputResolution))
|
||||||
SaveFaceDistances(ticks, mapLogic, distinctFilteredFaces, dFacesContentDirectory, d2FacePartsContentDirectory, d2FacePartsContentCollectionDirectory, idToWholePercentagesToMapping);
|
SaveFaceDistances(ticks, mapLogic, distinctValidImageFaces, dFacesContentDirectory, d2FacePartsContentDirectory, d2FacePartsContentCollectionDirectory, idToWholePercentagesToMapping);
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool? GetIsFocusModel(Shared.Models.Property? property)
|
private bool? GetIsFocusModel(Shared.Models.Property? property)
|
||||||
@ -779,16 +924,16 @@ public partial class DlibDotNet
|
|||||||
private void LogItemPropertyIsNull(Item item)
|
private void LogItemPropertyIsNull(Item item)
|
||||||
{
|
{
|
||||||
if (!item.SourceDirectoryFileHolder.Exists)
|
if (!item.SourceDirectoryFileHolder.Exists)
|
||||||
_Logger?.LogInformation(string.Concat("NoJson <", item.ImageFileHolder.FullName, '>'));
|
_Logger?.LogInformation(string.Concat("NoJson <", item.FilePath.FullName, '>'));
|
||||||
else if (item.FileSizeChanged.HasValue && item.FileSizeChanged.Value)
|
else if (item.FileSizeChanged.HasValue && item.FileSizeChanged.Value)
|
||||||
_Logger?.LogInformation(string.Concat("FileSizeChanged <", item.ImageFileHolder.FullName, '>'));
|
_Logger?.LogInformation(string.Concat("FileSizeChanged <", item.FilePath.FullName, '>'));
|
||||||
else if (item.LastWriteTimeChanged.HasValue && item.LastWriteTimeChanged.Value)
|
else if (item.LastWriteTimeChanged.HasValue && item.LastWriteTimeChanged.Value)
|
||||||
_Logger?.LogInformation(string.Concat("LastWriteTimeChanged <", item.ImageFileHolder.FullName, '>'));
|
_Logger?.LogInformation(string.Concat("LastWriteTimeChanged <", item.FilePath.FullName, '>'));
|
||||||
else if (item.Moved.HasValue && item.Moved.Value)
|
else if (item.Moved.HasValue && item.Moved.Value)
|
||||||
_Logger?.LogInformation(string.Concat("Moved <", item.ImageFileHolder.FullName, '>'));
|
_Logger?.LogInformation(string.Concat("Moved <", item.FilePath.FullName, '>'));
|
||||||
}
|
}
|
||||||
|
|
||||||
private int GetNotMappedCountAndUpdateMappingFromPersonThenSetMapping(MapLogic mapLogic, Item item, bool? isFocusRelativePath, ReadOnlyCollection<LocationContainer> locationContainers, MappingFromItem mappingFromItem, List<MappingFromPhotoPrism>? mappingFromPhotoPrismCollection, List<Shared.Models.Face> faces)
|
private int GetNotMappedCountAndUpdateMappingFromPersonThenSetMapping(MapLogic mapLogic, Item item, bool? isFocusRelativePath, MappingFromItem mappingFromItem, List<MappingFromPhotoPrism>? mappingFromPhotoPrismCollection, List<Shared.Models.Face> faces)
|
||||||
{
|
{
|
||||||
int result;
|
int result;
|
||||||
double? α;
|
double? α;
|
||||||
@ -809,7 +954,6 @@ public partial class DlibDotNet
|
|||||||
bool? isFocusModel = GetIsFocusModel(item.Property);
|
bool? isFocusModel = GetIsFocusModel(item.Property);
|
||||||
long[] jLinkResolvedPersonKeys = _JLinkResolvedDirectories.Select(l => l.PersonKey).ToArray();
|
long[] jLinkResolvedPersonKeys = _JLinkResolvedDirectories.Select(l => l.PersonKey).ToArray();
|
||||||
ReadOnlyDictionary<int, ReadOnlyCollection<PersonContainer>>? wholePercentagesToPersonContainers;
|
ReadOnlyDictionary<int, ReadOnlyCollection<PersonContainer>>? wholePercentagesToPersonContainers;
|
||||||
ReadOnlyCollection<string> locationContainersFiles = new((from l in locationContainers select l.FilePath.FullName).ToArray());
|
|
||||||
foreach (Shared.Models.Face face in faces)
|
foreach (Shared.Models.Face face in faces)
|
||||||
{
|
{
|
||||||
wholePercentagesToPersonContainers = mapLogic.GetWholePercentagesToPersonContainers(item.Property?.Id);
|
wholePercentagesToPersonContainers = mapLogic.GetWholePercentagesToPersonContainers(item.Property?.Id);
|
||||||
@ -850,76 +994,58 @@ public partial class DlibDotNet
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Map.Models.Configuration Get(Models.Configuration configuration, string facesFileNameExtension, string facesHiddenFileNameExtension, string facePartsFileNameExtension)
|
private static Map.Models.Configuration Get(Models.Configuration configuration, IDistanceLimits distanceLimits, string facesFileNameExtension, string facesHiddenFileNameExtension, string facePartsFileNameExtension)
|
||||||
{
|
{
|
||||||
Map.Models.Configuration result = new(
|
Map.Models.Configuration result = new(distanceLimits,
|
||||||
configuration.DeletePossibleDuplicates,
|
configuration.PropertyConfiguration,
|
||||||
configuration.DistanceMoveUnableToMatch,
|
configuration.DeletePossibleDuplicates,
|
||||||
configuration.DistanceRenameToMatch,
|
configuration.DistanceMoveUnableToMatch,
|
||||||
configuration.FaceConfidencePercent,
|
configuration.DistanceRenameToMatch,
|
||||||
configuration.FaceDistancePermyriad,
|
configuration.FaceConfidencePercent,
|
||||||
configuration.LocationContainerDebugDirectory,
|
configuration.FaceDistancePermyriad,
|
||||||
configuration.LocationContainerDirectoryPattern,
|
configuration.LinkedAlpha,
|
||||||
configuration.LocationContainerDistanceGroupMinimum,
|
configuration.LocationContainerDebugDirectory,
|
||||||
configuration.LocationContainerDistanceTake,
|
configuration.LocationContainerDirectoryPattern,
|
||||||
configuration.LocationContainerDistanceTolerance,
|
configuration.LocationContainerDistanceGroupMinimum,
|
||||||
configuration.LocationDigits,
|
configuration.LocationContainerDistanceTake,
|
||||||
configuration.MappingDefaultName,
|
configuration.LocationContainerDistanceTolerance,
|
||||||
configuration.PersonBirthdayFirstYear,
|
configuration.LocationDigits,
|
||||||
configuration.PersonBirthdayFormat,
|
configuration.MappingDefaultName,
|
||||||
configuration.PersonCharacters.ToArray(),
|
configuration.PersonBirthdayFirstYear,
|
||||||
configuration.RangeDaysDeltaTolerance,
|
configuration.PersonBirthdayFormat,
|
||||||
configuration.RangeDistanceTolerance,
|
configuration.PersonCharacters.ToArray(),
|
||||||
configuration.ReMap,
|
configuration.RangeDaysDeltaTolerance,
|
||||||
configuration.SaveIndividually,
|
configuration.RangeDistanceTolerance,
|
||||||
configuration.SaveSortingWithoutPerson,
|
configuration.ReMap,
|
||||||
configuration.SkipNotSkipDirectories,
|
configuration.SaveIndividually,
|
||||||
configuration.SortingMaximumPerKey,
|
configuration.SaveSortingWithoutPerson,
|
||||||
configuration.SortingMinimumToUseSigma,
|
configuration.SkipNotSkipDirectories,
|
||||||
facesFileNameExtension,
|
configuration.SortingMaximumPerKey,
|
||||||
facesHiddenFileNameExtension,
|
configuration.SortingMinimumToUseSigma,
|
||||||
facePartsFileNameExtension);
|
facesFileNameExtension,
|
||||||
|
facesHiddenFileNameExtension,
|
||||||
|
facePartsFileNameExtension);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
private (Mapping, int) GetMappingAndUpdateMappingFromPerson(MapLogic mapLogic, Item item, bool? isFocusRelativePath, MappingFromItem mappingFromItem)
|
private (Mapping, int) GetMappingAndUpdateMappingFromPerson(MapLogic mapLogic, Item item, bool? isFocusRelativePath, MappingFromItem mappingFromItem)
|
||||||
{
|
{
|
||||||
Mapping result;
|
Mapping result;
|
||||||
bool? canReMap;
|
|
||||||
int? eyeα = null;
|
int? eyeα = null;
|
||||||
bool? isFocusPerson;
|
|
||||||
bool? eyeReview = null;
|
bool? eyeReview = null;
|
||||||
bool? inSkipCollection;
|
|
||||||
int confidencePercent = 0;
|
int confidencePercent = 0;
|
||||||
int faceAreaPermyriad = 0;
|
int faceAreaPermyriad = 0;
|
||||||
int wholePercentRectangle;
|
|
||||||
string deterministicHashCodeKey;
|
|
||||||
MappingFromLocation? mappingFromLocation;
|
|
||||||
MappingFromFilterPre mappingFromFilterPre;
|
|
||||||
MappingFromFilterPost mappingFromFilterPost;
|
|
||||||
bool? isFocusModel = GetIsFocusModel(item.Property);
|
bool? isFocusModel = GetIsFocusModel(item.Property);
|
||||||
long[] jLinkResolvedPersonKeys = _JLinkResolvedDirectories.Select(l => l.PersonKey).ToArray();
|
long[] jLinkResolvedPersonKeys = _JLinkResolvedDirectories.Select(l => l.PersonKey).ToArray();
|
||||||
ReadOnlyDictionary<int, ReadOnlyCollection<PersonContainer>>? wholePercentagesToPersonContainers = mapLogic.GetWholePercentagesToPersonContainers(item.Property?.Id);
|
ReadOnlyDictionary<int, ReadOnlyCollection<PersonContainer>>? wholePercentagesToPersonContainers = mapLogic.GetWholePercentagesToPersonContainers(mappingFromItem.Id);
|
||||||
if (item.Property?.Id is null)
|
int wholePercentRectangle = Shared.Models.Stateless.Methods.ILocation.GetWholePercentages(Shared.Models.Stateless.ILocation.Digits);
|
||||||
{
|
string deterministicHashCodeKey = IMapping.GetDeterministicHashCodeKey(item.FilePath, Shared.Models.Stateless.ILocation.Digits);
|
||||||
canReMap = null;
|
MappingFromLocation? mappingFromLocation = new(faceAreaPermyriad, confidencePercent, deterministicHashCodeKey, eyeα, eyeReview, wholePercentRectangle);
|
||||||
isFocusPerson = null;
|
bool? inSkipCollection = mapLogic.InSkipCollection(mappingFromItem.Id, mappingFromLocation);
|
||||||
inSkipCollection = null;
|
MappingFromFilterPre mappingFromFilterPre = new(inSkipCollection, isFocusModel, isFocusRelativePath);
|
||||||
mappingFromLocation = null;
|
bool? canReMap = Map.Models.Stateless.Methods.IMapLogic.CanReMap(jLinkResolvedPersonKeys, wholePercentagesToPersonContainers, mappingFromLocation);
|
||||||
mappingFromFilterPost = new(canReMap, inSkipCollection, isFocusPerson);
|
bool? isFocusPerson = mapLogic.IsFocusPerson(_Configuration.SkipPersonWithMoreThen, jLinkResolvedPersonKeys, wholePercentagesToPersonContainers, mappingFromLocation);
|
||||||
mappingFromFilterPre = new(inSkipCollection, isFocusModel, isFocusRelativePath);
|
MappingFromFilterPost mappingFromFilterPost = new(canReMap, inSkipCollection, isFocusPerson);
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
wholePercentRectangle = Shared.Models.Stateless.Methods.ILocation.GetWholePercentages(Shared.Models.Stateless.ILocation.Digits);
|
|
||||||
deterministicHashCodeKey = IMapping.GetDeterministicHashCodeKey(item.FilePath, Shared.Models.Stateless.ILocation.Digits);
|
|
||||||
mappingFromLocation = new(faceAreaPermyriad, confidencePercent, deterministicHashCodeKey, eyeα, eyeReview, wholePercentRectangle);
|
|
||||||
inSkipCollection = mapLogic.InSkipCollection(item.Property.Id.Value, mappingFromLocation);
|
|
||||||
mappingFromFilterPre = new(inSkipCollection, isFocusModel, isFocusRelativePath);
|
|
||||||
canReMap = Map.Models.Stateless.Methods.IMapLogic.CanReMap(jLinkResolvedPersonKeys, wholePercentagesToPersonContainers, mappingFromLocation);
|
|
||||||
isFocusPerson = mapLogic.IsFocusPerson(_Configuration.SkipPersonWithMoreThen, jLinkResolvedPersonKeys, wholePercentagesToPersonContainers, mappingFromLocation);
|
|
||||||
mappingFromFilterPost = new(canReMap, inSkipCollection, isFocusPerson);
|
|
||||||
}
|
|
||||||
result = new(item.FilePath, mappingFromFilterPost, mappingFromFilterPre, mappingFromItem, mappingFromLocation, mappingFromPhotoPrismCollection: null);
|
result = new(item.FilePath, mappingFromFilterPost, mappingFromFilterPre, mappingFromItem, mappingFromLocation, mappingFromPhotoPrismCollection: null);
|
||||||
int notMapped = mapLogic.UpdateMappingFromPerson(wholePercentagesToPersonContainers, result);
|
int notMapped = mapLogic.UpdateMappingFromPerson(wholePercentagesToPersonContainers, result);
|
||||||
return (result, notMapped);
|
return (result, notMapped);
|
||||||
@ -951,7 +1077,6 @@ public partial class DlibDotNet
|
|||||||
string[] changesFrom = [nameof(A_Property)];
|
string[] changesFrom = [nameof(A_Property)];
|
||||||
List<Tuple<string, DateTime>> subFileTuples = [];
|
List<Tuple<string, DateTime>> subFileTuples = [];
|
||||||
FileHolder resizedFileHolder = _Resize.GetResizedFileHolder(cResultsFullGroupDirectory, item, outputResolutionHasNumber);
|
FileHolder resizedFileHolder = _Resize.GetResizedFileHolder(cResultsFullGroupDirectory, item, outputResolutionHasNumber);
|
||||||
ReadOnlyCollection<LocationContainer> locationContainers = mapLogic.GetLocationContainers(item);
|
|
||||||
if (item.Property is null || item.Property.Id is null || !item.SourceDirectoryFileHolder.Exists || item.SourceDirectoryFileHolder.CreationTime is null || item.SourceDirectoryFileHolder.LastWriteTime is null || item.Any())
|
if (item.Property is null || item.Property.Id is null || !item.SourceDirectoryFileHolder.Exists || item.SourceDirectoryFileHolder.CreationTime is null || item.SourceDirectoryFileHolder.LastWriteTime is null || item.Any())
|
||||||
{
|
{
|
||||||
LogItemPropertyIsNull(item);
|
LogItemPropertyIsNull(item);
|
||||||
@ -981,7 +1106,6 @@ public partial class DlibDotNet
|
|||||||
subFileTuples.Add(new Tuple<string, DateTime>(nameof(A_Property), item.SourceDirectoryFileHolder.LastWriteTime.Value));
|
subFileTuples.Add(new Tuple<string, DateTime>(nameof(A_Property), item.SourceDirectoryFileHolder.LastWriteTime.Value));
|
||||||
else
|
else
|
||||||
subFileTuples.Add(new Tuple<string, DateTime>(nameof(A_Property), new FileInfo(item.SourceDirectoryFileHolder.FullName).LastWriteTime));
|
subFileTuples.Add(new Tuple<string, DateTime>(nameof(A_Property), new FileInfo(item.SourceDirectoryFileHolder.FullName).LastWriteTime));
|
||||||
FilePath filePath = FilePath.Get(_Configuration.PropertyConfiguration, item.ImageFileHolder, index: null);
|
|
||||||
if (resizedFileHolder.Exists && item.Property.Width is not null && item.Property.Width.Value > 4 && _Configuration.SaveBlurHashForOutputResolutions.Contains(outputResolution))
|
if (resizedFileHolder.Exists && item.Property.Width is not null && item.Property.Width.Value > 4 && _Configuration.SaveBlurHashForOutputResolutions.Contains(outputResolution))
|
||||||
{
|
{
|
||||||
string? file = _BlurHasher.GetFile(item.FilePath);
|
string? file = _BlurHasher.GetFile(item.FilePath);
|
||||||
@ -994,7 +1118,6 @@ public partial class DlibDotNet
|
|||||||
item.SetResizedFileHolder(_Resize.FileNameExtension, resizedFileHolder);
|
item.SetResizedFileHolder(_Resize.FileNameExtension, resizedFileHolder);
|
||||||
MappingFromItem mappingFromItem = IMappingFromItem.GetMappingFromItem(containerDateTimes, item, resizedFileHolder);
|
MappingFromItem mappingFromItem = IMappingFromItem.GetMappingFromItem(containerDateTimes, item, resizedFileHolder);
|
||||||
ExifDirectory exifDirectory = metadata.GetMetadataCollection(item.FilePath, subFileTuples, parseExceptions, changesFrom, mappingFromItem);
|
ExifDirectory exifDirectory = metadata.GetMetadataCollection(item.FilePath, subFileTuples, parseExceptions, changesFrom, mappingFromItem);
|
||||||
Map.Models.Stateless.Methods.IMapLogic.SetCreationTimeMaybeMoveToDecade(_Configuration.PropertyConfiguration, _Configuration.MoveToDecade && _Configuration.LocationContainerDistanceTolerance is null, mappingFromItem, locationContainers);
|
|
||||||
if (_AppSettings.Places.Count > 0)
|
if (_AppSettings.Places.Count > 0)
|
||||||
{
|
{
|
||||||
float latitude;
|
float latitude;
|
||||||
@ -1029,15 +1152,23 @@ public partial class DlibDotNet
|
|||||||
List<MappingFromPhotoPrism>? mappingFromPhotoPrismCollection;
|
List<MappingFromPhotoPrism>? mappingFromPhotoPrismCollection;
|
||||||
if (!fileNameToCollection.TryGetValue(mappingFromItem.Id, out mappingFromPhotoPrismCollection))
|
if (!fileNameToCollection.TryGetValue(mappingFromItem.Id, out mappingFromPhotoPrismCollection))
|
||||||
mappingFromPhotoPrismCollection = null;
|
mappingFromPhotoPrismCollection = null;
|
||||||
faces = _Faces.GetFaces(outputResolution, dResultsFullGroupDirectory, item.FilePath, subFileTuples, parseExceptions, property, mappingFromItem, outputResolutionToResize, locationContainers, mappingFromPhotoPrismCollection);
|
bool move = _Configuration.DistanceMoveUnableToMatch || _Configuration.DistanceRenameToMatch && _Configuration.LoadOrCreateThenSaveDistanceResultsForOutputResolutions.Contains(outputResolution);
|
||||||
result = GetNotMappedCountAndUpdateMappingFromPersonThenSetMapping(mapLogic, item, isFocusRelativePath, locationContainers, mappingFromItem, mappingFromPhotoPrismCollection, faces);
|
faces = _Faces.GetFaces(outputResolution, dResultsFullGroupDirectory, item.FilePath, subFileTuples, parseExceptions, property, mappingFromItem, outputResolutionToResize, mappingFromPhotoPrismCollection);
|
||||||
List<(Shared.Models.Face, FileInfo?, string, bool Saved)> faceCollection = _Faces.SaveFaces(_FaceParts.FileNameExtension, dResultsFullGroupDirectory, item.FilePath, subFileTuples, parseExceptions, mappingFromItem, faces);
|
result = GetNotMappedCountAndUpdateMappingFromPersonThenSetMapping(mapLogic, item, isFocusRelativePath, mappingFromItem, mappingFromPhotoPrismCollection, faces);
|
||||||
|
List<(Shared.Models.Face, FileHolder?, string, bool Saved)> faceCollection = _Faces.SaveFaces(_FaceParts.FileNameExtension, dResultsFullGroupDirectory, item.FilePath, subFileTuples, parseExceptions, mappingFromItem, exifDirectory, faces);
|
||||||
if (_Configuration.CopyFacesAndSaveFaceLandmarkForOutputResolutions.Contains(outputResolution))
|
if (_Configuration.CopyFacesAndSaveFaceLandmarkForOutputResolutions.Contains(outputResolution))
|
||||||
_FaceParts.CopyFacesAndSaveFaceLandmarkImage(facePartsCollectionDirectory, mappingFromItem, faceCollection);
|
_FaceParts.CopyFacesAndSaveFaceLandmarkImage(facePartsCollectionDirectory, mappingFromItem, faceCollection);
|
||||||
if ((_Configuration.DistanceMoveUnableToMatch || _Configuration.DistanceRenameToMatch)
|
if (move && faceCollection.All(l => !l.Saved))
|
||||||
&& _Configuration.LoadOrCreateThenSaveDistanceResultsForOutputResolutions.Contains(outputResolution)
|
{
|
||||||
&& locationContainers is not null && faceCollection.All(l => !l.Saved))
|
ReadOnlyCollection<LocationContainer> locationContainers = mapLogic.GetLocationContainers(item);
|
||||||
_Distance.LookForMatchFacesAndPossiblyRename(_Faces.FileNameExtension, item.FilePath, mappingFromItem, faces, locationContainers);
|
if (locationContainers.Count > 0)
|
||||||
|
{
|
||||||
|
Map.Models.Stateless.Methods.IMapLogic.SetCreationTime(mappingFromItem, locationContainers);
|
||||||
|
if (_Configuration.LocationContainerDistanceTolerance is null && _Configuration.MoveToDecade)
|
||||||
|
Map.Models.Stateless.Methods.IMapLogic.MoveToDecade(_Configuration.PropertyConfiguration, mappingFromItem, locationContainers);
|
||||||
|
_Distance.LookForMatchFacesAndPossiblyRename(_Configuration.OverrideForFaceImages, _DistanceLimits, _Faces, item.FilePath, mappingFromItem, exifDirectory, faces, locationContainers);
|
||||||
|
}
|
||||||
|
}
|
||||||
(bool review, int[] eyesCollection) = Shared.Models.Stateless.Methods.IFace.GetEyeCollection(_Configuration.EyeThreshold, faces);
|
(bool review, int[] eyesCollection) = Shared.Models.Stateless.Methods.IFace.GetEyeCollection(_Configuration.EyeThreshold, faces);
|
||||||
if (review || _Configuration.SaveFaceLandmarkForOutputResolutions.Contains(outputResolution))
|
if (review || _Configuration.SaveFaceLandmarkForOutputResolutions.Contains(outputResolution))
|
||||||
{
|
{
|
||||||
@ -1066,7 +1197,7 @@ public partial class DlibDotNet
|
|||||||
List<Tuple<string, DateTime>> sourceDirectoryChanges,
|
List<Tuple<string, DateTime>> sourceDirectoryChanges,
|
||||||
Dictionary<int, List<MappingFromPhotoPrism>> fileNameToCollection,
|
Dictionary<int, List<MappingFromPhotoPrism>> fileNameToCollection,
|
||||||
Container container,
|
Container container,
|
||||||
Item[] filteredItems,
|
ReadOnlyCollection<Item> filteredItems,
|
||||||
string message)
|
string message)
|
||||||
{
|
{
|
||||||
int result = 0;
|
int result = 0;
|
||||||
@ -1078,8 +1209,8 @@ public partial class DlibDotNet
|
|||||||
bool? isFocusRelativePath = string.IsNullOrEmpty(_Configuration.FocusDirectory) ? null : container.SourceDirectory.StartsWith(focusRelativePath);
|
bool? isFocusRelativePath = string.IsNullOrEmpty(_Configuration.FocusDirectory) ? null : container.SourceDirectory.StartsWith(focusRelativePath);
|
||||||
string facePartsCollectionDirectory = _Configuration.CopyFacesAndSaveFaceLandmarkForOutputResolutions.Contains(outputResolution) ? _FaceParts.GetFacePartsDirectory(_Configuration.PropertyConfiguration, d2ResultsFullGroupDirectory, item: filteredItems.First(), includeNameWithoutExtension: false) : string.Empty;
|
string facePartsCollectionDirectory = _Configuration.CopyFacesAndSaveFaceLandmarkForOutputResolutions.Contains(outputResolution) ? _FaceParts.GetFacePartsDirectory(_Configuration.PropertyConfiguration, d2ResultsFullGroupDirectory, item: filteredItems.First(), includeNameWithoutExtension: false) : string.Empty;
|
||||||
bool anyPropertiesChangedForX = _Configuration.PropertyConfiguration.PropertiesChangedForProperty || _Configuration.PropertiesChangedForDistance || _Configuration.PropertiesChangedForFaces || _Configuration.PropertiesChangedForIndex || _Configuration.PropertiesChangedForMetadata || _Configuration.PropertiesChangedForResize;
|
bool anyPropertiesChangedForX = _Configuration.PropertyConfiguration.PropertiesChangedForProperty || _Configuration.PropertiesChangedForDistance || _Configuration.PropertiesChangedForFaces || _Configuration.PropertiesChangedForIndex || _Configuration.PropertiesChangedForMetadata || _Configuration.PropertiesChangedForResize;
|
||||||
using ProgressBar progressBar = new(filteredItems.Length, message, options);
|
using ProgressBar progressBar = new(filteredItems.Count, message, options);
|
||||||
_ = Parallel.For(0, filteredItems.Length, parallelOptions, (i, state) =>
|
_ = Parallel.For(0, filteredItems.Count, parallelOptions, (i, state) =>
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@ -1105,7 +1236,7 @@ public partial class DlibDotNet
|
|||||||
catch (Exception)
|
catch (Exception)
|
||||||
{
|
{
|
||||||
exceptionsCount++;
|
exceptionsCount++;
|
||||||
if (exceptionsCount == filteredItems.Length)
|
if (exceptionsCount == filteredItems.Count)
|
||||||
throw new Exception(string.Concat("All in [", container.SourceDirectory, "] failed!"));
|
throw new Exception(string.Concat("All in [", container.SourceDirectory, "] failed!"));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -1200,18 +1331,17 @@ public partial class DlibDotNet
|
|||||||
if (filteredFaceDistanceContainers.Length > 0)
|
if (filteredFaceDistanceContainers.Length > 0)
|
||||||
{
|
{
|
||||||
int updated = sortingContainers.Count == 0 ? 0 : mapLogic.UpdateFromSortingContainers(dFacesContentDirectory, d2FacePartsContentDirectory, d2FacePartsContentCollectionDirectory, idToWholePercentagesToMapping, sortingContainers);
|
int updated = sortingContainers.Count == 0 ? 0 : mapLogic.UpdateFromSortingContainers(dFacesContentDirectory, d2FacePartsContentDirectory, d2FacePartsContentCollectionDirectory, idToWholePercentagesToMapping, sortingContainers);
|
||||||
List<SaveContainer> saveContainers;
|
List<SaveContainer> saveContainers = mapLogic.GetSaveContainers(dFacesContentDirectory, d2FacePartsContentDirectory, d2FacePartsContentCollectionDirectory, idToWholePercentagesToMapping, distanceLimits, useFiltersCounter, sortingContainers);
|
||||||
saveContainers = mapLogic.GetSaveContainers(dFacesContentDirectory, d2FacePartsContentDirectory, d2FacePartsContentCollectionDirectory, idToWholePercentagesToMapping, distanceLimits, useFiltersCounter, sortingContainers);
|
|
||||||
if (saveContainers.Count > 0)
|
if (saveContainers.Count > 0)
|
||||||
mapLogic.SaveContainers(updated, saveContainers);
|
mapLogic.SaveContainers(updated, saveContainers);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void SaveFaceDistances(long ticks, MapLogic mapLogic, ReadOnlyCollection<Shared.Models.Face> distinctFilteredFaces, string dFacesContentDirectory, string d2FacePartsContentDirectory, string d2FacePartsContentCollectionDirectory, ReadOnlyDictionary<int, ReadOnlyDictionary<int, Mapping>> idToWholePercentagesToMapping)
|
private void SaveFaceDistances(long ticks, MapLogic mapLogic, ReadOnlyCollection<Shared.Models.Face> distinctValidImageFaces, string dFacesContentDirectory, string d2FacePartsContentDirectory, string d2FacePartsContentCollectionDirectory, ReadOnlyDictionary<int, ReadOnlyDictionary<int, Mapping>> idToWholePercentagesToMapping)
|
||||||
{
|
{
|
||||||
E_Distance.PreFilterSetFaceDistances(_AppSettings.MaxDegreeOfParallelism, ticks, distinctFilteredFaces);
|
E_Distance.PreFilterSetFaceDistances(_AppSettings.MaxDegreeOfParallelism, _MapConfiguration, ticks, distinctValidImageFaces);
|
||||||
ReadOnlyCollection<FaceDistanceContainer> faceDistanceContainers = E_Distance.GetFaceDistanceContainers(distinctFilteredFaces);
|
ReadOnlyCollection<FaceDistanceContainer> faceDistanceContainers = E_Distance.GetFaceDistanceContainers(distinctValidImageFaces);
|
||||||
if (faceDistanceContainers.Count > 0)
|
if (faceDistanceContainers.Count > 0)
|
||||||
{
|
{
|
||||||
List<FaceDistance> faceDistanceEncodings = [];
|
List<FaceDistance> faceDistanceEncodings = [];
|
||||||
|
@ -19,6 +19,23 @@ public class AppSettings
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void PreVerify(IConfigurationRoot configurationRoot, AppSettings? appSettings)
|
||||||
|
{
|
||||||
|
if (appSettings?.Company is null)
|
||||||
|
{
|
||||||
|
List<string> paths = [];
|
||||||
|
foreach (IConfigurationProvider configurationProvider in configurationRoot.Providers)
|
||||||
|
{
|
||||||
|
if (configurationProvider is not Microsoft.Extensions.Configuration.Json.JsonConfigurationProvider jsonConfigurationProvider)
|
||||||
|
continue;
|
||||||
|
if (jsonConfigurationProvider.Source.FileProvider is not Microsoft.Extensions.FileProviders.PhysicalFileProvider physicalFileProvider)
|
||||||
|
continue;
|
||||||
|
paths.Add(physicalFileProvider.Root);
|
||||||
|
}
|
||||||
|
throw new NotSupportedException($"Not found!{Environment.NewLine}{string.Join(Environment.NewLine, paths.Distinct())}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private static Models.AppSettings Get(AppSettings? appSettings)
|
private static Models.AppSettings Get(AppSettings? appSettings)
|
||||||
{
|
{
|
||||||
Models.AppSettings result;
|
Models.AppSettings result;
|
||||||
@ -42,6 +59,7 @@ public class AppSettings
|
|||||||
#pragma warning disable IL3050, IL2026
|
#pragma warning disable IL3050, IL2026
|
||||||
AppSettings? appSettings = configurationRoot.Get<AppSettings>();
|
AppSettings? appSettings = configurationRoot.Get<AppSettings>();
|
||||||
#pragma warning restore IL3050, IL2026
|
#pragma warning restore IL3050, IL2026
|
||||||
|
PreVerify(configurationRoot, appSettings);
|
||||||
result = Get(appSettings);
|
result = Get(appSettings);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -27,8 +27,10 @@ public class Configuration
|
|||||||
public bool? ForceMetadataLastWriteTimeToCreationTime { get; set; }
|
public bool? ForceMetadataLastWriteTimeToCreationTime { get; set; }
|
||||||
public bool? ForceResizeLastWriteTimeToCreationTime { get; set; }
|
public bool? ForceResizeLastWriteTimeToCreationTime { get; set; }
|
||||||
public string? GenealogicalDataCommunicationFile { get; set; }
|
public string? GenealogicalDataCommunicationFile { get; set; }
|
||||||
|
public string? ImmichAssetsFile { get; set; }
|
||||||
public string[]? IgnoreExtensions { get; set; }
|
public string[]? IgnoreExtensions { get; set; }
|
||||||
public string[]? JLinks { get; set; }
|
public string[]? JLinks { get; set; }
|
||||||
|
public string? LinkedAlpha { get; set; }
|
||||||
public string[]? LoadOrCreateThenSaveDistanceResultsForOutputResolutions { get; set; }
|
public string[]? LoadOrCreateThenSaveDistanceResultsForOutputResolutions { get; set; }
|
||||||
public string[]? LoadOrCreateThenSaveImageFacesResultsForOutputResolutions { get; set; }
|
public string[]? LoadOrCreateThenSaveImageFacesResultsForOutputResolutions { get; set; }
|
||||||
public bool? LoadPhotoPrismLocations { get; set; }
|
public bool? LoadPhotoPrismLocations { get; set; }
|
||||||
@ -102,7 +104,22 @@ public class Configuration
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
#pragma warning restore csharp_preserve_single_line_statements
|
private static void PreVerify(IConfigurationRoot configurationRoot, Configuration? configuration)
|
||||||
|
{
|
||||||
|
if (configuration?.CheckDFaceAndUpWriteDates is null)
|
||||||
|
{
|
||||||
|
List<string> paths = [];
|
||||||
|
foreach (IConfigurationProvider configurationProvider in configurationRoot.Providers)
|
||||||
|
{
|
||||||
|
if (configurationProvider is not Microsoft.Extensions.Configuration.Json.JsonConfigurationProvider jsonConfigurationProvider)
|
||||||
|
continue;
|
||||||
|
if (jsonConfigurationProvider.Source.FileProvider is not Microsoft.Extensions.FileProviders.PhysicalFileProvider physicalFileProvider)
|
||||||
|
continue;
|
||||||
|
paths.Add(physicalFileProvider.Root);
|
||||||
|
}
|
||||||
|
throw new NotSupportedException($"Not found!{Environment.NewLine}{string.Join(Environment.NewLine, paths.Distinct())}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private static Models.Configuration Get(Configuration? configuration, Property.Models.Configuration propertyConfiguration)
|
private static Models.Configuration Get(Configuration? configuration, Property.Models.Configuration propertyConfiguration)
|
||||||
{
|
{
|
||||||
@ -129,8 +146,10 @@ public class Configuration
|
|||||||
if (configuration?.ForceMetadataLastWriteTimeToCreationTime is null) throw new NullReferenceException(nameof(configuration.ForceMetadataLastWriteTimeToCreationTime));
|
if (configuration?.ForceMetadataLastWriteTimeToCreationTime is null) throw new NullReferenceException(nameof(configuration.ForceMetadataLastWriteTimeToCreationTime));
|
||||||
if (configuration?.ForceResizeLastWriteTimeToCreationTime is null) throw new NullReferenceException(nameof(configuration.ForceResizeLastWriteTimeToCreationTime));
|
if (configuration?.ForceResizeLastWriteTimeToCreationTime is null) throw new NullReferenceException(nameof(configuration.ForceResizeLastWriteTimeToCreationTime));
|
||||||
if (configuration?.GenealogicalDataCommunicationFile is null) throw new NullReferenceException(nameof(configuration.GenealogicalDataCommunicationFile));
|
if (configuration?.GenealogicalDataCommunicationFile is null) throw new NullReferenceException(nameof(configuration.GenealogicalDataCommunicationFile));
|
||||||
|
if (configuration?.ImmichAssetsFile is null) throw new NullReferenceException(nameof(configuration.ImmichAssetsFile));
|
||||||
// if (configuration?.IgnoreExtensions is null) throw new NullReferenceException(nameof(configuration.IgnoreExtensions));
|
// if (configuration?.IgnoreExtensions is null) throw new NullReferenceException(nameof(configuration.IgnoreExtensions));
|
||||||
// if (configuration?.JLinks is null) throw new NullReferenceException(nameof(configuration.JLinks));
|
// if (configuration?.JLinks is null) throw new NullReferenceException(nameof(configuration.JLinks));
|
||||||
|
// if (configuration?.LinkedAlpha is null) throw new NullReferenceException(nameof(configuration.LinkedAlpha));
|
||||||
// if (configuration?.LoadOrCreateThenSaveDistanceResultsForOutputResolutions is null) throw new NullReferenceException(nameof(configuration.LoadOrCreateThenSaveDistanceResultsForOutputResolutions));
|
// if (configuration?.LoadOrCreateThenSaveDistanceResultsForOutputResolutions is null) throw new NullReferenceException(nameof(configuration.LoadOrCreateThenSaveDistanceResultsForOutputResolutions));
|
||||||
// if (configuration?.LoadOrCreateThenSaveImageFacesResultsForOutputResolutions is null) throw new NullReferenceException(nameof(configuration.LoadOrCreateThenSaveImageFacesResultsForOutputResolutions));
|
// if (configuration?.LoadOrCreateThenSaveImageFacesResultsForOutputResolutions is null) throw new NullReferenceException(nameof(configuration.LoadOrCreateThenSaveImageFacesResultsForOutputResolutions));
|
||||||
if (configuration?.LoadPhotoPrismLocations is null) throw new NullReferenceException(nameof(configuration.LoadPhotoPrismLocations));
|
if (configuration?.LoadPhotoPrismLocations is null) throw new NullReferenceException(nameof(configuration.LoadPhotoPrismLocations));
|
||||||
@ -218,8 +237,10 @@ public class Configuration
|
|||||||
configuration.ForceMetadataLastWriteTimeToCreationTime.Value,
|
configuration.ForceMetadataLastWriteTimeToCreationTime.Value,
|
||||||
configuration.ForceResizeLastWriteTimeToCreationTime.Value,
|
configuration.ForceResizeLastWriteTimeToCreationTime.Value,
|
||||||
configuration.GenealogicalDataCommunicationFile,
|
configuration.GenealogicalDataCommunicationFile,
|
||||||
|
configuration.ImmichAssetsFile,
|
||||||
configuration.IgnoreExtensions ?? [],
|
configuration.IgnoreExtensions ?? [],
|
||||||
configuration.JLinks ?? [],
|
configuration.JLinks ?? [],
|
||||||
|
configuration.LinkedAlpha,
|
||||||
configuration.LoadOrCreateThenSaveDistanceResultsForOutputResolutions ?? [],
|
configuration.LoadOrCreateThenSaveDistanceResultsForOutputResolutions ?? [],
|
||||||
configuration.LoadOrCreateThenSaveImageFacesResultsForOutputResolutions ?? [],
|
configuration.LoadOrCreateThenSaveImageFacesResultsForOutputResolutions ?? [],
|
||||||
configuration.LoadPhotoPrismLocations.Value,
|
configuration.LoadPhotoPrismLocations.Value,
|
||||||
@ -294,14 +315,19 @@ public class Configuration
|
|||||||
Models.Configuration result;
|
Models.Configuration result;
|
||||||
Configuration? configuration;
|
Configuration? configuration;
|
||||||
if (isEnvironment is null)
|
if (isEnvironment is null)
|
||||||
|
#pragma warning disable IL3050, IL2026
|
||||||
configuration = configurationRoot.Get<Configuration>();
|
configuration = configurationRoot.Get<Configuration>();
|
||||||
|
#pragma warning restore IL3050, IL2026
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
string environmentName = IsEnvironment.GetEnvironmentName(isEnvironment);
|
string environmentName = IsEnvironment.GetEnvironmentName(isEnvironment);
|
||||||
string section = string.Concat(environmentName, ":", nameof(Configuration));
|
string section = string.Concat(environmentName, ":", nameof(Configuration));
|
||||||
IConfigurationSection configurationSection = configurationRoot.GetSection(section);
|
IConfigurationSection configurationSection = configurationRoot.GetSection(section);
|
||||||
|
#pragma warning disable IL3050, IL2026
|
||||||
configuration = configurationSection.Get<Configuration>();
|
configuration = configurationSection.Get<Configuration>();
|
||||||
|
#pragma warning restore IL3050, IL2026
|
||||||
}
|
}
|
||||||
|
PreVerify(configurationRoot, configuration);
|
||||||
result = Get(configuration, propertyConfiguration);
|
result = Get(configuration, propertyConfiguration);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -21,8 +21,10 @@ public record Configuration(Property.Models.Configuration PropertyConfiguration,
|
|||||||
bool ForceMetadataLastWriteTimeToCreationTime,
|
bool ForceMetadataLastWriteTimeToCreationTime,
|
||||||
bool ForceResizeLastWriteTimeToCreationTime,
|
bool ForceResizeLastWriteTimeToCreationTime,
|
||||||
string GenealogicalDataCommunicationFile,
|
string GenealogicalDataCommunicationFile,
|
||||||
|
string ImmichAssetsFile,
|
||||||
string[] IgnoreExtensions,
|
string[] IgnoreExtensions,
|
||||||
string[] JLinks,
|
string[] JLinks,
|
||||||
|
string? LinkedAlpha,
|
||||||
string[] LoadOrCreateThenSaveDistanceResultsForOutputResolutions,
|
string[] LoadOrCreateThenSaveDistanceResultsForOutputResolutions,
|
||||||
string[] LoadOrCreateThenSaveImageFacesResultsForOutputResolutions,
|
string[] LoadOrCreateThenSaveImageFacesResultsForOutputResolutions,
|
||||||
bool LoadPhotoPrismLocations,
|
bool LoadPhotoPrismLocations,
|
||||||
|
27
Instance/Models/Identifier.cs
Normal file
27
Instance/Models/Identifier.cs
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
using System.Text.Json;
|
||||||
|
using System.Text.Json.Serialization;
|
||||||
|
|
||||||
|
namespace View_by_Distance.Instance.Models;
|
||||||
|
|
||||||
|
internal record Identifier(int Id, string PaddedId)
|
||||||
|
{
|
||||||
|
|
||||||
|
public override string ToString()
|
||||||
|
{
|
||||||
|
string result = JsonSerializer.Serialize(this, IdentifierSourceGenerationContext.Default.Identifier);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
[JsonSourceGenerationOptions(WriteIndented = true)]
|
||||||
|
[JsonSerializable(typeof(Identifier))]
|
||||||
|
internal partial class IdentifierSourceGenerationContext : JsonSerializerContext
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
[JsonSourceGenerationOptions(WriteIndented = true)]
|
||||||
|
[JsonSerializable(typeof(Identifier[]))]
|
||||||
|
internal partial class IdentifierCollectionSourceGenerationContext : JsonSerializerContext
|
||||||
|
{
|
||||||
|
}
|
@ -1,5 +1,6 @@
|
|||||||
using System.Collections.ObjectModel;
|
using System.Collections.ObjectModel;
|
||||||
using System.Text.Json;
|
using System.Text.Json;
|
||||||
|
using View_by_Distance.Shared.Models;
|
||||||
|
|
||||||
namespace View_by_Distance.Instance.Models;
|
namespace View_by_Distance.Instance.Models;
|
||||||
|
|
||||||
@ -24,16 +25,18 @@ internal class F_Random
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static ReadOnlyDictionary<string, List<string>> GetDayToRelativePaths(ReadOnlyCollection<Shared.Models.Mapping> mappingCollection, string dateFormat, ReadOnlyDictionary<int, List<long>> idToPersonKeys)
|
private static ReadOnlyDictionary<string, List<string>> GetDayToRelativePaths(ReadOnlyCollection<Mapping> distinctValidImageMappingCollection, string dateFormat, Dictionary<string, ImmichAsset> immichAssets, ReadOnlyDictionary<int, List<long>> idToPersonKeys)
|
||||||
{
|
{
|
||||||
Dictionary<string, List<string>> results = [];
|
Dictionary<string, List<string>> results = [];
|
||||||
string key;
|
string key;
|
||||||
DateTime dateTime;
|
DateTime dateTime;
|
||||||
List<long>? personKeys;
|
List<long>? personKeys;
|
||||||
|
ImmichAsset? immichAsset;
|
||||||
List<string>? relativePaths;
|
List<string>? relativePaths;
|
||||||
foreach (Shared.Models.Mapping mapping in mappingCollection)
|
bool immichAssetsCountIsZero = immichAssets.Count == 0;
|
||||||
|
foreach (Mapping mapping in distinctValidImageMappingCollection)
|
||||||
{
|
{
|
||||||
if (mapping.MappingFromItem.ImageFileHolder.DirectoryName is null || mapping.MappingFromPerson is null)
|
if (mapping.MappingFromItem.FilePath.DirectoryName is null || mapping.MappingFromPerson is null)
|
||||||
continue;
|
continue;
|
||||||
if (!idToPersonKeys.TryGetValue(mapping.MappingFromItem.Id, out personKeys))
|
if (!idToPersonKeys.TryGetValue(mapping.MappingFromItem.Id, out personKeys))
|
||||||
continue;
|
continue;
|
||||||
@ -49,39 +52,72 @@ internal class F_Random
|
|||||||
if (!results.TryGetValue(key, out relativePaths))
|
if (!results.TryGetValue(key, out relativePaths))
|
||||||
throw new Exception();
|
throw new Exception();
|
||||||
}
|
}
|
||||||
relativePaths.Add(mapping.MappingFromItem.RelativePath);
|
if (immichAssetsCountIsZero)
|
||||||
|
relativePaths.Add(mapping.MappingFromItem.RelativePath);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (!immichAssets.TryGetValue(mapping.MappingFromItem.RelativePath, out immichAsset))
|
||||||
|
continue;
|
||||||
|
relativePaths.Add(immichAsset.PreviewPath);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return new(results);
|
return new(results);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void Random(Property.Models.Configuration configuration, int radomUseBirthdayMinimum, string[] validKeyWordsToIgnoreInRandom, string outputResolution, ReadOnlyDictionary<long, List<int>> personKeyToIds, ReadOnlyCollection<int>? notNineCollection, ReadOnlyCollection<Shared.Models.Mapping> mappingCollection)
|
private static Dictionary<string, ImmichAsset> GetImmichAssets(string immichAssetsFile)
|
||||||
|
{
|
||||||
|
Dictionary<string, ImmichAsset> results = [];
|
||||||
|
if (!string.IsNullOrEmpty(immichAssetsFile) && File.Exists(immichAssetsFile))
|
||||||
|
{
|
||||||
|
string json = File.ReadAllText(immichAssetsFile);
|
||||||
|
ImmichAsset[]? immichAssets = JsonSerializer.Deserialize(json, ImmichAssetCollectionSourceGenerationContext.Default.ImmichAssetArray);
|
||||||
|
if (immichAssets is not null)
|
||||||
|
{
|
||||||
|
foreach (ImmichAsset immichAsset in immichAssets)
|
||||||
|
results.Add(immichAsset.OriginalPath, immichAsset);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return results;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void Random(Property.Models.Configuration configuration, string immichAssetsFile, int radomUseBirthdayMinimum, string[] validKeyWordsToIgnoreInRandom, ReadOnlyDictionary<long, List<int>> personKeyToIds, ReadOnlyCollection<int>? notNineCollection, ReadOnlyCollection<Mapping> distinctValidImageMappingCollection)
|
||||||
{
|
{
|
||||||
string key;
|
string key;
|
||||||
string json;
|
string json;
|
||||||
string jsonFile;
|
string jsonFile;
|
||||||
Random random = new();
|
Random random = new();
|
||||||
List<string>? collection;
|
List<string>? collection;
|
||||||
|
ImmichAsset? immichAsset;
|
||||||
string dateFormat = "MM-dd";
|
string dateFormat = "MM-dd";
|
||||||
List<string> relativePaths = [];
|
List<string> relativePaths = [];
|
||||||
List<int> distinctCollection = [];
|
List<int> distinctCollection = [];
|
||||||
DateTime dateTime = new(2024, 1, 1); //Leap year
|
DateTime dateTime = new(2024, 1, 1); //Leap year
|
||||||
|
Dictionary<string, ImmichAsset> immichAssets = GetImmichAssets(immichAssetsFile);
|
||||||
ReadOnlyDictionary<int, List<long>> idToPersonKeys = Map.Models.Stateless.Methods.IMapLogic.GetIdToPersonKeys(personKeyToIds);
|
ReadOnlyDictionary<int, List<long>> idToPersonKeys = Map.Models.Stateless.Methods.IMapLogic.GetIdToPersonKeys(personKeyToIds);
|
||||||
ReadOnlyDictionary<string, List<string>> dayToRelativePaths = GetDayToRelativePaths(mappingCollection, dateFormat, idToPersonKeys);
|
ReadOnlyDictionary<string, List<string>> dayToRelativePaths = GetDayToRelativePaths(distinctValidImageMappingCollection, dateFormat, immichAssets, idToPersonKeys);
|
||||||
string fRandomCollectionDirectory = Property.Models.Stateless.IResult.GetResultsDateGroupDirectory(configuration, nameof(F_Random), "[]");
|
string fRandomCollectionDirectory = Property.Models.Stateless.IResult.GetResultsDateGroupDirectory(configuration, nameof(F_Random), "[]");
|
||||||
string[] files = Directory.GetFiles(fRandomCollectionDirectory, "*", SearchOption.TopDirectoryOnly);
|
string[] files = Directory.GetFiles(fRandomCollectionDirectory, "*", SearchOption.TopDirectoryOnly);
|
||||||
foreach (string file in files)
|
foreach (string file in files)
|
||||||
File.Delete(file);
|
File.Delete(file);
|
||||||
foreach (Shared.Models.Mapping mapping in mappingCollection)
|
bool immichAssetsCountIsZero = immichAssets.Count == 0;
|
||||||
|
foreach (Mapping mapping in distinctValidImageMappingCollection)
|
||||||
{
|
{
|
||||||
if (distinctCollection.Contains(mapping.MappingFromItem.Id))
|
if (distinctCollection.Contains(mapping.MappingFromItem.Id))
|
||||||
continue;
|
continue;
|
||||||
if (mapping.MappingFromItem.ImageFileHolder.DirectoryName is null)
|
if (mapping.MappingFromItem.FilePath.DirectoryName is null)
|
||||||
continue;
|
continue;
|
||||||
if (notNineCollection is not null && notNineCollection.Contains(mapping.MappingFromItem.Id))
|
if (notNineCollection is not null && notNineCollection.Contains(mapping.MappingFromItem.Id))
|
||||||
continue;
|
continue;
|
||||||
if (mapping.MappingFromItem.Keywords is not null && mapping.MappingFromItem.Keywords.Any(l => validKeyWordsToIgnoreInRandom.Contains(l)))
|
if (mapping.MappingFromItem.Keywords is not null && mapping.MappingFromItem.Keywords.Any(l => validKeyWordsToIgnoreInRandom.Contains(l)))
|
||||||
continue;
|
continue;
|
||||||
relativePaths.Add(mapping.MappingFromItem.RelativePath);
|
if (immichAssetsCountIsZero)
|
||||||
|
relativePaths.Add(mapping.MappingFromItem.RelativePath);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (!immichAssets.TryGetValue(mapping.MappingFromItem.RelativePath, out immichAsset))
|
||||||
|
continue;
|
||||||
|
relativePaths.Add(immichAsset.PreviewPath);
|
||||||
|
}
|
||||||
distinctCollection.Add(mapping.MappingFromItem.Id);
|
distinctCollection.Add(mapping.MappingFromItem.Id);
|
||||||
}
|
}
|
||||||
if (relativePaths.Count > 0)
|
if (relativePaths.Count > 0)
|
||||||
|
1
Map/.vscode/format-report.json
vendored
Normal file
1
Map/.vscode/format-report.json
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
[]
|
42
Map/.vscode/tasks.json
vendored
Normal file
42
Map/.vscode/tasks.json
vendored
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
{
|
||||||
|
"version": "2.0.0",
|
||||||
|
"tasks": [
|
||||||
|
{
|
||||||
|
"label": "Format",
|
||||||
|
"command": "dotnet",
|
||||||
|
"type": "process",
|
||||||
|
"args": [
|
||||||
|
"format",
|
||||||
|
"--report",
|
||||||
|
".vscode",
|
||||||
|
"--verbosity",
|
||||||
|
"detailed",
|
||||||
|
"--severity",
|
||||||
|
"warn"
|
||||||
|
],
|
||||||
|
"problemMatcher": "$msCompile"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": "Format-Whitespaces",
|
||||||
|
"command": "dotnet",
|
||||||
|
"type": "process",
|
||||||
|
"args": [
|
||||||
|
"format",
|
||||||
|
"whitespace"
|
||||||
|
],
|
||||||
|
"problemMatcher": "$msCompile"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": "build",
|
||||||
|
"command": "dotnet",
|
||||||
|
"type": "process",
|
||||||
|
"args": [
|
||||||
|
"build",
|
||||||
|
"${workspaceFolder}/Map.csproj",
|
||||||
|
"/property:GenerateFullPaths=true",
|
||||||
|
"/consoleloggerparameters:NoSummary"
|
||||||
|
],
|
||||||
|
"problemMatcher": "$msCompile"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
@ -1,10 +1,13 @@
|
|||||||
namespace View_by_Distance.Map.Models;
|
namespace View_by_Distance.Map.Models;
|
||||||
|
|
||||||
public record Configuration(bool DeletePossibleDuplicates,
|
public record Configuration(Shared.Models.Methods.IDistanceLimits DistanceLimits,
|
||||||
|
Shared.Models.Properties.IPropertyConfiguration PropertyConfiguration,
|
||||||
|
bool DeletePossibleDuplicates,
|
||||||
bool DistanceMoveUnableToMatch,
|
bool DistanceMoveUnableToMatch,
|
||||||
bool DistanceRenameToMatch,
|
bool DistanceRenameToMatch,
|
||||||
int FaceConfidencePercent,
|
int FaceConfidencePercent,
|
||||||
int FaceDistancePermyriad,
|
int FaceDistancePermyriad,
|
||||||
|
string? LinkedAlpha,
|
||||||
string LocationContainerDebugDirectory,
|
string LocationContainerDebugDirectory,
|
||||||
string LocationContainerDirectoryPattern,
|
string LocationContainerDirectoryPattern,
|
||||||
int LocationContainerDistanceGroupMinimum,
|
int LocationContainerDistanceGroupMinimum,
|
||||||
|
@ -23,6 +23,14 @@ public partial class MapLogic : Shared.Models.Methods.IMapLogic
|
|||||||
long? Ticks,
|
long? Ticks,
|
||||||
string? PersonDirectory);
|
string? PersonDirectory);
|
||||||
|
|
||||||
|
internal record FilteredOriginalImage(int Id,
|
||||||
|
FilePath FilePath,
|
||||||
|
int ApproximateYears,
|
||||||
|
string PersonKeyFormatted,
|
||||||
|
string Directory,
|
||||||
|
string PersonDirectory,
|
||||||
|
string CheckFile);
|
||||||
|
|
||||||
public void SaveContainers(int? updated, List<SaveContainer> saveContainers)
|
public void SaveContainers(int? updated, List<SaveContainer> saveContainers)
|
||||||
{
|
{
|
||||||
if (_Configuration is null)
|
if (_Configuration is null)
|
||||||
@ -137,7 +145,7 @@ public partial class MapLogic : Shared.Models.Methods.IMapLogic
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<SaveShortcutsForOutputResolutions> GetCollectionForSaveShortcutsForOutputResolutionsPreMapLogic(string eDistanceContentDirectory, ReadOnlyDictionary<long, List<int>> personKeyToIds, ReadOnlyCollection<Mapping> mappingCollection)
|
private List<SaveShortcutsForOutputResolutions> GetCollectionForSaveShortcutsForOutputResolutionsPreMapLogic(string eDistanceContentDirectory, ReadOnlyDictionary<long, List<int>> personKeyToIds, ReadOnlyCollection<Mapping> distinctValidImageMappingCollection)
|
||||||
{
|
{
|
||||||
List<SaveShortcutsForOutputResolutions> results = [];
|
List<SaveShortcutsForOutputResolutions> results = [];
|
||||||
if (_Configuration is null)
|
if (_Configuration is null)
|
||||||
@ -153,24 +161,24 @@ public partial class MapLogic : Shared.Models.Methods.IMapLogic
|
|||||||
string personKeyFormatted;
|
string personKeyFormatted;
|
||||||
Calendar calendar = new CultureInfo("en-US").Calendar;
|
Calendar calendar = new CultureInfo("en-US").Calendar;
|
||||||
ReadOnlyDictionary<int, List<long>> idToPersonKeys = IMapLogic.GetIdToPersonKeys(personKeyToIds);
|
ReadOnlyDictionary<int, List<long>> idToPersonKeys = IMapLogic.GetIdToPersonKeys(personKeyToIds);
|
||||||
foreach (Mapping mapping in mappingCollection)
|
foreach (Mapping mapping in distinctValidImageMappingCollection)
|
||||||
{
|
{
|
||||||
dateTime = mapping.MappingFromItem.GetDateTimeOriginalThenMinimumDateTime();
|
dateTime = mapping.MappingFromItem.GetDateTimeOriginalThenMinimumDateTime();
|
||||||
description = mapping.MappingFromLocation is null ? mapping.MappingFromItem.Id.ToString() : mapping.MappingFromLocation.DeterministicHashCodeKey;
|
description = mapping.MappingFromLocation is null ? mapping.MappingFromItem.Id.ToString() : mapping.MappingFromLocation.DeterministicHashCodeKey;
|
||||||
(season, _) = IProperty.GetSeason(dateTime.DayOfYear);
|
(season, _) = IProperty.GetSeason(dateTime.DayOfYear);
|
||||||
weekOfYear = calendar.GetWeekOfYear(dateTime, CalendarWeekRule.FirstDay, DayOfWeek.Sunday).ToString("00");
|
weekOfYear = calendar.GetWeekOfYear(dateTime, CalendarWeekRule.FirstDay, DayOfWeek.Sunday).ToString("00");
|
||||||
directory = Path.Combine($"{eDistanceContentDirectory}---", "Date Shortcuts", $"{dateTime.Year}.{season}-MM{dateTime.Month:00}-WW{weekOfYear}");
|
directory = Path.Combine($"{eDistanceContentDirectory}---", "Date Shortcuts", $"{dateTime.Year}.{season}-MM{dateTime.Month:00}-WW{weekOfYear}");
|
||||||
fileName = Path.Combine(directory, $"{mapping.MappingFromItem.ImageFileHolder.Name}.lnk");
|
fileName = Path.Combine(directory, $"{mapping.MappingFromItem.FilePath.Name}.lnk");
|
||||||
results.Add(new(mapping.MappingFromItem.ImageFileHolder.FullName, directory, dateTime, fileName, description, MakeAllHidden: false));
|
results.Add(new(mapping.MappingFromItem.FilePath.FullName, directory, dateTime, fileName, description, MakeAllHidden: false));
|
||||||
if (mapping.MappingFromItem.ImageFileHolder.DirectoryName is null)
|
if (mapping.MappingFromItem.FilePath.DirectoryName is null)
|
||||||
continue;
|
continue;
|
||||||
directoryName = Path.GetFileName(mapping.MappingFromItem.ImageFileHolder.DirectoryName);
|
directoryName = Path.GetFileName(mapping.MappingFromItem.FilePath.DirectoryName);
|
||||||
if (!string.IsNullOrEmpty(mapping.MappingFromItem.Model) && !string.IsNullOrEmpty(mapping.MappingFromItem.Model.Trim()))
|
if (!string.IsNullOrEmpty(mapping.MappingFromItem.Model) && !string.IsNullOrEmpty(mapping.MappingFromItem.Model.Trim()))
|
||||||
{
|
{
|
||||||
// Remove-Item -LiteralPath "\\?\D:\Tmp\a\EX-Z70 "
|
// Remove-Item -LiteralPath "\\?\D:\Tmp\a\EX-Z70 "
|
||||||
directory = Path.Combine($"{eDistanceContentDirectory}---", "Model Shortcuts", FileSystemSafe().Replace(mapping.MappingFromItem.Model.Trim(), "_"), directoryName);
|
directory = Path.Combine($"{eDistanceContentDirectory}---", "Model Shortcuts", FileSystemSafe().Replace(mapping.MappingFromItem.Model.Trim(), "_"), directoryName);
|
||||||
fileName = Path.Combine(directory, $"{mapping.MappingFromItem.ImageFileHolder.Name}.lnk");
|
fileName = Path.Combine(directory, $"{mapping.MappingFromItem.FilePath.Name}.lnk");
|
||||||
results.Add(new(mapping.MappingFromItem.ImageFileHolder.FullName, directory, dateTime, fileName, description, MakeAllHidden: false));
|
results.Add(new(mapping.MappingFromItem.FilePath.FullName, directory, dateTime, fileName, description, MakeAllHidden: false));
|
||||||
}
|
}
|
||||||
if (mapping.MappingFromPerson is null)
|
if (mapping.MappingFromPerson is null)
|
||||||
continue;
|
continue;
|
||||||
@ -180,13 +188,13 @@ public partial class MapLogic : Shared.Models.Methods.IMapLogic
|
|||||||
continue;
|
continue;
|
||||||
personKeyFormatted = IPersonBirthday.GetFormatted(_Configuration.PersonBirthdayFormat, mapping.MappingFromPerson.PersonKey);
|
personKeyFormatted = IPersonBirthday.GetFormatted(_Configuration.PersonBirthdayFormat, mapping.MappingFromPerson.PersonKey);
|
||||||
directory = Path.Combine($"{eDistanceContentDirectory}---", "Person Key Shortcuts", personKeyFormatted, directoryName);
|
directory = Path.Combine($"{eDistanceContentDirectory}---", "Person Key Shortcuts", personKeyFormatted, directoryName);
|
||||||
fileName = Path.Combine(directory, $"{mapping.MappingFromItem.ImageFileHolder.Name}.lnk");
|
fileName = Path.Combine(directory, $"{mapping.MappingFromItem.FilePath.Name}.lnk");
|
||||||
results.Add(new(mapping.MappingFromItem.ImageFileHolder.FullName, directory, mapping.MappingFromItem.GetDateTimeOriginalThenMinimumDateTime(), fileName, description, MakeAllHidden: false));
|
results.Add(new(mapping.MappingFromItem.FilePath.FullName, directory, dateTime, fileName, description, MakeAllHidden: false));
|
||||||
if (IPerson.IsDefaultName(mapping.MappingFromPerson))
|
if (IPerson.IsDefaultName(mapping.MappingFromPerson))
|
||||||
continue;
|
continue;
|
||||||
directory = Path.Combine($"{eDistanceContentDirectory}---", "Name Shortcuts", mapping.MappingFromPerson.DisplayDirectoryName, directoryName);
|
directory = Path.Combine($"{eDistanceContentDirectory}---", "Name Shortcuts", mapping.MappingFromPerson.DisplayDirectoryName, directoryName);
|
||||||
fileName = Path.Combine(directory, $"{mapping.MappingFromItem.ImageFileHolder.Name}.lnk");
|
fileName = Path.Combine(directory, $"{mapping.MappingFromItem.FilePath.Name}.lnk");
|
||||||
results.Add(new(mapping.MappingFromItem.ImageFileHolder.FullName, directory, mapping.MappingFromItem.GetDateTimeOriginalThenMinimumDateTime(), fileName, description, MakeAllHidden: false));
|
results.Add(new(mapping.MappingFromItem.FilePath.FullName, directory, dateTime, fileName, description, MakeAllHidden: false));
|
||||||
}
|
}
|
||||||
return results;
|
return results;
|
||||||
}
|
}
|
||||||
@ -225,11 +233,12 @@ public partial class MapLogic : Shared.Models.Methods.IMapLogic
|
|||||||
_Ticks = ticks;
|
_Ticks = ticks;
|
||||||
_Configuration = configuration;
|
_Configuration = configuration;
|
||||||
_PropertyConfiguration = propertyConfiguration;
|
_PropertyConfiguration = propertyConfiguration;
|
||||||
ReadOnlyDictionary<long, int> readOnlyPersonKeyToCount;
|
List<LocationContainer> locationContainers = [];
|
||||||
List<PersonContainer> notMappedPersonContainers = [];
|
List<PersonContainer> notMappedPersonContainers = [];
|
||||||
|
ReadOnlyDictionary<long, int> readOnlyPersonKeyToCount;
|
||||||
Dictionary<int, List<(string, int)>> skipCollection = [];
|
Dictionary<int, List<(string, int)>> skipCollection = [];
|
||||||
Dictionary<int, List<(string, int)>> skipNotSkipCollection = [];
|
Dictionary<int, List<(string, int)>> skipNotSkipCollection = [];
|
||||||
List<LocationContainer> locationContainers = [];
|
ReadOnlyDictionary<int, List<(string, int)>> readOnlySkipCollection;
|
||||||
string? rootDirectoryParent = Path.GetDirectoryName(propertyConfiguration.RootDirectory);
|
string? rootDirectoryParent = Path.GetDirectoryName(propertyConfiguration.RootDirectory);
|
||||||
string eDistanceContentTicksDirectory = Path.Combine(eDistanceContentDirectory, ticks.ToString());
|
string eDistanceContentTicksDirectory = Path.Combine(eDistanceContentDirectory, ticks.ToString());
|
||||||
ReadOnlyDictionary<int, ReadOnlyDictionary<int, ReadOnlyCollection<PersonContainer>>> idThenWholePercentagesToPersonContainers;
|
ReadOnlyDictionary<int, ReadOnlyDictionary<int, ReadOnlyCollection<PersonContainer>>> idThenWholePercentagesToPersonContainers;
|
||||||
@ -293,8 +302,10 @@ public partial class MapLogic : Shared.Models.Methods.IMapLogic
|
|||||||
readOnlyPersonKeyToCount,
|
readOnlyPersonKeyToCount,
|
||||||
readOnlyPossiblyNewPersonDisplayDirectoryNamesAndPersonContainer);
|
readOnlyPossiblyNewPersonDisplayDirectoryNamesAndPersonContainer);
|
||||||
idThenWholePercentagesToPersonContainers = Stateless.MapLogic.GetIdThenWholePercentagesToPersonContainers(configuration,
|
idThenWholePercentagesToPersonContainers = Stateless.MapLogic.GetIdThenWholePercentagesToPersonContainers(configuration,
|
||||||
|
skipCollection,
|
||||||
readOnlyPersonKeyFormattedToPersonContainer,
|
readOnlyPersonKeyFormattedToPersonContainer,
|
||||||
personKeyFormattedIdThenWholePercentagesCollection);
|
personKeyFormattedIdThenWholePercentagesCollection);
|
||||||
|
readOnlySkipCollection = new(skipCollection);
|
||||||
notMappedPersonContainers.AddRange(Stateless.MapLogic.GetNotMappedPersonContainers(configuration,
|
notMappedPersonContainers.AddRange(Stateless.MapLogic.GetNotMappedPersonContainers(configuration,
|
||||||
ticks,
|
ticks,
|
||||||
personContainers,
|
personContainers,
|
||||||
@ -304,7 +315,7 @@ public partial class MapLogic : Shared.Models.Methods.IMapLogic
|
|||||||
configuration,
|
configuration,
|
||||||
ticks,
|
ticks,
|
||||||
personContainers,
|
personContainers,
|
||||||
skipCollection,
|
readOnlySkipCollection,
|
||||||
records));
|
records));
|
||||||
int lossCount = records.Count - locationContainers.Count;
|
int lossCount = records.Count - locationContainers.Count;
|
||||||
int unableToMatchCount = records.Count - personKeyFormattedIdThenWholePercentagesCollection.Count;
|
int unableToMatchCount = records.Count - personKeyFormattedIdThenWholePercentagesCollection.Count;
|
||||||
@ -433,22 +444,47 @@ public partial class MapLogic : Shared.Models.Methods.IMapLogic
|
|||||||
{
|
{
|
||||||
string checkFile;
|
string checkFile;
|
||||||
string facesDirectory = Stateless.MapLogic.GetFacesDirectory(_PropertyConfiguration, dFacesContentDirectory, mapping.FilePath, mapping.MappingFromItem);
|
string facesDirectory = Stateless.MapLogic.GetFacesDirectory(_PropertyConfiguration, dFacesContentDirectory, mapping.FilePath, mapping.MappingFromItem);
|
||||||
FileHolder faceFileHolder = IFileHolder.Get(Path.Combine(facesDirectory, $"{mapping.MappingFromLocation.DeterministicHashCodeKey}{mapping.MappingFromItem.ImageFileHolder.ExtensionLowered}{_Configuration.FacesFileNameExtension}"));
|
FileHolder faceFileHolder = IFileHolder.Get(Path.Combine(facesDirectory, $"{mapping.MappingFromLocation.DeterministicHashCodeKey}{mapping.MappingFromItem.FilePath.ExtensionLowered}{_Configuration.FacesFileNameExtension}"));
|
||||||
if (!faceFileHolder.Exists)
|
if (!faceFileHolder.Exists)
|
||||||
result = null;
|
result = null;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
string shortcutFile = string.Empty;
|
string shortcutFile = string.Empty;
|
||||||
string facePartsDirectory = Stateless.MapLogic.GetFacePartsDirectory(_PropertyConfiguration, d2FacePartsContentDirectory, mapping.FilePath, mapping.MappingFromItem);
|
string facePartsDirectory = Stateless.MapLogic.GetFacePartsDirectory(_PropertyConfiguration, d2FacePartsContentDirectory, mapping.FilePath, mapping.MappingFromItem);
|
||||||
checkFile = Path.Combine(directory, $"{mapping.MappingFromLocation.DeterministicHashCodeKey}{mapping.MappingFromItem.ImageFileHolder.ExtensionLowered}");
|
checkFile = Path.Combine(directory, $"{mapping.MappingFromLocation.DeterministicHashCodeKey}{mapping.MappingFromItem.FilePath.ExtensionLowered}");
|
||||||
FileHolder hiddenFaceFileHolder = IFileHolder.Get(Path.Combine(facesDirectory, $"{mapping.MappingFromLocation.DeterministicHashCodeKey}{mapping.MappingFromItem.ImageFileHolder.ExtensionLowered}{_Configuration.FacesHiddenFileNameExtension}"));
|
FileHolder hiddenFaceFileHolder = IFileHolder.Get(Path.Combine(facesDirectory, $"{mapping.MappingFromLocation.DeterministicHashCodeKey}{mapping.MappingFromItem.FilePath.ExtensionLowered}{_Configuration.FacesHiddenFileNameExtension}"));
|
||||||
FileHolder facePartsFileHolder = IFileHolder.Get(Path.Combine(facePartsDirectory, $"{mapping.MappingFromLocation.DeterministicHashCodeKey}{mapping.MappingFromItem.ImageFileHolder.ExtensionLowered}{_Configuration.FacePartsFileNameExtension}"));
|
FileHolder facePartsFileHolder = IFileHolder.Get(Path.Combine(facePartsDirectory, $"{mapping.MappingFromLocation.DeterministicHashCodeKey}{mapping.MappingFromItem.FilePath.ExtensionLowered}{_Configuration.FacePartsFileNameExtension}"));
|
||||||
result = new(checkFile, directory, faceFileHolder, hiddenFaceFileHolder, facePartsFileHolder, mapping.MappingFromItem.ResizedFileHolder, shortcutFile);
|
result = new(checkFile, directory, faceFileHolder, hiddenFaceFileHolder, facePartsFileHolder, mapping.MappingFromItem.ResizedFileHolder, shortcutFile);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private (long?, string?) GetDirectory(Configuration configuration, string by, string segmentB)
|
||||||
|
{
|
||||||
|
long? ticks = null;
|
||||||
|
const int zero = 0;
|
||||||
|
string? directory = null;
|
||||||
|
string personKeyFormatted;
|
||||||
|
PersonBirthday personBirthday;
|
||||||
|
PersonContainer personContainer;
|
||||||
|
for (int i = _NotMappedPersonContainers.Count - 1; i > 0; i--)
|
||||||
|
{
|
||||||
|
if (configuration.SaveIndividually)
|
||||||
|
break;
|
||||||
|
personContainer = _NotMappedPersonContainers[i];
|
||||||
|
if (personContainer.Key is null || personContainer.Birthdays is null || personContainer.Birthdays.Length == 0)
|
||||||
|
continue;
|
||||||
|
personBirthday = personContainer.Birthdays[zero];
|
||||||
|
ticks = personBirthday.Value.Ticks;
|
||||||
|
personKeyFormatted = IPersonBirthday.GetFormatted(configuration.PersonBirthdayFormat, personBirthday);
|
||||||
|
directory = Path.Combine(_EDistanceContentTicksDirectory, by, personKeyFormatted, segmentB);
|
||||||
|
_NotMappedPersonContainers.RemoveAt(i);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return (ticks, directory);
|
||||||
|
}
|
||||||
|
|
||||||
private (long?, string?) GetDirectory(Configuration configuration, bool saveIndividually, int padLeft, string? segmentC, string by, MappingFromItem mappingFromItem)
|
private (long?, string?) GetDirectory(Configuration configuration, bool saveIndividually, int padLeft, string? segmentC, string by, MappingFromItem mappingFromItem)
|
||||||
{
|
{
|
||||||
long? ticks = null;
|
long? ticks = null;
|
||||||
@ -501,7 +537,30 @@ public partial class MapLogic : Shared.Models.Methods.IMapLogic
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Record Get(Configuration configuration, bool saveIndividually, string by, Mapping question, int padLeft)
|
private Record Get(Configuration configuration, string by, long? personKey, string? displayDirectoryName, string segmentB)
|
||||||
|
{
|
||||||
|
long? ticks;
|
||||||
|
string? directory;
|
||||||
|
string? debugDirectory;
|
||||||
|
string? personDirectory;
|
||||||
|
if (personKey is null || string.IsNullOrEmpty(displayDirectoryName))
|
||||||
|
{
|
||||||
|
debugDirectory = null;
|
||||||
|
(ticks, directory) = GetDirectory(configuration, by, segmentB);
|
||||||
|
personDirectory = directory is null ? null : Path.Combine(directory, $"X+{ticks}");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ticks = null;
|
||||||
|
string personKeyFormatted = IPersonBirthday.GetFormatted(configuration.PersonBirthdayFormat, personKey.Value);
|
||||||
|
debugDirectory = Path.Combine(_EDistanceContentTicksDirectory, by, personKeyFormatted, displayDirectoryName);
|
||||||
|
directory = Path.Combine(_EDistanceContentTicksDirectory, by, personKeyFormatted, segmentB);
|
||||||
|
personDirectory = Path.Combine(directory, displayDirectoryName, "lnk");
|
||||||
|
}
|
||||||
|
return new(debugDirectory, directory, ticks, personDirectory);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Record Get(Configuration configuration, bool saveIndividually, int padLeft, string by, Mapping question)
|
||||||
{
|
{
|
||||||
long? ticks;
|
long? ticks;
|
||||||
string? directory;
|
string? directory;
|
||||||
@ -529,7 +588,7 @@ public partial class MapLogic : Shared.Models.Methods.IMapLogic
|
|||||||
return new(debugDirectory, directory, ticks, personDirectory);
|
return new(debugDirectory, directory, ticks, personDirectory);
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<SaveContainer> GetSaveContainers(string dFacesContentDirectory, string d2FacePartsContentDirectory, ReadOnlyCollection<Mapping> mappingCollection, ReadOnlyDictionary<int, ReadOnlyDictionary<int, Mapping>> idToWholePercentagesToMapping, ReadOnlyDictionary<long, List<int>> personKeyToIds, int? useFiltersCounter, bool saveMapped, bool saveIndividually, bool sortingContainersAny)
|
private List<SaveContainer> GetSaveContainers(string dFacesContentDirectory, string d2FacePartsContentDirectory, ReadOnlyCollection<Mapping> distinctValidImageMappingCollection, ReadOnlyDictionary<int, ReadOnlyDictionary<int, Mapping>> idToWholePercentagesToMapping, ReadOnlyDictionary<long, List<int>> personKeyToIds, int? useFiltersCounter, bool saveMapped, bool saveIndividually, bool sortingContainersAny)
|
||||||
{
|
{
|
||||||
if (_Configuration is null)
|
if (_Configuration is null)
|
||||||
throw new NullReferenceException(nameof(_Configuration));
|
throw new NullReferenceException(nameof(_Configuration));
|
||||||
@ -554,7 +613,7 @@ public partial class MapLogic : Shared.Models.Methods.IMapLogic
|
|||||||
ReadOnlyDictionary<int, Mapping>? wholePercentagesToMapping;
|
ReadOnlyDictionary<int, Mapping>? wholePercentagesToMapping;
|
||||||
int padLeft = _Configuration.FaceDistancePermyriad.ToString().Length;
|
int padLeft = _Configuration.FaceDistancePermyriad.ToString().Length;
|
||||||
string forceSingleImageHumanized = nameof(Shared.Models.Stateless.IMapLogic.ForceSingleImage).Humanize(LetterCasing.Title);
|
string forceSingleImageHumanized = nameof(Shared.Models.Stateless.IMapLogic.ForceSingleImage).Humanize(LetterCasing.Title);
|
||||||
foreach (Mapping mapping in mappingCollection)
|
foreach (Mapping mapping in distinctValidImageMappingCollection)
|
||||||
{
|
{
|
||||||
if (mapping.MappingFromLocation is null)
|
if (mapping.MappingFromLocation is null)
|
||||||
continue;
|
continue;
|
||||||
@ -583,7 +642,7 @@ public partial class MapLogic : Shared.Models.Methods.IMapLogic
|
|||||||
if (!PreAndPostContinue(_Configuration, mapping, question))
|
if (!PreAndPostContinue(_Configuration, mapping, question))
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
record = Get(_Configuration, saveIndividually, by, mapping, padLeft);
|
record = Get(_Configuration, saveIndividually, padLeft, by, mapping);
|
||||||
if (string.IsNullOrEmpty(record.Directory) || string.IsNullOrEmpty(record.PersonDirectory))
|
if (string.IsNullOrEmpty(record.Directory) || string.IsNullOrEmpty(record.PersonDirectory))
|
||||||
continue;
|
continue;
|
||||||
directory = record.Directory;
|
directory = record.Directory;
|
||||||
@ -618,18 +677,18 @@ public partial class MapLogic : Shared.Models.Methods.IMapLogic
|
|||||||
results.Add(new(Path.Combine(directory, "Maybe")));
|
results.Add(new(Path.Combine(directory, "Maybe")));
|
||||||
}
|
}
|
||||||
facesDirectory = Stateless.MapLogic.GetFacesDirectory(_PropertyConfiguration, dFacesContentDirectory, mapping.FilePath, mapping.MappingFromItem);
|
facesDirectory = Stateless.MapLogic.GetFacesDirectory(_PropertyConfiguration, dFacesContentDirectory, mapping.FilePath, mapping.MappingFromItem);
|
||||||
faceFileHolder = IFileHolder.Get(Path.Combine(facesDirectory, $"{mapping.MappingFromLocation.DeterministicHashCodeKey}{mapping.MappingFromItem.ImageFileHolder.ExtensionLowered}{_Configuration.FacesFileNameExtension}"));
|
faceFileHolder = IFileHolder.Get(Path.Combine(facesDirectory, $"{mapping.MappingFromLocation.DeterministicHashCodeKey}{mapping.MappingFromItem.FilePath.ExtensionLowered}{_Configuration.FacesFileNameExtension}"));
|
||||||
if (!faceFileHolder.Exists)
|
if (!faceFileHolder.Exists)
|
||||||
continue;
|
continue;
|
||||||
if (isByMapping)
|
if (isByMapping)
|
||||||
{
|
{
|
||||||
checkFile = Path.Combine(record.PersonDirectory, $"{mapping.MappingFromLocation.DeterministicHashCodeKey}{mapping.MappingFromItem.ImageFileHolder.ExtensionLowered}");
|
checkFile = Path.Combine(record.PersonDirectory, $"{mapping.MappingFromLocation.DeterministicHashCodeKey}{mapping.MappingFromItem.FilePath.ExtensionLowered}");
|
||||||
saveContainer = new(checkFile, directory, faceFileHolder);
|
saveContainer = new(checkFile, directory, faceFileHolder);
|
||||||
}
|
}
|
||||||
else if (saveIndividually)
|
else if (saveIndividually)
|
||||||
{
|
{
|
||||||
facePartsDirectory = Stateless.MapLogic.GetFacePartsDirectory(_PropertyConfiguration, d2FacePartsContentDirectory, mapping.FilePath, mapping.MappingFromItem);
|
facePartsDirectory = Stateless.MapLogic.GetFacePartsDirectory(_PropertyConfiguration, d2FacePartsContentDirectory, mapping.FilePath, mapping.MappingFromItem);
|
||||||
facePartsFileHolder = IFileHolder.Get(Path.Combine(facePartsDirectory, $"{mapping.MappingFromLocation.DeterministicHashCodeKey}{mapping.MappingFromItem.ImageFileHolder.ExtensionLowered}{_Configuration.FacePartsFileNameExtension}"));
|
facePartsFileHolder = IFileHolder.Get(Path.Combine(facePartsDirectory, $"{mapping.MappingFromLocation.DeterministicHashCodeKey}{mapping.MappingFromItem.FilePath.ExtensionLowered}{_Configuration.FacePartsFileNameExtension}"));
|
||||||
(saveContainer, SaveContainer? extraSaveContainer) = Stateless.MapLogic.GetContainers(_Configuration.FacesFileNameExtension, _Configuration.FacePartsFileNameExtension, directory, faceFileHolder, facePartsFileHolder, mapping);
|
(saveContainer, SaveContainer? extraSaveContainer) = Stateless.MapLogic.GetContainers(_Configuration.FacesFileNameExtension, _Configuration.FacePartsFileNameExtension, directory, faceFileHolder, facePartsFileHolder, mapping);
|
||||||
if (extraSaveContainer is not null)
|
if (extraSaveContainer is not null)
|
||||||
results.Add(extraSaveContainer);
|
results.Add(extraSaveContainer);
|
||||||
@ -637,10 +696,10 @@ public partial class MapLogic : Shared.Models.Methods.IMapLogic
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
facePartsDirectory = Stateless.MapLogic.GetFacePartsDirectory(_PropertyConfiguration, d2FacePartsContentDirectory, mapping.FilePath, mapping.MappingFromItem);
|
facePartsDirectory = Stateless.MapLogic.GetFacePartsDirectory(_PropertyConfiguration, d2FacePartsContentDirectory, mapping.FilePath, mapping.MappingFromItem);
|
||||||
shortcutFile = Path.Combine(record.PersonDirectory, $"{mapping.MappingFromLocation.DeterministicHashCodeKey}{mapping.MappingFromItem.ImageFileHolder.ExtensionLowered}.lnk");
|
shortcutFile = Path.Combine(record.PersonDirectory, $"{mapping.MappingFromLocation.DeterministicHashCodeKey}{mapping.MappingFromItem.FilePath.ExtensionLowered}.lnk");
|
||||||
checkFile = Path.Combine(directory, $"{mapping.MappingFromLocation.DeterministicHashCodeKey}{mapping.MappingFromItem.ImageFileHolder.ExtensionLowered}");
|
checkFile = Path.Combine(directory, $"{mapping.MappingFromLocation.DeterministicHashCodeKey}{mapping.MappingFromItem.FilePath.ExtensionLowered}");
|
||||||
hiddenFaceFileHolder = IFileHolder.Get(Path.Combine(facesDirectory, $"{mapping.MappingFromLocation.DeterministicHashCodeKey}{mapping.MappingFromItem.ImageFileHolder.ExtensionLowered}{_Configuration.FacesHiddenFileNameExtension}"));
|
hiddenFaceFileHolder = IFileHolder.Get(Path.Combine(facesDirectory, $"{mapping.MappingFromLocation.DeterministicHashCodeKey}{mapping.MappingFromItem.FilePath.ExtensionLowered}{_Configuration.FacesHiddenFileNameExtension}"));
|
||||||
facePartsFileHolder = IFileHolder.Get(Path.Combine(facePartsDirectory, $"{mapping.MappingFromLocation.DeterministicHashCodeKey}{mapping.MappingFromItem.ImageFileHolder.ExtensionLowered}{_Configuration.FacePartsFileNameExtension}"));
|
facePartsFileHolder = IFileHolder.Get(Path.Combine(facePartsDirectory, $"{mapping.MappingFromLocation.DeterministicHashCodeKey}{mapping.MappingFromItem.FilePath.ExtensionLowered}{_Configuration.FacePartsFileNameExtension}"));
|
||||||
saveContainer = new(checkFile, directory, faceFileHolder, hiddenFaceFileHolder, facePartsFileHolder, mapping.MappingFromItem.ResizedFileHolder, shortcutFile);
|
saveContainer = new(checkFile, directory, faceFileHolder, hiddenFaceFileHolder, facePartsFileHolder, mapping.MappingFromItem.ResizedFileHolder, shortcutFile);
|
||||||
}
|
}
|
||||||
results.Add(saveContainer);
|
results.Add(saveContainer);
|
||||||
@ -648,7 +707,7 @@ public partial class MapLogic : Shared.Models.Methods.IMapLogic
|
|||||||
return results;
|
return results;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SaveMapped(string dFacesContentDirectory, string d2FacePartsContentDirectory, string d2FacePartsContentCollectionDirectory, ReadOnlyDictionary<long, List<int>> personKeyToIds, ReadOnlyCollection<Mapping> mappingCollection, ReadOnlyDictionary<int, ReadOnlyDictionary<int, Mapping>> idToWholePercentagesToMapping)
|
public void SaveMapped(string dFacesContentDirectory, string d2FacePartsContentDirectory, string d2FacePartsContentCollectionDirectory, ReadOnlyDictionary<long, List<int>> personKeyToIds, ReadOnlyCollection<Mapping> distinctValidImageMappingCollection, ReadOnlyDictionary<int, ReadOnlyDictionary<int, Mapping>> idToWholePercentagesToMapping)
|
||||||
{
|
{
|
||||||
if (_Configuration is null)
|
if (_Configuration is null)
|
||||||
throw new NullReferenceException(nameof(_Configuration));
|
throw new NullReferenceException(nameof(_Configuration));
|
||||||
@ -656,7 +715,7 @@ public partial class MapLogic : Shared.Models.Methods.IMapLogic
|
|||||||
bool saveMapped = true;
|
bool saveMapped = true;
|
||||||
int? useFiltersCounter = null;
|
int? useFiltersCounter = null;
|
||||||
string mappingDirectory = Path.Combine(_EDistanceContentTicksDirectory, nameof(Shared.Models.Stateless.IMapLogic.Mapping));
|
string mappingDirectory = Path.Combine(_EDistanceContentTicksDirectory, nameof(Shared.Models.Stateless.IMapLogic.Mapping));
|
||||||
List<SaveContainer> saveContainers = GetSaveContainers(dFacesContentDirectory, d2FacePartsContentDirectory, mappingCollection, idToWholePercentagesToMapping, personKeyToIds, useFiltersCounter, saveMapped, sortingContainersAny: true, saveIndividually: false);
|
List<SaveContainer> saveContainers = GetSaveContainers(dFacesContentDirectory, d2FacePartsContentDirectory, distinctValidImageMappingCollection, idToWholePercentagesToMapping, personKeyToIds, useFiltersCounter, saveMapped, sortingContainersAny: true, saveIndividually: false);
|
||||||
SaveContainers(updated, saveContainers);
|
SaveContainers(updated, saveContainers);
|
||||||
if (!string.IsNullOrEmpty(_EDistanceContentTicksDirectory) && Directory.Exists(mappingDirectory))
|
if (!string.IsNullOrEmpty(_EDistanceContentTicksDirectory) && Directory.Exists(mappingDirectory))
|
||||||
Stateless.MapLogic.SaveMappingShortcuts(mappingDirectory);
|
Stateless.MapLogic.SaveMappingShortcuts(mappingDirectory);
|
||||||
@ -750,7 +809,7 @@ public partial class MapLogic : Shared.Models.Methods.IMapLogic
|
|||||||
keyToCount.Add(key, new());
|
keyToCount.Add(key, new());
|
||||||
_ = keyToCount.TryAdd(key, 0);
|
_ = keyToCount.TryAdd(key, 0);
|
||||||
keyToCount[key]++;
|
keyToCount[key]++;
|
||||||
if (!_Configuration.SaveIndividually && keyToCount[key] < _Configuration.SortingMaximumPerKey)
|
if (!_Configuration.SaveIndividually && keyToCount[key] <= _Configuration.SortingMaximumPerKey)
|
||||||
segmentC = null;
|
segmentC = null;
|
||||||
else
|
else
|
||||||
segmentC = sortingContainer.Sorting.DistancePermyriad.ToString();
|
segmentC = sortingContainer.Sorting.DistancePermyriad.ToString();
|
||||||
@ -761,6 +820,94 @@ public partial class MapLogic : Shared.Models.Methods.IMapLogic
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private string? GetDisplayDirectoryName(string? displayDirectoryName, LocationContainer locationContainer)
|
||||||
|
{
|
||||||
|
string? result = displayDirectoryName;
|
||||||
|
ReadOnlyDictionary<int, ReadOnlyCollection<PersonContainer>>? wholePercentagesToPersonContainers = GetWholePercentagesToPersonContainers(locationContainer.Id);
|
||||||
|
if (wholePercentagesToPersonContainers is not null)
|
||||||
|
{
|
||||||
|
foreach (KeyValuePair<int, ReadOnlyCollection<PersonContainer>> keyValuePair in wholePercentagesToPersonContainers)
|
||||||
|
{
|
||||||
|
if (keyValuePair.Key != locationContainer.WholePercentages)
|
||||||
|
continue;
|
||||||
|
if (keyValuePair.Value.Count != 1)
|
||||||
|
continue;
|
||||||
|
result = keyValuePair.Value[0].DisplayDirectoryName;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<SaveContainer> GetSaveContainers(string cResultsFullGroupDirectory, string dResultsFullGroupDirectory, string d2ResultsFullGroupDirectory, Shared.Models.Methods.IDistanceLimits distanceLimits, ReadOnlyCollection<LocationContainer> matrix)
|
||||||
|
{
|
||||||
|
if (_Configuration is null)
|
||||||
|
throw new NullReferenceException(nameof(_Configuration));
|
||||||
|
List<SaveContainer> results = [];
|
||||||
|
string by;
|
||||||
|
Record record;
|
||||||
|
string segmentB;
|
||||||
|
bool isBySorting;
|
||||||
|
string checkFile;
|
||||||
|
string? directory;
|
||||||
|
string shortcutFile;
|
||||||
|
string facesDirectory;
|
||||||
|
List<string> added = [];
|
||||||
|
bool isCounterPersonYear;
|
||||||
|
string facePartsDirectory;
|
||||||
|
FileHolder? faceFileHolder;
|
||||||
|
SaveContainer? saveContainer;
|
||||||
|
string? displayDirectoryName;
|
||||||
|
FileHolder? resizedFileHolder;
|
||||||
|
int? useFiltersCounter = null;
|
||||||
|
string resizeContentDirectory;
|
||||||
|
FileHolder? facePartsFileHolder;
|
||||||
|
FileHolder? hiddenFaceFileHolder;
|
||||||
|
bool sortingContainersAny = matrix.Count > 0;
|
||||||
|
string cContentDirectory = Path.Combine(cResultsFullGroupDirectory, _Configuration.PropertyConfiguration.ResultContent);
|
||||||
|
string forceSingleImageHumanized = nameof(Shared.Models.Stateless.IMapLogic.ForceSingleImage).Humanize(LetterCasing.Title);
|
||||||
|
string d2FacePartsContentDirectory = Path.Combine(d2ResultsFullGroupDirectory, _Configuration.PropertyConfiguration.ResultContent);
|
||||||
|
foreach (LocationContainer locationContainer in matrix)
|
||||||
|
{
|
||||||
|
if (_Configuration.SaveIndividually)
|
||||||
|
break;
|
||||||
|
if (locationContainer.LengthPermyriad is null || locationContainer.LengthSource is null)
|
||||||
|
continue;
|
||||||
|
if (added.Contains(locationContainer.LengthSource.Name))
|
||||||
|
continue;
|
||||||
|
segmentB = locationContainer.LengthPermyriad.Value.ToString().PadLeft(2, '0')[..2];
|
||||||
|
isCounterPersonYear = locationContainer.PersonKey is not null && IPersonBirthday.IsCounterPersonYear(locationContainer.PersonKey.Value);
|
||||||
|
displayDirectoryName = isCounterPersonYear ? locationContainer.DisplayDirectoryName : GetDisplayDirectoryName(locationContainer.DisplayDirectoryName, locationContainer);
|
||||||
|
(by, _, isBySorting) = Stateless.MapLogic.Get(useFiltersCounter, _Configuration.SaveIndividually, sortingContainersAny, forceSingleImageHumanized, locationContainer.LengthPermyriad, locationContainer.PersonKey, displayDirectoryName);
|
||||||
|
record = Get(_Configuration, by, locationContainer.PersonKey, displayDirectoryName, segmentB);
|
||||||
|
if (string.IsNullOrEmpty(record.Directory) || string.IsNullOrEmpty(record.PersonDirectory))
|
||||||
|
continue;
|
||||||
|
directory = record.Directory;
|
||||||
|
if (!string.IsNullOrEmpty(record.DebugDirectory))
|
||||||
|
results.Add(new(record.DebugDirectory));
|
||||||
|
if (locationContainer.PersonKey is null)
|
||||||
|
{
|
||||||
|
if (!_Configuration.SaveSortingWithoutPerson)
|
||||||
|
throw new NotSupportedException();
|
||||||
|
if (record.Ticks is null)
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
results.Add(new(record.PersonDirectory));
|
||||||
|
facesDirectory = locationContainer.LengthSource.DirectoryName;
|
||||||
|
faceFileHolder = IFileHolder.Get(locationContainer.LengthSource.FullName);
|
||||||
|
checkFile = Path.Combine(directory, $"{locationContainer.LengthSource.Name}");
|
||||||
|
shortcutFile = Path.Combine(record.PersonDirectory, $"{locationContainer.LengthSource.Name}.lnk");
|
||||||
|
resizeContentDirectory = Stateless.MapLogic.GetResizeContentDirectory(_PropertyConfiguration, cContentDirectory, locationContainer.LengthSource);
|
||||||
|
facePartsDirectory = Stateless.MapLogic.GetFacePartsDirectoryX(_PropertyConfiguration, d2FacePartsContentDirectory, locationContainer.LengthSource);
|
||||||
|
hiddenFaceFileHolder = IFileHolder.Get(Path.Combine(facesDirectory, $"{locationContainer.LengthSource.NameWithoutExtension}{_Configuration.FacesHiddenFileNameExtension}"));
|
||||||
|
facePartsFileHolder = IFileHolder.Get(Path.Combine(facePartsDirectory, $"{locationContainer.LengthSource.NameWithoutExtension}{_Configuration.FacePartsFileNameExtension}"));
|
||||||
|
resizedFileHolder = IFileHolder.Get(Path.Combine(resizeContentDirectory, $"{locationContainer.LengthSource.FileNameFirstSegment}{Path.GetExtension(locationContainer.LengthSource.NameWithoutExtension)}"));
|
||||||
|
saveContainer = new(checkFile, directory, faceFileHolder, hiddenFaceFileHolder, facePartsFileHolder, resizedFileHolder, shortcutFile);
|
||||||
|
results.Add(saveContainer);
|
||||||
|
added.Add(locationContainer.LengthSource.Name);
|
||||||
|
}
|
||||||
|
return results;
|
||||||
|
}
|
||||||
|
|
||||||
public List<SaveContainer> GetSaveContainers(string dFacesContentDirectory, string d2FacePartsContentDirectory, string d2FacePartsContentCollectionDirectory, ReadOnlyDictionary<int, ReadOnlyDictionary<int, Mapping>> idToWholePercentagesToMapping, Shared.Models.Methods.IDistanceLimits distanceLimits, int? useFiltersCounter, ReadOnlyCollection<SortingContainer> sortingContainers)
|
public List<SaveContainer> GetSaveContainers(string dFacesContentDirectory, string d2FacePartsContentDirectory, string d2FacePartsContentCollectionDirectory, ReadOnlyDictionary<int, ReadOnlyDictionary<int, Mapping>> idToWholePercentagesToMapping, Shared.Models.Methods.IDistanceLimits distanceLimits, int? useFiltersCounter, ReadOnlyCollection<SortingContainer> sortingContainers)
|
||||||
{
|
{
|
||||||
if (_Configuration is null)
|
if (_Configuration is null)
|
||||||
@ -799,7 +946,7 @@ public partial class MapLogic : Shared.Models.Methods.IMapLogic
|
|||||||
throw new NotSupportedException();
|
throw new NotSupportedException();
|
||||||
if (question.MappingFromLocation is null)
|
if (question.MappingFromLocation is null)
|
||||||
continue;
|
continue;
|
||||||
record = Get(_Configuration, _Configuration.SaveIndividually, by, question, padLeft);
|
record = Get(_Configuration, _Configuration.SaveIndividually, padLeft, by, question);
|
||||||
if (string.IsNullOrEmpty(record.Directory) || string.IsNullOrEmpty(record.PersonDirectory))
|
if (string.IsNullOrEmpty(record.Directory) || string.IsNullOrEmpty(record.PersonDirectory))
|
||||||
continue;
|
continue;
|
||||||
directory = record.Directory;
|
directory = record.Directory;
|
||||||
@ -829,12 +976,12 @@ public partial class MapLogic : Shared.Models.Methods.IMapLogic
|
|||||||
if (_Configuration.SaveIndividually && question.MappingFromLocation.WholePercentages == question.MappingFromLocation.WholePercentages)
|
if (_Configuration.SaveIndividually && question.MappingFromLocation.WholePercentages == question.MappingFromLocation.WholePercentages)
|
||||||
results.Add(new(Path.Combine(directory, "Maybe")));
|
results.Add(new(Path.Combine(directory, "Maybe")));
|
||||||
facesDirectory = Stateless.MapLogic.GetFacesDirectory(_PropertyConfiguration, dFacesContentDirectory, question.FilePath, question.MappingFromItem);
|
facesDirectory = Stateless.MapLogic.GetFacesDirectory(_PropertyConfiguration, dFacesContentDirectory, question.FilePath, question.MappingFromItem);
|
||||||
faceFileHolder = IFileHolder.Get(Path.Combine(facesDirectory, $"{question.MappingFromLocation.DeterministicHashCodeKey}{question.MappingFromItem.ImageFileHolder.ExtensionLowered}{_Configuration.FacesFileNameExtension}"));
|
faceFileHolder = IFileHolder.Get(Path.Combine(facesDirectory, $"{question.MappingFromLocation.DeterministicHashCodeKey}{question.MappingFromItem.FilePath.ExtensionLowered}{_Configuration.FacesFileNameExtension}"));
|
||||||
facePartsDirectory = Stateless.MapLogic.GetFacePartsDirectory(_PropertyConfiguration, d2FacePartsContentDirectory, question.FilePath, question.MappingFromItem);
|
facePartsDirectory = Stateless.MapLogic.GetFacePartsDirectory(_PropertyConfiguration, d2FacePartsContentDirectory, question.FilePath, question.MappingFromItem);
|
||||||
shortcutFile = Path.Combine(record.PersonDirectory, $"{question.MappingFromLocation.DeterministicHashCodeKey}{question.MappingFromItem.ImageFileHolder.ExtensionLowered}.lnk");
|
shortcutFile = Path.Combine(record.PersonDirectory, $"{question.MappingFromLocation.DeterministicHashCodeKey}{question.MappingFromItem.FilePath.ExtensionLowered}.lnk");
|
||||||
checkFile = Path.Combine(directory, $"{question.MappingFromLocation.DeterministicHashCodeKey}{question.MappingFromItem.ImageFileHolder.ExtensionLowered}");
|
checkFile = Path.Combine(directory, $"{question.MappingFromLocation.DeterministicHashCodeKey}{question.MappingFromItem.FilePath.ExtensionLowered}");
|
||||||
hiddenFaceFileHolder = IFileHolder.Get(Path.Combine(facesDirectory, $"{question.MappingFromLocation.DeterministicHashCodeKey}{question.MappingFromItem.ImageFileHolder.ExtensionLowered}{_Configuration.FacesHiddenFileNameExtension}"));
|
hiddenFaceFileHolder = IFileHolder.Get(Path.Combine(facesDirectory, $"{question.MappingFromLocation.DeterministicHashCodeKey}{question.MappingFromItem.FilePath.ExtensionLowered}{_Configuration.FacesHiddenFileNameExtension}"));
|
||||||
facePartsFileHolder = IFileHolder.Get(Path.Combine(facePartsDirectory, $"{question.MappingFromLocation.DeterministicHashCodeKey}{question.MappingFromItem.ImageFileHolder.ExtensionLowered}{_Configuration.FacePartsFileNameExtension}"));
|
facePartsFileHolder = IFileHolder.Get(Path.Combine(facePartsDirectory, $"{question.MappingFromLocation.DeterministicHashCodeKey}{question.MappingFromItem.FilePath.ExtensionLowered}{_Configuration.FacePartsFileNameExtension}"));
|
||||||
saveContainer = new(checkFile, directory, faceFileHolder, hiddenFaceFileHolder, facePartsFileHolder, question.MappingFromItem.ResizedFileHolder, shortcutFile);
|
saveContainer = new(checkFile, directory, faceFileHolder, hiddenFaceFileHolder, facePartsFileHolder, question.MappingFromItem.ResizedFileHolder, shortcutFile);
|
||||||
results.Add(saveContainer);
|
results.Add(saveContainer);
|
||||||
if (!_Configuration.SaveIndividually && isBySorting && question.MappingFromPerson is null)
|
if (!_Configuration.SaveIndividually && isBySorting && question.MappingFromPerson is null)
|
||||||
@ -1026,7 +1173,7 @@ public partial class MapLogic : Shared.Models.Methods.IMapLogic
|
|||||||
collection.Add(new(personBirthday.Value.Ticks, Path.Combine(checkDirectory, personKeyFormatted, fileNameWithoutExtension, $"{ids.Count} Face(s)")));
|
collection.Add(new(personBirthday.Value.Ticks, Path.Combine(checkDirectory, personKeyFormatted, fileNameWithoutExtension, $"{ids.Count} Face(s)")));
|
||||||
foreach ((long personKey, string displayDirectoryName) in collection)
|
foreach ((long personKey, string displayDirectoryName) in collection)
|
||||||
{
|
{
|
||||||
matches = (from l in personContainers where l.Key == personKey && l.ApproximateYears.HasValue select l).ToArray();
|
matches = (from l in personContainers where l.Key == personKey select l).ToArray();
|
||||||
if (matches.Length == 0)
|
if (matches.Length == 0)
|
||||||
continue;
|
continue;
|
||||||
personKeyFormatted = IPersonBirthday.GetFormatted(_Configuration.PersonBirthdayFormat, personKey);
|
personKeyFormatted = IPersonBirthday.GetFormatted(_Configuration.PersonBirthdayFormat, personKey);
|
||||||
@ -1041,11 +1188,11 @@ public partial class MapLogic : Shared.Models.Methods.IMapLogic
|
|||||||
return results;
|
return results;
|
||||||
}
|
}
|
||||||
|
|
||||||
private (int, FileHolder, int, string, string, string, string)[] GetCollectionForSaveFilteredOriginalImagesFromJLinks(string[] jLinks, string a2PeopleContentDirectory, ReadOnlyCollection<PersonContainer> personContainers, ReadOnlyCollection<Mapping> mappingCollection, ReadOnlyDictionary<long, List<int>> personKeyToIds)
|
private FilteredOriginalImage[] GetCollectionForSaveFilteredOriginalImagesFromJLinks(string[] jLinks, string a2PeopleContentDirectory, ReadOnlyCollection<PersonContainer> personContainers, ReadOnlyCollection<Mapping> distinctValidImageMappingCollection, ReadOnlyDictionary<long, List<int>> personKeyToIds)
|
||||||
{
|
{
|
||||||
if (_Configuration is null)
|
if (_Configuration is null)
|
||||||
throw new NullReferenceException(nameof(_Configuration));
|
throw new NullReferenceException(nameof(_Configuration));
|
||||||
(int, FileHolder, int, string, string, string, string)[] results;
|
FilteredOriginalImage[] results;
|
||||||
int count = 0;
|
int count = 0;
|
||||||
int group = 65;
|
int group = 65;
|
||||||
string checkFile;
|
string checkFile;
|
||||||
@ -1055,9 +1202,9 @@ public partial class MapLogic : Shared.Models.Methods.IMapLogic
|
|||||||
string personKeyFormatted;
|
string personKeyFormatted;
|
||||||
List<int> distinctCollection = [];
|
List<int> distinctCollection = [];
|
||||||
bool usePersonKeyAndDeterministicHashCodeKey = false;
|
bool usePersonKeyAndDeterministicHashCodeKey = false;
|
||||||
|
List<FilteredOriginalImage> filteredOriginalImages = [];
|
||||||
List<string> personKeyFormattedCollection = GetPersonKeyFormattedCollection(jLinks, a2PeopleContentDirectory, personContainers, personKeyToIds);
|
List<string> personKeyFormattedCollection = GetPersonKeyFormattedCollection(jLinks, a2PeopleContentDirectory, personContainers, personKeyToIds);
|
||||||
List<(int Id, FileHolder ImageFileHolder, int ApproximateYears, string PersonKeyFormatted, string CheckFile, string Directory, string PersonDirectory)> collection = [];
|
foreach (Mapping mapping in distinctValidImageMappingCollection)
|
||||||
foreach (Mapping mapping in mappingCollection)
|
|
||||||
{
|
{
|
||||||
if (distinctCollection.Contains(mapping.MappingFromItem.Id))
|
if (distinctCollection.Contains(mapping.MappingFromItem.Id))
|
||||||
continue;
|
continue;
|
||||||
@ -1066,7 +1213,7 @@ public partial class MapLogic : Shared.Models.Methods.IMapLogic
|
|||||||
throw new NotSupportedException();
|
throw new NotSupportedException();
|
||||||
if (mapping.By is null or Shared.Models.Stateless.IMapLogic.Sorting)
|
if (mapping.By is null or Shared.Models.Stateless.IMapLogic.Sorting)
|
||||||
continue;
|
continue;
|
||||||
if (mapping.MappingFromPerson?.ApproximateYears is null || mapping.MappingFromLocation is null)
|
if (mapping.MappingFromPerson is null || mapping.MappingFromLocation is null)
|
||||||
continue;
|
continue;
|
||||||
if (string.IsNullOrEmpty(mapping.MappingFromPerson.SegmentB))
|
if (string.IsNullOrEmpty(mapping.MappingFromPerson.SegmentB))
|
||||||
throw new NotSupportedException();
|
throw new NotSupportedException();
|
||||||
@ -1086,45 +1233,52 @@ public partial class MapLogic : Shared.Models.Methods.IMapLogic
|
|||||||
}
|
}
|
||||||
directory = Path.Combine(_EDistanceContentTicksDirectory, ((char)group).ToString());
|
directory = Path.Combine(_EDistanceContentTicksDirectory, ((char)group).ToString());
|
||||||
personDirectory = Path.Combine(directory, mapping.MappingFromPerson.DisplayDirectoryName);
|
personDirectory = Path.Combine(directory, mapping.MappingFromPerson.DisplayDirectoryName);
|
||||||
checkFile = Path.Combine(directory, $"{mapping.MappingFromItem.Id}{mapping.MappingFromItem.ImageFileHolder.ExtensionLowered}");
|
checkFile = Path.Combine(directory, $"{mapping.MappingFromItem.Id}{mapping.MappingFromItem.FilePath.ExtensionLowered}");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
directory = Path.Combine(_EDistanceContentTicksDirectory, "Images", personKeyFormatted);
|
directory = Path.Combine(_EDistanceContentTicksDirectory, "Images", personKeyFormatted);
|
||||||
personDirectory = Path.Combine(directory, mapping.MappingFromPerson.DisplayDirectoryName);
|
personDirectory = Path.Combine(directory, mapping.MappingFromPerson.DisplayDirectoryName);
|
||||||
checkFile = Path.Combine(directory, $"{mapping.MappingFromLocation.DeterministicHashCodeKey}{mapping.MappingFromItem.ImageFileHolder.ExtensionLowered}");
|
checkFile = Path.Combine(directory, $"{mapping.MappingFromLocation.DeterministicHashCodeKey}{mapping.MappingFromItem.FilePath.ExtensionLowered}");
|
||||||
}
|
}
|
||||||
collection.Add(new(mapping.MappingFromItem.Id, mapping.MappingFromItem.ImageFileHolder, mapping.MappingFromPerson.ApproximateYears.Value, personKeyFormatted, directory, personDirectory, checkFile));
|
if (mapping is null)
|
||||||
|
continue;
|
||||||
|
if (mapping.MappingFromPerson.ApproximateYears is null)
|
||||||
|
filteredOriginalImages.Add(new(mapping.MappingFromItem.Id, mapping.MappingFromItem.FilePath, -1, personKeyFormatted, directory, personDirectory, checkFile));
|
||||||
|
else
|
||||||
|
filteredOriginalImages.Add(new(mapping.MappingFromItem.Id, mapping.MappingFromItem.FilePath, mapping.MappingFromPerson.ApproximateYears.Value, personKeyFormatted, directory, personDirectory, checkFile));
|
||||||
distinctCollection.Add(mapping.MappingFromItem.Id);
|
distinctCollection.Add(mapping.MappingFromItem.Id);
|
||||||
count += 1;
|
count += 1;
|
||||||
}
|
}
|
||||||
results = (from l in collection orderby l.ApproximateYears descending, l.PersonKeyFormatted descending select l).ToArray();
|
results = (from l in filteredOriginalImages orderby l.ApproximateYears descending, l.PersonKeyFormatted descending select l).ToArray();
|
||||||
return results;
|
return results;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SaveFilteredOriginalImagesFromJLinks(string[] jLinks, ReadOnlyCollection<PersonContainer> personContainers, string a2PeopleContentDirectory, ReadOnlyDictionary<long, List<int>> personKeyToIds, ReadOnlyCollection<Mapping> mappingCollection)
|
public void SaveFilteredOriginalImagesFromJLinks(string[] jLinks, ReadOnlyCollection<PersonContainer> personContainers, string a2PeopleContentDirectory, ReadOnlyDictionary<long, List<int>> personKeyToIds, ReadOnlyCollection<Mapping> distinctValidImageMappingCollection)
|
||||||
{
|
{
|
||||||
if (_Configuration is null)
|
if (_Configuration is null)
|
||||||
throw new NullReferenceException(nameof(_Configuration));
|
throw new NullReferenceException(nameof(_Configuration));
|
||||||
|
FileHolder fileHolder;
|
||||||
SaveContainer? saveContainer;
|
SaveContainer? saveContainer;
|
||||||
List<SaveContainer> saveContainers = [];
|
List<SaveContainer> saveContainers = [];
|
||||||
(int, FileHolder, int, string, string, string, string)[] collection = GetCollectionForSaveFilteredOriginalImagesFromJLinks(jLinks, a2PeopleContentDirectory, personContainers, mappingCollection, personKeyToIds);
|
FilteredOriginalImage[] filteredOriginalImages = GetCollectionForSaveFilteredOriginalImagesFromJLinks(jLinks, a2PeopleContentDirectory, personContainers, distinctValidImageMappingCollection, personKeyToIds);
|
||||||
foreach ((int id, FileHolder imageFileHolder, int approximateYears, string personKeyFormatted, string directory, string personDirectory, string checkFile) in collection)
|
foreach (FilteredOriginalImage filteredOriginalImage in filteredOriginalImages)
|
||||||
{
|
{
|
||||||
saveContainer = new(personDirectory);
|
fileHolder = FileHolder.Get(filteredOriginalImage.FilePath);
|
||||||
|
saveContainer = new(filteredOriginalImage.PersonDirectory);
|
||||||
saveContainers.Add(saveContainer);
|
saveContainers.Add(saveContainer);
|
||||||
saveContainer = new(imageFileHolder, checkFile, directory);
|
saveContainer = new(fileHolder, filteredOriginalImage.CheckFile, filteredOriginalImage.Directory);
|
||||||
saveContainers.Add(saveContainer);
|
saveContainers.Add(saveContainer);
|
||||||
}
|
}
|
||||||
SaveContainers(null, saveContainers);
|
SaveContainers(null, saveContainers);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SaveShortcutsForOutputResolutionsPreMapLogic(string eDistanceContentDirectory, ReadOnlyDictionary<long, List<int>> personKeyToIds, ReadOnlyCollection<Mapping> mappingCollection)
|
public void SaveShortcutsForOutputResolutionsPreMapLogic(string eDistanceContentDirectory, ReadOnlyDictionary<long, List<int>> personKeyToIds, ReadOnlyCollection<Mapping> distinctValidImageMappingCollection)
|
||||||
{
|
{
|
||||||
string hiddenFile;
|
string hiddenFile;
|
||||||
WindowsShortcut windowsShortcut;
|
WindowsShortcut windowsShortcut;
|
||||||
List<SaveShortcutsForOutputResolutions> collection = [];
|
List<SaveShortcutsForOutputResolutions> collection = [];
|
||||||
collection = GetCollectionForSaveShortcutsForOutputResolutionsPreMapLogic(eDistanceContentDirectory, personKeyToIds, mappingCollection);
|
collection = GetCollectionForSaveShortcutsForOutputResolutionsPreMapLogic(eDistanceContentDirectory, personKeyToIds, distinctValidImageMappingCollection);
|
||||||
string[] distinctDirectories = (from l in collection select l.Directory).Distinct().ToArray();
|
string[] distinctDirectories = (from l in collection select l.Directory).Distinct().ToArray();
|
||||||
foreach (string directory in distinctDirectories)
|
foreach (string directory in distinctDirectories)
|
||||||
{
|
{
|
||||||
@ -1158,7 +1312,7 @@ public partial class MapLogic : Shared.Models.Methods.IMapLogic
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private (List<(string, DateTime[])>, List<SaveShortcutsForOutputResolutions>) GetCollectionForSaveShortcutsForOutputResolutionsDuringMapLogic(ReadOnlyDictionary<long, List<int>> personKeyToIds, string dFacesContentDirectory, ReadOnlyCollection<Item> filteredItems, ReadOnlyCollection<Mapping> mappingCollection)
|
private (List<(string, DateTime[])>, List<SaveShortcutsForOutputResolutions>) GetCollectionForSaveShortcutsForOutputResolutionsDuringMapLogic(ReadOnlyDictionary<long, List<int>> personKeyToIds, string dFacesContentDirectory, ReadOnlyCollection<Item> validImageItems, ReadOnlyCollection<Mapping> distinctValidImageMappingCollection)
|
||||||
{
|
{
|
||||||
if (_Configuration is null)
|
if (_Configuration is null)
|
||||||
throw new NullReferenceException(nameof(_Configuration));
|
throw new NullReferenceException(nameof(_Configuration));
|
||||||
@ -1166,6 +1320,7 @@ public partial class MapLogic : Shared.Models.Methods.IMapLogic
|
|||||||
string fileName;
|
string fileName;
|
||||||
string fullName;
|
string fullName;
|
||||||
string directory;
|
string directory;
|
||||||
|
DateTime dateTime;
|
||||||
string facesDirectory;
|
string facesDirectory;
|
||||||
string? directoryName;
|
string? directoryName;
|
||||||
string personDirectory;
|
string personDirectory;
|
||||||
@ -1173,7 +1328,7 @@ public partial class MapLogic : Shared.Models.Methods.IMapLogic
|
|||||||
List<string> distinct = [];
|
List<string> distinct = [];
|
||||||
List<SaveShortcutsForOutputResolutions> collection = [];
|
List<SaveShortcutsForOutputResolutions> collection = [];
|
||||||
List<(string, DateTime[])> directoriesAndDateTimes = [];
|
List<(string, DateTime[])> directoriesAndDateTimes = [];
|
||||||
foreach (Item item in filteredItems)
|
foreach (Item item in validImageItems)
|
||||||
{
|
{
|
||||||
if (item.ResizedFileHolder is null)
|
if (item.ResizedFileHolder is null)
|
||||||
continue;
|
continue;
|
||||||
@ -1186,12 +1341,12 @@ public partial class MapLogic : Shared.Models.Methods.IMapLogic
|
|||||||
directoryName = Path.GetDirectoryName(face.Mapping.MappingFromItem.RelativePath);
|
directoryName = Path.GetDirectoryName(face.Mapping.MappingFromItem.RelativePath);
|
||||||
if (directoryName is null)
|
if (directoryName is null)
|
||||||
throw new NotSupportedException();
|
throw new NotSupportedException();
|
||||||
if (item.ResizedFileHolder?.DirectoryName is null || !item.ResizedFileHolder.Exists || item.ImageFileHolder.LastWriteTime is null)
|
if (item.ResizedFileHolder?.DirectoryName is null || !item.ResizedFileHolder.Exists)
|
||||||
continue;
|
continue;
|
||||||
directory = Path.Combine(item.ResizedFileHolder.DirectoryName, $"{_PropertyConfiguration.ResultAllInOne}Shortcuts", _PropertyConfiguration.ResultAllInOne);
|
directory = Path.Combine(item.ResizedFileHolder.DirectoryName, $"{_PropertyConfiguration.ResultAllInOne}Shortcuts", _PropertyConfiguration.ResultAllInOne);
|
||||||
personDirectory = Path.Combine(directory, "No Faces");
|
personDirectory = Path.Combine(directory, "No Faces");
|
||||||
fileName = Path.Combine(personDirectory, $"{item.ResizedFileHolder.Name}.lnk");
|
fileName = Path.Combine(personDirectory, $"{item.ResizedFileHolder.Name}.lnk");
|
||||||
collection.Add(new(item.ResizedFileHolder.FullName, personDirectory, item.ImageFileHolder.LastWriteTime.Value, fileName, face.Mapping.MappingFromItem.Id.ToString(), MakeAllHidden: false));
|
collection.Add(new(item.ResizedFileHolder.FullName, personDirectory, new(item.FilePath.LastWriteTicks), fileName, face.Mapping.MappingFromItem.Id.ToString(), MakeAllHidden: false));
|
||||||
if (face.Mapping.MappingFromItem.ContainerDateTimes.Length > 0 && !distinct.Contains(item.ResizedFileHolder.DirectoryName))
|
if (face.Mapping.MappingFromItem.ContainerDateTimes.Length > 0 && !distinct.Contains(item.ResizedFileHolder.DirectoryName))
|
||||||
{
|
{
|
||||||
distinct.Add(item.ResizedFileHolder.DirectoryName);
|
distinct.Add(item.ResizedFileHolder.DirectoryName);
|
||||||
@ -1199,13 +1354,14 @@ public partial class MapLogic : Shared.Models.Methods.IMapLogic
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
foreach (Mapping mapping in mappingCollection)
|
foreach (Mapping mapping in distinctValidImageMappingCollection)
|
||||||
{
|
{
|
||||||
directoryName = Path.GetDirectoryName(mapping.MappingFromItem.RelativePath);
|
directoryName = Path.GetDirectoryName(mapping.MappingFromItem.RelativePath);
|
||||||
if (directoryName is null)
|
if (directoryName is null)
|
||||||
throw new NotSupportedException();
|
throw new NotSupportedException();
|
||||||
if (mapping.MappingFromItem.ResizedFileHolder.DirectoryName is null || !mapping.MappingFromItem.ResizedFileHolder.Exists)
|
if (mapping.MappingFromItem.ResizedFileHolder.DirectoryName is null || !mapping.MappingFromItem.ResizedFileHolder.Exists)
|
||||||
continue;
|
continue;
|
||||||
|
dateTime = mapping.MappingFromItem.GetDateTimeOriginalThenMinimumDateTime();
|
||||||
if (mapping.By is null or Shared.Models.Stateless.IMapLogic.Sorting || mapping.MappingFromPerson?.ApproximateYears is null)
|
if (mapping.By is null or Shared.Models.Stateless.IMapLogic.Sorting || mapping.MappingFromPerson?.ApproximateYears is null)
|
||||||
{
|
{
|
||||||
if (mapping.MappingFromItem.ContainerDateTimes.Length > 0 && !distinct.Contains(mapping.MappingFromItem.ResizedFileHolder.DirectoryName))
|
if (mapping.MappingFromItem.ContainerDateTimes.Length > 0 && !distinct.Contains(mapping.MappingFromItem.ResizedFileHolder.DirectoryName))
|
||||||
@ -1216,13 +1372,13 @@ public partial class MapLogic : Shared.Models.Methods.IMapLogic
|
|||||||
directory = Path.Combine(mapping.MappingFromItem.ResizedFileHolder.DirectoryName, $"{_PropertyConfiguration.ResultAllInOne}Shortcuts", _PropertyConfiguration.ResultAllInOne);
|
directory = Path.Combine(mapping.MappingFromItem.ResizedFileHolder.DirectoryName, $"{_PropertyConfiguration.ResultAllInOne}Shortcuts", _PropertyConfiguration.ResultAllInOne);
|
||||||
personDirectory = Path.Combine(directory, "Unknown");
|
personDirectory = Path.Combine(directory, "Unknown");
|
||||||
fileName = Path.Combine(personDirectory, $"{mapping.MappingFromItem.ResizedFileHolder.Name}.lnk");
|
fileName = Path.Combine(personDirectory, $"{mapping.MappingFromItem.ResizedFileHolder.Name}.lnk");
|
||||||
collection.Add(new(mapping.MappingFromItem.ResizedFileHolder.FullName, personDirectory, mapping.MappingFromItem.GetDateTimeOriginalThenMinimumDateTime(), fileName, mapping.MappingFromLocation?.DeterministicHashCodeKey, MakeAllHidden: false));
|
collection.Add(new(mapping.MappingFromItem.ResizedFileHolder.FullName, personDirectory, dateTime, fileName, mapping.MappingFromLocation?.DeterministicHashCodeKey, MakeAllHidden: false));
|
||||||
facesDirectory = Stateless.MapLogic.GetFacesDirectory(_PropertyConfiguration, dFacesContentDirectory, mapping.FilePath, mapping.MappingFromItem);
|
facesDirectory = Stateless.MapLogic.GetFacesDirectory(_PropertyConfiguration, dFacesContentDirectory, mapping.FilePath, mapping.MappingFromItem);
|
||||||
if (mapping.MappingFromLocation is null)
|
if (mapping.MappingFromLocation is null)
|
||||||
continue;
|
continue;
|
||||||
fullName = Path.Combine(facesDirectory, $"{mapping.MappingFromLocation.DeterministicHashCodeKey}{mapping.MappingFromItem.ImageFileHolder.ExtensionLowered}{_Configuration.FacesFileNameExtension}");
|
fullName = Path.Combine(facesDirectory, $"{mapping.MappingFromLocation.DeterministicHashCodeKey}{mapping.MappingFromItem.FilePath.ExtensionLowered}{_Configuration.FacesFileNameExtension}");
|
||||||
fileName = Path.Combine(personDirectory, $"{mapping.MappingFromLocation.DeterministicHashCodeKey}{mapping.MappingFromItem.ResizedFileHolder.ExtensionLowered}{_Configuration.FacesFileNameExtension}.lnk");
|
fileName = Path.Combine(personDirectory, $"{mapping.MappingFromLocation.DeterministicHashCodeKey}{mapping.MappingFromItem.ResizedFileHolder.ExtensionLowered}{_Configuration.FacesFileNameExtension}.lnk");
|
||||||
collection.Add(new(fullName, personDirectory, mapping.MappingFromItem.GetDateTimeOriginalThenMinimumDateTime(), fileName, mapping.MappingFromLocation.DeterministicHashCodeKey, MakeAllHidden: true));
|
collection.Add(new(fullName, personDirectory, dateTime, fileName, mapping.MappingFromLocation.DeterministicHashCodeKey, MakeAllHidden: true));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -1242,21 +1398,21 @@ public partial class MapLogic : Shared.Models.Methods.IMapLogic
|
|||||||
else
|
else
|
||||||
personDirectory = Path.Combine(directory, mapping.MappingFromPerson.DisplayDirectoryName, $"{ids.Count} Face(s)");
|
personDirectory = Path.Combine(directory, mapping.MappingFromPerson.DisplayDirectoryName, $"{ids.Count} Face(s)");
|
||||||
fileName = Path.Combine(directory, $"{mapping.MappingFromItem.ResizedFileHolder.Name}.lnk");
|
fileName = Path.Combine(directory, $"{mapping.MappingFromItem.ResizedFileHolder.Name}.lnk");
|
||||||
collection.Add(new(mapping.MappingFromItem.ResizedFileHolder.FullName, personDirectory, mapping.MappingFromItem.GetDateTimeOriginalThenMinimumDateTime(), fileName, mapping.MappingFromLocation?.DeterministicHashCodeKey, MakeAllHidden: false));
|
collection.Add(new(mapping.MappingFromItem.ResizedFileHolder.FullName, personDirectory, dateTime, fileName, mapping.MappingFromLocation?.DeterministicHashCodeKey, MakeAllHidden: false));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return new(directoriesAndDateTimes, collection);
|
return new(directoriesAndDateTimes, collection);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SaveShortcutsForOutputResolutionsDuringMapLogic(ReadOnlyCollection<Container> containers, ReadOnlyDictionary<long, List<int>> personKeyToIds, string dFacesContentDirectory, ReadOnlyCollection<Mapping> mappingCollection)
|
public void SaveShortcutsForOutputResolutionsDuringMapLogic(ReadOnlyCollection<Container> containers, ReadOnlyDictionary<long, List<int>> personKeyToIds, string dFacesContentDirectory, ReadOnlyCollection<Mapping> distinctValidImageMappingCollection)
|
||||||
{
|
{
|
||||||
if (_Configuration is null)
|
if (_Configuration is null)
|
||||||
throw new NullReferenceException(nameof(_Configuration));
|
throw new NullReferenceException(nameof(_Configuration));
|
||||||
WindowsShortcut windowsShortcut;
|
WindowsShortcut windowsShortcut;
|
||||||
List<(string, DateTime[])> directoriesAndDateTimes;
|
List<(string, DateTime[])> directoriesAndDateTimes;
|
||||||
List<SaveShortcutsForOutputResolutions> collection;
|
List<SaveShortcutsForOutputResolutions> collection;
|
||||||
ReadOnlyCollection<Item> filteredItems = IContainer.GetItems(_PropertyConfiguration, containers, distinctItems: true, filterItems: true);
|
ReadOnlyCollection<Item> validImageItems = IContainer.GetValidImageItems(_PropertyConfiguration, containers, distinctItems: true, filterItems: true);
|
||||||
(directoriesAndDateTimes, collection) = GetCollectionForSaveShortcutsForOutputResolutionsDuringMapLogic(personKeyToIds, dFacesContentDirectory, filteredItems, mappingCollection);
|
(directoriesAndDateTimes, collection) = GetCollectionForSaveShortcutsForOutputResolutionsDuringMapLogic(personKeyToIds, dFacesContentDirectory, validImageItems, distinctValidImageMappingCollection);
|
||||||
string[] directories = (from l in collection select l.Directory).Distinct().ToArray();
|
string[] directories = (from l in collection select l.Directory).Distinct().ToArray();
|
||||||
foreach (string directory in directories)
|
foreach (string directory in directories)
|
||||||
{
|
{
|
||||||
@ -1300,10 +1456,13 @@ public partial class MapLogic : Shared.Models.Methods.IMapLogic
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool InSkipCollection(int id, MappingFromLocation mappingFromLocation) =>
|
public bool InSkipCollection(int id, int wholePercentages) =>
|
||||||
_SkipCollection.TryGetValue(id, out List<int>? wholePercentagesCollection) && wholePercentagesCollection.Contains(mappingFromLocation.WholePercentages);
|
_SkipCollection.TryGetValue(id, out List<int>? wholePercentagesCollection) && wholePercentagesCollection.Contains(wholePercentages);
|
||||||
|
|
||||||
public bool? IsFocusPerson(int? skipPersonWithMoreThen, long[] jLinkResolvedPersonKeys, ReadOnlyDictionary<int, ReadOnlyCollection<PersonContainer>>? wholePercentagesToPersonContainers, MappingFromLocation mappingFromLocation)
|
public bool InSkipCollection(int id, MappingFromLocation mappingFromLocation) =>
|
||||||
|
InSkipCollection(id, mappingFromLocation.WholePercentages);
|
||||||
|
|
||||||
|
public bool? IsFocusPerson(int? skipPersonWithMoreThen, long[] jLinkResolvedPersonKeys, ReadOnlyDictionary<int, ReadOnlyCollection<PersonContainer>>? wholePercentagesToPersonContainers, int wholePercentages)
|
||||||
{
|
{
|
||||||
bool? result;
|
bool? result;
|
||||||
ReadOnlyCollection<PersonContainer>? personContainers;
|
ReadOnlyCollection<PersonContainer>? personContainers;
|
||||||
@ -1311,7 +1470,7 @@ public partial class MapLogic : Shared.Models.Methods.IMapLogic
|
|||||||
result = null;
|
result = null;
|
||||||
else if (wholePercentagesToPersonContainers is null)
|
else if (wholePercentagesToPersonContainers is null)
|
||||||
result = null;
|
result = null;
|
||||||
else if (!wholePercentagesToPersonContainers.TryGetValue(mappingFromLocation.WholePercentages, out personContainers))
|
else if (!wholePercentagesToPersonContainers.TryGetValue(wholePercentages, out personContainers))
|
||||||
result = null;
|
result = null;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -1335,37 +1494,46 @@ public partial class MapLogic : Shared.Models.Methods.IMapLogic
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void LookForAbandoned(Property.Models.Configuration propertyConfiguration, string bResultsFullGroupDirectory, Container[] containers, string cResultsFullGroupDirectory, string dResultsFullGroupDirectory, string d2ResultsFullGroupDirectory)
|
public bool? IsFocusPerson(int? skipPersonWithMoreThen, long[] jLinkResolvedPersonKeys, ReadOnlyDictionary<int, ReadOnlyCollection<PersonContainer>>? wholePercentagesToPersonContainers, MappingFromLocation mappingFromLocation) =>
|
||||||
|
IsFocusPerson(skipPersonWithMoreThen, jLinkResolvedPersonKeys, wholePercentagesToPersonContainers, mappingFromLocation.WholePercentages);
|
||||||
|
|
||||||
|
public void LookForAbandoned(IDlibDotNet dlibDotNet, Property.Models.Configuration propertyConfiguration, string bResultsFullGroupDirectory, ReadOnlyCollection<Container> readOnlyContainers, string cResultsFullGroupDirectory, string dResultsFullGroupDirectory, string d2ResultsFullGroupDirectory)
|
||||||
{
|
{
|
||||||
string[] directories;
|
string[] directories;
|
||||||
string? directoryName;
|
string? directoryName;
|
||||||
List<int> distinctFilteredIds = IContainer.GetFilteredDistinctIds(propertyConfiguration, containers);
|
List<int> distinctFilteredIds = IContainer.GetFilteredDistinctIds(propertyConfiguration, readOnlyContainers);
|
||||||
LookForAbandoned(propertyConfiguration, distinctFilteredIds);
|
LookForAbandoned(propertyConfiguration, distinctFilteredIds);
|
||||||
Stateless.LookForAbandonedLogic.LookForAbandoned(propertyConfiguration, bResultsFullGroupDirectory, distinctFilteredIds);
|
dlibDotNet.Tick();
|
||||||
|
List<string> distinctFilteredFileNameFirstSegments = IContainer.GetFilteredDistinctFileNameFirstSegments(propertyConfiguration, readOnlyContainers);
|
||||||
|
Stateless.LookForAbandonedLogic.LookForAbandoned(propertyConfiguration, bResultsFullGroupDirectory, distinctFilteredFileNameFirstSegments);
|
||||||
|
dlibDotNet.Tick();
|
||||||
directories = Directory.GetDirectories(cResultsFullGroupDirectory, "*", SearchOption.TopDirectoryOnly);
|
directories = Directory.GetDirectories(cResultsFullGroupDirectory, "*", SearchOption.TopDirectoryOnly);
|
||||||
foreach (string directory in directories)
|
foreach (string directory in directories)
|
||||||
{
|
{
|
||||||
directoryName = Path.GetFileName(directory);
|
directoryName = Path.GetFileName(directory);
|
||||||
if (string.IsNullOrEmpty(directoryName) || directoryName.Length != 2 && directoryName.Length != 4)
|
if (string.IsNullOrEmpty(directoryName) || directoryName.Length != 2 && directoryName.Length != 4)
|
||||||
continue;
|
continue;
|
||||||
Stateless.LookForAbandonedLogic.LookForAbandoned(propertyConfiguration, distinctFilteredIds, directory, directoryName);
|
Stateless.LookForAbandonedLogic.LookForAbandoned(propertyConfiguration, distinctFilteredFileNameFirstSegments, directory, directoryName);
|
||||||
}
|
}
|
||||||
|
dlibDotNet.Tick();
|
||||||
directories = Directory.GetDirectories(dResultsFullGroupDirectory, "*", SearchOption.TopDirectoryOnly);
|
directories = Directory.GetDirectories(dResultsFullGroupDirectory, "*", SearchOption.TopDirectoryOnly);
|
||||||
foreach (string directory in directories)
|
foreach (string directory in directories)
|
||||||
{
|
{
|
||||||
directoryName = Path.GetFileName(directory);
|
directoryName = Path.GetFileName(directory);
|
||||||
if (string.IsNullOrEmpty(directoryName) || directoryName.Length != 2 && directoryName.Length != 4)
|
if (string.IsNullOrEmpty(directoryName) || directoryName.Length != 2 && directoryName.Length != 4)
|
||||||
continue;
|
continue;
|
||||||
Stateless.LookForAbandonedLogic.LookForAbandoned(propertyConfiguration, distinctFilteredIds, directory, directoryName);
|
Stateless.LookForAbandonedLogic.LookForAbandoned(propertyConfiguration, distinctFilteredFileNameFirstSegments, directory, directoryName);
|
||||||
}
|
}
|
||||||
|
dlibDotNet.Tick();
|
||||||
directories = Directory.GetDirectories(d2ResultsFullGroupDirectory, "*", SearchOption.TopDirectoryOnly);
|
directories = Directory.GetDirectories(d2ResultsFullGroupDirectory, "*", SearchOption.TopDirectoryOnly);
|
||||||
foreach (string directory in directories)
|
foreach (string directory in directories)
|
||||||
{
|
{
|
||||||
directoryName = Path.GetFileName(directory);
|
directoryName = Path.GetFileName(directory);
|
||||||
if (string.IsNullOrEmpty(directoryName) || directoryName.Length != 2 && directoryName.Length != 4)
|
if (string.IsNullOrEmpty(directoryName) || directoryName.Length != 2 && directoryName.Length != 4)
|
||||||
continue;
|
continue;
|
||||||
Stateless.LookForAbandonedLogic.LookForAbandoned(propertyConfiguration, distinctFilteredIds, directory, directoryName);
|
Stateless.LookForAbandonedLogic.LookForAbandoned(propertyConfiguration, distinctFilteredFileNameFirstSegments, directory, directoryName);
|
||||||
}
|
}
|
||||||
|
dlibDotNet.Tick();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -32,9 +32,23 @@ internal abstract class DecadeLogic
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static void SetCreationTimeMaybeMoveToDecade(Property.Models.Configuration propertyConfiguration, bool moveToDecade, MappingFromItem mappingFromItem, ReadOnlyCollection<LocationContainer> locationContainers)
|
internal static void SetCreationTime(MappingFromItem mappingFromItem, ReadOnlyCollection<LocationContainer> locationContainers)
|
||||||
{
|
{
|
||||||
DateTime dateTime;
|
DateTime dateTime;
|
||||||
|
foreach (LocationContainer locationContainer in locationContainers)
|
||||||
|
{
|
||||||
|
dateTime = mappingFromItem.DateTimeOriginal is null ? mappingFromItem.MinimumDateTime : mappingFromItem.DateTimeOriginal.Value;
|
||||||
|
if (locationContainer.CreationDateOnly.Year != dateTime.Year || locationContainer.CreationDateOnly.Month != dateTime.Month || locationContainer.CreationDateOnly.Day != dateTime.Day)
|
||||||
|
{
|
||||||
|
if (!File.Exists(locationContainer.FilePath.FullName))
|
||||||
|
continue;
|
||||||
|
File.SetCreationTime(locationContainer.FilePath.FullName, dateTime);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static void MoveToDecade(Property.Models.Configuration propertyConfiguration, MappingFromItem mappingFromItem, ReadOnlyCollection<LocationContainer> locationContainers)
|
||||||
|
{
|
||||||
string halfDecade;
|
string halfDecade;
|
||||||
string checkDirectory;
|
string checkDirectory;
|
||||||
string? yearDirectory;
|
string? yearDirectory;
|
||||||
@ -44,13 +58,6 @@ internal abstract class DecadeLogic
|
|||||||
string? personKeyFormattedDirectoryName;
|
string? personKeyFormattedDirectoryName;
|
||||||
foreach (LocationContainer locationContainer in locationContainers)
|
foreach (LocationContainer locationContainer in locationContainers)
|
||||||
{
|
{
|
||||||
if (!File.Exists(locationContainer.FilePath.FullName))
|
|
||||||
continue;
|
|
||||||
dateTime = mappingFromItem.DateTimeOriginal is null ? mappingFromItem.MinimumDateTime : mappingFromItem.DateTimeOriginal.Value;
|
|
||||||
if (locationContainer.CreationDateOnly.Year != dateTime.Year || locationContainer.CreationDateOnly.Month != dateTime.Month || locationContainer.CreationDateOnly.Day != dateTime.Day)
|
|
||||||
File.SetCreationTime(locationContainer.FilePath.FullName, dateTime);
|
|
||||||
if (!moveToDecade)
|
|
||||||
continue;
|
|
||||||
if (string.IsNullOrEmpty(locationContainer.FilePath.DirectoryName))
|
if (string.IsNullOrEmpty(locationContainer.FilePath.DirectoryName))
|
||||||
continue;
|
continue;
|
||||||
personNameDirectoryName = Path.GetFileName(locationContainer.FilePath.DirectoryName);
|
personNameDirectoryName = Path.GetFileName(locationContainer.FilePath.DirectoryName);
|
||||||
@ -68,6 +75,8 @@ internal abstract class DecadeLogic
|
|||||||
if (halfDecade == yearDirectoryName)
|
if (halfDecade == yearDirectoryName)
|
||||||
continue;
|
continue;
|
||||||
checkDirectory = Path.Combine(personKeyFormattedDirectory, halfDecade, personNameDirectoryName);
|
checkDirectory = Path.Combine(personKeyFormattedDirectory, halfDecade, personNameDirectoryName);
|
||||||
|
if (!File.Exists(locationContainer.FilePath.FullName))
|
||||||
|
continue;
|
||||||
if (!Directory.Exists(checkDirectory))
|
if (!Directory.Exists(checkDirectory))
|
||||||
_ = Directory.CreateDirectory(checkDirectory);
|
_ = Directory.CreateDirectory(checkDirectory);
|
||||||
File.Move(locationContainer.FilePath.FullName, Path.Combine(checkDirectory, locationContainer.FilePath.Name));
|
File.Move(locationContainer.FilePath.FullName, Path.Combine(checkDirectory, locationContainer.FilePath.Name));
|
||||||
|
@ -9,19 +9,21 @@ using View_by_Distance.Shared.Models.Stateless.Methods;
|
|||||||
|
|
||||||
namespace View_by_Distance.Map.Models.Stateless;
|
namespace View_by_Distance.Map.Models.Stateless;
|
||||||
|
|
||||||
internal record Record(string PersonKeyFormatted,
|
internal record Record(int DirectoryNumber,
|
||||||
int DirectoryNumber,
|
|
||||||
string? PersonDisplayDirectoryName,
|
|
||||||
bool? IsDefault,
|
bool? IsDefault,
|
||||||
FilePath MappedFaceFilePath);
|
int? LinksCount,
|
||||||
|
FilePath MappedFaceFilePath,
|
||||||
|
string? PersonDisplayDirectoryName,
|
||||||
|
string PersonKeyFormatted);
|
||||||
|
|
||||||
internal abstract class DistanceLogic
|
internal abstract class DistanceLogic
|
||||||
{
|
{
|
||||||
|
|
||||||
internal record TicksDirectory(string Directory,
|
internal record TicksDirectory(DateTime AlternateDirectoryDateTime,
|
||||||
string DirectoryName,
|
string Directory,
|
||||||
DateTime DirectoryDateTime,
|
DateTime DirectoryDateTime,
|
||||||
DateTime AlternateDirectoryDateTime,
|
string DirectoryName,
|
||||||
|
bool? IsLocationContainerDebugDirectory,
|
||||||
float? TotalDays);
|
float? TotalDays);
|
||||||
|
|
||||||
private static void MoveTo(string actionDirectory, TicksDirectory ticksDirectory, string directory, string personKeyFormatted, string yearDirectoryName, string alphaDirectoryName, string[] files, string[] facesFileNames)
|
private static void MoveTo(string actionDirectory, TicksDirectory ticksDirectory, string directory, string personKeyFormatted, string yearDirectoryName, string alphaDirectoryName, string[] files, string[] facesFileNames)
|
||||||
@ -89,6 +91,8 @@ internal abstract class DistanceLogic
|
|||||||
DirectoryInfo directoryInfo;
|
DirectoryInfo directoryInfo;
|
||||||
long? lastDirectoryTicks = null;
|
long? lastDirectoryTicks = null;
|
||||||
DateTime dateTime = DateTime.Now;
|
DateTime dateTime = DateTime.Now;
|
||||||
|
DateTime alternateDirectoryDateTime;
|
||||||
|
bool? isLocationContainerDebugDirectory;
|
||||||
long month = dateTime.AddMonths(1).Ticks - dateTime.Ticks;
|
long month = dateTime.AddMonths(1).Ticks - dateTime.Ticks;
|
||||||
for (int i = 1; i < 5; i++)
|
for (int i = 1; i < 5; i++)
|
||||||
_ = IPath.DeleteEmptyDirectories(eDistanceContentDirectory);
|
_ = IPath.DeleteEmptyDirectories(eDistanceContentDirectory);
|
||||||
@ -125,8 +129,10 @@ internal abstract class DistanceLogic
|
|||||||
Directory.SetCreationTime(ticksDirectory, new DateTime(directoryTicks));
|
Directory.SetCreationTime(ticksDirectory, new DateTime(directoryTicks));
|
||||||
if (directoryInfo.LastWriteTime.Ticks != directoryTicks)
|
if (directoryInfo.LastWriteTime.Ticks != directoryTicks)
|
||||||
Directory.SetLastWriteTime(ticksDirectory, new DateTime(directoryTicks));
|
Directory.SetLastWriteTime(ticksDirectory, new DateTime(directoryTicks));
|
||||||
|
alternateDirectoryDateTime = new DateTime(directoryDateTime.Year, directoryDateTime.Month, directoryDateTime.Day).AddMonths(1);
|
||||||
|
isLocationContainerDebugDirectory = configuration.LocationContainerDebugDirectory is null ? null : ticksDirectoryName.EndsWith(configuration.LocationContainerDebugDirectory);
|
||||||
totalDays = lastDirectoryTicks is null || new TimeSpan(dateTime.Ticks - directoryTicks).TotalDays < 1 ? null : (float)new TimeSpan(directoryTicks - lastDirectoryTicks.Value).TotalDays;
|
totalDays = lastDirectoryTicks is null || new TimeSpan(dateTime.Ticks - directoryTicks).TotalDays < 1 ? null : (float)new TimeSpan(directoryTicks - lastDirectoryTicks.Value).TotalDays;
|
||||||
results.Add(new(ticksDirectory, ticksDirectoryName, new(directoryTicks), new DateTime(directoryDateTime.Year, directoryDateTime.Month, directoryDateTime.Day).AddMonths(1), totalDays));
|
results.Add(new(alternateDirectoryDateTime, ticksDirectory, new(directoryTicks), ticksDirectoryName, isLocationContainerDebugDirectory, totalDays));
|
||||||
if (directoryDateTime.Hour == 0 && directoryDateTime.Minute == 0 && directoryDateTime.Second == 0)
|
if (directoryDateTime.Hour == 0 && directoryDateTime.Minute == 0 && directoryDateTime.Second == 0)
|
||||||
continue;
|
continue;
|
||||||
lastDirectoryTicks = directoryTicks;
|
lastDirectoryTicks = directoryTicks;
|
||||||
@ -210,7 +216,7 @@ internal abstract class DistanceLogic
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static List<Record> GetRecords(Shared.Models.Properties.IPropertyConfiguration propertyConfiguration, Configuration configuration, bool? isDefault, string[] files, int directoryNumber, string personKeyFormatted, List<string> distinct, string? personDisplayDirectoryName)
|
private static List<Record> GetRecords(Shared.Models.Properties.IPropertyConfiguration propertyConfiguration, Configuration configuration, bool? isDefault, string[] files, int directoryNumber, string personKeyFormatted, int? linksCount, List<string> distinct, string? personDisplayDirectoryName)
|
||||||
{
|
{
|
||||||
List<Record> results = [];
|
List<Record> results = [];
|
||||||
string fileName;
|
string fileName;
|
||||||
@ -239,19 +245,32 @@ internal abstract class DistanceLogic
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
distinct.Add(fileName);
|
distinct.Add(fileName);
|
||||||
results.Add(new(personKeyFormatted, directoryNumber, personDisplayDirectoryName, isDefault, filePath));
|
results.Add(new(directoryNumber, isDefault, linksCount, filePath, personDisplayDirectoryName, personKeyFormatted));
|
||||||
}
|
}
|
||||||
return results;
|
return results;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void RenameUnknown(string[] files)
|
private static string[] RenameBirth(string[] files)
|
||||||
{
|
{
|
||||||
|
List<string> results = [];
|
||||||
|
string checkFile;
|
||||||
foreach (string file in files)
|
foreach (string file in files)
|
||||||
{
|
{
|
||||||
if (file.EndsWith(".unk"))
|
if (file.EndsWith(".brt"))
|
||||||
|
{
|
||||||
|
results.Add(file);
|
||||||
continue;
|
continue;
|
||||||
File.Move(file, $"{file}.unk");
|
}
|
||||||
|
checkFile = $"{file}.brt";
|
||||||
|
if (File.Exists(checkFile))
|
||||||
|
{
|
||||||
|
results.Add(file);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
File.Move(file, checkFile);
|
||||||
|
results.Add(checkFile);
|
||||||
}
|
}
|
||||||
|
return results.ToArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void MovedToNewestPersonKeyFormatted(string personKeyFormatted, string newestPersonKeyFormatted, TicksDirectory ticksDirectory, string personKeyDirectory)
|
private static void MovedToNewestPersonKeyFormatted(string personKeyFormatted, string newestPersonKeyFormatted, TicksDirectory ticksDirectory, string personKeyDirectory)
|
||||||
@ -263,6 +282,23 @@ internal abstract class DistanceLogic
|
|||||||
Directory.Move(personKeyDirectory, newestPersonKeyDirectory);
|
Directory.Move(personKeyDirectory, newestPersonKeyDirectory);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static int? GetLinksCount(string yearDirectory)
|
||||||
|
{
|
||||||
|
int? result;
|
||||||
|
string[] yearDirectoryNameSegments = Path.GetFileName(yearDirectory).Split('-');
|
||||||
|
if (yearDirectoryNameSegments.Length != 3)
|
||||||
|
result = null;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
string lastSegment = yearDirectoryNameSegments[^1];
|
||||||
|
if (lastSegment.Length != 3 || !lastSegment.All(l => l == lastSegment[0]))
|
||||||
|
result = null;
|
||||||
|
else
|
||||||
|
result = lastSegment[0] - 65;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
internal static List<Record> DeleteEmptyDirectoriesAndGetCollection(Shared.Models.Properties.IPropertyConfiguration propertyConfiguration, Configuration configuration, long ticks, string eDistanceContentDirectory, ReadOnlyDictionary<string, string> personKeyFormattedToNewestPersonKeyFormatted, ReadOnlyCollection<string> personKeyFormattedCollection)
|
internal static List<Record> DeleteEmptyDirectoriesAndGetCollection(Shared.Models.Properties.IPropertyConfiguration propertyConfiguration, Configuration configuration, long ticks, string eDistanceContentDirectory, ReadOnlyDictionary<string, string> personKeyFormattedToNewestPersonKeyFormatted, ReadOnlyCollection<string> personKeyFormattedCollection)
|
||||||
{
|
{
|
||||||
List<Record> results = [];
|
List<Record> results = [];
|
||||||
@ -270,6 +306,7 @@ internal abstract class DistanceLogic
|
|||||||
string message;
|
string message;
|
||||||
string[] files;
|
string[] files;
|
||||||
bool? isDefault;
|
bool? isDefault;
|
||||||
|
int? linksCount;
|
||||||
int totalSeconds;
|
int totalSeconds;
|
||||||
DateTime dateTime;
|
DateTime dateTime;
|
||||||
TimeSpan timeSpan;
|
TimeSpan timeSpan;
|
||||||
@ -327,6 +364,10 @@ internal abstract class DistanceLogic
|
|||||||
{
|
{
|
||||||
if (check && !Directory.Exists(yearDirectory))
|
if (check && !Directory.Exists(yearDirectory))
|
||||||
continue;
|
continue;
|
||||||
|
if (ticksDirectory.IsLocationContainerDebugDirectory is null || !ticksDirectory.IsLocationContainerDebugDirectory.Value)
|
||||||
|
linksCount = null;
|
||||||
|
else
|
||||||
|
linksCount = GetLinksCount(yearDirectory);
|
||||||
if (ticksDirectory.DirectoryName != configuration.LocationContainerDebugDirectory)
|
if (ticksDirectory.DirectoryName != configuration.LocationContainerDebugDirectory)
|
||||||
{
|
{
|
||||||
files = Directory.GetFiles(yearDirectory, "*", SearchOption.TopDirectoryOnly);
|
files = Directory.GetFiles(yearDirectory, "*", SearchOption.TopDirectoryOnly);
|
||||||
@ -338,7 +379,7 @@ internal abstract class DistanceLogic
|
|||||||
isDefault = null;
|
isDefault = null;
|
||||||
personDisplayDirectoryName = null;
|
personDisplayDirectoryName = null;
|
||||||
files = Directory.GetFiles(yearDirectory, "*", SearchOption.TopDirectoryOnly);
|
files = Directory.GetFiles(yearDirectory, "*", SearchOption.TopDirectoryOnly);
|
||||||
results.AddRange(GetRecords(propertyConfiguration, configuration, isDefault, files, directoryNumber, personKeyFormatted, distinct, personDisplayDirectoryName));
|
results.AddRange(GetRecords(propertyConfiguration, configuration, isDefault, files, directoryNumber, personKeyFormatted, linksCount, distinct, personDisplayDirectoryName));
|
||||||
files = Directory.GetFiles(yearDirectory, "*.lnk", SearchOption.AllDirectories);
|
files = Directory.GetFiles(yearDirectory, "*.lnk", SearchOption.AllDirectories);
|
||||||
foreach (string file in files)
|
foreach (string file in files)
|
||||||
File.Delete(file);
|
File.Delete(file);
|
||||||
@ -346,7 +387,7 @@ internal abstract class DistanceLogic
|
|||||||
}
|
}
|
||||||
personNameDirectories = Directory.GetDirectories(yearDirectory, "*", SearchOption.TopDirectoryOnly);
|
personNameDirectories = Directory.GetDirectories(yearDirectory, "*", SearchOption.TopDirectoryOnly);
|
||||||
if (personNameDirectories.Length > 1)
|
if (personNameDirectories.Length > 1)
|
||||||
throw new NotSupportedException();
|
throw new NotSupportedException("Try deleting *.lnk files!");
|
||||||
foreach (string personNameDirectory in personNameDirectories)
|
foreach (string personNameDirectory in personNameDirectories)
|
||||||
{
|
{
|
||||||
directoryNumber++;
|
directoryNumber++;
|
||||||
@ -394,7 +435,7 @@ internal abstract class DistanceLogic
|
|||||||
if (!isDefault.Value)
|
if (!isDefault.Value)
|
||||||
{
|
{
|
||||||
if (personKeyFormattedToNewestPersonKeyFormatted.Count > 0 && newestPersonKeyFormatted is null)
|
if (personKeyFormattedToNewestPersonKeyFormatted.Count > 0 && newestPersonKeyFormatted is null)
|
||||||
RenameUnknown(files);
|
files = RenameBirth(files);
|
||||||
else if (newestPersonKeyFormatted is not null && personKeyFormatted != newestPersonKeyFormatted)
|
else if (newestPersonKeyFormatted is not null && personKeyFormatted != newestPersonKeyFormatted)
|
||||||
{
|
{
|
||||||
if (!check)
|
if (!check)
|
||||||
@ -426,7 +467,7 @@ internal abstract class DistanceLogic
|
|||||||
Directory.Move(personNameDirectory, personFirstInitialDirectory);
|
Directory.Move(personNameDirectory, personFirstInitialDirectory);
|
||||||
files = Directory.GetFiles(personFirstInitialDirectory, "*", SearchOption.TopDirectoryOnly);
|
files = Directory.GetFiles(personFirstInitialDirectory, "*", SearchOption.TopDirectoryOnly);
|
||||||
}
|
}
|
||||||
results.AddRange(GetRecords(propertyConfiguration, configuration, isDefault, files, directoryNumber, personKeyFormatted, distinct, personDisplayDirectoryName));
|
results.AddRange(GetRecords(propertyConfiguration, configuration, isDefault, files, directoryNumber, personKeyFormatted, linksCount, distinct, personDisplayDirectoryName));
|
||||||
personNameLinkDirectories = Directory.GetDirectories(personFirstInitialDirectory, "*", SearchOption.TopDirectoryOnly);
|
personNameLinkDirectories = Directory.GetDirectories(personFirstInitialDirectory, "*", SearchOption.TopDirectoryOnly);
|
||||||
foreach (string personNameLinkDirectory in personNameLinkDirectories)
|
foreach (string personNameLinkDirectory in personNameLinkDirectories)
|
||||||
{
|
{
|
||||||
|
212
Map/Models/Stateless/FaceFileLogic.cs
Normal file
212
Map/Models/Stateless/FaceFileLogic.cs
Normal file
@ -0,0 +1,212 @@
|
|||||||
|
using ShellProgressBar;
|
||||||
|
using System.Collections.ObjectModel;
|
||||||
|
using System.Drawing;
|
||||||
|
using System.Text.Json;
|
||||||
|
using View_by_Distance.Shared.Models;
|
||||||
|
using View_by_Distance.Shared.Models.Stateless.Methods;
|
||||||
|
using static View_by_Distance.Map.Models.Stateless.MapLogic;
|
||||||
|
|
||||||
|
namespace View_by_Distance.Map.Models.Stateless;
|
||||||
|
|
||||||
|
internal abstract class FaceFileLogic
|
||||||
|
{
|
||||||
|
|
||||||
|
private static void MappedParallelFor(Shared.Models.Properties.IPropertyConfiguration propertyConfiguration, Configuration configuration, ReadOnlyDictionary<int, List<(string, int)>> skipCollection, List<LocationContainer> locationContainers, MappedFile mappedFile)
|
||||||
|
{
|
||||||
|
int? id;
|
||||||
|
string checkFile;
|
||||||
|
DateOnly dateOnly;
|
||||||
|
FilePath filePath;
|
||||||
|
string[] fileMatches;
|
||||||
|
FileHolder fileHolder;
|
||||||
|
int? wholePercentages;
|
||||||
|
const string lnk = ".lnk";
|
||||||
|
ExifDirectory? exifDirectory;
|
||||||
|
string personDisplayDirectoryName;
|
||||||
|
const bool fromDistanceContent = true;
|
||||||
|
List<(string File, int WholePercentages)>? wholePercentagesCollection;
|
||||||
|
if (!mappedFile.FilePath.Name.EndsWith(lnk))
|
||||||
|
{
|
||||||
|
if (mappedFile.FilePath.Id is null)
|
||||||
|
return;
|
||||||
|
id = mappedFile.FilePath.Id;
|
||||||
|
wholePercentages = IMapping.GetWholePercentages(configuration.FacesFileNameExtension, mappedFile.FilePath);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
fileHolder = IFileHolder.Get(mappedFile.FilePath.FullName[..^4]);
|
||||||
|
filePath = FilePath.Get(propertyConfiguration, fileHolder, index: null);
|
||||||
|
if (filePath.Id is null)
|
||||||
|
return;
|
||||||
|
id = filePath.Id;
|
||||||
|
wholePercentages = IMapping.GetWholePercentages(configuration.FacesFileNameExtension, filePath);
|
||||||
|
}
|
||||||
|
if (wholePercentages is null)
|
||||||
|
return;
|
||||||
|
if (configuration.LinkedAlpha is null && string.IsNullOrEmpty(configuration.LocationContainerDebugDirectory) && skipCollection.TryGetValue(id.Value, out wholePercentagesCollection))
|
||||||
|
{
|
||||||
|
fileMatches = (from l in wholePercentagesCollection where l.WholePercentages == wholePercentages select l.File).ToArray();
|
||||||
|
foreach (string fileMatch in fileMatches)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrEmpty(fileMatch) || !File.Exists(fileMatch))
|
||||||
|
continue;
|
||||||
|
checkFile = $"{fileMatch}.dup";
|
||||||
|
if (File.Exists(checkFile))
|
||||||
|
continue;
|
||||||
|
File.Move(fileMatch, checkFile);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dateOnly = DateOnly.FromDateTime(new DateTime(mappedFile.FilePath.CreationTicks));
|
||||||
|
if (mappedFile.FilePath.Name.EndsWith(lnk) || !File.Exists(mappedFile.FilePath.FullName))
|
||||||
|
exifDirectory = null;
|
||||||
|
else
|
||||||
|
exifDirectory = Metadata.Models.Stateless.Methods.IMetadata.GetExifDirectory(mappedFile.FilePath);
|
||||||
|
RectangleF? rectangle = ILocation.GetPercentagesRectangle(configuration.LocationDigits, wholePercentages.Value);
|
||||||
|
personDisplayDirectoryName = mappedFile.PersonDisplayDirectoryName is null ? configuration.MappingDefaultName : mappedFile.PersonDisplayDirectoryName;
|
||||||
|
lock (locationContainers)
|
||||||
|
locationContainers.Add(new(dateOnly,
|
||||||
|
exifDirectory,
|
||||||
|
mappedFile.DirectoryNumber,
|
||||||
|
personDisplayDirectoryName,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
mappedFile.FilePath,
|
||||||
|
fromDistanceContent,
|
||||||
|
id.Value,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
mappedFile.PersonKey,
|
||||||
|
rectangle,
|
||||||
|
wholePercentages.Value));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static ReadOnlyDictionary<int, ReadOnlyDictionary<int, LocationContainer>> GetReadOnly(Dictionary<int, Dictionary<int, LocationContainer>> keyValuePairs)
|
||||||
|
{
|
||||||
|
Dictionary<int, ReadOnlyDictionary<int, LocationContainer>> results = [];
|
||||||
|
foreach (KeyValuePair<int, Dictionary<int, LocationContainer>> keyValuePair in keyValuePairs)
|
||||||
|
results.Add(keyValuePair.Key, new(keyValuePair.Value));
|
||||||
|
return new(results);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static ReadOnlyDictionary<int, ReadOnlyDictionary<int, LocationContainer>> GetMapped(int maxDegreeOfParallelism, Property.Models.Configuration propertyConfiguration, Configuration configuration, long ticks, ReadOnlyCollection<PersonContainer> personContainers, string a2PeopleSingletonDirectory, string eDistanceContentDirectory)
|
||||||
|
{
|
||||||
|
Dictionary<int, Dictionary<int, LocationContainer>> results = [];
|
||||||
|
List<LocationContainer> locationContainers = [];
|
||||||
|
Dictionary<int, LocationContainer>? keyValuePairs;
|
||||||
|
Dictionary<int, List<(string, int)>> skipCollection = [];
|
||||||
|
Dictionary<int, List<(string, int)>> skipNotSkipCollection = [];
|
||||||
|
ReadOnlyCollection<string> readOnlyPersonKeyFormattedCollection;
|
||||||
|
ReadOnlyDictionary<string, string> readOnlyPersonKeyFormattedToNewestPersonKeyFormatted;
|
||||||
|
SetSkipCollections(configuration, personContainers, a2PeopleSingletonDirectory, skipCollection, skipNotSkipCollection);
|
||||||
|
{
|
||||||
|
List<string> personKeyFormattedCollection = [];
|
||||||
|
Dictionary<string, string> personKeyFormattedToNewestPersonKeyFormatted = [];
|
||||||
|
SetPersonCollections(configuration, personContainers, personKeyFormattedToNewestPersonKeyFormatted, personKeyFormattedCollection);
|
||||||
|
readOnlyPersonKeyFormattedCollection = new(personKeyFormattedCollection);
|
||||||
|
readOnlyPersonKeyFormattedToNewestPersonKeyFormatted = new(personKeyFormattedToNewestPersonKeyFormatted);
|
||||||
|
}
|
||||||
|
List<Record> records = DistanceLogic.DeleteEmptyDirectoriesAndGetCollection(propertyConfiguration, configuration, ticks, eDistanceContentDirectory, readOnlyPersonKeyFormattedToNewestPersonKeyFormatted, readOnlyPersonKeyFormattedCollection);
|
||||||
|
List<MappedFile> mappedFiles = GetMappedFiles(propertyConfiguration, configuration, personContainers, records);
|
||||||
|
if (mappedFiles.Count > 0)
|
||||||
|
{
|
||||||
|
int totalSeconds = (int)Math.Floor(new TimeSpan(DateTime.Now.Ticks - ticks).TotalSeconds);
|
||||||
|
string message = $") Building Mapped Face Files Collection - {totalSeconds} total second(s)";
|
||||||
|
ParallelOptions parallelOptions = new() { MaxDegreeOfParallelism = maxDegreeOfParallelism };
|
||||||
|
ReadOnlyDictionary<int, List<(string, int)>> readOnlySkipNotSkipCollection = new(skipCollection);
|
||||||
|
ProgressBarOptions options = new() { ProgressCharacter = '─', ProgressBarOnBottom = true, DisableBottomPercentage = true };
|
||||||
|
using ProgressBar progressBar = new(mappedFiles.Count, message, options);
|
||||||
|
_ = Parallel.For(0, mappedFiles.Count, parallelOptions, (i, state) =>
|
||||||
|
{
|
||||||
|
progressBar.Tick();
|
||||||
|
MappedParallelFor(propertyConfiguration, configuration, readOnlySkipNotSkipCollection, locationContainers, mappedFiles[i]);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
foreach (LocationContainer locationContainer in locationContainers)
|
||||||
|
{
|
||||||
|
if (!results.TryGetValue(locationContainer.Id, out keyValuePairs))
|
||||||
|
{
|
||||||
|
results.Add(locationContainer.Id, []);
|
||||||
|
if (!results.TryGetValue(locationContainer.Id, out keyValuePairs))
|
||||||
|
throw new Exception();
|
||||||
|
}
|
||||||
|
if (keyValuePairs.ContainsKey(locationContainer.WholePercentages))
|
||||||
|
continue;
|
||||||
|
keyValuePairs.Add(locationContainer.WholePercentages, locationContainer);
|
||||||
|
}
|
||||||
|
return GetReadOnly(results);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void MoveUnableToMatch(FilePath filePath)
|
||||||
|
{
|
||||||
|
string checkFile = $"{filePath.FullName}.unk";
|
||||||
|
if (File.Exists(filePath.FullName) && !File.Exists(checkFile))
|
||||||
|
File.Move(filePath.FullName, checkFile);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void AvailableParallelFor(Shared.Models.Properties.IPropertyConfiguration propertyConfiguration, Configuration configuration, IFaceD dFace, List<LocationContainer> locationContainers, FilePath filePath)
|
||||||
|
{
|
||||||
|
string? json;
|
||||||
|
const bool fromDistanceContent = false;
|
||||||
|
if (filePath.Id is null)
|
||||||
|
return;
|
||||||
|
DateOnly dateOnly = DateOnly.FromDateTime(new DateTime(filePath.CreationTicks));
|
||||||
|
int? wholePercentages = IMapping.GetWholePercentages(dFace.FileNameExtension, filePath);
|
||||||
|
if (wholePercentages is null)
|
||||||
|
{
|
||||||
|
if (configuration.DistanceMoveUnableToMatch)
|
||||||
|
MoveUnableToMatch(filePath);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ExifDirectory exifDirectory = Metadata.Models.Stateless.Methods.IMetadata.GetExifDirectory(filePath);
|
||||||
|
json = Metadata.Models.Stateless.Methods.IMetadata.GetOutputResolution(exifDirectory);
|
||||||
|
if (json is null || !json.Contains(nameof(DateTime)))
|
||||||
|
{
|
||||||
|
if (configuration.DistanceMoveUnableToMatch)
|
||||||
|
MoveUnableToMatch(filePath);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
FaceFile? faceFile = JsonSerializer.Deserialize(json, FaceFileGenerationContext.Default.FaceFile);
|
||||||
|
if (faceFile is null || faceFile.Location is null)
|
||||||
|
{
|
||||||
|
if (configuration.DistanceMoveUnableToMatch)
|
||||||
|
MoveUnableToMatch(filePath);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
RectangleF? rectangle = ILocation.GetPercentagesRectangle(configuration.LocationDigits, wholePercentages.Value);
|
||||||
|
if (rectangle is null)
|
||||||
|
return;
|
||||||
|
lock (locationContainers)
|
||||||
|
locationContainers.Add(new(dateOnly,
|
||||||
|
exifDirectory,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
faceFile,
|
||||||
|
filePath,
|
||||||
|
fromDistanceContent,
|
||||||
|
filePath.Id.Value,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
rectangle,
|
||||||
|
wholePercentages.Value));
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static List<LocationContainer> GetAvailable(int maxDegreeOfParallelism, Property.Models.Configuration propertyConfiguration, Configuration configuration, IFaceD dFace, long ticks, string dFacesContentDirectory, ReadOnlyCollection<FilePath> filePaths)
|
||||||
|
{
|
||||||
|
List<LocationContainer> results = [];
|
||||||
|
int totalSeconds = (int)Math.Floor(new TimeSpan(DateTime.Now.Ticks - ticks).TotalSeconds);
|
||||||
|
ParallelOptions parallelOptions = new() { MaxDegreeOfParallelism = maxDegreeOfParallelism };
|
||||||
|
string message = $") Building Available Face Files Collection - {totalSeconds} total second(s)";
|
||||||
|
ProgressBarOptions options = new() { ProgressCharacter = '─', ProgressBarOnBottom = true, DisableBottomPercentage = true };
|
||||||
|
using ProgressBar progressBar = new(filePaths.Count, message, options);
|
||||||
|
_ = Parallel.For(0, filePaths.Count, parallelOptions, (i, state) =>
|
||||||
|
{
|
||||||
|
progressBar.Tick();
|
||||||
|
AvailableParallelFor(propertyConfiguration, configuration, dFace, results, filePaths[i]);
|
||||||
|
});
|
||||||
|
return results;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -6,13 +6,12 @@ namespace View_by_Distance.Map.Models.Stateless;
|
|||||||
internal abstract class LookForAbandonedLogic
|
internal abstract class LookForAbandonedLogic
|
||||||
{
|
{
|
||||||
|
|
||||||
internal static void LookForAbandoned(Property.Models.Configuration propertyConfiguration, List<int> distinctFilteredIds, string directory, string directoryName)
|
internal static void LookForAbandoned(Property.Models.Configuration propertyConfiguration, List<string> distinctFilteredFileNameFirstSegments, string directory, string directoryName)
|
||||||
{
|
{
|
||||||
FilePath filePath;
|
FilePath filePath;
|
||||||
FileHolder fileHolder;
|
FileHolder fileHolder;
|
||||||
string fileNameFirstSegment;
|
string fileNameFirstSegment;
|
||||||
List<string> renameCollection = [];
|
List<string> renameCollection = [];
|
||||||
string[] distinctFilteredIdsValues = distinctFilteredIds.Select(l => l.ToString()).ToArray();
|
|
||||||
string[] files = Directory.GetFiles(directory, "*", SearchOption.AllDirectories);
|
string[] files = Directory.GetFiles(directory, "*", SearchOption.AllDirectories);
|
||||||
foreach (string file in files)
|
foreach (string file in files)
|
||||||
{
|
{
|
||||||
@ -21,7 +20,7 @@ internal abstract class LookForAbandonedLogic
|
|||||||
fileNameFirstSegment = fileHolder.NameWithoutExtension.Split('.')[0];
|
fileNameFirstSegment = fileHolder.NameWithoutExtension.Split('.')[0];
|
||||||
if (!filePath.IsIntelligentIdFormat && filePath.SortOrder is null)
|
if (!filePath.IsIntelligentIdFormat && filePath.SortOrder is null)
|
||||||
continue;
|
continue;
|
||||||
if (distinctFilteredIdsValues.Contains(fileNameFirstSegment))
|
if (distinctFilteredFileNameFirstSegments.Contains(fileNameFirstSegment))
|
||||||
continue;
|
continue;
|
||||||
renameCollection.Add(file);
|
renameCollection.Add(file);
|
||||||
}
|
}
|
||||||
@ -36,7 +35,7 @@ internal abstract class LookForAbandonedLogic
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static void LookForAbandoned(Property.Models.Configuration propertyConfiguration, string bResultsFullGroupDirectory, List<int> distinctFilteredIds)
|
internal static void LookForAbandoned(Property.Models.Configuration propertyConfiguration, string bResultsFullGroupDirectory, List<string> distinctFilteredFileNameFirstSegments)
|
||||||
{
|
{
|
||||||
string[] directories = Directory.GetDirectories(bResultsFullGroupDirectory, "*", SearchOption.TopDirectoryOnly);
|
string[] directories = Directory.GetDirectories(bResultsFullGroupDirectory, "*", SearchOption.TopDirectoryOnly);
|
||||||
foreach (string directory in directories)
|
foreach (string directory in directories)
|
||||||
@ -44,7 +43,7 @@ internal abstract class LookForAbandonedLogic
|
|||||||
string? directoryName = Path.GetFileName(directory);
|
string? directoryName = Path.GetFileName(directory);
|
||||||
if (string.IsNullOrEmpty(directoryName) || (directoryName.Length != 2 && directoryName.Length != 4))
|
if (string.IsNullOrEmpty(directoryName) || (directoryName.Length != 2 && directoryName.Length != 4))
|
||||||
continue;
|
continue;
|
||||||
LookForAbandoned(propertyConfiguration, distinctFilteredIds, directory, directoryName);
|
LookForAbandoned(propertyConfiguration, distinctFilteredFileNameFirstSegments, directory, directoryName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -27,6 +27,7 @@ internal abstract class MapLogic
|
|||||||
internal record PersonKeyFormattedIdThenWholePercentages(string PersonKeyFormatted,
|
internal record PersonKeyFormattedIdThenWholePercentages(string PersonKeyFormatted,
|
||||||
string? PersonDisplayDirectoryName,
|
string? PersonDisplayDirectoryName,
|
||||||
bool? IsDefault,
|
bool? IsDefault,
|
||||||
|
int? LinksCount,
|
||||||
FilePath MappedFaceFilePath,
|
FilePath MappedFaceFilePath,
|
||||||
int Id,
|
int Id,
|
||||||
int WholePercentages);
|
int WholePercentages);
|
||||||
@ -67,7 +68,7 @@ internal abstract class MapLogic
|
|||||||
wholePercentages = IMapping.GetWholePercentages(configuration.FacesFileNameExtension, filePath);
|
wholePercentages = IMapping.GetWholePercentages(configuration.FacesFileNameExtension, filePath);
|
||||||
if (wholePercentages is null)
|
if (wholePercentages is null)
|
||||||
continue;
|
continue;
|
||||||
if (!skipNotSkipDirectoriesAny || !checkDirectories.Any(l => filePath.FullName.StartsWith(l)))
|
if (!skipNotSkipDirectoriesAny || !checkDirectories.Any(filePath.FullName.StartsWith))
|
||||||
{
|
{
|
||||||
if (!skipCollection.ContainsKey(filePath.Id.Value))
|
if (!skipCollection.ContainsKey(filePath.Id.Value))
|
||||||
skipCollection.Add(filePath.Id.Value, []);
|
skipCollection.Add(filePath.Id.Value, []);
|
||||||
@ -105,8 +106,9 @@ internal abstract class MapLogic
|
|||||||
internal static string GetMappingSegmentB(long ticks, long personKey, int? approximateYears, MappingFromItem mappingFromItem)
|
internal static string GetMappingSegmentB(long ticks, long personKey, int? approximateYears, MappingFromItem mappingFromItem)
|
||||||
{
|
{
|
||||||
string result;
|
string result;
|
||||||
|
DateTime dateTime = mappingFromItem.GetDateTimeOriginalThenMinimumDateTime();
|
||||||
PersonBirthday personBirthday = IPersonBirthday.GetPersonBirthday(personKey);
|
PersonBirthday personBirthday = IPersonBirthday.GetPersonBirthday(personKey);
|
||||||
result = GetMappingSegmentB(ticks, personBirthday, approximateYears, mappingFromItem.GetDateTimeOriginalThenMinimumDateTime(), mappingFromItem.IsWrongYear);
|
result = GetMappingSegmentB(ticks, personBirthday, approximateYears, dateTime, mappingFromItem.IsWrongYear);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -177,7 +179,9 @@ internal abstract class MapLogic
|
|||||||
|
|
||||||
internal static string GetMappingSegmentB(long ticks, PersonBirthday personBirthday, int? approximateYears, MappingFromItem mappingFromItem)
|
internal static string GetMappingSegmentB(long ticks, PersonBirthday personBirthday, int? approximateYears, MappingFromItem mappingFromItem)
|
||||||
{
|
{
|
||||||
string result = GetMappingSegmentB(ticks, personBirthday, approximateYears, mappingFromItem.GetDateTimeOriginalThenMinimumDateTime(), mappingFromItem.IsWrongYear);
|
string result;
|
||||||
|
DateTime dateTime = mappingFromItem.GetDateTimeOriginalThenMinimumDateTime();
|
||||||
|
result = GetMappingSegmentB(ticks, personBirthday, approximateYears, dateTime, mappingFromItem.IsWrongYear);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -234,7 +238,7 @@ internal abstract class MapLogic
|
|||||||
{
|
{
|
||||||
string result;
|
string result;
|
||||||
(string directoryName, _) = IPath.GetDirectoryNameAndIndex(propertyConfiguration, filePath);
|
(string directoryName, _) = IPath.GetDirectoryNameAndIndex(propertyConfiguration, filePath);
|
||||||
result = Path.Combine(dFacesContentDirectory, directoryName, mappingFromItem.ImageFileHolder.NameWithoutExtension);
|
result = Path.Combine(dFacesContentDirectory, directoryName, mappingFromItem.FilePath.NameWithoutExtension);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -298,13 +302,14 @@ internal abstract class MapLogic
|
|||||||
return results;
|
return results;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Dictionary<int, Dictionary<int, List<PersonContainer>>> GetAll(Configuration configuration, ReadOnlyDictionary<string, PersonContainer> personKeyFormattedToPersonContainer, ReadOnlyCollection<PersonKeyFormattedIdThenWholePercentages> personKeyFormattedIdThenWholePercentagesCollection)
|
private static Dictionary<int, Dictionary<int, List<PersonContainer>>> GetAll(Configuration configuration, Dictionary<int, List<(string, int)>> skipCollection, ReadOnlyDictionary<string, PersonContainer> personKeyFormattedToPersonContainer, ReadOnlyCollection<PersonKeyFormattedIdThenWholePercentages> personKeyFormattedIdThenWholePercentagesCollection)
|
||||||
{
|
{
|
||||||
Dictionary<int, Dictionary<int, List<PersonContainer>>> results = [];
|
Dictionary<int, Dictionary<int, List<PersonContainer>>> results = [];
|
||||||
PersonBirthday? personBirthday;
|
PersonBirthday? personBirthday;
|
||||||
PersonContainer? personContainer;
|
PersonContainer? personContainer;
|
||||||
List<PersonContainer>? personContainers;
|
List<PersonContainer>? personContainers;
|
||||||
Dictionary<int, List<PersonContainer>>? idTo;
|
Dictionary<int, List<PersonContainer>>? idTo;
|
||||||
|
int? linkedAlphaCheck = string.IsNullOrEmpty(configuration.LinkedAlpha) ? null : configuration.LinkedAlpha[0] - 65;
|
||||||
if (personKeyFormattedIdThenWholePercentagesCollection.Count > 0)
|
if (personKeyFormattedIdThenWholePercentagesCollection.Count > 0)
|
||||||
{
|
{
|
||||||
foreach (PersonKeyFormattedIdThenWholePercentages personKeyFormattedIdThenWholePercentages in personKeyFormattedIdThenWholePercentagesCollection)
|
foreach (PersonKeyFormattedIdThenWholePercentages personKeyFormattedIdThenWholePercentages in personKeyFormattedIdThenWholePercentagesCollection)
|
||||||
@ -312,6 +317,13 @@ internal abstract class MapLogic
|
|||||||
personBirthday = IPersonBirthday.GetPersonBirthday(configuration.PersonBirthdayFormat, personKeyFormattedIdThenWholePercentages.PersonKeyFormatted);
|
personBirthday = IPersonBirthday.GetPersonBirthday(configuration.PersonBirthdayFormat, personKeyFormattedIdThenWholePercentages.PersonKeyFormatted);
|
||||||
if (personBirthday is null)
|
if (personBirthday is null)
|
||||||
throw new Exception();
|
throw new Exception();
|
||||||
|
if (linkedAlphaCheck is not null && personKeyFormattedIdThenWholePercentages.LinksCount is not null && personKeyFormattedIdThenWholePercentages.LinksCount.Value < linkedAlphaCheck.Value)
|
||||||
|
{
|
||||||
|
if (!skipCollection.ContainsKey(personKeyFormattedIdThenWholePercentages.Id))
|
||||||
|
skipCollection.Add(personKeyFormattedIdThenWholePercentages.Id, []);
|
||||||
|
skipCollection[personKeyFormattedIdThenWholePercentages.Id].Add((personKeyFormattedIdThenWholePercentages.MappedFaceFilePath.FullName, personKeyFormattedIdThenWholePercentages.WholePercentages));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
if (!personKeyFormattedToPersonContainer.TryGetValue(personKeyFormattedIdThenWholePercentages.PersonKeyFormatted, out personContainer))
|
if (!personKeyFormattedToPersonContainer.TryGetValue(personKeyFormattedIdThenWholePercentages.PersonKeyFormatted, out personContainer))
|
||||||
throw new Exception();
|
throw new Exception();
|
||||||
if (!results.TryGetValue(personKeyFormattedIdThenWholePercentages.Id, out idTo))
|
if (!results.TryGetValue(personKeyFormattedIdThenWholePercentages.Id, out idTo))
|
||||||
@ -426,7 +438,7 @@ internal abstract class MapLogic
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static List<MappedFile> GetMappedFiles(Shared.Models.Properties.IPropertyConfiguration propertyConfiguration, Configuration configuration, ReadOnlyCollection<PersonContainer> personContainers, List<Record> records)
|
internal static List<MappedFile> GetMappedFiles(Shared.Models.Properties.IPropertyConfiguration propertyConfiguration, Configuration configuration, ReadOnlyCollection<PersonContainer> personContainers, List<Record> records)
|
||||||
{
|
{
|
||||||
List<MappedFile> results = [];
|
List<MappedFile> results = [];
|
||||||
long personKey;
|
long personKey;
|
||||||
@ -455,9 +467,9 @@ internal abstract class MapLogic
|
|||||||
results.RemoveAt(i);
|
results.RemoveAt(i);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (!filePath.Name.EndsWith(".dup") && !filePath.Name.EndsWith(".unk") && !filePath.Name.EndsWith(".abd"))
|
if (!filePath.Name.EndsWith(".abd") && !filePath.Name.EndsWith(".brt") && !filePath.Name.EndsWith(".dup") && !filePath.Name.EndsWith(".unk"))
|
||||||
continue;
|
continue;
|
||||||
if (!File.Exists(filePath.Name))
|
if (!File.Exists(filePath.FullName))
|
||||||
continue;
|
continue;
|
||||||
checkFile = filePath.FullName[..^4];
|
checkFile = filePath.FullName[..^4];
|
||||||
if (File.Exists(checkFile))
|
if (File.Exists(checkFile))
|
||||||
@ -470,7 +482,7 @@ internal abstract class MapLogic
|
|||||||
return results;
|
return results;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void ParallelFor(Shared.Models.Properties.IPropertyConfiguration propertyConfiguration, Configuration configuration, Dictionary<int, List<(string, int)>> skipCollection, List<LocationContainer> locationContainers, MappedFile mappedFile)
|
private static void ParallelFor(Shared.Models.Properties.IPropertyConfiguration propertyConfiguration, Configuration configuration, ReadOnlyDictionary<int, List<(string, int)>> skipCollection, List<LocationContainer> locationContainers, MappedFile mappedFile)
|
||||||
{
|
{
|
||||||
int? id;
|
int? id;
|
||||||
string checkFile;
|
string checkFile;
|
||||||
@ -502,7 +514,7 @@ internal abstract class MapLogic
|
|||||||
}
|
}
|
||||||
if (wholePercentages is null)
|
if (wholePercentages is null)
|
||||||
return;
|
return;
|
||||||
if (string.IsNullOrEmpty(configuration.LocationContainerDebugDirectory) && skipCollection.TryGetValue(id.Value, out wholePercentagesCollection))
|
if (configuration.LinkedAlpha is null && string.IsNullOrEmpty(configuration.LocationContainerDebugDirectory) && skipCollection.TryGetValue(id.Value, out wholePercentagesCollection))
|
||||||
{
|
{
|
||||||
fileMatches = (from l in wholePercentagesCollection where l.WholePercentages == wholePercentages select l.File).ToArray();
|
fileMatches = (from l in wholePercentagesCollection where l.WholePercentages == wholePercentages select l.File).ToArray();
|
||||||
foreach (string fileMatch in fileMatches)
|
foreach (string fileMatch in fileMatches)
|
||||||
@ -528,10 +540,13 @@ internal abstract class MapLogic
|
|||||||
exifDirectory,
|
exifDirectory,
|
||||||
mappedFile.DirectoryNumber,
|
mappedFile.DirectoryNumber,
|
||||||
personDisplayDirectoryName,
|
personDisplayDirectoryName,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
mappedFile.FilePath,
|
mappedFile.FilePath,
|
||||||
fromDistanceContent,
|
fromDistanceContent,
|
||||||
id.Value,
|
id.Value,
|
||||||
null,
|
null,
|
||||||
|
null,
|
||||||
mappedFile.PersonKey,
|
mappedFile.PersonKey,
|
||||||
rectangle,
|
rectangle,
|
||||||
wholePercentages.Value));
|
wholePercentages.Value));
|
||||||
@ -549,6 +564,8 @@ internal abstract class MapLogic
|
|||||||
Dictionary<string, (FilePath, int)> distinct = [];
|
Dictionary<string, (FilePath, int)> distinct = [];
|
||||||
foreach (LocationContainer locationContainer in locationContainers)
|
foreach (LocationContainer locationContainer in locationContainers)
|
||||||
{
|
{
|
||||||
|
if (locationContainer.PersonKey is null)
|
||||||
|
continue;
|
||||||
key = string.Concat(locationContainer.PersonKey, locationContainer.Id);
|
key = string.Concat(locationContainer.PersonKey, locationContainer.Id);
|
||||||
if (distinct.TryGetValue(key, out item))
|
if (distinct.TryGetValue(key, out item))
|
||||||
{
|
{
|
||||||
@ -564,7 +581,7 @@ internal abstract class MapLogic
|
|||||||
}
|
}
|
||||||
delete.Add(item.FilePath);
|
delete.Add(item.FilePath);
|
||||||
delete.Add(locationContainer.FilePath);
|
delete.Add(locationContainer.FilePath);
|
||||||
duplicates.Add(new(locationContainer.PersonKey, locationContainer.Id, locationContainer.FilePath, percent));
|
duplicates.Add(new(locationContainer.PersonKey.Value, locationContainer.Id, locationContainer.FilePath, percent));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
distinct.Add(key, new(locationContainer.FilePath, locationContainer.WholePercentages));
|
distinct.Add(key, new(locationContainer.FilePath, locationContainer.WholePercentages));
|
||||||
@ -596,16 +613,16 @@ internal abstract class MapLogic
|
|||||||
result = null;
|
result = null;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
string checkFile = Path.Combine(directory, $"{keyMapping.MappingFromItem.ImageFileHolder.Name}{facePartsFileNameExtension}");
|
string checkFile = Path.Combine(directory, $"{keyMapping.MappingFromItem.FilePath.Name}{facePartsFileNameExtension}");
|
||||||
result = new(checkFile, directory, IFileHolder.Get(facePartsContentCollectionFile));
|
result = new(checkFile, directory, IFileHolder.Get(facePartsContentCollectionFile));
|
||||||
}
|
}
|
||||||
string facesDirectory = GetFacesDirectory(propertyConfiguration, dFacesContentDirectory, keyMapping.FilePath, keyMapping.MappingFromItem);
|
string facesDirectory = GetFacesDirectory(propertyConfiguration, dFacesContentDirectory, keyMapping.FilePath, keyMapping.MappingFromItem);
|
||||||
FileHolder faceFileHolder = IFileHolder.Get(Path.Combine(facesDirectory, $"{keyMapping.MappingFromLocation.DeterministicHashCodeKey}{keyMapping.MappingFromItem.ImageFileHolder.ExtensionLowered}{facesFileNameExtension}"));
|
FileHolder faceFileHolder = IFileHolder.Get(Path.Combine(facesDirectory, $"{keyMapping.MappingFromLocation.DeterministicHashCodeKey}{keyMapping.MappingFromItem.FilePath.ExtensionLowered}{facesFileNameExtension}"));
|
||||||
if (!faceFileHolder.Exists)
|
if (!faceFileHolder.Exists)
|
||||||
saveContainer = null;
|
saveContainer = null;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
string checkFile = Path.Combine(directory, $"{keyMapping.MappingFromLocation.DeterministicHashCodeKey}{keyMapping.MappingFromItem.ImageFileHolder.ExtensionLowered}{facesFileNameExtension}");
|
string checkFile = Path.Combine(directory, $"{keyMapping.MappingFromLocation.DeterministicHashCodeKey}{keyMapping.MappingFromItem.FilePath.ExtensionLowered}{facesFileNameExtension}");
|
||||||
saveContainer = new(checkFile, directory, faceFileHolder);
|
saveContainer = new(checkFile, directory, faceFileHolder);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -734,11 +751,11 @@ internal abstract class MapLogic
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static ReadOnlyDictionary<int, ReadOnlyDictionary<int, ReadOnlyCollection<PersonContainer>>> GetIdThenWholePercentagesToPersonContainers(Configuration configuration, ReadOnlyDictionary<string, PersonContainer> personKeyFormattedToPersonContainer, ReadOnlyCollection<PersonKeyFormattedIdThenWholePercentages> personKeyFormattedIdThenWholePercentagesCollection)
|
internal static ReadOnlyDictionary<int, ReadOnlyDictionary<int, ReadOnlyCollection<PersonContainer>>> GetIdThenWholePercentagesToPersonContainers(Configuration configuration, Dictionary<int, List<(string, int)>> skipCollection, ReadOnlyDictionary<string, PersonContainer> personKeyFormattedToPersonContainer, ReadOnlyCollection<PersonKeyFormattedIdThenWholePercentages> personKeyFormattedIdThenWholePercentagesCollection)
|
||||||
{
|
{
|
||||||
ReadOnlyDictionary<int, ReadOnlyDictionary<int, ReadOnlyCollection<PersonContainer>>> results;
|
ReadOnlyDictionary<int, ReadOnlyDictionary<int, ReadOnlyCollection<PersonContainer>>> results;
|
||||||
Dictionary<int, Dictionary<int, List<PersonContainer>>> idThenWholePercentagesToPersonContainerCollection;
|
Dictionary<int, Dictionary<int, List<PersonContainer>>> idThenWholePercentagesToPersonContainerCollection;
|
||||||
idThenWholePercentagesToPersonContainerCollection = GetAll(configuration, personKeyFormattedToPersonContainer, personKeyFormattedIdThenWholePercentagesCollection);
|
idThenWholePercentagesToPersonContainerCollection = GetAll(configuration, skipCollection, personKeyFormattedToPersonContainer, personKeyFormattedIdThenWholePercentagesCollection);
|
||||||
results = GetReadOnly(idThenWholePercentagesToPersonContainerCollection);
|
results = GetReadOnly(idThenWholePercentagesToPersonContainerCollection);
|
||||||
return results;
|
return results;
|
||||||
}
|
}
|
||||||
@ -766,7 +783,7 @@ internal abstract class MapLogic
|
|||||||
wholePercentagesCollection = idToWholePercentagesCollection[record.MappedFaceFilePath.Id.Value];
|
wholePercentagesCollection = idToWholePercentagesCollection[record.MappedFaceFilePath.Id.Value];
|
||||||
wholePercentagesCollection.Add(wholePercentages.Value);
|
wholePercentagesCollection.Add(wholePercentages.Value);
|
||||||
idToWholePercentagesCollection[record.MappedFaceFilePath.Id.Value].Add(wholePercentages.Value);
|
idToWholePercentagesCollection[record.MappedFaceFilePath.Id.Value].Add(wholePercentages.Value);
|
||||||
results.Add(new(record.PersonKeyFormatted, record.PersonDisplayDirectoryName, record.IsDefault, record.MappedFaceFilePath, record.MappedFaceFilePath.Id.Value, wholePercentages.Value));
|
results.Add(new(record.PersonKeyFormatted, record.PersonDisplayDirectoryName, record.IsDefault, record.LinksCount, record.MappedFaceFilePath, record.MappedFaceFilePath.Id.Value, wholePercentages.Value));
|
||||||
}
|
}
|
||||||
return new(results);
|
return new(results);
|
||||||
}
|
}
|
||||||
@ -890,7 +907,7 @@ internal abstract class MapLogic
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static List<LocationContainer> GetLocationContainers(int maxDegreeOfParallelism, Shared.Models.Properties.IPropertyConfiguration propertyConfiguration, Configuration configuration, long ticks, ReadOnlyCollection<PersonContainer> personContainers, Dictionary<int, List<(string, int)>> skipCollection, List<Record> records)
|
internal static List<LocationContainer> GetLocationContainers(int maxDegreeOfParallelism, Shared.Models.Properties.IPropertyConfiguration propertyConfiguration, Configuration configuration, long ticks, ReadOnlyCollection<PersonContainer> personContainers, ReadOnlyDictionary<int, List<(string, int)>> skipCollection, List<Record> records)
|
||||||
{
|
{
|
||||||
List<LocationContainer> results = [];
|
List<LocationContainer> results = [];
|
||||||
List<MappedFile> mappedFiles = GetMappedFiles(propertyConfiguration, configuration, personContainers, records);
|
List<MappedFile> mappedFiles = GetMappedFiles(propertyConfiguration, configuration, personContainers, records);
|
||||||
@ -966,7 +983,7 @@ internal abstract class MapLogic
|
|||||||
if (directoryName is null)
|
if (directoryName is null)
|
||||||
result = null;
|
result = null;
|
||||||
else
|
else
|
||||||
result = Path.Combine($"{d2FacePartsContentCollectionDirectory}{directoryName}", $"{mappingFromItem.ImageFileHolder.Name}{extension}");
|
result = Path.Combine($"{d2FacePartsContentCollectionDirectory}{directoryName}", $"{mappingFromItem.FilePath.Name}{extension}");
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -974,7 +991,23 @@ internal abstract class MapLogic
|
|||||||
{
|
{
|
||||||
string result;
|
string result;
|
||||||
(string directoryName, _) = IPath.GetDirectoryNameAndIndex(propertyConfiguration, filePath);
|
(string directoryName, _) = IPath.GetDirectoryNameAndIndex(propertyConfiguration, filePath);
|
||||||
result = Path.Combine(d2FacePartsContentDirectory, directoryName, mappingFromItem.ImageFileHolder.NameWithoutExtension);
|
result = Path.Combine(d2FacePartsContentDirectory, directoryName, mappingFromItem.FilePath.NameWithoutExtension);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static string GetFacePartsDirectoryX(Shared.Models.Properties.IPropertyConfiguration propertyConfiguration, string d2FacePartsContentDirectory, FilePath filePath)
|
||||||
|
{
|
||||||
|
string result;
|
||||||
|
(string directoryName, _) = IPath.GetDirectoryNameAndIndex(propertyConfiguration, filePath);
|
||||||
|
result = Path.Combine(d2FacePartsContentDirectory, directoryName, filePath.NameWithoutExtension);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static string GetResizeContentDirectory(Shared.Models.Properties.IPropertyConfiguration propertyConfiguration, string cContentDirectory, FilePath filePath)
|
||||||
|
{
|
||||||
|
string result;
|
||||||
|
(string directoryName, _) = IPath.GetDirectoryNameAndIndex(propertyConfiguration, filePath);
|
||||||
|
result = Path.Combine(cContentDirectory, directoryName);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -986,9 +1019,9 @@ internal abstract class MapLogic
|
|||||||
throw new NullReferenceException(nameof(sortingContainer.Source.MappingFromLocation));
|
throw new NullReferenceException(nameof(sortingContainer.Source.MappingFromLocation));
|
||||||
FileHolder faceFileHolder = IFileHolder.Get($"C:/{sortingContainer.Sorting.Id}.{sortingContainer.Sorting.WholePercentages}");
|
FileHolder faceFileHolder = IFileHolder.Get($"C:/{sortingContainer.Sorting.Id}.{sortingContainer.Sorting.WholePercentages}");
|
||||||
if (keyMapping.MappingFromPerson is not null && keyMapping.MappingFromLocation is not null)
|
if (keyMapping.MappingFromPerson is not null && keyMapping.MappingFromLocation is not null)
|
||||||
shortcutFile = Path.Combine(directory, $"{keyMapping.MappingFromLocation.DeterministicHashCodeKey}{keyMapping.MappingFromItem.ImageFileHolder.ExtensionLowered}.{sortingContainer.Sorting.DistancePermyriad}.lnk");
|
shortcutFile = Path.Combine(directory, $"{keyMapping.MappingFromLocation.DeterministicHashCodeKey}{keyMapping.MappingFromItem.FilePath.ExtensionLowered}.{sortingContainer.Sorting.DistancePermyriad}.lnk");
|
||||||
else
|
else
|
||||||
shortcutFile = Path.Combine(directory, $"{sortingContainer.Source.MappingFromLocation.DeterministicHashCodeKey}{sortingContainer.Source.MappingFromItem.ImageFileHolder.ExtensionLowered}.{sortingContainer.Sorting.DistancePermyriad}.lnk");
|
shortcutFile = Path.Combine(directory, $"{sortingContainer.Source.MappingFromLocation.DeterministicHashCodeKey}{sortingContainer.Source.MappingFromItem.FilePath.ExtensionLowered}.{sortingContainer.Sorting.DistancePermyriad}.lnk");
|
||||||
result = new(directory, faceFileHolder, sortingContainer.Source.MappingFromItem.ResizedFileHolder, shortcutFile);
|
result = new(directory, faceFileHolder, sortingContainer.Source.MappingFromItem.ResizedFileHolder, shortcutFile);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@ -999,9 +1032,9 @@ internal abstract class MapLogic
|
|||||||
SaveContainer? saveContainer;
|
SaveContainer? saveContainer;
|
||||||
if (mapping.MappingFromLocation is null)
|
if (mapping.MappingFromLocation is null)
|
||||||
throw new NullReferenceException(nameof(mapping.MappingFromLocation));
|
throw new NullReferenceException(nameof(mapping.MappingFromLocation));
|
||||||
checkFile = Path.Combine(directory, $"{mapping.MappingFromItem.ImageFileHolder.Name}{facePartsFileNameExtension}");
|
checkFile = Path.Combine(directory, $"{mapping.MappingFromItem.FilePath.Name}{facePartsFileNameExtension}");
|
||||||
saveContainer = !facePartsFileHolder.Exists ? null : new(checkFile, directory, facePartsFileHolder);
|
saveContainer = !facePartsFileHolder.Exists ? null : new(checkFile, directory, facePartsFileHolder);
|
||||||
checkFile = Path.Combine(directory, $"{mapping.MappingFromLocation.DeterministicHashCodeKey}{mapping.MappingFromItem.ImageFileHolder.ExtensionLowered}{facesFileNameExtension}");
|
checkFile = Path.Combine(directory, $"{mapping.MappingFromLocation.DeterministicHashCodeKey}{mapping.MappingFromItem.FilePath.ExtensionLowered}{facesFileNameExtension}");
|
||||||
return (new(checkFile, directory, faceFileHolder), saveContainer);
|
return (new(checkFile, directory, faceFileHolder), saveContainer);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1086,11 +1119,11 @@ internal abstract class MapLogic
|
|||||||
return new(results);
|
return new(results);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static ReadOnlyDictionary<int, ReadOnlyDictionary<int, Mapping>> GetIdToWholePercentagesToFace(ReadOnlyCollection<Mapping> mappingCollection)
|
internal static ReadOnlyDictionary<int, ReadOnlyDictionary<int, Mapping>> GetIdToWholePercentagesToFace(ReadOnlyCollection<Mapping> distinctValidImageMappingCollection)
|
||||||
{
|
{
|
||||||
Dictionary<int, Dictionary<int, Mapping>> results = [];
|
Dictionary<int, Dictionary<int, Mapping>> results = [];
|
||||||
Dictionary<int, Mapping>? keyValuePairs;
|
Dictionary<int, Mapping>? keyValuePairs;
|
||||||
foreach (Mapping mapping in mappingCollection)
|
foreach (Mapping mapping in distinctValidImageMappingCollection)
|
||||||
{
|
{
|
||||||
if (mapping.MappingFromLocation is null)
|
if (mapping.MappingFromLocation is null)
|
||||||
continue;
|
continue;
|
||||||
@ -1159,29 +1192,29 @@ internal abstract class MapLogic
|
|||||||
return results;
|
return results;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static (string, bool, bool) Get(int? useFiltersCounter, bool saveIndividually, bool sortingContainersAny, string forceSingleImageHumanized, int? distancePermyriad, Mapping mapping)
|
internal static (string, bool, bool) Get(int? useFiltersCounter, bool saveIndividually, bool sortingContainersAny, string forceSingleImageHumanized, int? distancePermyriad, int? by, string? displayDirectoryName)
|
||||||
{
|
{
|
||||||
string by;
|
string byValue;
|
||||||
bool isByMapping;
|
bool isByMapping;
|
||||||
bool isBySorting;
|
bool isBySorting;
|
||||||
if (mapping.By is null)
|
if (by is null)
|
||||||
{
|
{
|
||||||
isByMapping = false;
|
isByMapping = false;
|
||||||
isBySorting = !sortingContainersAny;
|
isBySorting = !sortingContainersAny;
|
||||||
by = $"{nameof(Shared.Models.Stateless.IMapLogic.Mapping)}Null";
|
byValue = $"{nameof(Shared.Models.Stateless.IMapLogic.Mapping)}Null";
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
isByMapping = mapping.By == Shared.Models.Stateless.IMapLogic.Mapping;
|
isByMapping = by == Shared.Models.Stateless.IMapLogic.Mapping;
|
||||||
isBySorting = mapping.By == Shared.Models.Stateless.IMapLogic.Sorting;
|
isBySorting = by == Shared.Models.Stateless.IMapLogic.Sorting;
|
||||||
bool isDefaultName = mapping.MappingFromPerson is not null && IPerson.IsDefaultName(mapping.MappingFromPerson.DisplayDirectoryName);
|
bool isDefaultName = displayDirectoryName is not null && IPerson.IsDefaultName(displayDirectoryName);
|
||||||
if (isBySorting && mapping.MappingFromPerson is null)
|
if (isBySorting && displayDirectoryName is null)
|
||||||
by = saveIndividually ? nameof(Shared.Models.Stateless.IMapLogic.Individually) : $"{nameof(Shared.Models.Stateless.IMapLogic.Sorting)} Without Person{(distancePermyriad < 2000 ? "-A" : "-Z")}";
|
byValue = saveIndividually ? nameof(Shared.Models.Stateless.IMapLogic.Individually) : $"{nameof(Shared.Models.Stateless.IMapLogic.Sorting)} Without Person{(distancePermyriad < 2000 ? "-A" : "-Z")}";
|
||||||
else if (isBySorting && useFiltersCounter.HasValue)
|
else if (isBySorting && useFiltersCounter.HasValue)
|
||||||
by = $"{nameof(Shared.Models.Stateless.IMapLogic.Sorting)}{(!isDefaultName ? "-A" : "-Z")} Modified Filters - {useFiltersCounter.Value}";
|
byValue = $"{nameof(Shared.Models.Stateless.IMapLogic.Sorting)}{(!isDefaultName ? "-A" : "-Z")} Modified Filters - {useFiltersCounter.Value}";
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
by = $"{mapping.By.Value switch
|
byValue = $"{by.Value switch
|
||||||
{
|
{
|
||||||
Shared.Models.Stateless.IMapLogic.Mapping => nameof(Shared.Models.Stateless.IMapLogic.Mapping),
|
Shared.Models.Stateless.IMapLogic.Mapping => nameof(Shared.Models.Stateless.IMapLogic.Mapping),
|
||||||
Shared.Models.Stateless.IMapLogic.Sorting => saveIndividually ? nameof(Shared.Models.Stateless.IMapLogic.Individually) : nameof(Shared.Models.Stateless.IMapLogic.Sorting),
|
Shared.Models.Stateless.IMapLogic.Sorting => saveIndividually ? nameof(Shared.Models.Stateless.IMapLogic.Individually) : nameof(Shared.Models.Stateless.IMapLogic.Sorting),
|
||||||
@ -1190,9 +1223,15 @@ internal abstract class MapLogic
|
|||||||
}}{(!isDefaultName ? "-A" : "-Z")}";
|
}}{(!isDefaultName ? "-A" : "-Z")}";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return new(by, isByMapping, isBySorting);
|
return new(byValue, isByMapping, isBySorting);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal static (string, bool, bool) Get(int? useFiltersCounter, bool saveIndividually, bool sortingContainersAny, string forceSingleImageHumanized, int? distancePermyriad, long? personKey, string? displayDirectoryName) =>
|
||||||
|
Get(useFiltersCounter, saveIndividually, sortingContainersAny, forceSingleImageHumanized, distancePermyriad, personKey is null ? null : Shared.Models.Stateless.IMapLogic.Mapping, displayDirectoryName);
|
||||||
|
|
||||||
|
internal static (string, bool, bool) Get(int? useFiltersCounter, bool saveIndividually, bool sortingContainersAny, string forceSingleImageHumanized, int? distancePermyriad, Mapping mapping) =>
|
||||||
|
Get(useFiltersCounter, saveIndividually, sortingContainersAny, forceSingleImageHumanized, distancePermyriad, mapping.By, mapping.MappingFromPerson?.DisplayDirectoryName);
|
||||||
|
|
||||||
internal static void CheckCollection(Shared.Models.Properties.IPropertyConfiguration propertyConfiguration, string? rootDirectoryParent)
|
internal static void CheckCollection(Shared.Models.Properties.IPropertyConfiguration propertyConfiguration, string? rootDirectoryParent)
|
||||||
{
|
{
|
||||||
string json;
|
string json;
|
||||||
@ -1260,7 +1299,7 @@ internal abstract class MapLogic
|
|||||||
return new(results);
|
return new(results);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static bool? CanReMap(long[] jLinkResolvedPersonKeys, ReadOnlyDictionary<int, ReadOnlyCollection<PersonContainer>>? wholePercentagesToPersonContainers, MappingFromLocation mappingFromLocation)
|
internal static bool? CanReMap(long[] jLinkResolvedPersonKeys, ReadOnlyDictionary<int, ReadOnlyCollection<PersonContainer>>? wholePercentagesToPersonContainers, int wholePercentages)
|
||||||
{
|
{
|
||||||
bool? result;
|
bool? result;
|
||||||
ReadOnlyCollection<PersonContainer>? personContainers;
|
ReadOnlyCollection<PersonContainer>? personContainers;
|
||||||
@ -1268,7 +1307,7 @@ internal abstract class MapLogic
|
|||||||
result = null;
|
result = null;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (!wholePercentagesToPersonContainers.TryGetValue(mappingFromLocation.WholePercentages, out personContainers))
|
if (!wholePercentagesToPersonContainers.TryGetValue(wholePercentages, out personContainers))
|
||||||
result = null;
|
result = null;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -1,4 +1,6 @@
|
|||||||
using System.Collections.ObjectModel;
|
using System.Collections.ObjectModel;
|
||||||
|
using View_by_Distance.Shared.Models;
|
||||||
|
using View_by_Distance.Shared.Models.Stateless.Methods;
|
||||||
|
|
||||||
namespace View_by_Distance.Map.Models.Stateless.Methods;
|
namespace View_by_Distance.Map.Models.Stateless.Methods;
|
||||||
|
|
||||||
@ -10,44 +12,64 @@ public interface IMapLogic
|
|||||||
static ReadOnlyDictionary<int, List<long>> GetIdToPersonKeys(ReadOnlyDictionary<long, List<int>> personKeyToIds) =>
|
static ReadOnlyDictionary<int, List<long>> GetIdToPersonKeys(ReadOnlyDictionary<long, List<int>> personKeyToIds) =>
|
||||||
MapLogic.GetIdToPersonKeys(personKeyToIds);
|
MapLogic.GetIdToPersonKeys(personKeyToIds);
|
||||||
|
|
||||||
ReadOnlyCollection<Shared.Models.Face> TestStatic_GetFaces(ReadOnlyCollection<Shared.Models.Item> items) =>
|
ReadOnlyCollection<Face> TestStatic_GetFaces(ReadOnlyCollection<Item> items) =>
|
||||||
GetFaces(items);
|
GetFaces(items);
|
||||||
static ReadOnlyCollection<Shared.Models.Face> GetFaces(ReadOnlyCollection<Shared.Models.Item> items) =>
|
static ReadOnlyCollection<Face> GetFaces(ReadOnlyCollection<Item> items) =>
|
||||||
MapLogic.GetFaces(items);
|
MapLogic.GetFaces(items);
|
||||||
|
|
||||||
Shared.Models.Mapping[] TestStatic_GetSelectedMappingCollection(ReadOnlyCollection<Shared.Models.Item> items) =>
|
Mapping[] TestStatic_GetSelectedMappingCollection(ReadOnlyCollection<Item> items) =>
|
||||||
GetSelectedMappingCollection(items);
|
GetSelectedMappingCollection(items);
|
||||||
static Shared.Models.Mapping[] GetSelectedMappingCollection(ReadOnlyCollection<Shared.Models.Item> items) =>
|
static Mapping[] GetSelectedMappingCollection(ReadOnlyCollection<Item> items) =>
|
||||||
MapLogic.GetSelectedMappingCollection(items);
|
MapLogic.GetSelectedMappingCollection(items);
|
||||||
|
|
||||||
Shared.Models.Mapping[] TestStatic_GetSelectedMappingCollection(ReadOnlyCollection<Shared.Models.Face> faces) =>
|
Mapping[] TestStatic_GetSelectedMappingCollection(ReadOnlyCollection<Face> faces) =>
|
||||||
GetSelectedMappingCollection(faces);
|
GetSelectedMappingCollection(faces);
|
||||||
static Shared.Models.Mapping[] GetSelectedMappingCollection(ReadOnlyCollection<Shared.Models.Face> faces) =>
|
static Mapping[] GetSelectedMappingCollection(ReadOnlyCollection<Face> faces) =>
|
||||||
MapLogic.GetSelectedMappingCollection(faces);
|
MapLogic.GetSelectedMappingCollection(faces);
|
||||||
|
|
||||||
ReadOnlyDictionary<int, ReadOnlyDictionary<int, Shared.Models.Mapping>> TestStatic_GetIdToWholePercentagesToFace(ReadOnlyCollection<Shared.Models.Mapping> mappingCollection) =>
|
ReadOnlyDictionary<int, ReadOnlyDictionary<int, Mapping>> TestStatic_GetIdToWholePercentagesToFace(ReadOnlyCollection<Mapping> distinctValidImageMappingCollection) =>
|
||||||
GetIdToWholePercentagesToFace(mappingCollection);
|
GetIdToWholePercentagesToFace(distinctValidImageMappingCollection);
|
||||||
static ReadOnlyDictionary<int, ReadOnlyDictionary<int, Shared.Models.Mapping>> GetIdToWholePercentagesToFace(ReadOnlyCollection<Shared.Models.Mapping> mappingCollection) =>
|
static ReadOnlyDictionary<int, ReadOnlyDictionary<int, Mapping>> GetIdToWholePercentagesToFace(ReadOnlyCollection<Mapping> distinctValidImageMappingCollection) =>
|
||||||
MapLogic.GetIdToWholePercentagesToFace(mappingCollection);
|
MapLogic.GetIdToWholePercentagesToFace(distinctValidImageMappingCollection);
|
||||||
|
|
||||||
List<(string, long)> TestStatic_GetJLinkDirectories(string genealogicalDataCommunicationFile, string[] jLinks, string personBirthdayFormat, char[] personCharacters, string a2PeopleSingletonDirectory, string a2PeopleContentDirectory) =>
|
List<(string, long)> TestStatic_GetJLinkDirectories(string genealogicalDataCommunicationFile, string[] jLinks, string personBirthdayFormat, char[] personCharacters, string a2PeopleSingletonDirectory, string a2PeopleContentDirectory) =>
|
||||||
GetJLinkDirectories(genealogicalDataCommunicationFile, jLinks, personBirthdayFormat, personCharacters, a2PeopleSingletonDirectory, a2PeopleContentDirectory);
|
GetJLinkDirectories(genealogicalDataCommunicationFile, jLinks, personBirthdayFormat, personCharacters, a2PeopleSingletonDirectory, a2PeopleContentDirectory);
|
||||||
static List<(string, long)> GetJLinkDirectories(string genealogicalDataCommunicationFile, string[] jLinks, string personBirthdayFormat, char[] personCharacters, string a2PeopleSingletonDirectory, string a2PeopleContentDirectory) =>
|
static List<(string, long)> GetJLinkDirectories(string genealogicalDataCommunicationFile, string[] jLinks, string personBirthdayFormat, char[] personCharacters, string a2PeopleSingletonDirectory, string a2PeopleContentDirectory) =>
|
||||||
MapLogic.GetJLinkDirectories(genealogicalDataCommunicationFile, jLinks, personBirthdayFormat, personCharacters, a2PeopleSingletonDirectory, a2PeopleContentDirectory);
|
MapLogic.GetJLinkDirectories(genealogicalDataCommunicationFile, jLinks, personBirthdayFormat, personCharacters, a2PeopleSingletonDirectory, a2PeopleContentDirectory);
|
||||||
|
|
||||||
void TestStatic_SetCreationTimeMaybeMoveToDecade(Property.Models.Configuration propertyConfiguration, bool moveToDecade, Shared.Models.MappingFromItem mappingFromItem, ReadOnlyCollection<Shared.Models.LocationContainer> locationContainers) =>
|
void TestStatic_SetCreationTime(MappingFromItem mappingFromItem, ReadOnlyCollection<LocationContainer> locationContainers) =>
|
||||||
SetCreationTimeMaybeMoveToDecade(propertyConfiguration, moveToDecade, mappingFromItem, locationContainers);
|
SetCreationTime(mappingFromItem, locationContainers);
|
||||||
static void SetCreationTimeMaybeMoveToDecade(Property.Models.Configuration propertyConfiguration, bool moveToDecade, Shared.Models.MappingFromItem mappingFromItem, ReadOnlyCollection<Shared.Models.LocationContainer> locationContainers) =>
|
static void SetCreationTime(MappingFromItem mappingFromItem, ReadOnlyCollection<LocationContainer> locationContainers) =>
|
||||||
DecadeLogic.SetCreationTimeMaybeMoveToDecade(propertyConfiguration, moveToDecade, mappingFromItem, locationContainers);
|
DecadeLogic.SetCreationTime(mappingFromItem, locationContainers);
|
||||||
|
|
||||||
bool? TestStatic_CanReMap(long[] jLinkResolvedPersonKeys, ReadOnlyDictionary<int, ReadOnlyCollection<Shared.Models.PersonContainer>>? wholePercentagesToPersonContainers, Shared.Models.MappingFromLocation mappingFromLocation) =>
|
void TestStatic_MoveToDecade(Property.Models.Configuration propertyConfiguration, MappingFromItem mappingFromItem, ReadOnlyCollection<LocationContainer> locationContainers) =>
|
||||||
|
MoveToDecade(propertyConfiguration, mappingFromItem, locationContainers);
|
||||||
|
static void MoveToDecade(Property.Models.Configuration propertyConfiguration, MappingFromItem mappingFromItem, ReadOnlyCollection<LocationContainer> locationContainers) =>
|
||||||
|
DecadeLogic.MoveToDecade(propertyConfiguration, mappingFromItem, locationContainers);
|
||||||
|
|
||||||
|
bool? TestStatic_CanReMap(long[] jLinkResolvedPersonKeys, ReadOnlyDictionary<int, ReadOnlyCollection<PersonContainer>>? wholePercentagesToPersonContainers, MappingFromLocation mappingFromLocation) =>
|
||||||
CanReMap(jLinkResolvedPersonKeys, wholePercentagesToPersonContainers, mappingFromLocation);
|
CanReMap(jLinkResolvedPersonKeys, wholePercentagesToPersonContainers, mappingFromLocation);
|
||||||
static bool? CanReMap(long[] jLinkResolvedPersonKeys, ReadOnlyDictionary<int, ReadOnlyCollection<Shared.Models.PersonContainer>>? wholePercentagesToPersonContainers, Shared.Models.MappingFromLocation mappingFromLocation) =>
|
static bool? CanReMap(long[] jLinkResolvedPersonKeys, ReadOnlyDictionary<int, ReadOnlyCollection<PersonContainer>>? wholePercentagesToPersonContainers, MappingFromLocation mappingFromLocation) =>
|
||||||
MapLogic.CanReMap(jLinkResolvedPersonKeys, wholePercentagesToPersonContainers, mappingFromLocation);
|
MapLogic.CanReMap(jLinkResolvedPersonKeys, wholePercentagesToPersonContainers, mappingFromLocation.WholePercentages);
|
||||||
|
|
||||||
string TestStatic_GetDecade(Shared.Models.MappingFromItem mappingFromItem) =>
|
bool? TestStatic_CanReMap(long[] jLinkResolvedPersonKeys, ReadOnlyDictionary<int, ReadOnlyCollection<PersonContainer>>? wholePercentagesToPersonContainers, int wholePercentages) =>
|
||||||
|
CanReMap(jLinkResolvedPersonKeys, wholePercentagesToPersonContainers, wholePercentages);
|
||||||
|
static bool? CanReMap(long[] jLinkResolvedPersonKeys, ReadOnlyDictionary<int, ReadOnlyCollection<PersonContainer>>? wholePercentagesToPersonContainers, int wholePercentages) =>
|
||||||
|
MapLogic.CanReMap(jLinkResolvedPersonKeys, wholePercentagesToPersonContainers, wholePercentages);
|
||||||
|
|
||||||
|
string TestStatic_GetDecade(MappingFromItem mappingFromItem) =>
|
||||||
GetDecade(mappingFromItem);
|
GetDecade(mappingFromItem);
|
||||||
static string GetDecade(Shared.Models.MappingFromItem mappingFromItem) =>
|
static string GetDecade(MappingFromItem mappingFromItem) =>
|
||||||
DecadeLogic.GetDecade(mappingFromItem, null);
|
DecadeLogic.GetDecade(mappingFromItem, null);
|
||||||
|
|
||||||
|
ReadOnlyDictionary<int, ReadOnlyDictionary<int, LocationContainer>> TestStatic_GetMappedFiles(int maxDegreeOfParallelism, Property.Models.Configuration propertyConfiguration, Configuration configuration, long ticks, ReadOnlyCollection<PersonContainer> personContainers, string a2PeopleSingletonDirectory, string eDistanceContentDirectory) =>
|
||||||
|
GetMapped(maxDegreeOfParallelism, propertyConfiguration, configuration, ticks, personContainers, a2PeopleSingletonDirectory, eDistanceContentDirectory);
|
||||||
|
static ReadOnlyDictionary<int, ReadOnlyDictionary<int, LocationContainer>> GetMapped(int maxDegreeOfParallelism, Property.Models.Configuration propertyConfiguration, Configuration configuration, long ticks, ReadOnlyCollection<PersonContainer> personContainers, string a2PeopleSingletonDirectory, string eDistanceContentDirectory) =>
|
||||||
|
FaceFileLogic.GetMapped(maxDegreeOfParallelism, propertyConfiguration, configuration, ticks, personContainers, a2PeopleSingletonDirectory, eDistanceContentDirectory);
|
||||||
|
|
||||||
|
List<LocationContainer> TestStatic_GetAvailable(int maxDegreeOfParallelism, Property.Models.Configuration propertyConfiguration, Configuration configuration, IFaceD dFace, long ticks, string dFacesContentDirectory, ReadOnlyCollection<FilePath> filePaths) =>
|
||||||
|
GetAvailable(maxDegreeOfParallelism, propertyConfiguration, configuration, dFace, ticks, dFacesContentDirectory, filePaths);
|
||||||
|
static List<LocationContainer> GetAvailable(int maxDegreeOfParallelism, Property.Models.Configuration propertyConfiguration, Configuration configuration, IFaceD dFace, long ticks, string dFacesContentDirectory, ReadOnlyCollection<FilePath> filePaths) =>
|
||||||
|
FaceFileLogic.GetAvailable(maxDegreeOfParallelism, propertyConfiguration, configuration, dFace, ticks, dFacesContentDirectory, filePaths);
|
||||||
|
|
||||||
}
|
}
|
@ -17,14 +17,16 @@ internal abstract class RelationLogic
|
|||||||
Dictionary<long, Dictionary<int, List<LocationContainer>>> personKeyTo = [];
|
Dictionary<long, Dictionary<int, List<LocationContainer>>> personKeyTo = [];
|
||||||
foreach (LocationContainer locationContainer in locationContainers)
|
foreach (LocationContainer locationContainer in locationContainers)
|
||||||
{
|
{
|
||||||
|
if (locationContainer.PersonKey is null)
|
||||||
|
continue;
|
||||||
if (!locationContainer.FromDistanceContent)
|
if (!locationContainer.FromDistanceContent)
|
||||||
continue;
|
continue;
|
||||||
if (!locationContainer.FilePath.FullName.Contains(configuration.LocationContainerDirectoryPattern))
|
if (!locationContainer.FilePath.FullName.Contains(configuration.LocationContainerDirectoryPattern))
|
||||||
continue;
|
continue;
|
||||||
if (!personKeyTo.TryGetValue(locationContainer.PersonKey, out yearTo))
|
if (!personKeyTo.TryGetValue(locationContainer.PersonKey.Value, out yearTo))
|
||||||
{
|
{
|
||||||
personKeyTo.Add(locationContainer.PersonKey, []);
|
personKeyTo.Add(locationContainer.PersonKey.Value, []);
|
||||||
if (!personKeyTo.TryGetValue(locationContainer.PersonKey, out yearTo))
|
if (!personKeyTo.TryGetValue(locationContainer.PersonKey.Value, out yearTo))
|
||||||
throw new Exception();
|
throw new Exception();
|
||||||
}
|
}
|
||||||
if (!yearTo.TryGetValue(locationContainer.CreationDateOnly.Year, out collection))
|
if (!yearTo.TryGetValue(locationContainer.CreationDateOnly.Year, out collection))
|
||||||
@ -45,6 +47,7 @@ internal abstract class RelationLogic
|
|||||||
int lastIndex;
|
int lastIndex;
|
||||||
List<int> years = [];
|
List<int> years = [];
|
||||||
List<int> indices = [];
|
List<int> indices = [];
|
||||||
|
LocationContainer locationContainer;
|
||||||
List<(int Index, int Year)> sort = [];
|
List<(int Index, int Year)> sort = [];
|
||||||
List<LocationContainer> collection = [];
|
List<LocationContainer> collection = [];
|
||||||
KeyValuePair<int, List<LocationContainer>> keyValue;
|
KeyValuePair<int, List<LocationContainer>> keyValue;
|
||||||
@ -76,7 +79,10 @@ internal abstract class RelationLogic
|
|||||||
key = $"{years.Min()}-{keyValue.Key}";
|
key = $"{years.Min()}-{keyValue.Key}";
|
||||||
if (collection.Count == 0)
|
if (collection.Count == 0)
|
||||||
continue;
|
continue;
|
||||||
results.Add(new(key, collection[0].PersonKey, new(collection)));
|
locationContainer = collection[0];
|
||||||
|
if (locationContainer.PersonKey is null)
|
||||||
|
continue;
|
||||||
|
results.Add(new(key, locationContainer.PersonKey.Value, new(collection)));
|
||||||
collection = [];
|
collection = [];
|
||||||
years.Clear();
|
years.Clear();
|
||||||
}
|
}
|
||||||
@ -84,7 +90,7 @@ internal abstract class RelationLogic
|
|||||||
return new(results);
|
return new(results);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static ReadOnlyDictionary<string, string> MoveFiles(Configuration configuration, string key, bool isCounterPersonYear, string? displayDirectoryName, ReadOnlyCollection<RelationContainer> relationContainers, List<string> linked1, List<string> linked2, List<string> linked3, List<string> linked4, List<string> linked5, List<string> linked6, List<string> linked7, List<string> linked8, List<string> linked9)
|
private static ReadOnlyDictionary<string, string> MoveFiles(Configuration configuration, string key, bool isCounterPersonYear, string? displayDirectoryName, ReadOnlyCollection<RelationContainer> relationContainers, List<List<string>> linked)
|
||||||
{
|
{
|
||||||
Dictionary<string, string> results = [];
|
Dictionary<string, string> results = [];
|
||||||
string value;
|
string value;
|
||||||
@ -105,23 +111,55 @@ internal abstract class RelationLogic
|
|||||||
maybeTicksDirectoryName = Path.GetFileName(personKeyFormattedDirectory);
|
maybeTicksDirectoryName = Path.GetFileName(personKeyFormattedDirectory);
|
||||||
if (string.IsNullOrEmpty(personNameDirectory) || string.IsNullOrEmpty(yearDirectory) || string.IsNullOrEmpty(personKeyFormattedDirectory) || string.IsNullOrEmpty(personNameDirectoryName))
|
if (string.IsNullOrEmpty(personNameDirectory) || string.IsNullOrEmpty(yearDirectory) || string.IsNullOrEmpty(personKeyFormattedDirectory) || string.IsNullOrEmpty(personNameDirectoryName))
|
||||||
continue;
|
continue;
|
||||||
if (linked9.Contains(fileHolder.FullName))
|
if (linked[24].Contains(fileHolder.FullName))
|
||||||
|
value = "ZZZ";
|
||||||
|
else if (linked[23].Contains(fileHolder.FullName))
|
||||||
|
value = "YYY";
|
||||||
|
else if (linked[22].Contains(fileHolder.FullName))
|
||||||
|
value = "XXX";
|
||||||
|
else if (linked[21].Contains(fileHolder.FullName))
|
||||||
|
value = "WWW";
|
||||||
|
else if (linked[20].Contains(fileHolder.FullName))
|
||||||
|
value = "VVV";
|
||||||
|
else if (linked[19].Contains(fileHolder.FullName))
|
||||||
|
value = "UUU";
|
||||||
|
else if (linked[18].Contains(fileHolder.FullName))
|
||||||
|
value = "TTT";
|
||||||
|
else if (linked[17].Contains(fileHolder.FullName))
|
||||||
|
value = "SSS";
|
||||||
|
else if (linked[16].Contains(fileHolder.FullName))
|
||||||
|
value = "RRR";
|
||||||
|
else if (linked[15].Contains(fileHolder.FullName))
|
||||||
|
value = "QQQ";
|
||||||
|
else if (linked[14].Contains(fileHolder.FullName))
|
||||||
|
value = "PPP";
|
||||||
|
else if (linked[13].Contains(fileHolder.FullName))
|
||||||
|
value = "OOO";
|
||||||
|
else if (linked[12].Contains(fileHolder.FullName))
|
||||||
|
value = "NNN";
|
||||||
|
else if (linked[11].Contains(fileHolder.FullName))
|
||||||
|
value = "MMM";
|
||||||
|
else if (linked[10].Contains(fileHolder.FullName))
|
||||||
|
value = "LLL";
|
||||||
|
else if (linked[9].Contains(fileHolder.FullName))
|
||||||
|
value = "KKK";
|
||||||
|
else if (linked[8].Contains(fileHolder.FullName))
|
||||||
value = "JJJ";
|
value = "JJJ";
|
||||||
else if (linked8.Contains(fileHolder.FullName))
|
else if (linked[7].Contains(fileHolder.FullName))
|
||||||
value = "III";
|
value = "III";
|
||||||
else if (linked7.Contains(fileHolder.FullName))
|
else if (linked[6].Contains(fileHolder.FullName))
|
||||||
value = "HHH";
|
value = "HHH";
|
||||||
else if (linked6.Contains(fileHolder.FullName))
|
else if (linked[5].Contains(fileHolder.FullName))
|
||||||
value = "GGG";
|
value = "GGG";
|
||||||
else if (linked5.Contains(fileHolder.FullName))
|
else if (linked[4].Contains(fileHolder.FullName))
|
||||||
value = "FFF";
|
value = "FFF";
|
||||||
else if (linked4.Contains(fileHolder.FullName))
|
else if (linked[3].Contains(fileHolder.FullName))
|
||||||
value = "EEE";
|
value = "EEE";
|
||||||
else if (linked3.Contains(fileHolder.FullName))
|
else if (linked[2].Contains(fileHolder.FullName))
|
||||||
value = "DDD";
|
value = "DDD";
|
||||||
else if (linked2.Contains(fileHolder.FullName))
|
else if (linked[1].Contains(fileHolder.FullName))
|
||||||
value = "CCC";
|
value = "CCC";
|
||||||
else if (linked1.Contains(fileHolder.FullName))
|
else if (linked[0].Contains(fileHolder.FullName))
|
||||||
value = "BBB";
|
value = "BBB";
|
||||||
else
|
else
|
||||||
value = "AAA";
|
value = "AAA";
|
||||||
@ -222,7 +260,7 @@ internal abstract class RelationLogic
|
|||||||
_ = Directory.CreateDirectory(vsCodeDirectory);
|
_ = Directory.CreateDirectory(vsCodeDirectory);
|
||||||
if (displayDirectoryName is not null)
|
if (displayDirectoryName is not null)
|
||||||
File.WriteAllText(Path.Combine(directory, $"_ {displayDirectoryName}.txt"), string.Empty);
|
File.WriteAllText(Path.Combine(directory, $"_ {displayDirectoryName}.txt"), string.Empty);
|
||||||
json = "{ \"[markdown]\": { \"editor.wordWrap\": \"off\" }, \"foam.links.hover.enable\": false, \"foam.graph.style\": { \"background\": \"#202020\", \"node\": { \"note\": \"#f2cb1d\", \"distance\": \"green\", \"image\": \"orange\", \"placeholder\": \"white\", } } }";
|
json = /*lang=json*/ """{ "[markdown]": { "editor.wordWrap": "off" }, "foam.links.hover.enable": false, "foam.graph.style": { "background": "#202020", "node": { "note": "#f2cb1d", "distance": "green", "image": "orange", "placeholder": "white", } } }""";
|
||||||
_ = IPath.WriteAllText(Path.Combine(vsCodeDirectory, "settings.json"), json, updateDateWhenMatches: false, compareBeforeWrite: true, updateToWhenMatches: null);
|
_ = IPath.WriteAllText(Path.Combine(vsCodeDirectory, "settings.json"), json, updateDateWhenMatches: false, compareBeforeWrite: true, updateToWhenMatches: null);
|
||||||
json = string.Concat("{ \"version\": \"2.0.0\", \"tasks\": [ { \"label\": \"MKLink\", \"type\": \"shell\", \"command\": \"New-Item\", \"args\": [ \"-ItemType\", \"Junction\", \"-Path\", \"'", directory.Replace('\\', '/'), "/()'\", \"-Target\", \"'", eDistanceContentDirectory.Replace('\\', '/'), "'\" ], \"problemMatcher\": [] } ] }");
|
json = string.Concat("{ \"version\": \"2.0.0\", \"tasks\": [ { \"label\": \"MKLink\", \"type\": \"shell\", \"command\": \"New-Item\", \"args\": [ \"-ItemType\", \"Junction\", \"-Path\", \"'", directory.Replace('\\', '/'), "/()'\", \"-Target\", \"'", eDistanceContentDirectory.Replace('\\', '/'), "'\" ], \"problemMatcher\": [] } ] }");
|
||||||
_ = IPath.WriteAllText(Path.Combine(vsCodeDirectory, "tasks.json"), json, updateDateWhenMatches: false, compareBeforeWrite: true, updateToWhenMatches: null);
|
_ = IPath.WriteAllText(Path.Combine(vsCodeDirectory, "tasks.json"), json, updateDateWhenMatches: false, compareBeforeWrite: true, updateToWhenMatches: null);
|
||||||
@ -231,67 +269,24 @@ internal abstract class RelationLogic
|
|||||||
private static ReadOnlyDictionary<string, string> GetMoveFiles(Configuration configuration, string key, int take, bool isCounterPersonYear, string? displayDirectoryName, ReadOnlyCollection<RelationContainer> relationContainers)
|
private static ReadOnlyDictionary<string, string> GetMoveFiles(Configuration configuration, string key, int take, bool isCounterPersonYear, string? displayDirectoryName, ReadOnlyCollection<RelationContainer> relationContainers)
|
||||||
{
|
{
|
||||||
ReadOnlyDictionary<string, string> results;
|
ReadOnlyDictionary<string, string> results;
|
||||||
List<string> linked1 = [];
|
List<List<string>> linked = [];
|
||||||
List<string> linked2 = [];
|
for (int i = 0; i < 25; i++)
|
||||||
List<string> linked3 = [];
|
linked.Add([]);
|
||||||
List<string> linked4 = [];
|
|
||||||
List<string> linked5 = [];
|
|
||||||
List<string> linked6 = [];
|
|
||||||
List<string> linked7 = [];
|
|
||||||
List<string> linked8 = [];
|
|
||||||
List<string> linked9 = [];
|
|
||||||
foreach ((FileHolder fileHolder, ReadOnlyCollection<Relation> relations) in relationContainers)
|
foreach ((FileHolder fileHolder, ReadOnlyCollection<Relation> relations) in relationContainers)
|
||||||
{
|
{
|
||||||
foreach (Relation relation in relations.Take(take))
|
foreach (Relation relation in relations.Take(take))
|
||||||
{
|
{
|
||||||
if (!linked1.Contains(relation.File))
|
for (int i = 0; i < 25; i++)
|
||||||
{
|
{
|
||||||
linked1.Add(relation.File);
|
if (!linked[i].Contains(relation.File))
|
||||||
continue;
|
{
|
||||||
}
|
linked[i].Add(relation.File);
|
||||||
if (!linked2.Contains(relation.File))
|
break;
|
||||||
{
|
}
|
||||||
linked2.Add(relation.File);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (!linked3.Contains(relation.File))
|
|
||||||
{
|
|
||||||
linked3.Add(relation.File);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (!linked4.Contains(relation.File))
|
|
||||||
{
|
|
||||||
linked4.Add(relation.File);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (!linked5.Contains(relation.File))
|
|
||||||
{
|
|
||||||
linked5.Add(relation.File);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (!linked6.Contains(relation.File))
|
|
||||||
{
|
|
||||||
linked6.Add(relation.File);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (!linked7.Contains(relation.File))
|
|
||||||
{
|
|
||||||
linked7.Add(relation.File);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (!linked8.Contains(relation.File))
|
|
||||||
{
|
|
||||||
linked8.Add(relation.File);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (!linked9.Contains(relation.File))
|
|
||||||
{
|
|
||||||
linked9.Add(relation.File);
|
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
results = MoveFiles(configuration, key, isCounterPersonYear, displayDirectoryName, relationContainers, linked1, linked2, linked3, linked4, linked5, linked6, linked7, linked8, linked9);
|
results = MoveFiles(configuration, key, isCounterPersonYear, displayDirectoryName, relationContainers, linked);
|
||||||
return results;
|
return results;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -433,7 +428,7 @@ internal abstract class RelationLogic
|
|||||||
if (!Directory.Exists(directory))
|
if (!Directory.Exists(directory))
|
||||||
_ = Directory.CreateDirectory(directory);
|
_ = Directory.CreateDirectory(directory);
|
||||||
WriteVsCodeFiles(eDistanceContentDirectory, displayDirectoryName, directory);
|
WriteVsCodeFiles(eDistanceContentDirectory, displayDirectoryName, directory);
|
||||||
relationContainers = distance.GetRelationContainers(configuration.FaceDistancePermyriad, configuration.LocationContainerDistanceTake, configuration.LocationContainerDistanceTolerance.Value, group.RelationContainersCollection);
|
relationContainers = distance.GetRelationContainers(configuration.DistanceLimits, configuration.FaceDistancePermyriad, configuration.LocationContainerDistanceTake, configuration.LocationContainerDistanceTolerance.Value, group.RelationContainersCollection);
|
||||||
movedFiles = GetMoveFiles(configuration, group.Key, take, isCounterPersonYear, displayDirectoryName, relationContainers);
|
movedFiles = GetMoveFiles(configuration, group.Key, take, isCounterPersonYear, displayDirectoryName, relationContainers);
|
||||||
WriteFile(take, group.PersonKey, isCounterPersonYear, personKeyFormatted, displayDirectoryName, directory, ticks, uri, relationContainers, movedFiles);
|
WriteFile(take, group.PersonKey, isCounterPersonYear, personKeyFormatted, displayDirectoryName, directory, ticks, uri, relationContainers, movedFiles);
|
||||||
}
|
}
|
||||||
|
@ -4,6 +4,7 @@ using Phares.Shared;
|
|||||||
using ShellProgressBar;
|
using ShellProgressBar;
|
||||||
using System.Collections.ObjectModel;
|
using System.Collections.ObjectModel;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
using System.Text.Json;
|
||||||
using View_by_Distance.Metadata.Query.Models;
|
using View_by_Distance.Metadata.Query.Models;
|
||||||
using View_by_Distance.Shared.Models;
|
using View_by_Distance.Shared.Models;
|
||||||
using View_by_Distance.Shared.Models.Methods;
|
using View_by_Distance.Shared.Models.Methods;
|
||||||
@ -58,12 +59,13 @@ public class MetadataQuery
|
|||||||
|
|
||||||
private List<(string FileName, string TagGroup, string TagIdName, string Value)> GetCollection(long ticks)
|
private List<(string FileName, string TagGroup, string TagIdName, string Value)> GetCollection(long ticks)
|
||||||
{
|
{
|
||||||
|
string json;
|
||||||
|
string? model;
|
||||||
|
string? maker;
|
||||||
string message;
|
string message;
|
||||||
FileInfo fileInfo;
|
FileInfo fileInfo;
|
||||||
FilePath filePath;
|
|
||||||
FileHolder fileHolder;
|
|
||||||
ProgressBar progressBar;
|
ProgressBar progressBar;
|
||||||
ExifDirectory exifDirectory;
|
ExifDirectory? exifDirectory;
|
||||||
const string fileSearchFilter = "*";
|
const string fileSearchFilter = "*";
|
||||||
const bool useCeilingAverage = true;
|
const bool useCeilingAverage = true;
|
||||||
const string directorySearchFilter = "*";
|
const string directorySearchFilter = "*";
|
||||||
@ -80,17 +82,12 @@ public class MetadataQuery
|
|||||||
{
|
{
|
||||||
progressBar.Tick();
|
progressBar.Tick();
|
||||||
fileInfo = new(file);
|
fileInfo = new(file);
|
||||||
fileHolder = FileHolder.Get(fileInfo);
|
json = File.ReadAllText(fileInfo.FullName);
|
||||||
filePath = FilePath.Get(_PropertyConfiguration, fileHolder, index: null);
|
exifDirectory = JsonSerializer.Deserialize(json, ExifDirectorySourceGenerationContext.Default.ExifDirectory);
|
||||||
exifDirectory = Metadata.Models.Stateless.Methods.IMetadata.GetExifDirectory(filePath);
|
if (exifDirectory is null)
|
||||||
// exifDirectory.ExifDirectoryBase.Artist;
|
continue;
|
||||||
// exifDirectory.ExifDirectoryBase.WinComment;
|
maker = Metadata.Models.Stateless.Methods.IMetadata.GetMaker(exifDirectory);
|
||||||
// exifDirectory.ExifDirectoryBase.Model;
|
model = Metadata.Models.Stateless.Methods.IMetadata.GetModel(exifDirectory);
|
||||||
// exifDirectory.ExifDirectoryBase.CameraOwnerName;
|
|
||||||
// exifDirectory.ExifDirectoryBase.Make;
|
|
||||||
// exifDirectory.ExifDirectoryBase.BodySerialNumber;
|
|
||||||
// exifDirectory.ExifDirectoryBase.LensSerialNumber;
|
|
||||||
// exifDirectory.ExifDirectoryBase.Software;
|
|
||||||
// collection.Add(new(fileInfo.Name, keyValuePair.Key, keyValue.Key, keyValue.Value));
|
// collection.Add(new(fileInfo.Name, keyValuePair.Key, keyValue.Key, keyValue.Value));
|
||||||
}
|
}
|
||||||
progressBar.Dispose();
|
progressBar.Dispose();
|
||||||
|
@ -16,6 +16,23 @@ public class AppSettings
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void PreVerify(IConfigurationRoot configurationRoot, AppSettings? appSettings)
|
||||||
|
{
|
||||||
|
if (appSettings?.Company is null)
|
||||||
|
{
|
||||||
|
List<string> paths = [];
|
||||||
|
foreach (IConfigurationProvider configurationProvider in configurationRoot.Providers)
|
||||||
|
{
|
||||||
|
if (configurationProvider is not Microsoft.Extensions.Configuration.Json.JsonConfigurationProvider jsonConfigurationProvider)
|
||||||
|
continue;
|
||||||
|
if (jsonConfigurationProvider.Source.FileProvider is not Microsoft.Extensions.FileProviders.PhysicalFileProvider physicalFileProvider)
|
||||||
|
continue;
|
||||||
|
paths.Add(physicalFileProvider.Root);
|
||||||
|
}
|
||||||
|
throw new NotSupportedException($"Not found!{Environment.NewLine}{string.Join(Environment.NewLine, paths.Distinct())}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private static Models.AppSettings Get(AppSettings? appSettings)
|
private static Models.AppSettings Get(AppSettings? appSettings)
|
||||||
{
|
{
|
||||||
Models.AppSettings result;
|
Models.AppSettings result;
|
||||||
@ -36,7 +53,10 @@ public class AppSettings
|
|||||||
public static Models.AppSettings Get(IConfigurationRoot configurationRoot)
|
public static Models.AppSettings Get(IConfigurationRoot configurationRoot)
|
||||||
{
|
{
|
||||||
Models.AppSettings result;
|
Models.AppSettings result;
|
||||||
|
#pragma warning disable IL3050, IL2026
|
||||||
AppSettings? appSettings = configurationRoot.Get<AppSettings>();
|
AppSettings? appSettings = configurationRoot.Get<AppSettings>();
|
||||||
|
#pragma warning restore IL3050, IL2026
|
||||||
|
PreVerify(configurationRoot, appSettings);
|
||||||
result = Get(appSettings);
|
result = Get(appSettings);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -7,13 +7,9 @@ namespace View_by_Distance.Metadata.Query.Models.Binder;
|
|||||||
public class Configuration
|
public class Configuration
|
||||||
{
|
{
|
||||||
|
|
||||||
#nullable disable
|
public string[]? IgnoreExtensions { get; set; }
|
||||||
|
public Property.Models.Configuration? PropertyConfiguration { get; set; }
|
||||||
public string[] IgnoreExtensions { get; set; }
|
public string? PersonBirthdayFormat { get; set; }
|
||||||
public Property.Models.Configuration PropertyConfiguration { get; set; }
|
|
||||||
public string PersonBirthdayFormat { get; set; }
|
|
||||||
|
|
||||||
#nullable restore
|
|
||||||
|
|
||||||
public override string ToString()
|
public override string ToString()
|
||||||
{
|
{
|
||||||
@ -21,12 +17,30 @@ public class Configuration
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void PreVerify(IConfigurationRoot configurationRoot, Configuration? configuration)
|
||||||
|
{
|
||||||
|
if (configuration?.IgnoreExtensions is null)
|
||||||
|
{
|
||||||
|
List<string> paths = [];
|
||||||
|
foreach (IConfigurationProvider configurationProvider in configurationRoot.Providers)
|
||||||
|
{
|
||||||
|
if (configurationProvider is not Microsoft.Extensions.Configuration.Json.JsonConfigurationProvider jsonConfigurationProvider)
|
||||||
|
continue;
|
||||||
|
if (jsonConfigurationProvider.Source.FileProvider is not Microsoft.Extensions.FileProviders.PhysicalFileProvider physicalFileProvider)
|
||||||
|
continue;
|
||||||
|
paths.Add(physicalFileProvider.Root);
|
||||||
|
}
|
||||||
|
throw new NotSupportedException($"Not found!{Environment.NewLine}{string.Join(Environment.NewLine, paths.Distinct())}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private static Models.Configuration Get(Configuration? configuration)
|
private static Models.Configuration Get(Configuration? configuration)
|
||||||
{
|
{
|
||||||
Models.Configuration result;
|
Models.Configuration result;
|
||||||
if (configuration is null) throw new NullReferenceException(nameof(configuration));
|
if (configuration is null) throw new NullReferenceException(nameof(configuration));
|
||||||
if (configuration.IgnoreExtensions is null) throw new NullReferenceException(nameof(configuration.IgnoreExtensions));
|
if (configuration.IgnoreExtensions is null) throw new NullReferenceException(nameof(configuration.IgnoreExtensions));
|
||||||
if (configuration.PersonBirthdayFormat is null) throw new NullReferenceException(nameof(configuration.PersonBirthdayFormat));
|
if (configuration.PersonBirthdayFormat is null) throw new NullReferenceException(nameof(configuration.PersonBirthdayFormat));
|
||||||
|
if (configuration.PropertyConfiguration is null) throw new NullReferenceException(nameof(configuration.PropertyConfiguration));
|
||||||
result = new(
|
result = new(
|
||||||
configuration.IgnoreExtensions,
|
configuration.IgnoreExtensions,
|
||||||
configuration.PersonBirthdayFormat,
|
configuration.PersonBirthdayFormat,
|
||||||
@ -39,14 +53,19 @@ public class Configuration
|
|||||||
Models.Configuration result;
|
Models.Configuration result;
|
||||||
Configuration? configuration;
|
Configuration? configuration;
|
||||||
if (isEnvironment is null)
|
if (isEnvironment is null)
|
||||||
|
#pragma warning disable IL3050, IL2026
|
||||||
configuration = configurationRoot.Get<Configuration>();
|
configuration = configurationRoot.Get<Configuration>();
|
||||||
|
#pragma warning restore IL3050, IL2026
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
string environmentName = IsEnvironment.GetEnvironmentName(isEnvironment);
|
string environmentName = IsEnvironment.GetEnvironmentName(isEnvironment);
|
||||||
string section = string.Concat(environmentName, ":", nameof(Configuration));
|
string section = string.Concat(environmentName, ":", nameof(Configuration));
|
||||||
IConfigurationSection configurationSection = configurationRoot.GetSection(section);
|
IConfigurationSection configurationSection = configurationRoot.GetSection(section);
|
||||||
|
#pragma warning disable IL3050, IL2026
|
||||||
configuration = configurationSection.Get<Configuration>();
|
configuration = configurationSection.Get<Configuration>();
|
||||||
|
#pragma warning restore IL3050, IL2026
|
||||||
}
|
}
|
||||||
|
PreVerify(configurationRoot, configuration);
|
||||||
result = Get(configuration);
|
result = Get(configuration);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -48,7 +48,7 @@ public class B_Metadata : IMetadata<MetadataExtractor.Directory>
|
|||||||
ExifDirectory? result = null;
|
ExifDirectory? result = null;
|
||||||
List<DateTime> dateTimes = (from l in subFileTuples where changesFrom.Contains(l.Item1) select l.Item2).ToList();
|
List<DateTime> dateTimes = (from l in subFileTuples where changesFrom.Contains(l.Item1) select l.Item2).ToList();
|
||||||
(_, int directoryIndex) = Shared.Models.Stateless.Methods.IPath.GetDirectoryNameAndIndex(_PropertyConfiguration, filePath);
|
(_, int directoryIndex) = Shared.Models.Stateless.Methods.IPath.GetDirectoryNameAndIndex(_PropertyConfiguration, filePath);
|
||||||
FileInfo fileInfo = new(Path.Combine(_FileGroups[_PropertyConfiguration.ResultSingleton][directoryIndex], $"{mappingFromItem.ImageFileHolder.NameWithoutExtension}{mappingFromItem.ImageFileHolder.ExtensionLowered}.json"));
|
FileInfo fileInfo = new(Path.Combine(_FileGroups[_PropertyConfiguration.ResultSingleton][directoryIndex], $"{mappingFromItem.FilePath.NameWithoutExtension}{mappingFromItem.FilePath.ExtensionLowered}.json"));
|
||||||
if (_ForceMetadataLastWriteTimeToCreationTime && !fileInfo.Exists && File.Exists(Path.ChangeExtension(fileInfo.FullName, ".delete")))
|
if (_ForceMetadataLastWriteTimeToCreationTime && !fileInfo.Exists && File.Exists(Path.ChangeExtension(fileInfo.FullName, ".delete")))
|
||||||
{
|
{
|
||||||
File.Move(Path.ChangeExtension(fileInfo.FullName, ".delete"), fileInfo.FullName);
|
File.Move(Path.ChangeExtension(fileInfo.FullName, ".delete"), fileInfo.FullName);
|
||||||
@ -104,7 +104,7 @@ public class B_Metadata : IMetadata<MetadataExtractor.Directory>
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
(DateTime?, DateTime?[]) IMetadata<MetadataExtractor.Directory>.GetDateTimes(FileHolder fileHolder, IReadOnlyList<MetadataExtractor.Directory> directories)
|
(DateTime?, DateTime?[]) IMetadata<MetadataExtractor.Directory>.GetDateTimes(FilePath filePath, IReadOnlyList<MetadataExtractor.Directory> directories)
|
||||||
{
|
{
|
||||||
List<DateTime?> results = [];
|
List<DateTime?> results = [];
|
||||||
DateTime? result = null;
|
DateTime? result = null;
|
||||||
@ -112,8 +112,8 @@ public class B_Metadata : IMetadata<MetadataExtractor.Directory>
|
|||||||
DateTime checkDateTime;
|
DateTime checkDateTime;
|
||||||
string dateTimeFormat = Property.Models.Stateless.IProperty.DateTimeFormat();
|
string dateTimeFormat = Property.Models.Stateless.IProperty.DateTimeFormat();
|
||||||
MetadataExtractor.Formats.Exif.ExifDirectoryBase? exifDirectoryBase = directories.OfType<MetadataExtractor.Formats.Exif.ExifDirectoryBase>().FirstOrDefault();
|
MetadataExtractor.Formats.Exif.ExifDirectoryBase? exifDirectoryBase = directories.OfType<MetadataExtractor.Formats.Exif.ExifDirectoryBase>().FirstOrDefault();
|
||||||
results.Add(fileHolder.CreationTime);
|
results.Add(new DateTime(filePath.CreationTicks));
|
||||||
results.Add(fileHolder.LastWriteTime);
|
results.Add(new DateTime(filePath.LastWriteTicks));
|
||||||
if (exifDirectoryBase is not null)
|
if (exifDirectoryBase is not null)
|
||||||
{
|
{
|
||||||
if (exifDirectoryBase.TryGetDateTime(MetadataExtractor.Formats.Exif.ExifDirectoryBase.TagDateTime, out checkDateTime))
|
if (exifDirectoryBase.TryGetDateTime(MetadataExtractor.Formats.Exif.ExifDirectoryBase.TagDateTime, out checkDateTime))
|
||||||
|
@ -5,7 +5,7 @@ namespace View_by_Distance.Metadata.Models.Stateless.Methods;
|
|||||||
internal static class Base
|
internal static class Base
|
||||||
{
|
{
|
||||||
|
|
||||||
internal static string GetMaker(ExifDirectoryBase[]? exifBaseDirectories)
|
internal static string? GetMaker(ExifDirectoryBase[]? exifBaseDirectories)
|
||||||
{
|
{
|
||||||
string? result = null;
|
string? result = null;
|
||||||
if (exifBaseDirectories is not null)
|
if (exifBaseDirectories is not null)
|
||||||
@ -23,12 +23,10 @@ internal static class Base
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (string.IsNullOrEmpty(result))
|
|
||||||
result = "Unknown";
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static string GetModel(ExifDirectoryBase[]? exifBaseDirectories)
|
internal static string? GetModel(ExifDirectoryBase[]? exifBaseDirectories)
|
||||||
{
|
{
|
||||||
string? result = null;
|
string? result = null;
|
||||||
if (exifBaseDirectories is not null)
|
if (exifBaseDirectories is not null)
|
||||||
@ -46,8 +44,6 @@ internal static class Base
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (string.IsNullOrEmpty(result))
|
|
||||||
result = "Unknown";
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -519,8 +519,12 @@ internal abstract class Exif
|
|||||||
|
|
||||||
internal static Shared.Models.ExifDirectory GetExifDirectory(Shared.Models.FilePath filePath)
|
internal static Shared.Models.ExifDirectory GetExifDirectory(Shared.Models.FilePath filePath)
|
||||||
{
|
{
|
||||||
Shared.Models.ExifDirectory? result;
|
Shared.Models.ExifDirectory result;
|
||||||
System.Drawing.Size? size = Dimensions.GetDimensions(filePath.FullName);
|
System.Drawing.Size? size;
|
||||||
|
try
|
||||||
|
{ size = Dimensions.GetDimensions(filePath.FullName); }
|
||||||
|
catch (Exception)
|
||||||
|
{ size = null; }
|
||||||
IReadOnlyList<MetadataExtractor.Directory> directories = ImageMetadataReader.ReadMetadata(filePath.FullName);
|
IReadOnlyList<MetadataExtractor.Directory> directories = ImageMetadataReader.ReadMetadata(filePath.FullName);
|
||||||
result = Covert(filePath, size, directories);
|
result = Covert(filePath, size, directories);
|
||||||
return result;
|
return result;
|
||||||
|
@ -35,6 +35,17 @@ internal static class Face
|
|||||||
result = pngDirectory.TextualData[artist.Length..];
|
result = pngDirectory.TextualData[artist.Length..];
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
if (result is null)
|
||||||
|
{
|
||||||
|
const string author = "Author:";
|
||||||
|
foreach (PngDirectory pngDirectory in pngDirectories)
|
||||||
|
{
|
||||||
|
if (pngDirectory.TextualData is null || !pngDirectory.TextualData.StartsWith(author))
|
||||||
|
continue;
|
||||||
|
result = pngDirectory.TextualData[author.Length..];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -19,14 +19,14 @@ public interface IMetadata
|
|||||||
static ExifDirectory GetExifDirectory(FilePath filePath) =>
|
static ExifDirectory GetExifDirectory(FilePath filePath) =>
|
||||||
Exif.GetExifDirectory(filePath);
|
Exif.GetExifDirectory(filePath);
|
||||||
|
|
||||||
string TestStatic_GetMaker(ExifDirectory? exifDirectory) =>
|
string? TestStatic_GetMaker(ExifDirectory? exifDirectory) =>
|
||||||
GetMaker(exifDirectory);
|
GetMaker(exifDirectory);
|
||||||
static string GetMaker(ExifDirectory? exifDirectory) =>
|
static string? GetMaker(ExifDirectory? exifDirectory) =>
|
||||||
Base.GetMaker(exifDirectory?.ExifBaseDirectories);
|
Base.GetMaker(exifDirectory?.ExifBaseDirectories);
|
||||||
|
|
||||||
string TestStatic_GetModel(ExifDirectory? exifDirectory) =>
|
string? TestStatic_GetModel(ExifDirectory? exifDirectory) =>
|
||||||
GetModel(exifDirectory);
|
GetModel(exifDirectory);
|
||||||
static string GetModel(ExifDirectory? exifDirectory) =>
|
static string? GetModel(ExifDirectory? exifDirectory) =>
|
||||||
Base.GetModel(exifDirectory?.ExifBaseDirectories);
|
Base.GetModel(exifDirectory?.ExifBaseDirectories);
|
||||||
|
|
||||||
string? TestStatic_GetOutputResolution(ExifDirectory? exifDirectory) =>
|
string? TestStatic_GetOutputResolution(ExifDirectory? exifDirectory) =>
|
||||||
|
@ -17,6 +17,23 @@ public class AppSettings
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void PreVerify(IConfigurationRoot configurationRoot, AppSettings? appSettings)
|
||||||
|
{
|
||||||
|
if (appSettings?.Company is null)
|
||||||
|
{
|
||||||
|
List<string> paths = [];
|
||||||
|
foreach (IConfigurationProvider configurationProvider in configurationRoot.Providers)
|
||||||
|
{
|
||||||
|
if (configurationProvider is not Microsoft.Extensions.Configuration.Json.JsonConfigurationProvider jsonConfigurationProvider)
|
||||||
|
continue;
|
||||||
|
if (jsonConfigurationProvider.Source.FileProvider is not Microsoft.Extensions.FileProviders.PhysicalFileProvider physicalFileProvider)
|
||||||
|
continue;
|
||||||
|
paths.Add(physicalFileProvider.Root);
|
||||||
|
}
|
||||||
|
throw new NotSupportedException($"Not found!{Environment.NewLine}{string.Join(Environment.NewLine, paths.Distinct())}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private static Models.AppSettings Get(AppSettings? appSettings)
|
private static Models.AppSettings Get(AppSettings? appSettings)
|
||||||
{
|
{
|
||||||
Models.AppSettings result;
|
Models.AppSettings result;
|
||||||
@ -40,7 +57,10 @@ public class AppSettings
|
|||||||
public static Models.AppSettings Get(IConfigurationRoot configurationRoot)
|
public static Models.AppSettings Get(IConfigurationRoot configurationRoot)
|
||||||
{
|
{
|
||||||
Models.AppSettings result;
|
Models.AppSettings result;
|
||||||
|
#pragma warning disable IL3050, IL2026
|
||||||
AppSettings? appSettings = configurationRoot.Get<AppSettings>();
|
AppSettings? appSettings = configurationRoot.Get<AppSettings>();
|
||||||
|
#pragma warning restore IL3050, IL2026
|
||||||
|
PreVerify(configurationRoot, appSettings);
|
||||||
result = Get(appSettings);
|
result = Get(appSettings);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -7,13 +7,9 @@ namespace View_by_Distance.Mirror.Length.Models.Binder;
|
|||||||
public class Configuration
|
public class Configuration
|
||||||
{
|
{
|
||||||
|
|
||||||
#nullable disable
|
public string[]? IgnoreExtensions { get; set; }
|
||||||
|
public Property.Models.Configuration? PropertyConfiguration { get; set; }
|
||||||
public string[] IgnoreExtensions { get; set; }
|
public string? PersonBirthdayFormat { get; set; }
|
||||||
public Property.Models.Configuration PropertyConfiguration { get; set; }
|
|
||||||
public string PersonBirthdayFormat { get; set; }
|
|
||||||
|
|
||||||
#nullable restore
|
|
||||||
|
|
||||||
public override string ToString()
|
public override string ToString()
|
||||||
{
|
{
|
||||||
@ -21,12 +17,30 @@ public class Configuration
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void PreVerify(IConfigurationRoot configurationRoot, Configuration? configuration)
|
||||||
|
{
|
||||||
|
if (configuration?.IgnoreExtensions is null)
|
||||||
|
{
|
||||||
|
List<string> paths = [];
|
||||||
|
foreach (IConfigurationProvider configurationProvider in configurationRoot.Providers)
|
||||||
|
{
|
||||||
|
if (configurationProvider is not Microsoft.Extensions.Configuration.Json.JsonConfigurationProvider jsonConfigurationProvider)
|
||||||
|
continue;
|
||||||
|
if (jsonConfigurationProvider.Source.FileProvider is not Microsoft.Extensions.FileProviders.PhysicalFileProvider physicalFileProvider)
|
||||||
|
continue;
|
||||||
|
paths.Add(physicalFileProvider.Root);
|
||||||
|
}
|
||||||
|
throw new NotSupportedException($"Not found!{Environment.NewLine}{string.Join(Environment.NewLine, paths.Distinct())}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private static Models.Configuration Get(Configuration? configuration)
|
private static Models.Configuration Get(Configuration? configuration)
|
||||||
{
|
{
|
||||||
Models.Configuration result;
|
Models.Configuration result;
|
||||||
if (configuration is null) throw new NullReferenceException(nameof(configuration));
|
if (configuration is null) throw new NullReferenceException(nameof(configuration));
|
||||||
if (configuration.IgnoreExtensions is null) throw new NullReferenceException(nameof(configuration.IgnoreExtensions));
|
if (configuration.IgnoreExtensions is null) throw new NullReferenceException(nameof(configuration.IgnoreExtensions));
|
||||||
if (configuration.PersonBirthdayFormat is null) throw new NullReferenceException(nameof(configuration.PersonBirthdayFormat));
|
if (configuration.PersonBirthdayFormat is null) throw new NullReferenceException(nameof(configuration.PersonBirthdayFormat));
|
||||||
|
if (configuration.PropertyConfiguration is null) throw new NullReferenceException(nameof(configuration.PropertyConfiguration));
|
||||||
result = new(
|
result = new(
|
||||||
configuration.IgnoreExtensions,
|
configuration.IgnoreExtensions,
|
||||||
configuration.PersonBirthdayFormat,
|
configuration.PersonBirthdayFormat,
|
||||||
@ -39,14 +53,19 @@ public class Configuration
|
|||||||
Models.Configuration result;
|
Models.Configuration result;
|
||||||
Configuration? configuration;
|
Configuration? configuration;
|
||||||
if (isEnvironment is null)
|
if (isEnvironment is null)
|
||||||
|
#pragma warning disable IL3050, IL2026
|
||||||
configuration = configurationRoot.Get<Configuration>();
|
configuration = configurationRoot.Get<Configuration>();
|
||||||
|
#pragma warning restore IL3050, IL2026
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
string environmentName = IsEnvironment.GetEnvironmentName(isEnvironment);
|
string environmentName = IsEnvironment.GetEnvironmentName(isEnvironment);
|
||||||
string section = string.Concat(environmentName, ":", nameof(Configuration));
|
string section = string.Concat(environmentName, ":", nameof(Configuration));
|
||||||
IConfigurationSection configurationSection = configurationRoot.GetSection(section);
|
IConfigurationSection configurationSection = configurationRoot.GetSection(section);
|
||||||
|
#pragma warning disable IL3050, IL2026
|
||||||
configuration = configurationSection.Get<Configuration>();
|
configuration = configurationSection.Get<Configuration>();
|
||||||
|
#pragma warning restore IL3050, IL2026
|
||||||
}
|
}
|
||||||
|
PreVerify(configurationRoot, configuration);
|
||||||
result = Get(configuration);
|
result = Get(configuration);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -23,6 +23,23 @@ public class AppSettings
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void PreVerify(IConfigurationRoot configurationRoot, AppSettings? appSettings)
|
||||||
|
{
|
||||||
|
if (appSettings?.Company is null)
|
||||||
|
{
|
||||||
|
List<string> paths = [];
|
||||||
|
foreach (IConfigurationProvider configurationProvider in configurationRoot.Providers)
|
||||||
|
{
|
||||||
|
if (configurationProvider is not Microsoft.Extensions.Configuration.Json.JsonConfigurationProvider jsonConfigurationProvider)
|
||||||
|
continue;
|
||||||
|
if (jsonConfigurationProvider.Source.FileProvider is not Microsoft.Extensions.FileProviders.PhysicalFileProvider physicalFileProvider)
|
||||||
|
continue;
|
||||||
|
paths.Add(physicalFileProvider.Root);
|
||||||
|
}
|
||||||
|
throw new NotSupportedException($"Not found!{Environment.NewLine}{string.Join(Environment.NewLine, paths.Distinct())}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private static Models.AppSettings Get(AppSettings? appSettings)
|
private static Models.AppSettings Get(AppSettings? appSettings)
|
||||||
{
|
{
|
||||||
Models.AppSettings result;
|
Models.AppSettings result;
|
||||||
@ -44,7 +61,10 @@ public class AppSettings
|
|||||||
public static Models.AppSettings Get(IConfigurationRoot configurationRoot)
|
public static Models.AppSettings Get(IConfigurationRoot configurationRoot)
|
||||||
{
|
{
|
||||||
Models.AppSettings result;
|
Models.AppSettings result;
|
||||||
|
#pragma warning disable IL3050, IL2026
|
||||||
AppSettings? appSettings = configurationRoot.Get<AppSettings>();
|
AppSettings? appSettings = configurationRoot.Get<AppSettings>();
|
||||||
|
#pragma warning restore IL3050, IL2026
|
||||||
|
PreVerify(configurationRoot, appSettings);
|
||||||
result = Get(appSettings);
|
result = Get(appSettings);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -7,13 +7,9 @@ namespace View_by_Distance.Move.By.Id.Models.Binder;
|
|||||||
public class Configuration
|
public class Configuration
|
||||||
{
|
{
|
||||||
|
|
||||||
#nullable disable
|
public string[]? IgnoreExtensions { get; set; }
|
||||||
|
public Property.Models.Configuration? PropertyConfiguration { get; set; }
|
||||||
public string[] IgnoreExtensions { get; set; }
|
public string? PersonBirthdayFormat { get; set; }
|
||||||
public Property.Models.Configuration PropertyConfiguration { get; set; }
|
|
||||||
public string PersonBirthdayFormat { get; set; }
|
|
||||||
|
|
||||||
#nullable restore
|
|
||||||
|
|
||||||
public override string ToString()
|
public override string ToString()
|
||||||
{
|
{
|
||||||
@ -21,12 +17,30 @@ public class Configuration
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void PreVerify(IConfigurationRoot configurationRoot, Configuration? configuration)
|
||||||
|
{
|
||||||
|
if (configuration?.IgnoreExtensions is null)
|
||||||
|
{
|
||||||
|
List<string> paths = [];
|
||||||
|
foreach (IConfigurationProvider configurationProvider in configurationRoot.Providers)
|
||||||
|
{
|
||||||
|
if (configurationProvider is not Microsoft.Extensions.Configuration.Json.JsonConfigurationProvider jsonConfigurationProvider)
|
||||||
|
continue;
|
||||||
|
if (jsonConfigurationProvider.Source.FileProvider is not Microsoft.Extensions.FileProviders.PhysicalFileProvider physicalFileProvider)
|
||||||
|
continue;
|
||||||
|
paths.Add(physicalFileProvider.Root);
|
||||||
|
}
|
||||||
|
throw new NotSupportedException($"Not found!{Environment.NewLine}{string.Join(Environment.NewLine, paths.Distinct())}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private static Models.Configuration Get(Configuration? configuration)
|
private static Models.Configuration Get(Configuration? configuration)
|
||||||
{
|
{
|
||||||
Models.Configuration result;
|
Models.Configuration result;
|
||||||
if (configuration is null) throw new NullReferenceException(nameof(configuration));
|
if (configuration is null) throw new NullReferenceException(nameof(configuration));
|
||||||
if (configuration.IgnoreExtensions is null) throw new NullReferenceException(nameof(configuration.IgnoreExtensions));
|
if (configuration.IgnoreExtensions is null) throw new NullReferenceException(nameof(configuration.IgnoreExtensions));
|
||||||
if (configuration.PersonBirthdayFormat is null) throw new NullReferenceException(nameof(configuration.PersonBirthdayFormat));
|
if (configuration.PersonBirthdayFormat is null) throw new NullReferenceException(nameof(configuration.PersonBirthdayFormat));
|
||||||
|
if (configuration.PropertyConfiguration is null) throw new NullReferenceException(nameof(configuration.PropertyConfiguration));
|
||||||
result = new(
|
result = new(
|
||||||
configuration.IgnoreExtensions,
|
configuration.IgnoreExtensions,
|
||||||
configuration.PersonBirthdayFormat,
|
configuration.PersonBirthdayFormat,
|
||||||
@ -39,14 +53,19 @@ public class Configuration
|
|||||||
Models.Configuration result;
|
Models.Configuration result;
|
||||||
Configuration? configuration;
|
Configuration? configuration;
|
||||||
if (isEnvironment is null)
|
if (isEnvironment is null)
|
||||||
|
#pragma warning disable IL3050, IL2026
|
||||||
configuration = configurationRoot.Get<Configuration>();
|
configuration = configurationRoot.Get<Configuration>();
|
||||||
|
#pragma warning restore IL3050, IL2026
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
string environmentName = IsEnvironment.GetEnvironmentName(isEnvironment);
|
string environmentName = IsEnvironment.GetEnvironmentName(isEnvironment);
|
||||||
string section = string.Concat(environmentName, ":", nameof(Configuration));
|
string section = string.Concat(environmentName, ":", nameof(Configuration));
|
||||||
IConfigurationSection configurationSection = configurationRoot.GetSection(section);
|
IConfigurationSection configurationSection = configurationRoot.GetSection(section);
|
||||||
|
#pragma warning disable IL3050, IL2026
|
||||||
configuration = configurationSection.Get<Configuration>();
|
configuration = configurationSection.Get<Configuration>();
|
||||||
|
#pragma warning restore IL3050, IL2026
|
||||||
}
|
}
|
||||||
|
PreVerify(configurationRoot, configuration);
|
||||||
result = Get(configuration);
|
result = Get(configuration);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -128,7 +128,7 @@ public class MoveById
|
|||||||
if (filePath.IsIntelligentIdFormat || filePath.SortOrder is not null)
|
if (filePath.IsIntelligentIdFormat || filePath.SortOrder is not null)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
(_, _, id, message) = Property.Models.Stateless.IProperty.Get(_PropertyConfiguration.PopulatePropertyId, fileHolder, isIgnoreExtension, isValidImageFormatExtension, asciiEncoding);
|
(_, _, id, message) = Property.Models.Stateless.IProperty.Get(_PropertyConfiguration, _PropertyConfiguration.PopulatePropertyId, fileHolder, isIgnoreExtension, isValidImageFormatExtension, asciiEncoding);
|
||||||
if (id is null)
|
if (id is null)
|
||||||
continue;
|
continue;
|
||||||
matches = (from l in allFiles where l.Contains($"{id}{fileHolder.ExtensionLowered}") select l).ToArray();
|
matches = (from l in allFiles where l.Contains($"{id}{fileHolder.ExtensionLowered}") select l).ToArray();
|
||||||
|
@ -16,6 +16,23 @@ public class AppSettings
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void PreVerify(IConfigurationRoot configurationRoot, AppSettings? appSettings)
|
||||||
|
{
|
||||||
|
if (appSettings?.Company is null)
|
||||||
|
{
|
||||||
|
List<string> paths = [];
|
||||||
|
foreach (IConfigurationProvider configurationProvider in configurationRoot.Providers)
|
||||||
|
{
|
||||||
|
if (configurationProvider is not Microsoft.Extensions.Configuration.Json.JsonConfigurationProvider jsonConfigurationProvider)
|
||||||
|
continue;
|
||||||
|
if (jsonConfigurationProvider.Source.FileProvider is not Microsoft.Extensions.FileProviders.PhysicalFileProvider physicalFileProvider)
|
||||||
|
continue;
|
||||||
|
paths.Add(physicalFileProvider.Root);
|
||||||
|
}
|
||||||
|
throw new NotSupportedException($"Not found!{Environment.NewLine}{string.Join(Environment.NewLine, paths.Distinct())}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private static Models.AppSettings Get(AppSettings? appSettings)
|
private static Models.AppSettings Get(AppSettings? appSettings)
|
||||||
{
|
{
|
||||||
Models.AppSettings result;
|
Models.AppSettings result;
|
||||||
@ -36,7 +53,10 @@ public class AppSettings
|
|||||||
public static Models.AppSettings Get(IConfigurationRoot configurationRoot)
|
public static Models.AppSettings Get(IConfigurationRoot configurationRoot)
|
||||||
{
|
{
|
||||||
Models.AppSettings result;
|
Models.AppSettings result;
|
||||||
|
#pragma warning disable IL3050, IL2026
|
||||||
AppSettings? appSettings = configurationRoot.Get<AppSettings>();
|
AppSettings? appSettings = configurationRoot.Get<AppSettings>();
|
||||||
|
#pragma warning restore IL3050, IL2026
|
||||||
|
PreVerify(configurationRoot, appSettings);
|
||||||
result = Get(appSettings);
|
result = Get(appSettings);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -7,13 +7,9 @@ namespace View_by_Distance.Offset.Date.Time.Original.Models.Binder;
|
|||||||
public class Configuration
|
public class Configuration
|
||||||
{
|
{
|
||||||
|
|
||||||
#nullable disable
|
public string[]? IgnoreExtensions { get; set; }
|
||||||
|
public Property.Models.Configuration? PropertyConfiguration { get; set; }
|
||||||
public string[] IgnoreExtensions { get; set; }
|
public string? PersonBirthdayFormat { get; set; }
|
||||||
public Property.Models.Configuration PropertyConfiguration { get; set; }
|
|
||||||
public string PersonBirthdayFormat { get; set; }
|
|
||||||
|
|
||||||
#nullable restore
|
|
||||||
|
|
||||||
public override string ToString()
|
public override string ToString()
|
||||||
{
|
{
|
||||||
@ -21,12 +17,30 @@ public class Configuration
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void PreVerify(IConfigurationRoot configurationRoot, Configuration? configuration)
|
||||||
|
{
|
||||||
|
if (configuration?.IgnoreExtensions is null)
|
||||||
|
{
|
||||||
|
List<string> paths = [];
|
||||||
|
foreach (IConfigurationProvider configurationProvider in configurationRoot.Providers)
|
||||||
|
{
|
||||||
|
if (configurationProvider is not Microsoft.Extensions.Configuration.Json.JsonConfigurationProvider jsonConfigurationProvider)
|
||||||
|
continue;
|
||||||
|
if (jsonConfigurationProvider.Source.FileProvider is not Microsoft.Extensions.FileProviders.PhysicalFileProvider physicalFileProvider)
|
||||||
|
continue;
|
||||||
|
paths.Add(physicalFileProvider.Root);
|
||||||
|
}
|
||||||
|
throw new NotSupportedException($"Not found!{Environment.NewLine}{string.Join(Environment.NewLine, paths.Distinct())}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private static Models.Configuration Get(Configuration? configuration)
|
private static Models.Configuration Get(Configuration? configuration)
|
||||||
{
|
{
|
||||||
Models.Configuration result;
|
Models.Configuration result;
|
||||||
if (configuration is null) throw new NullReferenceException(nameof(configuration));
|
if (configuration is null) throw new NullReferenceException(nameof(configuration));
|
||||||
if (configuration.IgnoreExtensions is null) throw new NullReferenceException(nameof(configuration.IgnoreExtensions));
|
if (configuration.IgnoreExtensions is null) throw new NullReferenceException(nameof(configuration.IgnoreExtensions));
|
||||||
if (configuration.PersonBirthdayFormat is null) throw new NullReferenceException(nameof(configuration.PersonBirthdayFormat));
|
if (configuration.PersonBirthdayFormat is null) throw new NullReferenceException(nameof(configuration.PersonBirthdayFormat));
|
||||||
|
if (configuration.PropertyConfiguration is null) throw new NullReferenceException(nameof(configuration.PropertyConfiguration));
|
||||||
result = new(
|
result = new(
|
||||||
configuration.IgnoreExtensions,
|
configuration.IgnoreExtensions,
|
||||||
configuration.PersonBirthdayFormat,
|
configuration.PersonBirthdayFormat,
|
||||||
@ -39,14 +53,19 @@ public class Configuration
|
|||||||
Models.Configuration result;
|
Models.Configuration result;
|
||||||
Configuration? configuration;
|
Configuration? configuration;
|
||||||
if (isEnvironment is null)
|
if (isEnvironment is null)
|
||||||
|
#pragma warning disable IL3050, IL2026
|
||||||
configuration = configurationRoot.Get<Configuration>();
|
configuration = configurationRoot.Get<Configuration>();
|
||||||
|
#pragma warning restore IL3050, IL2026
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
string environmentName = IsEnvironment.GetEnvironmentName(isEnvironment);
|
string environmentName = IsEnvironment.GetEnvironmentName(isEnvironment);
|
||||||
string section = string.Concat(environmentName, ":", nameof(Configuration));
|
string section = string.Concat(environmentName, ":", nameof(Configuration));
|
||||||
IConfigurationSection configurationSection = configurationRoot.GetSection(section);
|
IConfigurationSection configurationSection = configurationRoot.GetSection(section);
|
||||||
|
#pragma warning disable IL3050, IL2026
|
||||||
configuration = configurationSection.Get<Configuration>();
|
configuration = configurationSection.Get<Configuration>();
|
||||||
|
#pragma warning restore IL3050, IL2026
|
||||||
}
|
}
|
||||||
|
PreVerify(configurationRoot, configuration);
|
||||||
result = Get(configuration);
|
result = Get(configuration);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -85,7 +85,7 @@ public class OffsetDateTimeOriginal
|
|||||||
fileHolder = Shared.Models.Stateless.Methods.IFileHolder.Get(file);
|
fileHolder = Shared.Models.Stateless.Methods.IFileHolder.Get(file);
|
||||||
isValidImageFormatExtension = _PropertyConfiguration.ValidImageFormatExtensions.Contains(fileHolder.ExtensionLowered);
|
isValidImageFormatExtension = _PropertyConfiguration.ValidImageFormatExtensions.Contains(fileHolder.ExtensionLowered);
|
||||||
isIgnoreExtension = isValidImageFormatExtension && _PropertyConfiguration.IgnoreExtensions.Contains(fileHolder.ExtensionLowered);
|
isIgnoreExtension = isValidImageFormatExtension && _PropertyConfiguration.IgnoreExtensions.Contains(fileHolder.ExtensionLowered);
|
||||||
(dateTimeOriginal, dateTimes, id, message) = Property.Models.Stateless.IProperty.Get(_PropertyConfiguration.PopulatePropertyId, fileHolder, isIgnoreExtension, isValidImageFormatExtension, asciiEncoding);
|
(dateTimeOriginal, dateTimes, id, message) = Property.Models.Stateless.IProperty.Get(_PropertyConfiguration, _PropertyConfiguration.PopulatePropertyId, fileHolder, isIgnoreExtension, isValidImageFormatExtension, asciiEncoding);
|
||||||
if (message is not null)
|
if (message is not null)
|
||||||
throw new Exception(message);
|
throw new Exception(message);
|
||||||
if (id is null || dateTimeOriginal is null)
|
if (id is null || dateTimeOriginal is null)
|
||||||
@ -112,7 +112,7 @@ public class OffsetDateTimeOriginal
|
|||||||
string checkFile;
|
string checkFile;
|
||||||
PropertyItem? propertyItem;
|
PropertyItem? propertyItem;
|
||||||
string? ticksDirectory = null;
|
string? ticksDirectory = null;
|
||||||
int dateTimeOriginal = MetadataExtractor.Formats.Exif.ExifDirectoryBase.TagDateTimeOriginal;
|
const int dateTimeOriginal = MetadataExtractor.Formats.Exif.ExifDirectoryBase.TagDateTimeOriginal; // 36867
|
||||||
for (int i = 0; i < int.MaxValue; i++)
|
for (int i = 0; i < int.MaxValue; i++)
|
||||||
{
|
{
|
||||||
ticksDirectory = Path.Combine(sourceDirectory, ticks.ToString());
|
ticksDirectory = Path.Combine(sourceDirectory, ticks.ToString());
|
||||||
@ -141,7 +141,7 @@ public class OffsetDateTimeOriginal
|
|||||||
bitmap.SetPropertyItem(propertyItem);
|
bitmap.SetPropertyItem(propertyItem);
|
||||||
bitmap.Save(checkFile);
|
bitmap.Save(checkFile);
|
||||||
bitmap.Dispose();
|
bitmap.Dispose();
|
||||||
(_, _, id, message) = Property.Models.Stateless.IProperty.Get(_PropertyConfiguration.PopulatePropertyId, record.FileHolder, record.IsIgnoreExtension, record.IsValidImageFormatExtension, asciiEncoding);
|
(_, _, id, message) = Property.Models.Stateless.IProperty.Get(_PropertyConfiguration, _PropertyConfiguration.PopulatePropertyId, record.FileHolder, record.IsIgnoreExtension, record.IsValidImageFormatExtension, asciiEncoding);
|
||||||
if (message is not null)
|
if (message is not null)
|
||||||
throw new Exception(message);
|
throw new Exception(message);
|
||||||
if (id is null || id.Value != record.Id)
|
if (id is null || id.Value != record.Id)
|
||||||
@ -200,12 +200,12 @@ public class OffsetDateTimeOriginal
|
|||||||
targetIsIgnoreExtension = targetIsValidImageFormatExtension && _PropertyConfiguration.IgnoreExtensions.Contains(targetFileHolder.ExtensionLowered);
|
targetIsIgnoreExtension = targetIsValidImageFormatExtension && _PropertyConfiguration.IgnoreExtensions.Contains(targetFileHolder.ExtensionLowered);
|
||||||
DateTime minimumDateTime = DateTime.ParseExact(Path.GetFileName(minimumDirectory.First()), format, CultureInfo.InvariantCulture, DateTimeStyles.None);
|
DateTime minimumDateTime = DateTime.ParseExact(Path.GetFileName(minimumDirectory.First()), format, CultureInfo.InvariantCulture, DateTimeStyles.None);
|
||||||
DateTime maximumDateTime = DateTime.ParseExact(Path.GetFileName(maximumDirectory.First()), format, CultureInfo.InvariantCulture, DateTimeStyles.None).AddHours(23);
|
DateTime maximumDateTime = DateTime.ParseExact(Path.GetFileName(maximumDirectory.First()), format, CultureInfo.InvariantCulture, DateTimeStyles.None).AddHours(23);
|
||||||
(badDateTimeOriginal, badDateTimes, badId, badMessage) = Property.Models.Stateless.IProperty.Get(_PropertyConfiguration.PopulatePropertyId, badFileHolder, badIsIgnoreExtension, badIsValidImageFormatExtension, asciiEncoding);
|
(badDateTimeOriginal, badDateTimes, badId, badMessage) = Property.Models.Stateless.IProperty.Get(_PropertyConfiguration, _PropertyConfiguration.PopulatePropertyId, badFileHolder, badIsIgnoreExtension, badIsValidImageFormatExtension, asciiEncoding);
|
||||||
if (badMessage is not null)
|
if (badMessage is not null)
|
||||||
throw new Exception(badMessage);
|
throw new Exception(badMessage);
|
||||||
if (badDateTimes.Length == 0 || badId is null)
|
if (badDateTimes.Length == 0 || badId is null)
|
||||||
throw new Exception(badMessage);
|
throw new Exception(badMessage);
|
||||||
(targetDateTimeOriginal, targetDateTimes, targetId, targetMessage) = Property.Models.Stateless.IProperty.Get(_PropertyConfiguration.PopulatePropertyId, targetFileHolder, targetIsIgnoreExtension, targetIsValidImageFormatExtension, asciiEncoding);
|
(targetDateTimeOriginal, targetDateTimes, targetId, targetMessage) = Property.Models.Stateless.IProperty.Get(_PropertyConfiguration, _PropertyConfiguration.PopulatePropertyId, targetFileHolder, targetIsIgnoreExtension, targetIsValidImageFormatExtension, asciiEncoding);
|
||||||
if (targetMessage is not null)
|
if (targetMessage is not null)
|
||||||
throw new Exception(targetMessage);
|
throw new Exception(targetMessage);
|
||||||
if (targetDateTimes.Length == 0 || targetId is null)
|
if (targetDateTimes.Length == 0 || targetId is null)
|
||||||
|
@ -169,7 +169,7 @@ public class F_PhotoPrism
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void WriteMatches(string fPhotoPrismContentDirectory, string personBirthdayFormat, float[] rectangleIntersectMinimums, long ticks, ReadOnlyCollection<Face> distinctFilteredFaces, Shared.Models.Methods.IMapLogic mapLogic)
|
public static void WriteMatches(string fPhotoPrismContentDirectory, string personBirthdayFormat, float[] rectangleIntersectMinimums, long ticks, ReadOnlyCollection<Face> distinctValidImageFaces, Shared.Models.Methods.IMapLogic mapLogic)
|
||||||
{
|
{
|
||||||
string file;
|
string file;
|
||||||
string text;
|
string text;
|
||||||
@ -189,7 +189,7 @@ public class F_PhotoPrism
|
|||||||
ReadOnlyDictionary<int, ReadOnlyCollection<PersonContainer>>? wholePercentagesToPersonContainers;
|
ReadOnlyDictionary<int, ReadOnlyCollection<PersonContainer>>? wholePercentagesToPersonContainers;
|
||||||
(MappingFromPhotoPrism MappingFromPhotoPrism, Shared.Models.Marker Marker, float Percent)[] sortedCollection;
|
(MappingFromPhotoPrism MappingFromPhotoPrism, Shared.Models.Marker Marker, float Percent)[] sortedCollection;
|
||||||
List<(MappingFromPhotoPrism MappingFromPhotoPrism, Shared.Models.Marker Marker, float Percent)> collection = [];
|
List<(MappingFromPhotoPrism MappingFromPhotoPrism, Shared.Models.Marker Marker, float Percent)> collection = [];
|
||||||
foreach (Face face in distinctFilteredFaces)
|
foreach (Face face in distinctValidImageFaces)
|
||||||
{
|
{
|
||||||
collection.Clear();
|
collection.Clear();
|
||||||
wholePercentages = face.Mapping?.MappingFromLocation?.WholePercentages;
|
wholePercentages = face.Mapping?.MappingFromLocation?.WholePercentages;
|
||||||
|
@ -20,6 +20,23 @@ public class AppSettings
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void PreVerify(IConfigurationRoot configurationRoot, AppSettings? appSettings)
|
||||||
|
{
|
||||||
|
if (appSettings?.Company is null)
|
||||||
|
{
|
||||||
|
List<string> paths = [];
|
||||||
|
foreach (IConfigurationProvider configurationProvider in configurationRoot.Providers)
|
||||||
|
{
|
||||||
|
if (configurationProvider is not Microsoft.Extensions.Configuration.Json.JsonConfigurationProvider jsonConfigurationProvider)
|
||||||
|
continue;
|
||||||
|
if (jsonConfigurationProvider.Source.FileProvider is not Microsoft.Extensions.FileProviders.PhysicalFileProvider physicalFileProvider)
|
||||||
|
continue;
|
||||||
|
paths.Add(physicalFileProvider.Root);
|
||||||
|
}
|
||||||
|
throw new NotSupportedException($"Not found!{Environment.NewLine}{string.Join(Environment.NewLine, paths.Distinct())}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private static Models.AppSettings Get(AppSettings? appSettings)
|
private static Models.AppSettings Get(AppSettings? appSettings)
|
||||||
{
|
{
|
||||||
Models.AppSettings result;
|
Models.AppSettings result;
|
||||||
@ -36,7 +53,10 @@ public class AppSettings
|
|||||||
public static Models.AppSettings Get(IConfigurationRoot configurationRoot)
|
public static Models.AppSettings Get(IConfigurationRoot configurationRoot)
|
||||||
{
|
{
|
||||||
Models.AppSettings result;
|
Models.AppSettings result;
|
||||||
|
#pragma warning disable IL3050, IL2026
|
||||||
AppSettings? appSettings = configurationRoot.Get<AppSettings>();
|
AppSettings? appSettings = configurationRoot.Get<AppSettings>();
|
||||||
|
#pragma warning restore IL3050, IL2026
|
||||||
|
PreVerify(configurationRoot, appSettings);
|
||||||
result = Get(appSettings);
|
result = Get(appSettings);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -5,12 +5,8 @@ namespace View_by_Distance.PrepareForOld.Models.Binder;
|
|||||||
public class Configuration
|
public class Configuration
|
||||||
{
|
{
|
||||||
|
|
||||||
#nullable disable
|
public Property.Models.Configuration? PropertyConfiguration { get; set; }
|
||||||
|
public string[]? Spelling { get; set; }
|
||||||
public Property.Models.Configuration PropertyConfiguration { get; set; }
|
|
||||||
public string[] Spelling { get; set; }
|
|
||||||
|
|
||||||
#nullable restore
|
|
||||||
|
|
||||||
public override string ToString()
|
public override string ToString()
|
||||||
{
|
{
|
||||||
|
@ -54,11 +54,11 @@ public class A_Property
|
|||||||
string angleBracket = _AngleBracketCollection[0];
|
string angleBracket = _AngleBracketCollection[0];
|
||||||
bool populateId = _Configuration.PopulatePropertyId;
|
bool populateId = _Configuration.PopulatePropertyId;
|
||||||
if (!item.IsUniqueFileName)
|
if (!item.IsUniqueFileName)
|
||||||
fileInfo = new(Path.Combine(angleBracket.Replace("<>", _PropertyConfiguration.ResultSingleton), $"{item.ImageFileHolder.NameWithoutExtension}{item.ImageFileHolder.ExtensionLowered}.json"));
|
fileInfo = new(Path.Combine(angleBracket.Replace("<>", _PropertyConfiguration.ResultSingleton), $"{item.FilePath.NameWithoutExtension}{item.FilePath.ExtensionLowered}.json"));
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
(_, int directoryIndex) = Shared.Models.Stateless.Methods.IPath.GetDirectoryNameAndIndex(_PropertyConfiguration, item.FilePath);
|
(_, int directoryIndex) = Shared.Models.Stateless.Methods.IPath.GetDirectoryNameAndIndex(_PropertyConfiguration, item.FilePath);
|
||||||
fileInfo = new(Path.Combine(_FileGroups[_PropertyConfiguration.ResultSingleton][directoryIndex], $"{item.ImageFileHolder.NameWithoutExtension}{item.ImageFileHolder.ExtensionLowered}.json"));
|
fileInfo = new(Path.Combine(_FileGroups[_PropertyConfiguration.ResultSingleton][directoryIndex], $"{item.FilePath.NameWithoutExtension}{item.FilePath.ExtensionLowered}.json"));
|
||||||
}
|
}
|
||||||
List<DateTime> dateTimes = (from l in sourceDirectoryFileTuples where l is not null && changesFrom.Contains(l.Item1) select l.Item2).ToList();
|
List<DateTime> dateTimes = (from l in sourceDirectoryFileTuples where l is not null && changesFrom.Contains(l.Item1) select l.Item2).ToList();
|
||||||
if (_Configuration.ForcePropertyLastWriteTimeToCreationTime && !fileInfo.Exists && File.Exists(Path.ChangeExtension(fileInfo.FullName, ".delete")))
|
if (_Configuration.ForcePropertyLastWriteTimeToCreationTime && !fileInfo.Exists && File.Exists(Path.ChangeExtension(fileInfo.FullName, ".delete")))
|
||||||
@ -99,19 +99,19 @@ public class A_Property
|
|||||||
id = result?.Id;
|
id = result?.Id;
|
||||||
result = null;
|
result = null;
|
||||||
}
|
}
|
||||||
if (!isIgnoreExtension && item.IsValidImageFormatExtension && populateId && result is not null && result.LastWriteTime != item.ImageFileHolder.LastWriteTime)
|
if (!isIgnoreExtension && item.IsValidImageFormatExtension && populateId && result is not null && result.LastWriteTime.Ticks != item.FilePath.LastWriteTicks)
|
||||||
{
|
{
|
||||||
id = null;
|
id = null;
|
||||||
result = null;
|
result = null;
|
||||||
}
|
}
|
||||||
if (!isIgnoreExtension && item.IsValidImageFormatExtension && result?.Width is not null && result.Height is not null && result.Width.Value == result.Height.Value && item.ImageFileHolder.Exists)
|
if (!isIgnoreExtension && item.IsValidImageFormatExtension && result?.Width is not null && result.Height is not null && result.Width.Value == result.Height.Value)
|
||||||
{
|
{
|
||||||
id = result.Id;
|
id = result.Id;
|
||||||
result = null;
|
result = null;
|
||||||
if (result?.Width is not null && result.Height is not null && result.Width.Value != result.Height.Value)
|
if (result?.Width is not null && result.Height is not null && result.Width.Value != result.Height.Value)
|
||||||
throw new Exception("Was square!");
|
throw new Exception("Was square!");
|
||||||
}
|
}
|
||||||
if (!isIgnoreExtension && item.IsValidImageFormatExtension && result is not null && result.FileSize != item.ImageFileHolder.Length)
|
if (!isIgnoreExtension && item.IsValidImageFormatExtension && result is not null && result.FileSize != item.FilePath.Length)
|
||||||
{
|
{
|
||||||
id = result.Id;
|
id = result.Id;
|
||||||
result = null;
|
result = null;
|
||||||
@ -135,7 +135,7 @@ public class A_Property
|
|||||||
if (result is null)
|
if (result is null)
|
||||||
{
|
{
|
||||||
id ??= item.FilePath.Id;
|
id ??= item.FilePath.Id;
|
||||||
(_, _, result) = Stateless.Property.GetProperty(populateId, metadata, item.ImageFileHolder, result, isIgnoreExtension, item.IsValidImageFormatExtension, id, _ASCIIEncoding);
|
(_, _, result) = Stateless.Property.GetProperty(populateId, metadata, item.FilePath, result, isIgnoreExtension, item.IsValidImageFormatExtension, id, _ASCIIEncoding);
|
||||||
json = JsonSerializer.Serialize(result, PropertyGenerationContext.Default.Property);
|
json = JsonSerializer.Serialize(result, PropertyGenerationContext.Default.Property);
|
||||||
if (populateId && Shared.Models.Stateless.Methods.IPath.WriteAllText(fileInfo.FullName, json, updateDateWhenMatches: true, compareBeforeWrite: true))
|
if (populateId && Shared.Models.Stateless.Methods.IPath.WriteAllText(fileInfo.FullName, json, updateDateWhenMatches: true, compareBeforeWrite: true))
|
||||||
{
|
{
|
||||||
@ -183,10 +183,10 @@ public class A_Property
|
|||||||
{
|
{
|
||||||
Shared.Models.Property property;
|
Shared.Models.Property property;
|
||||||
List<string> parseExceptions = [];
|
List<string> parseExceptions = [];
|
||||||
bool isIgnoreExtension = item.IsValidImageFormatExtension && _PropertyConfiguration.IgnoreExtensions.Contains(item.ImageFileHolder.ExtensionLowered);
|
bool isIgnoreExtension = item.IsValidImageFormatExtension && _PropertyConfiguration.IgnoreExtensions.Contains(item.FilePath.ExtensionLowered);
|
||||||
string filteredSourceDirectoryFileExtensionLowered = Path.Combine(sourceDirectory, $"{item.ImageFileHolder.NameWithoutExtension}{item.ImageFileHolder.ExtensionLowered}");
|
string filteredSourceDirectoryFileExtensionLowered = Path.Combine(sourceDirectory, $"{item.FilePath.NameWithoutExtension}{item.FilePath.ExtensionLowered}");
|
||||||
if (item.IsValidImageFormatExtension && item.ImageFileHolder.FullName.Length == filteredSourceDirectoryFileExtensionLowered.Length && item.ImageFileHolder.FullName != filteredSourceDirectoryFileExtensionLowered)
|
if (item.IsValidImageFormatExtension && item.FilePath.FullName.Length == filteredSourceDirectoryFileExtensionLowered.Length && item.FilePath.FullName != filteredSourceDirectoryFileExtensionLowered)
|
||||||
File.Move(item.ImageFileHolder.FullName, filteredSourceDirectoryFileExtensionLowered);
|
File.Move(item.FilePath.FullName, filteredSourceDirectoryFileExtensionLowered);
|
||||||
if (item.FileSizeChanged is null || item.FileSizeChanged.Value || item.LastWriteTimeChanged is null || item.LastWriteTimeChanged.Value || item.Property is null)
|
if (item.FileSizeChanged is null || item.FileSizeChanged.Value || item.LastWriteTimeChanged is null || item.LastWriteTimeChanged.Value || item.Property is null)
|
||||||
{
|
{
|
||||||
property = GetImageProperty(metadata, item, sourceDirectoryFileTuples, parseExceptions, isIgnoreExtension);
|
property = GetImageProperty(metadata, item, sourceDirectoryFileTuples, parseExceptions, isIgnoreExtension);
|
||||||
@ -209,7 +209,7 @@ public class A_Property
|
|||||||
SetAngleBracketCollection(aResultsFullGroupDirectory, sourceDirectory, anyNullOrNoIsUniqueFileName);
|
SetAngleBracketCollection(aResultsFullGroupDirectory, sourceDirectory, anyNullOrNoIsUniqueFileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void SavePropertyParallelWork(int maxDegreeOfParallelism, Shared.Models.Methods.IMetadata<MetadataExtractor.Directory> metadata, List<Exception> exceptions, List<Tuple<string, DateTime>> sourceDirectoryChanges, Container container, List<Item> items, string message)
|
private void SavePropertyParallelWork(int maxDegreeOfParallelism, Shared.Models.Methods.IMetadata<MetadataExtractor.Directory> metadata, List<Exception> exceptions, List<Tuple<string, DateTime>> sourceDirectoryChanges, Container container, ReadOnlyCollection<Item> items, string message)
|
||||||
{
|
{
|
||||||
List<Tuple<string, DateTime>> sourceDirectoryFileTuples = [];
|
List<Tuple<string, DateTime>> sourceDirectoryFileTuples = [];
|
||||||
ParallelOptions parallelOptions = new() { MaxDegreeOfParallelism = maxDegreeOfParallelism };
|
ParallelOptions parallelOptions = new() { MaxDegreeOfParallelism = maxDegreeOfParallelism };
|
||||||
@ -277,11 +277,11 @@ public class A_Property
|
|||||||
bool angleBracketCollectionAny = _AngleBracketCollection.Count != 0;
|
bool angleBracketCollectionAny = _AngleBracketCollection.Count != 0;
|
||||||
if (!angleBracketCollectionAny)
|
if (!angleBracketCollectionAny)
|
||||||
{
|
{
|
||||||
if (item.ImageFileHolder.DirectoryName is null)
|
if (item.FilePath.DirectoryName is null)
|
||||||
throw new NullReferenceException(nameof(item.ImageFileHolder.DirectoryName));
|
throw new NullReferenceException(nameof(item.FilePath.DirectoryName));
|
||||||
SetAngleBracketCollection(item.ImageFileHolder.DirectoryName, !item.IsUniqueFileName);
|
SetAngleBracketCollection(item.FilePath.DirectoryName, !item.IsUniqueFileName);
|
||||||
}
|
}
|
||||||
bool isIgnoreExtension = item.IsValidImageFormatExtension && _PropertyConfiguration.IgnoreExtensions.Contains(item.ImageFileHolder.ExtensionLowered);
|
bool isIgnoreExtension = item.IsValidImageFormatExtension && _PropertyConfiguration.IgnoreExtensions.Contains(item.FilePath.ExtensionLowered);
|
||||||
result = GetImageProperty(metadata, item, sourceDirectoryFileTuples, parseExceptions, isIgnoreExtension);
|
result = GetImageProperty(metadata, item, sourceDirectoryFileTuples, parseExceptions, isIgnoreExtension);
|
||||||
if (!angleBracketCollectionAny)
|
if (!angleBracketCollectionAny)
|
||||||
_AngleBracketCollection.Clear();
|
_AngleBracketCollection.Clear();
|
||||||
|
@ -39,6 +39,23 @@ public class Configuration
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void PreVerify(IConfigurationRoot configurationRoot, Configuration? configuration)
|
||||||
|
{
|
||||||
|
if (configuration?.DateGroup is null)
|
||||||
|
{
|
||||||
|
List<string> paths = [];
|
||||||
|
foreach (IConfigurationProvider configurationProvider in configurationRoot.Providers)
|
||||||
|
{
|
||||||
|
if (configurationProvider is not Microsoft.Extensions.Configuration.Json.JsonConfigurationProvider jsonConfigurationProvider)
|
||||||
|
continue;
|
||||||
|
if (jsonConfigurationProvider.Source.FileProvider is not Microsoft.Extensions.FileProviders.PhysicalFileProvider physicalFileProvider)
|
||||||
|
continue;
|
||||||
|
paths.Add(physicalFileProvider.Root);
|
||||||
|
}
|
||||||
|
throw new NotSupportedException($"Not found!{Environment.NewLine}{string.Join(Environment.NewLine, paths.Distinct())}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private static Models.Configuration Get(Configuration? configuration)
|
private static Models.Configuration Get(Configuration? configuration)
|
||||||
{
|
{
|
||||||
Models.Configuration result;
|
Models.Configuration result;
|
||||||
@ -101,15 +118,19 @@ public class Configuration
|
|||||||
Models.Configuration result;
|
Models.Configuration result;
|
||||||
Configuration? configuration;
|
Configuration? configuration;
|
||||||
if (isEnvironment is null)
|
if (isEnvironment is null)
|
||||||
|
#pragma warning disable IL3050, IL2026
|
||||||
configuration = configurationRoot.Get<Configuration>();
|
configuration = configurationRoot.Get<Configuration>();
|
||||||
|
#pragma warning restore IL3050, IL2026
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
string environmentName = IsEnvironment.GetEnvironmentName(isEnvironment);
|
string environmentName = IsEnvironment.GetEnvironmentName(isEnvironment);
|
||||||
string section = string.Concat(environmentName, ":", nameof(Configuration));
|
string section = string.Concat(environmentName, ":", nameof(Configuration));
|
||||||
IConfigurationSection configurationSection = configurationRoot.GetSection(section);
|
IConfigurationSection configurationSection = configurationRoot.GetSection(section);
|
||||||
|
#pragma warning disable IL3050, IL2026
|
||||||
configuration = configurationSection.Get<Configuration>();
|
configuration = configurationSection.Get<Configuration>();
|
||||||
|
#pragma warning restore IL3050, IL2026
|
||||||
}
|
}
|
||||||
if (configuration is null) throw new NullReferenceException(nameof(configuration));
|
PreVerify(configurationRoot, configuration);
|
||||||
result = Get(configuration);
|
result = Get(configuration);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,9 @@
|
|||||||
using System.Drawing.Imaging;
|
using System.Drawing.Imaging;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
using View_by_Distance.Shared.Models;
|
||||||
using View_by_Distance.Shared.Models.Methods;
|
using View_by_Distance.Shared.Models.Methods;
|
||||||
|
using View_by_Distance.Shared.Models.Properties;
|
||||||
|
|
||||||
namespace View_by_Distance.Property.Models.Stateless;
|
namespace View_by_Distance.Property.Models.Stateless;
|
||||||
|
|
||||||
@ -28,19 +30,29 @@ public interface IProperty
|
|||||||
static PropertyItem GetPropertyItem(ConstructorInfo constructorInfo, int id, short type, string value) =>
|
static PropertyItem GetPropertyItem(ConstructorInfo constructorInfo, int id, short type, string value) =>
|
||||||
Property.GetPropertyItem(constructorInfo, id, type, value);
|
Property.GetPropertyItem(constructorInfo, id, type, value);
|
||||||
|
|
||||||
(string?, DateTime[], Shared.Models.Property) TestStatic_GetProperty(bool populateId, IMetadata<MetadataExtractor.Directory>? metadata, Shared.Models.FileHolder fileHolder, Shared.Models.Property? property, bool isIgnoreExtension, bool isValidImageFormatExtension, int? id, ASCIIEncoding asciiEncoding) =>
|
(string?, DateTime[], Shared.Models.Property) TestStatic_GetProperty(bool populateId, IMetadata<MetadataExtractor.Directory>? metadata, FilePath filePath, Shared.Models.Property? property, bool isIgnoreExtension, bool isValidImageFormatExtension, int? id, ASCIIEncoding asciiEncoding) =>
|
||||||
GetProperty(populateId, metadata, fileHolder, property, isIgnoreExtension, isValidImageFormatExtension, id, asciiEncoding);
|
GetProperty(populateId, metadata, filePath, property, isIgnoreExtension, isValidImageFormatExtension, id, asciiEncoding);
|
||||||
static (string?, DateTime[], Shared.Models.Property) GetProperty(bool populateId, IMetadata<MetadataExtractor.Directory>? metadata, Shared.Models.FileHolder fileHolder, Shared.Models.Property? property, bool isIgnoreExtension, bool isValidImageFormatExtension, int? id, ASCIIEncoding asciiEncoding) =>
|
static (string?, DateTime[], Shared.Models.Property) GetProperty(bool populateId, IMetadata<MetadataExtractor.Directory>? metadata, FilePath filePath, Shared.Models.Property? property, bool isIgnoreExtension, bool isValidImageFormatExtension, int? id, ASCIIEncoding asciiEncoding) =>
|
||||||
Property.GetProperty(populateId, metadata, fileHolder, property, isIgnoreExtension, isValidImageFormatExtension, id, asciiEncoding);
|
Property.GetProperty(populateId, metadata, filePath, property, isIgnoreExtension, isValidImageFormatExtension, id, asciiEncoding);
|
||||||
|
|
||||||
(DateTime?, DateTime[], int?, string?) TestStatic_Get(bool populateId, Shared.Models.FileHolder fileHolder, bool isIgnoreExtension, bool isValidImageFormatExtension, ASCIIEncoding asciiEncoding) =>
|
(DateTime?, DateTime[], int?, string?) TestStatic_Get(IPropertyConfiguration propertyConfiguration, bool populateId, FileHolder fileHolder, bool isIgnoreExtension, bool isValidImageFormatExtension, ASCIIEncoding asciiEncoding) =>
|
||||||
Get(populateId, fileHolder, isIgnoreExtension, isValidImageFormatExtension, asciiEncoding);
|
Get(propertyConfiguration, populateId, fileHolder, isIgnoreExtension, isValidImageFormatExtension, asciiEncoding);
|
||||||
static (DateTime?, DateTime[], int?, string?) Get(bool populateId, Shared.Models.FileHolder fileHolder, bool isIgnoreExtension, bool isValidImageFormatExtension, ASCIIEncoding asciiEncoding) =>
|
static (DateTime?, DateTime[], int?, string?) Get(IPropertyConfiguration propertyConfiguration, bool populateId, FileHolder fileHolder, bool isIgnoreExtension, bool isValidImageFormatExtension, ASCIIEncoding asciiEncoding) =>
|
||||||
Property.Get(populateId, null, fileHolder, isIgnoreExtension, isValidImageFormatExtension, asciiEncoding);
|
Property.Get(populateId, null, FilePath.Get(propertyConfiguration, fileHolder, index: null), isIgnoreExtension, isValidImageFormatExtension, asciiEncoding);
|
||||||
|
|
||||||
(DateTime?, DateTime[], int?, string?) TestStatic_Get(bool populateId, IMetadata<MetadataExtractor.Directory>? metadata, Shared.Models.FileHolder fileHolder, bool isIgnoreExtension, bool isValidImageFormatExtension, ASCIIEncoding asciiEncoding) =>
|
(DateTime?, DateTime[], int?, string?) TestStatic_Get(bool populateId, FilePath filePath, bool isIgnoreExtension, bool isValidImageFormatExtension, ASCIIEncoding asciiEncoding) =>
|
||||||
Get(populateId, metadata, fileHolder, isIgnoreExtension, isValidImageFormatExtension, asciiEncoding);
|
Get(populateId, filePath, isIgnoreExtension, isValidImageFormatExtension, asciiEncoding);
|
||||||
static (DateTime?, DateTime[], int?, string?) Get(bool populateId, IMetadata<MetadataExtractor.Directory>? metadata, Shared.Models.FileHolder fileHolder, bool isIgnoreExtension, bool isValidImageFormatExtension, ASCIIEncoding asciiEncoding) =>
|
static (DateTime?, DateTime[], int?, string?) Get(bool populateId, FilePath filePath, bool isIgnoreExtension, bool isValidImageFormatExtension, ASCIIEncoding asciiEncoding) =>
|
||||||
Property.Get(populateId, metadata, fileHolder, isIgnoreExtension, isValidImageFormatExtension, asciiEncoding);
|
Property.Get(populateId, null, filePath, isIgnoreExtension, isValidImageFormatExtension, asciiEncoding);
|
||||||
|
|
||||||
|
(DateTime?, DateTime[], int?, string?) TestStatic_Get(bool populateId, IMetadata<MetadataExtractor.Directory>? metadata, FilePath filePath, bool isIgnoreExtension, bool isValidImageFormatExtension, ASCIIEncoding asciiEncoding) =>
|
||||||
|
Get(populateId, metadata, filePath, isIgnoreExtension, isValidImageFormatExtension, asciiEncoding);
|
||||||
|
static (DateTime?, DateTime[], int?, string?) Get(bool populateId, IMetadata<MetadataExtractor.Directory>? metadata, FilePath filePath, bool isIgnoreExtension, bool isValidImageFormatExtension, ASCIIEncoding asciiEncoding) =>
|
||||||
|
Property.Get(populateId, metadata, filePath, isIgnoreExtension, isValidImageFormatExtension, asciiEncoding);
|
||||||
|
|
||||||
|
(DateTime?, DateTime[], int?, string?) TestStatic_Get(IPropertyConfiguration propertyConfiguration, bool populateId, IMetadata<MetadataExtractor.Directory>? metadata, FileHolder fileHolder, bool isIgnoreExtension, bool isValidImageFormatExtension, ASCIIEncoding asciiEncoding) =>
|
||||||
|
Get(propertyConfiguration, populateId, metadata, fileHolder, isIgnoreExtension, isValidImageFormatExtension, asciiEncoding);
|
||||||
|
static (DateTime?, DateTime[], int?, string?) Get(IPropertyConfiguration propertyConfiguration, bool populateId, IMetadata<MetadataExtractor.Directory>? metadata, FileHolder fileHolder, bool isIgnoreExtension, bool isValidImageFormatExtension, ASCIIEncoding asciiEncoding) =>
|
||||||
|
Property.Get(populateId, metadata, FilePath.Get(propertyConfiguration, fileHolder, index: null), isIgnoreExtension, isValidImageFormatExtension, asciiEncoding);
|
||||||
|
|
||||||
}
|
}
|
@ -47,10 +47,10 @@ internal partial class Property
|
|||||||
return results;
|
return results;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static List<DateTime> GetDateTimes(FileHolder fileHolder, DateTime?[] dateTimes)
|
private static List<DateTime> GetDateTimes(FilePath filePath, DateTime?[] dateTimes)
|
||||||
{
|
{
|
||||||
List<DateTime> results = [];
|
List<DateTime> results = [];
|
||||||
string[] digits = Digit().Split(fileHolder.FullName);
|
string[] digits = Digit().Split(filePath.FullName);
|
||||||
foreach (string digit in digits)
|
foreach (string digit in digits)
|
||||||
{
|
{
|
||||||
if (digit.Length != 4 || digit[..2] is not "19" and not "20" || !int.TryParse(digit, out int year))
|
if (digit.Length != 4 || digit[..2] is not "19" and not "20" || !int.TryParse(digit, out int year))
|
||||||
@ -75,7 +75,7 @@ internal partial class Property
|
|||||||
return results;
|
return results;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static DateTime? GetDateTimeFromName(FileHolder fileHolder)
|
internal static DateTime? GetDateTimeFromName(FilePath filePath)
|
||||||
{
|
{
|
||||||
DateTime? result = null;
|
DateTime? result = null;
|
||||||
int length;
|
int length;
|
||||||
@ -90,7 +90,7 @@ internal partial class Property
|
|||||||
[string.Empty, "yyyyMMdd_", ticksExample],
|
[string.Empty, "yyyyMMdd_", ticksExample],
|
||||||
[string.Empty, "yyyy-MM-dd_", ticksExample],
|
[string.Empty, "yyyy-MM-dd_", ticksExample],
|
||||||
[string.Empty, "yyyy-MM-dd.", ticksExample],
|
[string.Empty, "yyyy-MM-dd.", ticksExample],
|
||||||
[string.Empty, "yyyy-MM-dd.", $"{ticksExample}.{fileHolder.Length}"],
|
[string.Empty, "yyyy-MM-dd.", $"{ticksExample}.{filePath.Length}"],
|
||||||
[string.Empty, "yyyy-MM-dd HH.mm.ss", string.Empty],
|
[string.Empty, "yyyy-MM-dd HH.mm.ss", string.Empty],
|
||||||
[string.Empty, "yyyyMMdd_HHmmss", "_LLS"],
|
[string.Empty, "yyyyMMdd_HHmmss", "_LLS"],
|
||||||
[string.Empty, "yyyyMMdd_HHmmss", "_HDR"],
|
[string.Empty, "yyyyMMdd_HHmmss", "_HDR"],
|
||||||
@ -106,17 +106,17 @@ internal partial class Property
|
|||||||
if (dateFormat.Length != 3)
|
if (dateFormat.Length != 3)
|
||||||
throw new Exception();
|
throw new Exception();
|
||||||
fullFormat = string.Join(string.Empty, dateFormat);
|
fullFormat = string.Join(string.Empty, dateFormat);
|
||||||
if (fileHolder.NameWithoutExtension.Length != fullFormat.Length)
|
if (filePath.NameWithoutExtension.Length != fullFormat.Length)
|
||||||
continue;
|
continue;
|
||||||
format = dateFormat[1];
|
format = dateFormat[1];
|
||||||
length = dateFormat[0].Length + dateFormat[1].Length;
|
length = dateFormat[0].Length + dateFormat[1].Length;
|
||||||
for (int i = dateFormat[0].Length; i < length; i++)
|
for (int i = dateFormat[0].Length; i < length; i++)
|
||||||
_ = value.Append(fileHolder.NameWithoutExtension[i]);
|
_ = value.Append(filePath.NameWithoutExtension[i]);
|
||||||
if (value.Length != format.Length)
|
if (value.Length != format.Length)
|
||||||
continue;
|
continue;
|
||||||
if (DateTime.TryParseExact(value.ToString(), format, CultureInfo.InvariantCulture, DateTimeStyles.None, out DateTime checkDateTime))
|
if (DateTime.TryParseExact(value.ToString(), format, CultureInfo.InvariantCulture, DateTimeStyles.None, out DateTime checkDateTime))
|
||||||
{
|
{
|
||||||
if (fileHolder.NameWithoutExtension.Length < ticksExample.Length || !long.TryParse(fileHolder.NameWithoutExtension[^ticksExample.Length..], out long ticks))
|
if (filePath.NameWithoutExtension.Length < ticksExample.Length || !long.TryParse(filePath.NameWithoutExtension[^ticksExample.Length..], out long ticks))
|
||||||
result = checkDateTime;
|
result = checkDateTime;
|
||||||
else
|
else
|
||||||
result = new DateTime(ticks);
|
result = new DateTime(ticks);
|
||||||
@ -183,12 +183,11 @@ internal partial class Property
|
|||||||
|
|
||||||
#pragma warning disable CA1416
|
#pragma warning disable CA1416
|
||||||
|
|
||||||
internal static (string?, DateTime[], Shared.Models.Property) GetProperty(bool populateId, IMetadata<MetadataExtractor.Directory>? metadata, FileHolder fileHolder, Shared.Models.Property? property, bool isIgnoreExtension, bool isValidImageFormatExtension, int? id, ASCIIEncoding asciiEncoding)
|
internal static (string?, DateTime[], Shared.Models.Property) GetProperty(bool populateId, IMetadata<MetadataExtractor.Directory>? metadata, FilePath filePath, Shared.Models.Property? property, bool isIgnoreExtension, bool isValidImageFormatExtension, int? id, ASCIIEncoding asciiEncoding)
|
||||||
{
|
{
|
||||||
Shared.Models.Property result;
|
Shared.Models.Property result;
|
||||||
byte[] bytes;
|
byte[] bytes;
|
||||||
string value;
|
string value;
|
||||||
long fileLength;
|
|
||||||
string? message;
|
string? message;
|
||||||
int? width = null;
|
int? width = null;
|
||||||
int? height = null;
|
int? height = null;
|
||||||
@ -206,27 +205,27 @@ internal partial class Property
|
|||||||
DateTime? dateTimeOriginal = null;
|
DateTime? dateTimeOriginal = null;
|
||||||
DateTime? dateTimeDigitized = null;
|
DateTime? dateTimeDigitized = null;
|
||||||
DateTime? dateTimeOriginalByLogic = null;
|
DateTime? dateTimeOriginalByLogic = null;
|
||||||
DateTime? dateTimeFromName = GetDateTimeFromName(fileHolder);
|
DateTime? dateTimeFromName = GetDateTimeFromName(filePath);
|
||||||
if (!isValidImageFormatExtension && fileHolder.Exists && metadata is not null)
|
if (!isValidImageFormatExtension && metadata is not null)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
IReadOnlyList<MetadataExtractor.Directory> directories = MetadataExtractor.ImageMetadataReader.ReadMetadata(fileHolder.FullName);
|
IReadOnlyList<MetadataExtractor.Directory> directories = MetadataExtractor.ImageMetadataReader.ReadMetadata(filePath.FullName);
|
||||||
(dateTimeOriginalByLogic, DateTime?[] metadataDateTimes) = metadata.GetDateTimes(fileHolder, directories);
|
(dateTimeOriginalByLogic, DateTime?[] metadataDateTimes) = metadata.GetDateTimes(filePath, directories);
|
||||||
dateTimesByLogic = GetDateTimes(metadataDateTimes);
|
dateTimesByLogic = GetDateTimes(metadataDateTimes);
|
||||||
message = null;
|
message = null;
|
||||||
}
|
}
|
||||||
catch (Exception)
|
catch (Exception)
|
||||||
{
|
{
|
||||||
dateTimesByLogic = [];
|
dateTimesByLogic = [];
|
||||||
message = string.Concat(new StackFrame().GetMethod()?.Name, " <", fileHolder.FullName, ">");
|
message = string.Concat(new StackFrame().GetMethod()?.Name, " <", filePath.FullName, ">");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (!isIgnoreExtension && isValidImageFormatExtension && fileHolder.Exists)
|
else if (!isIgnoreExtension && isValidImageFormatExtension)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
using Image image = Image.FromFile(fileHolder.FullName);
|
using Image image = Image.FromFile(filePath.FullName);
|
||||||
width = image.Width;
|
width = image.Width;
|
||||||
height = image.Height;
|
height = image.Height;
|
||||||
if (populateId && id is null)
|
if (populateId && id is null)
|
||||||
@ -320,51 +319,41 @@ internal partial class Property
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
message = null;
|
message = null;
|
||||||
dateTimes = [fileHolder.LastWriteTime, fileHolder.CreationTime, dateTime, dateTimeDigitized, dateTimeOriginal, gpsDateStamp];
|
dateTimes = [new(filePath.LastWriteTicks), new(filePath.CreationTicks), dateTime, dateTimeDigitized, dateTimeOriginal, gpsDateStamp];
|
||||||
}
|
}
|
||||||
catch (Exception)
|
catch (Exception)
|
||||||
{
|
{
|
||||||
dateTimes = [];
|
dateTimes = [];
|
||||||
message = string.Concat(new StackFrame().GetMethod()?.Name, " <", fileHolder.FullName, ">");
|
message = string.Concat(new StackFrame().GetMethod()?.Name, " <", filePath.FullName, ">");
|
||||||
}
|
}
|
||||||
if (metadata is not null && dateTimeOriginal is null)
|
if (metadata is not null && dateTimeOriginal is null)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
IReadOnlyList<MetadataExtractor.Directory> directories = MetadataExtractor.ImageMetadataReader.ReadMetadata(fileHolder.FullName);
|
IReadOnlyList<MetadataExtractor.Directory> directories = MetadataExtractor.ImageMetadataReader.ReadMetadata(filePath.FullName);
|
||||||
(dateTimeOriginalByLogic, DateTime?[] metadataDateTimes) = metadata.GetDateTimes(fileHolder, directories);
|
(dateTimeOriginalByLogic, DateTime?[] metadataDateTimes) = metadata.GetDateTimes(filePath, directories);
|
||||||
dateTimesByLogic = GetDateTimes(dateTimes, metadataDateTimes);
|
dateTimesByLogic = GetDateTimes(dateTimes, metadataDateTimes);
|
||||||
message = null;
|
message = null;
|
||||||
}
|
}
|
||||||
catch (Exception) { message = string.Concat(new StackFrame().GetMethod()?.Name, " <", fileHolder.FullName, ">"); }
|
catch (Exception) { message = string.Concat(new StackFrame().GetMethod()?.Name, " <", filePath.FullName, ">"); }
|
||||||
}
|
}
|
||||||
if (dateTimeFromName is null)
|
if (dateTimeFromName is null)
|
||||||
(dateTimeOriginalByLogic, dateTimesByLogic) = (dateTimeOriginal, GetDateTimes(fileHolder, dateTimes));
|
(dateTimeOriginalByLogic, dateTimesByLogic) = (dateTimeOriginal, GetDateTimes(filePath, dateTimes));
|
||||||
else
|
else
|
||||||
(dateTimeOriginalByLogic, dateTimesByLogic) = (dateTimeOriginal, GetDateTimes(dateTimeFromName.Value, dateTimes));
|
(dateTimeOriginalByLogic, dateTimesByLogic) = (dateTimeOriginal, GetDateTimes(dateTimeFromName.Value, dateTimes));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
(message, dateTimeOriginalByLogic, dateTimesByLogic) = (null, null, []);
|
(message, dateTimeOriginalByLogic, dateTimesByLogic) = (null, null, []);
|
||||||
if (fileHolder.Length is null)
|
if (property is not null)
|
||||||
fileLength = 0;
|
result = new(property.CreationTime, dateTime, dateTimeDigitized, dateTimeFromName, dateTimeOriginalByLogic, filePath.Length, gpsDateStamp, height, id, keywords, property.LastWriteTime, make, model, orientation?.ToString(), width);
|
||||||
else
|
else
|
||||||
fileLength = fileHolder.Length.Value;
|
result = new(new(filePath.CreationTicks), dateTime, dateTimeDigitized, dateTimeFromName, dateTimeOriginalByLogic, filePath.Length, gpsDateStamp, height, id, keywords, new(filePath.LastWriteTicks), make, model, orientation?.ToString(), width);
|
||||||
if (fileHolder.CreationTime is null && property?.CreationTime is null)
|
|
||||||
throw new NullReferenceException(nameof(fileHolder.CreationTime));
|
|
||||||
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?.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?.ToString(), width);
|
|
||||||
else
|
|
||||||
throw new NullReferenceException(nameof(property));
|
|
||||||
return (message, dateTimesByLogic.ToArray(), result);
|
return (message, dateTimesByLogic.ToArray(), result);
|
||||||
}
|
}
|
||||||
|
|
||||||
#pragma warning restore CA1416
|
#pragma warning restore CA1416
|
||||||
|
|
||||||
internal static (DateTime?, DateTime[], int?, string?) Get(bool populateId, IMetadata<MetadataExtractor.Directory>? metadata, FileHolder fileHolder, bool isIgnoreExtension, bool isValidImageFormatExtension, ASCIIEncoding asciiEncoding)
|
internal static (DateTime?, DateTime[], int?, string?) Get(bool populateId, IMetadata<MetadataExtractor.Directory>? metadata, FilePath filePath, bool isIgnoreExtension, bool isValidImageFormatExtension, ASCIIEncoding asciiEncoding)
|
||||||
{
|
{
|
||||||
int? id = null;
|
int? id = null;
|
||||||
string? message;
|
string? message;
|
||||||
@ -373,7 +362,7 @@ internal partial class Property
|
|||||||
if (isIgnoreExtension || !isValidImageFormatExtension)
|
if (isIgnoreExtension || !isValidImageFormatExtension)
|
||||||
(message, dateTimes, property) = (null, [], null);
|
(message, dateTimes, property) = (null, [], null);
|
||||||
else
|
else
|
||||||
(message, dateTimes, property) = GetProperty(populateId, metadata, fileHolder, property, isIgnoreExtension, isValidImageFormatExtension, id, asciiEncoding);
|
(message, dateTimes, property) = GetProperty(populateId, metadata, filePath, property, isIgnoreExtension, isValidImageFormatExtension, id, asciiEncoding);
|
||||||
return new(property?.DateTimeOriginal, dateTimes, property?.Id, message);
|
return new(property?.DateTimeOriginal, dateTimes, property?.Id, message);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -21,6 +21,23 @@ public class AppSettings
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void PreVerify(IConfigurationRoot configurationRoot, AppSettings? appSettings)
|
||||||
|
{
|
||||||
|
if (appSettings?.Company is null)
|
||||||
|
{
|
||||||
|
List<string> paths = [];
|
||||||
|
foreach (IConfigurationProvider configurationProvider in configurationRoot.Providers)
|
||||||
|
{
|
||||||
|
if (configurationProvider is not Microsoft.Extensions.Configuration.Json.JsonConfigurationProvider jsonConfigurationProvider)
|
||||||
|
continue;
|
||||||
|
if (jsonConfigurationProvider.Source.FileProvider is not Microsoft.Extensions.FileProviders.PhysicalFileProvider physicalFileProvider)
|
||||||
|
continue;
|
||||||
|
paths.Add(physicalFileProvider.Root);
|
||||||
|
}
|
||||||
|
throw new NotSupportedException($"Not found!{Environment.NewLine}{string.Join(Environment.NewLine, paths.Distinct())}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private static Models.AppSettings Get(AppSettings? appSettings)
|
private static Models.AppSettings Get(AppSettings? appSettings)
|
||||||
{
|
{
|
||||||
Models.AppSettings result;
|
Models.AppSettings result;
|
||||||
@ -49,6 +66,7 @@ public class AppSettings
|
|||||||
#pragma warning disable IL3050, IL2026
|
#pragma warning disable IL3050, IL2026
|
||||||
AppSettings? appSettings = configurationRoot.Get<AppSettings>();
|
AppSettings? appSettings = configurationRoot.Get<AppSettings>();
|
||||||
#pragma warning restore IL3050, IL2026
|
#pragma warning restore IL3050, IL2026
|
||||||
|
PreVerify(configurationRoot, appSettings);
|
||||||
result = Get(appSettings);
|
result = Get(appSettings);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -18,6 +18,23 @@ public class Configuration
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void PreVerify(IConfigurationRoot configurationRoot, Configuration? configuration)
|
||||||
|
{
|
||||||
|
if (configuration?.ForceMetadataLastWriteTimeToCreationTime is null)
|
||||||
|
{
|
||||||
|
List<string> paths = [];
|
||||||
|
foreach (IConfigurationProvider configurationProvider in configurationRoot.Providers)
|
||||||
|
{
|
||||||
|
if (configurationProvider is not Microsoft.Extensions.Configuration.Json.JsonConfigurationProvider jsonConfigurationProvider)
|
||||||
|
continue;
|
||||||
|
if (jsonConfigurationProvider.Source.FileProvider is not Microsoft.Extensions.FileProviders.PhysicalFileProvider physicalFileProvider)
|
||||||
|
continue;
|
||||||
|
paths.Add(physicalFileProvider.Root);
|
||||||
|
}
|
||||||
|
throw new NotSupportedException($"Not found!{Environment.NewLine}{string.Join(Environment.NewLine, paths.Distinct())}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private static Models.Configuration Get(Configuration? configuration, Property.Models.Configuration propertyConfiguration)
|
private static Models.Configuration Get(Configuration? configuration, Property.Models.Configuration propertyConfiguration)
|
||||||
{
|
{
|
||||||
Models.Configuration result;
|
Models.Configuration result;
|
||||||
@ -39,14 +56,19 @@ public class Configuration
|
|||||||
Models.Configuration result;
|
Models.Configuration result;
|
||||||
Configuration? configuration;
|
Configuration? configuration;
|
||||||
if (isEnvironment is null)
|
if (isEnvironment is null)
|
||||||
|
#pragma warning disable IL3050, IL2026
|
||||||
configuration = configurationRoot.Get<Configuration>();
|
configuration = configurationRoot.Get<Configuration>();
|
||||||
|
#pragma warning restore IL3050, IL2026
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
string environmentName = IsEnvironment.GetEnvironmentName(isEnvironment);
|
string environmentName = IsEnvironment.GetEnvironmentName(isEnvironment);
|
||||||
string section = string.Concat(environmentName, ":", nameof(Configuration));
|
string section = string.Concat(environmentName, ":", nameof(Configuration));
|
||||||
IConfigurationSection configurationSection = configurationRoot.GetSection(section);
|
IConfigurationSection configurationSection = configurationRoot.GetSection(section);
|
||||||
|
#pragma warning disable IL3050, IL2026
|
||||||
configuration = configurationSection.Get<Configuration>();
|
configuration = configurationSection.Get<Configuration>();
|
||||||
|
#pragma warning restore IL3050, IL2026
|
||||||
}
|
}
|
||||||
|
PreVerify(configurationRoot, configuration);
|
||||||
result = Get(configuration, propertyConfiguration);
|
result = Get(configuration, propertyConfiguration);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -268,7 +268,7 @@ public class Rename
|
|||||||
if (fileHolder.DirectoryName is null)
|
if (fileHolder.DirectoryName is null)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
(dateTimeOriginal, dateTimes, id, message) = Property.Models.Stateless.IProperty.Get(_PropertyConfiguration.PopulatePropertyId, metadata, fileHolder, isIgnoreExtension, isValidImageFormatExtension, asciiEncoding);
|
(dateTimeOriginal, dateTimes, id, message) = Property.Models.Stateless.IProperty.Get(_PropertyConfiguration, _PropertyConfiguration.PopulatePropertyId, metadata, fileHolder, isIgnoreExtension, isValidImageFormatExtension, asciiEncoding);
|
||||||
if (ffmpegFiles is not null)
|
if (ffmpegFiles is not null)
|
||||||
{
|
{
|
||||||
fileHolder = Shared.Models.Stateless.Methods.IFileHolder.Get(files[i]);
|
fileHolder = Shared.Models.Stateless.Methods.IFileHolder.Get(files[i]);
|
||||||
@ -402,7 +402,7 @@ public class Rename
|
|||||||
{
|
{
|
||||||
if (record.Id is null)
|
if (record.Id is null)
|
||||||
continue;
|
continue;
|
||||||
paddedId = IId.GetPaddedId(_PropertyConfiguration, record.Index, record.Id.Value);
|
paddedId = IId.GetPaddedId(_PropertyConfiguration, record.Id.Value, ignore: null, record.Index);
|
||||||
checkFileExtension = fileHolder.ExtensionLowered == jpeg ? jpg : fileHolder.ExtensionLowered;
|
checkFileExtension = fileHolder.ExtensionLowered == jpeg ? jpg : fileHolder.ExtensionLowered;
|
||||||
checkFile = Path.Combine(seasonDirectory, $"{paddedId}{checkFileExtension}");
|
checkFile = Path.Combine(seasonDirectory, $"{paddedId}{checkFileExtension}");
|
||||||
if (checkFile == fileHolder.FullName)
|
if (checkFile == fileHolder.FullName)
|
||||||
|
@ -193,7 +193,7 @@ public class C_Resize
|
|||||||
{
|
{
|
||||||
Bitmap bitmap;
|
Bitmap bitmap;
|
||||||
int outputResolutionWidth = resize[_OutputResolutionWidthIndex];
|
int outputResolutionWidth = resize[_OutputResolutionWidthIndex];
|
||||||
using Bitmap temp = new(mappingFromItem.ImageFileHolder.FullName, useIcm: false);
|
using Bitmap temp = new(mappingFromItem.FilePath.FullName, useIcm: false);
|
||||||
int outputResolutionHeight = resize[_OutputResolutionHeightIndex];
|
int outputResolutionHeight = resize[_OutputResolutionHeightIndex];
|
||||||
PropertyItem[] propertyItems = temp.PropertyItems;
|
PropertyItem[] propertyItems = temp.PropertyItems;
|
||||||
int outputResolutionOrientation = resize[_OutputResolutionOrientationIndex];
|
int outputResolutionOrientation = resize[_OutputResolutionOrientationIndex];
|
||||||
@ -236,7 +236,7 @@ public class C_Resize
|
|||||||
private void SaveResizedSubfile5(MappingFromItem mappingFromItem, int[] resize, byte[] bytes)
|
private void SaveResizedSubfile5(MappingFromItem mappingFromItem, int[] resize, byte[] bytes)
|
||||||
{
|
{
|
||||||
Bitmap bitmap;
|
Bitmap bitmap;
|
||||||
using Bitmap temp = new(mappingFromItem.ImageFileHolder.FullName, useIcm: false);
|
using Bitmap temp = new(mappingFromItem.FilePath.FullName, useIcm: false);
|
||||||
PropertyItem[] propertyItems = temp.PropertyItems;
|
PropertyItem[] propertyItems = temp.PropertyItems;
|
||||||
int tempResolutionWidth = resize[_TempResolutionWidth];
|
int tempResolutionWidth = resize[_TempResolutionWidth];
|
||||||
int tempResolutionHeight = resize[_TempResolutionHeight];
|
int tempResolutionHeight = resize[_TempResolutionHeight];
|
||||||
@ -312,10 +312,12 @@ public class C_Resize
|
|||||||
{
|
{
|
||||||
if (mappingFromItem.ResizedFileHolder is null)
|
if (mappingFromItem.ResizedFileHolder is null)
|
||||||
throw new NullReferenceException(nameof(mappingFromItem.ResizedFileHolder));
|
throw new NullReferenceException(nameof(mappingFromItem.ResizedFileHolder));
|
||||||
|
#pragma warning disable CA1854
|
||||||
if (!outputResolutionToResize.ContainsKey(_Original))
|
if (!outputResolutionToResize.ContainsKey(_Original))
|
||||||
throw new Exception();
|
throw new Exception();
|
||||||
if (!outputResolutionToResize.ContainsKey(outputResolution))
|
if (!outputResolutionToResize.ContainsKey(outputResolution))
|
||||||
throw new Exception();
|
throw new Exception();
|
||||||
|
#pragma warning restore CA1854
|
||||||
FileInfo fileInfo = new(mappingFromItem.ResizedFileHolder.FullName);
|
FileInfo fileInfo = new(mappingFromItem.ResizedFileHolder.FullName);
|
||||||
bool check = false;
|
bool check = false;
|
||||||
int[] resize = outputResolutionToResize[outputResolution];
|
int[] resize = outputResolutionToResize[outputResolution];
|
||||||
@ -337,7 +339,7 @@ public class C_Resize
|
|||||||
{
|
{
|
||||||
// if (fileInfo.Exists)
|
// if (fileInfo.Exists)
|
||||||
// File.Delete(fileInfo.FullName);
|
// File.Delete(fileInfo.FullName);
|
||||||
// File.Copy(mappingFromItem.ImageFileHolder.FullName, fileInfo.FullName);
|
// File.Copy(mappingFromItem.FilePath.FullName, fileInfo.FullName);
|
||||||
// item.SetResizedFileHolder(_FileNameExtension, Shared.Models.Stateless.Methods.IFileHolder.Refresh(mappingFromItem.ResizedFileHolder));
|
// item.SetResizedFileHolder(_FileNameExtension, Shared.Models.Stateless.Methods.IFileHolder.Refresh(mappingFromItem.ResizedFileHolder));
|
||||||
// subFileTuples.Add(new Tuple<string, DateTime>(nameof(C_Resize), DateTime.Now));
|
// subFileTuples.Add(new Tuple<string, DateTime>(nameof(C_Resize), DateTime.Now));
|
||||||
}
|
}
|
||||||
@ -429,10 +431,10 @@ public class C_Resize
|
|||||||
}
|
}
|
||||||
|
|
||||||
public FileHolder GetResizedFileHolder(string cResultsFullGroupDirectory, Item item, bool outputResolutionHasNumber) =>
|
public FileHolder GetResizedFileHolder(string cResultsFullGroupDirectory, Item item, bool outputResolutionHasNumber) =>
|
||||||
GetResizedFileHolder(cResultsFullGroupDirectory, item.FilePath, outputResolutionHasNumber, item.ImageFileHolder.Name);
|
GetResizedFileHolder(cResultsFullGroupDirectory, item.FilePath, outputResolutionHasNumber, item.FilePath.Name);
|
||||||
|
|
||||||
public FileHolder GetResizedFileHolder(string cResultsFullGroupDirectory, Item item, bool outputResolutionHasNumber, int id) =>
|
public FileHolder GetResizedFileHolder(string cResultsFullGroupDirectory, Item item, bool outputResolutionHasNumber, int id) =>
|
||||||
GetResizedFileHolder(cResultsFullGroupDirectory, item.FilePath, outputResolutionHasNumber, $"{id}{item.ImageFileHolder.ExtensionLowered}");
|
GetResizedFileHolder(cResultsFullGroupDirectory, item.FilePath, outputResolutionHasNumber, $"{id}{item.FilePath.ExtensionLowered}");
|
||||||
|
|
||||||
public Dictionary<string, int[]> GetResizeKeyValuePairs(Configuration configuration, string cResultsFullGroupDirectory, FilePath filePath, List<Tuple<string, DateTime>> subFileTuples, List<string> parseExceptions, Shared.Models.Property property, MappingFromItem mappingFromItem)
|
public Dictionary<string, int[]> GetResizeKeyValuePairs(Configuration configuration, string cResultsFullGroupDirectory, FilePath filePath, List<Tuple<string, DateTime>> subFileTuples, List<string> parseExceptions, Shared.Models.Property property, MappingFromItem mappingFromItem)
|
||||||
{
|
{
|
||||||
@ -441,7 +443,7 @@ public class C_Resize
|
|||||||
string[] changesFrom = [nameof(A_Property), nameof(B_Metadata)];
|
string[] changesFrom = [nameof(A_Property), nameof(B_Metadata)];
|
||||||
List<DateTime> dateTimes = (from l in subFileTuples where changesFrom.Contains(l.Item1) select l.Item2).ToList();
|
List<DateTime> dateTimes = (from l in subFileTuples where changesFrom.Contains(l.Item1) select l.Item2).ToList();
|
||||||
(_, int directoryIndex) = Shared.Models.Stateless.Methods.IPath.GetDirectoryNameAndIndex(_PropertyConfiguration, filePath);
|
(_, int directoryIndex) = Shared.Models.Stateless.Methods.IPath.GetDirectoryNameAndIndex(_PropertyConfiguration, filePath);
|
||||||
FileInfo fileInfo = new(Path.Combine(_FileGroups[_PropertyConfiguration.ResultSingleton][directoryIndex], $"{mappingFromItem.ImageFileHolder.NameWithoutExtension}{mappingFromItem.ImageFileHolder.ExtensionLowered}.json"));
|
FileInfo fileInfo = new(Path.Combine(_FileGroups[_PropertyConfiguration.ResultSingleton][directoryIndex], $"{mappingFromItem.FilePath.NameWithoutExtension}{mappingFromItem.FilePath.ExtensionLowered}.json"));
|
||||||
if (_ForceResizeLastWriteTimeToCreationTime && !fileInfo.Exists && File.Exists(Path.ChangeExtension(fileInfo.FullName, ".delete")))
|
if (_ForceResizeLastWriteTimeToCreationTime && !fileInfo.Exists && File.Exists(Path.ChangeExtension(fileInfo.FullName, ".delete")))
|
||||||
{
|
{
|
||||||
File.Move(Path.ChangeExtension(fileInfo.FullName, ".delete"), fileInfo.FullName);
|
File.Move(Path.ChangeExtension(fileInfo.FullName, ".delete"), fileInfo.FullName);
|
||||||
|
@ -21,6 +21,23 @@ public class AppSettings
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void PreVerify(IConfigurationRoot configurationRoot, AppSettings? appSettings)
|
||||||
|
{
|
||||||
|
if (appSettings?.Company is null)
|
||||||
|
{
|
||||||
|
List<string> paths = [];
|
||||||
|
foreach (IConfigurationProvider configurationProvider in configurationRoot.Providers)
|
||||||
|
{
|
||||||
|
if (configurationProvider is not Microsoft.Extensions.Configuration.Json.JsonConfigurationProvider jsonConfigurationProvider)
|
||||||
|
continue;
|
||||||
|
if (jsonConfigurationProvider.Source.FileProvider is not Microsoft.Extensions.FileProviders.PhysicalFileProvider physicalFileProvider)
|
||||||
|
continue;
|
||||||
|
paths.Add(physicalFileProvider.Root);
|
||||||
|
}
|
||||||
|
throw new NotSupportedException($"Not found!{Environment.NewLine}{string.Join(Environment.NewLine, paths.Distinct())}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private static Models.AppSettings Get(AppSettings? appSettings)
|
private static Models.AppSettings Get(AppSettings? appSettings)
|
||||||
{
|
{
|
||||||
Models.AppSettings result;
|
Models.AppSettings result;
|
||||||
@ -38,7 +55,10 @@ public class AppSettings
|
|||||||
public static Models.AppSettings Get(IConfigurationRoot configurationRoot)
|
public static Models.AppSettings Get(IConfigurationRoot configurationRoot)
|
||||||
{
|
{
|
||||||
Models.AppSettings result;
|
Models.AppSettings result;
|
||||||
|
#pragma warning disable IL3050, IL2026
|
||||||
AppSettings? appSettings = configurationRoot.Get<AppSettings>();
|
AppSettings? appSettings = configurationRoot.Get<AppSettings>();
|
||||||
|
#pragma warning restore IL3050, IL2026
|
||||||
|
PreVerify(configurationRoot, appSettings);
|
||||||
result = Get(appSettings);
|
result = Get(appSettings);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -7,13 +7,9 @@ namespace View_by_Distance.Set.Created.Date.Models.Binder;
|
|||||||
public class Configuration
|
public class Configuration
|
||||||
{
|
{
|
||||||
|
|
||||||
#nullable disable
|
public string[]? IgnoreExtensions { get; set; }
|
||||||
|
public Property.Models.Configuration? PropertyConfiguration { get; set; }
|
||||||
public string[] IgnoreExtensions { get; set; }
|
public string? PersonBirthdayFormat { get; set; }
|
||||||
public Property.Models.Configuration PropertyConfiguration { get; set; }
|
|
||||||
public string PersonBirthdayFormat { get; set; }
|
|
||||||
|
|
||||||
#nullable restore
|
|
||||||
|
|
||||||
public override string ToString()
|
public override string ToString()
|
||||||
{
|
{
|
||||||
@ -21,12 +17,30 @@ public class Configuration
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void PreVerify(IConfigurationRoot configurationRoot, Configuration? configuration)
|
||||||
|
{
|
||||||
|
if (configuration?.IgnoreExtensions is null)
|
||||||
|
{
|
||||||
|
List<string> paths = [];
|
||||||
|
foreach (IConfigurationProvider configurationProvider in configurationRoot.Providers)
|
||||||
|
{
|
||||||
|
if (configurationProvider is not Microsoft.Extensions.Configuration.Json.JsonConfigurationProvider jsonConfigurationProvider)
|
||||||
|
continue;
|
||||||
|
if (jsonConfigurationProvider.Source.FileProvider is not Microsoft.Extensions.FileProviders.PhysicalFileProvider physicalFileProvider)
|
||||||
|
continue;
|
||||||
|
paths.Add(physicalFileProvider.Root);
|
||||||
|
}
|
||||||
|
throw new NotSupportedException($"Not found!{Environment.NewLine}{string.Join(Environment.NewLine, paths.Distinct())}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private static Models.Configuration Get(Configuration? configuration)
|
private static Models.Configuration Get(Configuration? configuration)
|
||||||
{
|
{
|
||||||
Models.Configuration result;
|
Models.Configuration result;
|
||||||
if (configuration is null) throw new NullReferenceException(nameof(configuration));
|
if (configuration is null) throw new NullReferenceException(nameof(configuration));
|
||||||
if (configuration.IgnoreExtensions is null) throw new NullReferenceException(nameof(configuration.IgnoreExtensions));
|
if (configuration.IgnoreExtensions is null) throw new NullReferenceException(nameof(configuration.IgnoreExtensions));
|
||||||
if (configuration.PersonBirthdayFormat is null) throw new NullReferenceException(nameof(configuration.PersonBirthdayFormat));
|
if (configuration.PersonBirthdayFormat is null) throw new NullReferenceException(nameof(configuration.PersonBirthdayFormat));
|
||||||
|
if (configuration.PropertyConfiguration is null) throw new NullReferenceException(nameof(configuration.PropertyConfiguration));
|
||||||
result = new(
|
result = new(
|
||||||
configuration.IgnoreExtensions,
|
configuration.IgnoreExtensions,
|
||||||
configuration.PersonBirthdayFormat,
|
configuration.PersonBirthdayFormat,
|
||||||
@ -39,14 +53,19 @@ public class Configuration
|
|||||||
Models.Configuration result;
|
Models.Configuration result;
|
||||||
Configuration? configuration;
|
Configuration? configuration;
|
||||||
if (isEnvironment is null)
|
if (isEnvironment is null)
|
||||||
|
#pragma warning disable IL3050, IL2026
|
||||||
configuration = configurationRoot.Get<Configuration>();
|
configuration = configurationRoot.Get<Configuration>();
|
||||||
|
#pragma warning restore IL3050, IL2026
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
string environmentName = IsEnvironment.GetEnvironmentName(isEnvironment);
|
string environmentName = IsEnvironment.GetEnvironmentName(isEnvironment);
|
||||||
string section = string.Concat(environmentName, ":", nameof(Configuration));
|
string section = string.Concat(environmentName, ":", nameof(Configuration));
|
||||||
IConfigurationSection configurationSection = configurationRoot.GetSection(section);
|
IConfigurationSection configurationSection = configurationRoot.GetSection(section);
|
||||||
|
#pragma warning disable IL3050, IL2026
|
||||||
configuration = configurationSection.Get<Configuration>();
|
configuration = configurationSection.Get<Configuration>();
|
||||||
|
#pragma warning restore IL3050, IL2026
|
||||||
}
|
}
|
||||||
|
PreVerify(configurationRoot, configuration);
|
||||||
result = Get(configuration);
|
result = Get(configuration);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -86,7 +86,7 @@ public class SetCreatedDate
|
|||||||
isIgnoreExtension = isValidImageFormatExtension && _PropertyConfiguration.IgnoreExtensions.Contains(fileHolder.ExtensionLowered);
|
isIgnoreExtension = isValidImageFormatExtension && _PropertyConfiguration.IgnoreExtensions.Contains(fileHolder.ExtensionLowered);
|
||||||
if (isIgnoreExtension || !isValidImageFormatExtension)
|
if (isIgnoreExtension || !isValidImageFormatExtension)
|
||||||
continue;
|
continue;
|
||||||
(dateTimeOriginal, dateTimes, id, message) = Property.Models.Stateless.IProperty.Get(_PropertyConfiguration.PopulatePropertyId, metadata, fileHolder, isIgnoreExtension, isValidImageFormatExtension, asciiEncoding);
|
(dateTimeOriginal, dateTimes, id, message) = Property.Models.Stateless.IProperty.Get(_PropertyConfiguration, _PropertyConfiguration.PopulatePropertyId, metadata, fileHolder, isIgnoreExtension, isValidImageFormatExtension, asciiEncoding);
|
||||||
if (dateTimeOriginal is null)
|
if (dateTimeOriginal is null)
|
||||||
results.Add(new(fileHolder, false, dateTimes.Min()));
|
results.Add(new(fileHolder, false, dateTimes.Min()));
|
||||||
else
|
else
|
||||||
|
19
Shared/Models/Aggregations.cs
Normal file
19
Shared/Models/Aggregations.cs
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
using System.Text.Json.Serialization;
|
||||||
|
|
||||||
|
namespace View_by_Distance.Shared.Models;
|
||||||
|
|
||||||
|
public record Aggregations(
|
||||||
|
[property: JsonPropertyName("allPeople")] IReadOnlyList<AllPerson> AllPeople,
|
||||||
|
[property: JsonPropertyName("clusterId")] IReadOnlyList<ClusterId> ClusterId,
|
||||||
|
[property: JsonPropertyName("location")] IReadOnlyList<LocationAmazon> Location,
|
||||||
|
[property: JsonPropertyName("people")] IReadOnlyList<PersonAmazon> People,
|
||||||
|
[property: JsonPropertyName("things")] IReadOnlyList<Thing> Things,
|
||||||
|
[property: JsonPropertyName("time")] IReadOnlyList<Time> Time,
|
||||||
|
[property: JsonPropertyName("type")] IReadOnlyList<Type> Type
|
||||||
|
);
|
||||||
|
|
||||||
|
[JsonSourceGenerationOptions(WriteIndented = true)]
|
||||||
|
[JsonSerializable(typeof(Aggregations))]
|
||||||
|
public partial class AggregationsGenerationContext : JsonSerializerContext
|
||||||
|
{
|
||||||
|
}
|
15
Shared/Models/AllPerson.cs
Normal file
15
Shared/Models/AllPerson.cs
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
using System.Text.Json.Serialization;
|
||||||
|
|
||||||
|
namespace View_by_Distance.Shared.Models;
|
||||||
|
|
||||||
|
public record AllPerson(
|
||||||
|
[property: JsonPropertyName("count")] int Count,
|
||||||
|
[property: JsonPropertyName("match")] string Match,
|
||||||
|
[property: JsonPropertyName("searchData")] SearchData SearchData
|
||||||
|
);
|
||||||
|
|
||||||
|
[JsonSourceGenerationOptions(WriteIndented = true)]
|
||||||
|
[JsonSerializable(typeof(AllPerson))]
|
||||||
|
public partial class AllPersonGenerationContext : JsonSerializerContext
|
||||||
|
{
|
||||||
|
}
|
15
Shared/Models/ClusterId.cs
Normal file
15
Shared/Models/ClusterId.cs
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
using System.Text.Json.Serialization;
|
||||||
|
|
||||||
|
namespace View_by_Distance.Shared.Models;
|
||||||
|
|
||||||
|
public record ClusterId(
|
||||||
|
[property: JsonPropertyName("count")] int Count,
|
||||||
|
[property: JsonPropertyName("match")] string Match,
|
||||||
|
[property: JsonPropertyName("searchData")] SearchData SearchData
|
||||||
|
);
|
||||||
|
|
||||||
|
[JsonSourceGenerationOptions(WriteIndented = true)]
|
||||||
|
[JsonSerializable(typeof(ClusterId))]
|
||||||
|
public partial class ClusterIdGenerationContext : JsonSerializerContext
|
||||||
|
{
|
||||||
|
}
|
@ -1,8 +1,9 @@
|
|||||||
|
using System.Collections.ObjectModel;
|
||||||
using System.Text.Json;
|
using System.Text.Json;
|
||||||
|
|
||||||
namespace View_by_Distance.Shared.Models;
|
namespace View_by_Distance.Shared.Models;
|
||||||
|
|
||||||
public record Container(string SourceDirectory, List<Item> Items)
|
public record Container(string SourceDirectory, ReadOnlyCollection<Item> Items)
|
||||||
{
|
{
|
||||||
|
|
||||||
public override string ToString()
|
public override string ToString()
|
||||||
|
20
Shared/Models/ContentProperties.cs
Normal file
20
Shared/Models/ContentProperties.cs
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
using System.Text.Json.Serialization;
|
||||||
|
|
||||||
|
namespace View_by_Distance.Shared.Models;
|
||||||
|
|
||||||
|
public record ContentProperties(
|
||||||
|
[property: JsonPropertyName("contentDate")] DateTime ContentDate,
|
||||||
|
[property: JsonPropertyName("contentSignatures")] IReadOnlyList<ContentSignature> ContentSignatures,
|
||||||
|
[property: JsonPropertyName("contentType")] string ContentType,
|
||||||
|
[property: JsonPropertyName("extension")] string Extension,
|
||||||
|
[property: JsonPropertyName("image")] ImageAmazon Image,
|
||||||
|
[property: JsonPropertyName("md5")] string Md5,
|
||||||
|
[property: JsonPropertyName("size")] int Size,
|
||||||
|
[property: JsonPropertyName("version")] int Version
|
||||||
|
);
|
||||||
|
|
||||||
|
[JsonSourceGenerationOptions(WriteIndented = true)]
|
||||||
|
[JsonSerializable(typeof(ContentProperties))]
|
||||||
|
public partial class ContentPropertiesGenerationContext : JsonSerializerContext
|
||||||
|
{
|
||||||
|
}
|
14
Shared/Models/ContentSignature.cs
Normal file
14
Shared/Models/ContentSignature.cs
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
using System.Text.Json.Serialization;
|
||||||
|
|
||||||
|
namespace View_by_Distance.Shared.Models;
|
||||||
|
|
||||||
|
public record ContentSignature(
|
||||||
|
[property: JsonPropertyName("contentSignature")] string Value,
|
||||||
|
[property: JsonPropertyName("contentSignatureType")] string ContentSignatureType
|
||||||
|
);
|
||||||
|
|
||||||
|
[JsonSourceGenerationOptions(WriteIndented = true)]
|
||||||
|
[JsonSerializable(typeof(ContentSignature))]
|
||||||
|
public partial class ContentSignatureGenerationContext : JsonSerializerContext
|
||||||
|
{
|
||||||
|
}
|
45
Shared/Models/Datum.cs
Normal file
45
Shared/Models/Datum.cs
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
using System.Text.Json.Serialization;
|
||||||
|
|
||||||
|
namespace View_by_Distance.Shared.Models;
|
||||||
|
|
||||||
|
public record Datum(
|
||||||
|
[property: JsonPropertyName("accessRuleIds")] IReadOnlyList<object> AccessRuleIds,
|
||||||
|
[property: JsonPropertyName("childAssetTypeInfo")] IReadOnlyList<object> ChildAssetTypeInfo,
|
||||||
|
[property: JsonPropertyName("contentProperties")] ContentProperties ContentProperties,
|
||||||
|
[property: JsonPropertyName("createdBy")] string CreatedBy,
|
||||||
|
[property: JsonPropertyName("createdDate")] DateTime CreatedDate,
|
||||||
|
[property: JsonPropertyName("eTagResponse")] string ETagResponse,
|
||||||
|
[property: JsonPropertyName("groupPermissions")] IReadOnlyList<object> GroupPermissions,
|
||||||
|
[property: JsonPropertyName("id")] string Id,
|
||||||
|
[property: JsonPropertyName("isRoot")] bool IsRoot,
|
||||||
|
[property: JsonPropertyName("isShared")] bool IsShared,
|
||||||
|
[property: JsonPropertyName("keywords")] IReadOnlyList<object> Keywords,
|
||||||
|
[property: JsonPropertyName("kind")] string Kind,
|
||||||
|
[property: JsonPropertyName("labels")] IReadOnlyList<object> Labels,
|
||||||
|
[property: JsonPropertyName("modifiedDate")] DateTime ModifiedDate,
|
||||||
|
[property: JsonPropertyName("name")] string Name,
|
||||||
|
[property: JsonPropertyName("ownerId")] string OwnerId,
|
||||||
|
[property: JsonPropertyName("parentMap")] ParentMap ParentMap,
|
||||||
|
[property: JsonPropertyName("parents")] IReadOnlyList<string> Parents,
|
||||||
|
[property: JsonPropertyName("protectedFolder")] bool ProtectedFolder,
|
||||||
|
[property: JsonPropertyName("restricted")] bool Restricted,
|
||||||
|
[property: JsonPropertyName("status")] string Status,
|
||||||
|
[property: JsonPropertyName("subKinds")] IReadOnlyList<object> SubKinds,
|
||||||
|
[property: JsonPropertyName("transforms")] IReadOnlyList<string> Transforms,
|
||||||
|
[property: JsonPropertyName("version")] int Version,
|
||||||
|
[property: JsonPropertyName("xAccntParentMap")] XAccntParentMap XAccntParentMap,
|
||||||
|
[property: JsonPropertyName("xAccntParents")] IReadOnlyList<object> XAccntParents,
|
||||||
|
[property: JsonPropertyName("match")] bool? Match
|
||||||
|
);
|
||||||
|
|
||||||
|
[JsonSourceGenerationOptions(WriteIndented = true)]
|
||||||
|
[JsonSerializable(typeof(Datum))]
|
||||||
|
public partial class DatumGenerationContext : JsonSerializerContext
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
[JsonSourceGenerationOptions(WriteIndented = true)]
|
||||||
|
[JsonSerializable(typeof(Dictionary<string, Datum>))]
|
||||||
|
public partial class DictionaryDatumGenerationContext : JsonSerializerContext
|
||||||
|
{
|
||||||
|
}
|
19
Shared/Models/FaceFile.cs
Normal file
19
Shared/Models/FaceFile.cs
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
using System.Text.Json.Serialization;
|
||||||
|
|
||||||
|
namespace View_by_Distance.Shared.Models;
|
||||||
|
|
||||||
|
public record FaceFile(int? AreaPermyriad,
|
||||||
|
int? ConfidencePercent,
|
||||||
|
DateTime DateTime,
|
||||||
|
string? DMS,
|
||||||
|
Dictionary<Stateless.FacePart, FacePoint[]>? FaceParts,
|
||||||
|
Location? Location,
|
||||||
|
string? Maker,
|
||||||
|
string? Model,
|
||||||
|
OutputResolution? OutputResolution);
|
||||||
|
|
||||||
|
[JsonSourceGenerationOptions(WriteIndented = false)]
|
||||||
|
[JsonSerializable(typeof(FaceFile))]
|
||||||
|
public partial class FaceFileGenerationContext : JsonSerializerContext
|
||||||
|
{
|
||||||
|
}
|
@ -48,6 +48,21 @@ public record FileHolder(DateTime? CreationTime,
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static FileHolder Get(FilePath filePath)
|
||||||
|
{
|
||||||
|
FileHolder result;
|
||||||
|
result = new(new(filePath.CreationTicks),
|
||||||
|
filePath.DirectoryName,
|
||||||
|
true,
|
||||||
|
filePath.ExtensionLowered,
|
||||||
|
filePath.FullName,
|
||||||
|
new(filePath.LastWriteTicks),
|
||||||
|
filePath.Length,
|
||||||
|
filePath.Name,
|
||||||
|
Path.GetFileNameWithoutExtension(filePath.FullName));
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[JsonSourceGenerationOptions(WriteIndented = true)]
|
[JsonSourceGenerationOptions(WriteIndented = true)]
|
||||||
|
@ -10,6 +10,7 @@ public record FilePath(long CreationTicks,
|
|||||||
string FileNameFirstSegment,
|
string FileNameFirstSegment,
|
||||||
string FullName,
|
string FullName,
|
||||||
int? Id,
|
int? Id,
|
||||||
|
bool? IsIgnore,
|
||||||
bool IsIntelligentIdFormat,
|
bool IsIntelligentIdFormat,
|
||||||
long LastWriteTicks,
|
long LastWriteTicks,
|
||||||
long Length,
|
long Length,
|
||||||
@ -38,14 +39,15 @@ public record FilePath(long CreationTicks,
|
|||||||
string fileNameFirstSegment = fileHolder.Name.Split('.')[0];
|
string fileNameFirstSegment = fileHolder.Name.Split('.')[0];
|
||||||
int sortOrderOnlyLengthIndex = propertyConfiguration.Offset.ToString().Length;
|
int sortOrderOnlyLengthIndex = propertyConfiguration.Offset.ToString().Length;
|
||||||
string fileDirectoryName = fileHolder.DirectoryName ?? throw new NullReferenceException();
|
string fileDirectoryName = fileHolder.DirectoryName ?? throw new NullReferenceException();
|
||||||
bool fileNameFirstSegmentIsIntelligentIdFormat = IId.NameWithoutExtensionIsIntelligentIdFormat(propertyConfiguration, fileNameFirstSegment);
|
bool isIntelligentIdFormat = IId.NameWithoutExtensionIsIntelligentIdFormat(propertyConfiguration, fileNameFirstSegment);
|
||||||
bool fileNameFirstSegmentIsPaddedIntelligentIdFormat = IId.NameWithoutExtensionIsPaddedIntelligentIdFormat(propertyConfiguration, sortOrderOnlyLengthIndex, fileNameFirstSegment);
|
bool isPaddedIntelligentIdFormat = IId.NameWithoutExtensionIsPaddedIntelligentIdFormat(propertyConfiguration, sortOrderOnlyLengthIndex, fileNameFirstSegment);
|
||||||
bool fileNameFirstSegmentIsIdFormat = !fileNameFirstSegmentIsPaddedIntelligentIdFormat && !fileNameFirstSegmentIsIntelligentIdFormat && IId.NameWithoutExtensionIsIdFormat(propertyConfiguration, fileHolder);
|
bool fileNameFirstSegmentIsIdFormat = !isPaddedIntelligentIdFormat && !isIntelligentIdFormat && IId.NameWithoutExtensionIsIdFormat(propertyConfiguration, fileHolder);
|
||||||
if (!fileNameFirstSegmentIsIdFormat && !fileNameFirstSegmentIsIntelligentIdFormat && !fileNameFirstSegmentIsPaddedIntelligentIdFormat)
|
bool? isIgnore = !isIntelligentIdFormat && !isPaddedIntelligentIdFormat ? null : fileNameFirstSegment[^1] is '2' or '8';
|
||||||
|
if (!fileNameFirstSegmentIsIdFormat && !isIntelligentIdFormat && !isPaddedIntelligentIdFormat)
|
||||||
(id, sortOder) = (null, null);
|
(id, sortOder) = (null, null);
|
||||||
else if (fileNameFirstSegmentIsIntelligentIdFormat)
|
else if (isIntelligentIdFormat)
|
||||||
(id, sortOder) = (IId.GetId(propertyConfiguration, fileNameFirstSegment), null);
|
(id, sortOder) = (IId.GetId(propertyConfiguration, fileNameFirstSegment), null);
|
||||||
else if (fileNameFirstSegmentIsPaddedIntelligentIdFormat)
|
else if (isPaddedIntelligentIdFormat)
|
||||||
{
|
{
|
||||||
if (!int.TryParse(fileNameFirstSegment[..sortOrderOnlyLengthIndex], out int absoluteValueOfSortOrder))
|
if (!int.TryParse(fileNameFirstSegment[..sortOrderOnlyLengthIndex], out int absoluteValueOfSortOrder))
|
||||||
(id, sortOder) = (null, null);
|
(id, sortOder) = (null, null);
|
||||||
@ -68,7 +70,8 @@ public record FilePath(long CreationTicks,
|
|||||||
fileNameFirstSegment,
|
fileNameFirstSegment,
|
||||||
fileHolder.FullName,
|
fileHolder.FullName,
|
||||||
id,
|
id,
|
||||||
fileNameFirstSegmentIsIntelligentIdFormat,
|
isIgnore,
|
||||||
|
isIntelligentIdFormat,
|
||||||
fileHolder.LastWriteTime.Value.Ticks,
|
fileHolder.LastWriteTime.Value.Ticks,
|
||||||
fileHolder.Length.Value,
|
fileHolder.Length.Value,
|
||||||
fileHolder.Name,
|
fileHolder.Name,
|
||||||
|
36
Shared/Models/ImageAmazon.cs
Normal file
36
Shared/Models/ImageAmazon.cs
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
using System.Text.Json.Serialization;
|
||||||
|
|
||||||
|
namespace View_by_Distance.Shared.Models;
|
||||||
|
|
||||||
|
public record ImageAmazon(
|
||||||
|
[property: JsonPropertyName("colorSpace")] string ColorSpace,
|
||||||
|
[property: JsonPropertyName("dateTime")] DateTime DateTime,
|
||||||
|
[property: JsonPropertyName("dateTimeDigitized")] DateTime DateTimeDigitized,
|
||||||
|
[property: JsonPropertyName("dateTimeOriginal")] DateTime DateTimeOriginal,
|
||||||
|
[property: JsonPropertyName("exposureMode")] string ExposureMode,
|
||||||
|
[property: JsonPropertyName("exposureProgram")] string ExposureProgram,
|
||||||
|
[property: JsonPropertyName("exposureTime")] string ExposureTime,
|
||||||
|
[property: JsonPropertyName("flash")] string Flash,
|
||||||
|
[property: JsonPropertyName("focalLength")] string FocalLength,
|
||||||
|
[property: JsonPropertyName("height")] int Height,
|
||||||
|
[property: JsonPropertyName("make")] string Make,
|
||||||
|
[property: JsonPropertyName("meteringMode")] string MeteringMode,
|
||||||
|
[property: JsonPropertyName("model")] string Model,
|
||||||
|
[property: JsonPropertyName("orientation")] string Orientation,
|
||||||
|
[property: JsonPropertyName("resolutionUnit")] string ResolutionUnit,
|
||||||
|
[property: JsonPropertyName("sensingMethod")] string SensingMethod,
|
||||||
|
[property: JsonPropertyName("sharpness")] string Sharpness,
|
||||||
|
[property: JsonPropertyName("software")] string Software,
|
||||||
|
[property: JsonPropertyName("subSecTime")] string SubSecTime,
|
||||||
|
[property: JsonPropertyName("subSecTimeDigitized")] string SubSecTimeDigitized,
|
||||||
|
[property: JsonPropertyName("subSecTimeOriginal")] string SubSecTimeOriginal,
|
||||||
|
[property: JsonPropertyName("whiteBalance")] string WhiteBalance,
|
||||||
|
[property: JsonPropertyName("width")] int Width,
|
||||||
|
[property: JsonPropertyName("apertureValue")] string ApertureValue
|
||||||
|
);
|
||||||
|
|
||||||
|
[JsonSourceGenerationOptions(WriteIndented = true)]
|
||||||
|
[JsonSerializable(typeof(ImageAmazon))]
|
||||||
|
public partial class ImageAmazonGenerationContext : JsonSerializerContext
|
||||||
|
{
|
||||||
|
}
|
33
Shared/Models/ImmichAsset.cs
Normal file
33
Shared/Models/ImmichAsset.cs
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
using System.Text.Json;
|
||||||
|
using System.Text.Json.Serialization;
|
||||||
|
|
||||||
|
namespace View_by_Distance.Shared.Models;
|
||||||
|
|
||||||
|
public record ImmichAsset([property: JsonPropertyName("id")] string Id,
|
||||||
|
[property: JsonPropertyName("deviceAssetId")] string DeviceAssetId,
|
||||||
|
[property: JsonPropertyName("originalPath")] string OriginalPath,
|
||||||
|
[property: JsonPropertyName("previewPath")] string PreviewPath,
|
||||||
|
[property: JsonPropertyName("isFavorite")] bool IsFavorite,
|
||||||
|
[property: JsonPropertyName("thumbnailPath")] string ThumbnailPath,
|
||||||
|
[property: JsonPropertyName("thumbhash")] string Thumbhash)
|
||||||
|
{
|
||||||
|
|
||||||
|
public override string ToString()
|
||||||
|
{
|
||||||
|
string result = JsonSerializer.Serialize(this, ImmichAssetSourceGenerationContext.Default.ImmichAsset);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
[JsonSourceGenerationOptions(WriteIndented = true, DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull)]
|
||||||
|
[JsonSerializable(typeof(ImmichAsset))]
|
||||||
|
public partial class ImmichAssetSourceGenerationContext : JsonSerializerContext
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
[JsonSourceGenerationOptions(WriteIndented = true, DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull)]
|
||||||
|
[JsonSerializable(typeof(ImmichAsset[]))]
|
||||||
|
public partial class ImmichAssetCollectionSourceGenerationContext : JsonSerializerContext
|
||||||
|
{
|
||||||
|
}
|
@ -9,7 +9,6 @@ public class Item : Properties.IItem
|
|||||||
protected List<Face> _Faces;
|
protected List<Face> _Faces;
|
||||||
protected readonly bool? _FileSizeChanged;
|
protected readonly bool? _FileSizeChanged;
|
||||||
protected readonly FilePath _FilePath;
|
protected readonly FilePath _FilePath;
|
||||||
protected readonly FileHolder _ImageFileHolder;
|
|
||||||
protected bool? _IsNotUniqueAndNeedsReview;
|
protected bool? _IsNotUniqueAndNeedsReview;
|
||||||
protected bool _IsUniqueFileName;
|
protected bool _IsUniqueFileName;
|
||||||
protected bool _IsValidImageFormatExtension;
|
protected bool _IsValidImageFormatExtension;
|
||||||
@ -22,7 +21,6 @@ public class Item : Properties.IItem
|
|||||||
public List<Face> Faces => _Faces;
|
public List<Face> Faces => _Faces;
|
||||||
public bool? FileSizeChanged => _FileSizeChanged;
|
public bool? FileSizeChanged => _FileSizeChanged;
|
||||||
public FilePath FilePath => _FilePath;
|
public FilePath FilePath => _FilePath;
|
||||||
public FileHolder ImageFileHolder => _ImageFileHolder;
|
|
||||||
public bool? IsNotUniqueAndNeedsReview => _IsNotUniqueAndNeedsReview;
|
public bool? IsNotUniqueAndNeedsReview => _IsNotUniqueAndNeedsReview;
|
||||||
public bool IsUniqueFileName => _IsUniqueFileName;
|
public bool IsUniqueFileName => _IsUniqueFileName;
|
||||||
public bool IsValidImageFormatExtension => _IsValidImageFormatExtension;
|
public bool IsValidImageFormatExtension => _IsValidImageFormatExtension;
|
||||||
@ -34,12 +32,11 @@ public class Item : Properties.IItem
|
|||||||
public FileHolder SourceDirectoryFileHolder => _SourceDirectoryFileHolder;
|
public FileHolder SourceDirectoryFileHolder => _SourceDirectoryFileHolder;
|
||||||
|
|
||||||
[JsonConstructor]
|
[JsonConstructor]
|
||||||
public Item(List<Face> faces, FilePath filePath, bool? fileSizeChanged, FileHolder imageFileHolder, bool? isNotUniqueAndNeedsReview, bool isUniqueFileName, bool isValidImageFormatExtension, bool? lastWriteTimeChanged, bool? moved, Property? property, string relativePath, FileHolder? resizedFileHolder, FileHolder sourceDirectoryFileHolder)
|
public Item(List<Face> faces, FilePath filePath, bool? fileSizeChanged, bool? isNotUniqueAndNeedsReview, bool isUniqueFileName, bool isValidImageFormatExtension, bool? lastWriteTimeChanged, bool? moved, Property? property, string relativePath, FileHolder? resizedFileHolder, FileHolder sourceDirectoryFileHolder)
|
||||||
{
|
{
|
||||||
_Faces = faces;
|
_Faces = faces;
|
||||||
_FilePath = filePath;
|
_FilePath = filePath;
|
||||||
_FileSizeChanged = fileSizeChanged;
|
_FileSizeChanged = fileSizeChanged;
|
||||||
_ImageFileHolder = imageFileHolder;
|
|
||||||
_IsNotUniqueAndNeedsReview = isNotUniqueAndNeedsReview;
|
_IsNotUniqueAndNeedsReview = isNotUniqueAndNeedsReview;
|
||||||
_IsUniqueFileName = isUniqueFileName;
|
_IsUniqueFileName = isUniqueFileName;
|
||||||
_IsValidImageFormatExtension = isValidImageFormatExtension;
|
_IsValidImageFormatExtension = isValidImageFormatExtension;
|
||||||
@ -51,17 +48,17 @@ public class Item : Properties.IItem
|
|||||||
_SourceDirectoryFileHolder = sourceDirectoryFileHolder;
|
_SourceDirectoryFileHolder = sourceDirectoryFileHolder;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Item(FilePath filePath, FileHolder sourceDirectoryFileHolder, string relativePath, FileHolder imageFileInfo, bool? isNotUniqueAndNeedsReview, bool isUniqueFileName, bool isValidImageFormatExtension, Property? property, bool? abandoned, bool? fileSizeChanged, bool? lastWriteTimeChanged) :
|
public Item(FilePath filePath, FileHolder sourceDirectoryFileHolder, string relativePath, bool? isNotUniqueAndNeedsReview, bool isUniqueFileName, bool isValidImageFormatExtension, Property? property, bool? abandoned, bool? fileSizeChanged, bool? lastWriteTimeChanged) :
|
||||||
this([], filePath, fileSizeChanged, imageFileInfo, isNotUniqueAndNeedsReview, isUniqueFileName, isValidImageFormatExtension, lastWriteTimeChanged, null, property, relativePath, null, sourceDirectoryFileHolder)
|
this([], filePath, fileSizeChanged, isNotUniqueAndNeedsReview, isUniqueFileName, isValidImageFormatExtension, lastWriteTimeChanged, null, property, relativePath, null, sourceDirectoryFileHolder)
|
||||||
{
|
{
|
||||||
if (relativePath.EndsWith(".json"))
|
if (relativePath.EndsWith(".json"))
|
||||||
throw new ArgumentException("Can not be a *.json file!");
|
throw new ArgumentException("Can not be a *.json file!");
|
||||||
if (imageFileInfo is not null && imageFileInfo.ExtensionLowered is ".json")
|
if (filePath is not null && filePath.ExtensionLowered is ".json")
|
||||||
throw new ArgumentException("Can not be a *.json file!");
|
throw new ArgumentException("Can not be a *.json file!");
|
||||||
}
|
}
|
||||||
|
|
||||||
public Item(FilePath filePath, FileHolder sourceDirectoryFileHolder, string relativePath, bool isValidImageFormatExtension) :
|
public Item(FilePath filePath, FileHolder sourceDirectoryFileHolder, string relativePath, bool isValidImageFormatExtension) :
|
||||||
this(filePath, sourceDirectoryFileHolder, relativePath, sourceDirectoryFileHolder, null, false, isValidImageFormatExtension, null, null, null, null)
|
this(filePath, sourceDirectoryFileHolder, relativePath, null, false, isValidImageFormatExtension, null, null, null, null)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
public override string ToString()
|
public override string ToString()
|
||||||
|
15
Shared/Models/LocationAmazon.cs
Normal file
15
Shared/Models/LocationAmazon.cs
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
using System.Text.Json.Serialization;
|
||||||
|
|
||||||
|
namespace View_by_Distance.Shared.Models;
|
||||||
|
|
||||||
|
public record LocationAmazon(
|
||||||
|
[property: JsonPropertyName("count")] int Count,
|
||||||
|
[property: JsonPropertyName("match")] string Match,
|
||||||
|
[property: JsonPropertyName("searchData")] SearchData SearchData
|
||||||
|
);
|
||||||
|
|
||||||
|
[JsonSourceGenerationOptions(WriteIndented = true)]
|
||||||
|
[JsonSerializable(typeof(LocationAmazon))]
|
||||||
|
public partial class LocationAmazonGenerationContext : JsonSerializerContext
|
||||||
|
{
|
||||||
|
}
|
@ -5,11 +5,57 @@ namespace View_by_Distance.Shared.Models;
|
|||||||
public record LocationContainer(DateOnly CreationDateOnly,
|
public record LocationContainer(DateOnly CreationDateOnly,
|
||||||
ExifDirectory? ExifDirectory,
|
ExifDirectory? ExifDirectory,
|
||||||
int? DirectoryNumber,
|
int? DirectoryNumber,
|
||||||
string DisplayDirectoryName,
|
string? DisplayDirectoryName,
|
||||||
|
object? Encoding,
|
||||||
|
FaceFile? FaceFile,
|
||||||
FilePath FilePath,
|
FilePath FilePath,
|
||||||
bool FromDistanceContent,
|
bool FromDistanceContent,
|
||||||
int Id,
|
int Id,
|
||||||
Location? Location,
|
int? LengthPermyriad,
|
||||||
long PersonKey,
|
FilePath? LengthSource,
|
||||||
|
long? PersonKey,
|
||||||
RectangleF? Rectangle,
|
RectangleF? Rectangle,
|
||||||
int WholePercentages);
|
int WholePercentages)
|
||||||
|
{
|
||||||
|
|
||||||
|
public static LocationContainer Get(LocationContainer locationContainer, object? encoding, bool keepExifDirectory)
|
||||||
|
{
|
||||||
|
LocationContainer result;
|
||||||
|
result = new(locationContainer.CreationDateOnly,
|
||||||
|
keepExifDirectory ? locationContainer.ExifDirectory : null,
|
||||||
|
locationContainer.DirectoryNumber,
|
||||||
|
locationContainer.DisplayDirectoryName,
|
||||||
|
encoding,
|
||||||
|
locationContainer.FaceFile,
|
||||||
|
locationContainer.FilePath,
|
||||||
|
locationContainer.FromDistanceContent,
|
||||||
|
locationContainer.Id,
|
||||||
|
locationContainer.LengthPermyriad,
|
||||||
|
locationContainer.LengthSource,
|
||||||
|
locationContainer.PersonKey,
|
||||||
|
locationContainer.Rectangle,
|
||||||
|
locationContainer.WholePercentages);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static LocationContainer Get(LocationContainer source, LocationContainer locationContainer, int lengthPermyriad, bool keepExifDirectory, bool keepEncoding)
|
||||||
|
{
|
||||||
|
LocationContainer result;
|
||||||
|
result = new(locationContainer.CreationDateOnly,
|
||||||
|
keepExifDirectory ? locationContainer.ExifDirectory : null,
|
||||||
|
locationContainer.DirectoryNumber,
|
||||||
|
locationContainer.DisplayDirectoryName,
|
||||||
|
keepEncoding ? locationContainer.Encoding : null,
|
||||||
|
locationContainer.FaceFile,
|
||||||
|
locationContainer.FilePath,
|
||||||
|
locationContainer.FromDistanceContent,
|
||||||
|
locationContainer.Id,
|
||||||
|
lengthPermyriad,
|
||||||
|
source.FilePath,
|
||||||
|
locationContainer.PersonKey,
|
||||||
|
locationContainer.Rectangle,
|
||||||
|
locationContainer.WholePercentages);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
17
Shared/Models/LocationInfo.cs
Normal file
17
Shared/Models/LocationInfo.cs
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
using System.Text.Json.Serialization;
|
||||||
|
|
||||||
|
namespace View_by_Distance.Shared.Models;
|
||||||
|
|
||||||
|
public record LocationInfo(
|
||||||
|
[property: JsonPropertyName("city")] string City,
|
||||||
|
[property: JsonPropertyName("country")] string Country,
|
||||||
|
[property: JsonPropertyName("countryIso3Code")] string CountryIso3Code,
|
||||||
|
[property: JsonPropertyName("state")] string State,
|
||||||
|
[property: JsonPropertyName("stateCode")] string StateCode
|
||||||
|
);
|
||||||
|
|
||||||
|
[JsonSourceGenerationOptions(WriteIndented = true)]
|
||||||
|
[JsonSerializable(typeof(LocationInfo))]
|
||||||
|
public partial class LocationInfoGenerationContext : JsonSerializerContext
|
||||||
|
{
|
||||||
|
}
|
@ -14,6 +14,9 @@ public record MappingFromFilterPre(bool? InSkipCollection,
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal static void Constructor() =>
|
||||||
|
_ = new MappingFromFilterPre(null, null, null);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[JsonSourceGenerationOptions(WriteIndented = true)]
|
[JsonSourceGenerationOptions(WriteIndented = true)]
|
||||||
|
@ -7,7 +7,7 @@ public record MappingFromItem(DateTime[] ContainerDateTimes,
|
|||||||
DateTime? DateTimeDigitized,
|
DateTime? DateTimeDigitized,
|
||||||
DateTime? DateTimeOriginal,
|
DateTime? DateTimeOriginal,
|
||||||
int Id,
|
int Id,
|
||||||
FileHolder ImageFileHolder,
|
FilePath FilePath,
|
||||||
bool? IsWrongYear,
|
bool? IsWrongYear,
|
||||||
string[] Keywords,
|
string[] Keywords,
|
||||||
DateTime MinimumDateTime,
|
DateTime MinimumDateTime,
|
||||||
@ -34,8 +34,8 @@ public record MappingFromItem(DateTime[] ContainerDateTimes,
|
|||||||
throw new NotSupportedException();
|
throw new NotSupportedException();
|
||||||
List<DateTime> dateTimes = item.Property.GetDateTimes();
|
List<DateTime> dateTimes = item.Property.GetDateTimes();
|
||||||
DateTime minimumDateTime = Stateless.Methods.IProperty.GetMinimumDateTime(item.Property);
|
DateTime minimumDateTime = Stateless.Methods.IProperty.GetMinimumDateTime(item.Property);
|
||||||
(bool? isWrongYear, _) = Stateless.Methods.IProperty.IsWrongYear(item.ImageFileHolder, item.Property.DateTimeOriginal, dateTimes);
|
(bool? isWrongYear, _) = Stateless.Methods.IProperty.IsWrongYear(item.FilePath, item.Property.DateTimeOriginal, dateTimes);
|
||||||
result = new(containerDateTimes, item.Property.DateTimeDigitized, item.Property.DateTimeOriginal, item.Property.Id.Value, item.ImageFileHolder, isWrongYear, item.Property.Keywords ?? [], minimumDateTime, item.Property.Model, item.RelativePath, resizedFileHolder);
|
result = new(containerDateTimes, item.Property.DateTimeDigitized, item.Property.DateTimeOriginal, item.Property.Id.Value, item.FilePath, isWrongYear, item.Property.Keywords ?? [], minimumDateTime, item.Property.Model, item.RelativePath, resizedFileHolder);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5,6 +5,6 @@ namespace View_by_Distance.Shared.Models.Methods;
|
|||||||
public interface IDistance
|
public interface IDistance
|
||||||
{
|
{
|
||||||
|
|
||||||
ReadOnlyCollection<RelationContainer> GetRelationContainers(int faceDistancePermyriad, int locationContainerDistanceTake, float locationContainerDistanceTolerance, ReadOnlyCollection<LocationContainer> locationContainers);
|
ReadOnlyCollection<RelationContainer> GetRelationContainers(IDistanceLimits distanceLimits, int faceDistancePermyriad, int locationContainerDistanceTake, float locationContainerDistanceTolerance, ReadOnlyCollection<LocationContainer> locationContainers);
|
||||||
|
|
||||||
}
|
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user