Mass push

This commit is contained in:
Mike Phares 2022-12-16 11:26:00 -07:00
parent ae1baaaf46
commit 33c5ce6e23
132 changed files with 5869 additions and 3712 deletions

212
.vscode/launch.json vendored
View File

@ -2,36 +2,145 @@
"version": "0.2.0",
"configurations": [
{
// Use IntelliSense to find out which attributes exist for C# debugging
// Use hover for the description of the existing attributes
// For further information visit https://github.com/OmniSharp/omnisharp-vscode/blob/master/debugger-launchjson.md
"name": ".NET Core Launch (console)",
"name": ".NET Core Attach",
"type": "coreclr",
"request": "attach"
},
{
"name": "Compare",
"type": "coreclr",
"request": "launch",
"preLaunchTask": "build",
// If you have changed target frameworks, make sure to update the program path.
"programC": "${workspaceFolder}/Compare/bin/Debug/net7.0/win-x64/Compare.dll",
"programD": "${workspaceFolder}/Date-Group/bin/Debug/net7.0/win-x64/Date-Group.dll",
"programDD": "${workspaceFolder}/Drag-Drop/bin/Debug/net7.0-windows/win-x64/Drag-Drop.dll",
"program": "${workspaceFolder}/Instance/bin/Debug/net7.0/win-x64/Instance.dll",
"programN": "${workspaceFolder}/Not-Copy-Copy/bin/Debug/net7.0/win-x64/Not-Copy-Copy.dll",
"programP": "${workspaceFolder}/PrepareForOld/bin/Debug/net7.0/win-x64/PrepareForOld.dll",
"program": "${workspaceFolder}/Compare/bin/Debug/net7.0/win-x64/Compare.dll",
"args": [
"s"
],
"env": {
"ASPNETCORE_ENVIRONMENT": "Development",
"ASPNETCORE_ENVIRONMENT": "Development"
},
"cwd": "${workspaceFolder}",
// For more information about the 'console' field, see https://aka.ms/VSCode-CS-LaunchJson-Console
"console": "externalTerminal",
"stopAtEntry": false,
"requireExactSource": false
},
{
"name": ".NET Core Attach",
"name": "Duplicate-Search",
"type": "coreclr",
"request": "attach"
"request": "launch",
"preLaunchTask": "build",
"program": "${workspaceFolder}/Duplicate-Search/bin/Debug/net7.0/win-x64/Duplicate-Search.dll",
"args": [
"s"
],
"env": {
"ASPNETCORE_ENVIRONMENT": "Development"
},
"cwd": "${workspaceFolder}",
"console": "externalTerminal",
"stopAtEntry": false,
"requireExactSource": false
},
{
"name": "Date-Group",
"type": "coreclr",
"request": "launch",
"preLaunchTask": "build",
"program": "${workspaceFolder}/Date-Group/bin/Debug/net7.0/win-x64/Date-Group.dll",
"args": [
"s"
],
"env": {
"ASPNETCORE_ENVIRONMENT": "Development"
},
"cwd": "${workspaceFolder}",
"console": "externalTerminal",
"stopAtEntry": false,
"requireExactSource": false
},
{
"name": "Delete-By-Relative",
"type": "coreclr",
"request": "launch",
"preLaunchTask": "build",
"program": "${workspaceFolder}/Delete-By-Relative/bin/Debug/net7.0/win-x64/Delete-By-Relative.dll",
"args": [
"s"
],
"env": {
"ASPNETCORE_ENVIRONMENT": "Development"
},
"cwd": "${workspaceFolder}",
"console": "externalTerminal",
"stopAtEntry": false,
"requireExactSource": false
},
{
"name": "Drag-Drop",
"type": "coreclr",
"request": "launch",
"preLaunchTask": "build",
"program": "${workspaceFolder}/Drag-Drop/bin/Debug/net7.0-windows/win-x64/Drag-Drop.dll",
"args": [
"s"
],
"env": {
"ASPNETCORE_ENVIRONMENT": "Development"
},
"cwd": "${workspaceFolder}",
"console": "externalTerminal",
"stopAtEntry": false,
"requireExactSource": false
},
{
"name": "Instance",
"type": "coreclr",
"request": "launch",
"preLaunchTask": "build",
"program": "${workspaceFolder}/Instance/bin/Debug/net7.0/win-x64/Instance.dll",
"args": [
"s"
],
"env": {
"ASPNETCORE_ENVIRONMENT": "Development"
},
"cwd": "${workspaceFolder}",
"console": "externalTerminal",
"stopAtEntry": false,
"requireExactSource": false
},
{
"name": "Not-Copy-Copy",
"type": "coreclr",
"request": "launch",
"preLaunchTask": "build",
"program": "${workspaceFolder}/Not-Copy-Copy/bin/Debug/net7.0/win-x64/Not-Copy-Copy.dll",
"args": [
"s"
],
"env": {
"ASPNETCORE_ENVIRONMENT": "Development"
},
"cwd": "${workspaceFolder}",
"console": "externalTerminal",
"stopAtEntry": false,
"requireExactSource": false
},
{
"name": "PrepareForOld",
"type": "coreclr",
"request": "launch",
"preLaunchTask": "build",
"program": "${workspaceFolder}/PrepareForOld/bin/Debug/net7.0/win-x64/PrepareForOld.dll",
"args": [
"s"
],
"env": {
"ASPNETCORE_ENVIRONMENT": "Development"
},
"cwd": "${workspaceFolder}",
"console": "externalTerminal",
"stopAtEntry": false,
"requireExactSource": false
}
]
}
@ -147,41 +256,46 @@
// https://scontent-lax3-1.xx.fbcdn.net/v/t1.18169-9/25110_107749419250772_1842086_n.jpg?_nc_cat=104&ccb=1-7&_nc_sid=09cbfe&_nc_ohc=xPyRCvImlaoAX9Z_UTs&_nc_ht=scontent-lax3-1.xx&oh=00_AT85xffhHDJlhzyFTBvWs8j3Gd4GyDCte_Pnd7hNM006sw&oe=635880C2
// https://scontent-lax3-2.xx.fbcdn.net/v/t1.18169-9/10259940_10153561109653458_6837681277740526675_n.jpg?_nc_cat=100&ccb=1-7&_nc_sid=8bfeb9&_nc_ohc=T1v9Wfqz8rUAX8y6bxq&tn=D0unuoVdv--xjhpM&_nc_ht=scontent-lax3-2.xx&oh=00_AT9Y9j5s19n0EzgO_dZMom8tAweFYIrJLOEsrsr4HAWHkQ&oe=63588CAE
// https://scontent-lax3-1.xx.fbcdn.net/v/t31.18172-8/17621858_10154253751886426_3939148233753829194_o.jpg?_nc_cat=104&ccb=1-7&_nc_sid=ad2b24&_nc_ohc=yMOqJQQBV80AX8Xlzr-&_nc_ht=scontent-lax3-1.xx&oh=00_AT_z0oeHJ0fqKhVA4WdgGE2cZSgL0bIKNXzPsY0zeLipAg&oe=6356AF4C
// FileSizeChanged <F:\Tmp\Phares\Compare\Images 2022-11-12 - c6aa7e8 - III\Kristy Google Photos from 2012\2012-10-19 12.00.31.jpg>
// FileSizeChanged <F:\Tmp\Phares\Compare\Images 2022-11-12 - c6aa7e8 - III\Kristy Google Photos from 2012\2012-10-20 15.41.37.jpg>
// FileSizeChanged <F:\Tmp\Phares\Compare\Images 2022-11-12 - c6aa7e8 - III\Kristy Google Photos from 2012\2012-10-23 09.57.51.jpg>
// FileSizeChanged <F:\Tmp\Phares\Compare\Images 2022-11-12 - c6aa7e8 - III\Kristy Google Photos from 2012\2012-10-25 13.46.09.jpg>
// FileSizeChanged <F:\Tmp\Phares\Compare\Images 2022-11-12 - c6aa7e8 - III\Kristy Google Photos from 2012\2012-10-30 21.47.53.jpg>
// FileSizeChanged <F:\Tmp\Phares\Compare\Images 2022-11-12 - c6aa7e8 - III\Kristy Google Photos from 2012\2012-10-31 11.33.13.jpg>
// FileSizeChanged <F:\Tmp\Phares\Compare\Images 2022-11-12 - c6aa7e8 - III\Kristy Google Photos from 2012\2012-11-05 10.28.25.jpg>
// FileSizeChanged <F:\Tmp\Phares\Compare\Images 2022-11-12 - c6aa7e8 - III\Kristy Google Photos from 2012\2012-11-11 19.57.27.jpg>
// FileSizeChanged <F:\Tmp\Phares\Compare\Images 2022-11-12 - c6aa7e8 - III\Kristy Google Photos from 2012\2012-11-12 14.15.39.jpg>
// FileSizeChanged <F:\Tmp\Phares\Compare\Images 2022-11-12 - c6aa7e8 - III\Kristy Google Photos from 2012\2012-11-13 09.49.09.jpg>
// FileSizeChanged <F:\Tmp\Phares\Compare\Images 2022-11-12 - c6aa7e8 - III\Kristy Google Photos from 2012\2012-11-15 08.55.19.jpg>
// FileSizeChanged <F:\Tmp\Phares\Compare\Images 2022-11-12 - c6aa7e8 - III\Kristy Google Photos from 2012\2012-12-01 18.03.13.jpg>
// FileSizeChanged <F:\Tmp\Phares\Compare\Images 2022-11-12 - c6aa7e8 - III\Kristy Google Photos from 2012\2012-12-04 08.44.23.jpg>
// FileSizeChanged <F:\Tmp\Phares\Compare\Images 2022-11-12 - c6aa7e8 - III\Kristy Google Photos from 2012\2012-12-10 21.20.31.jpg>
// FileSizeChanged <F:\Tmp\Phares\Compare\Images 2022-11-12 - c6aa7e8 - III\Kristy Google Photos from 2012\2012-12-16 18.17.53.jpg>
// FileSizeChanged <F:\Tmp\Phares\Compare\Images 2022-11-12 - c6aa7e8 - III\Kristy Google Photos from 2013\IMG_20130317_113053.jpg>
// FileSizeChanged <F:\Tmp\Phares\Compare\Images 2022-11-12 - c6aa7e8 - III\Kristy Google Photos from 2013\IMG_20130324_133916.jpg>
// FileSizeChanged <F:\Tmp\Phares\Compare\Images 2022-11-12 - c6aa7e8 - III\Kristy Google Photos from 2013\IMG_20130330_114757.jpg>
// FileSizeChanged <F:\Tmp\Phares\Compare\Images 2022-11-12 - c6aa7e8 - III\Kristy Google Photos from 2013\IMG_20130418_175845.jpg>
// FileSizeChanged <F:\Tmp\Phares\Compare\Images 2022-11-12 - c6aa7e8 - III\Kristy Google Photos from 2013\IMG_20130418_175934.jpg>
// FileSizeChanged <F:\Tmp\Phares\Compare\Images 2022-11-12 - c6aa7e8 - III\Kristy Google Photos from 2013\IMG_20130424_202523.jpg>
// FileSizeChanged <F:\Tmp\Phares\Compare\Images 2022-11-12 - c6aa7e8 - III\Kristy Google Photos from 2013\IMG_20130424_202634.jpg>
// FileSizeChanged <F:\Tmp\Phares\Compare\Images 2022-11-12 - c6aa7e8 - III\Kristy Google Photos from 2013\IMG_20130514_190936.jpg>
// LastWriteTimeChanged <F:\Tmp\Phares\Compare\Images 2022-11-12 - c6aa7e8 - III\Kristy Google Photos from 2013\IMG_20130516_104450.jpg>
// LastWriteTimeChanged <F:\Tmp\Phares\Compare\Images 2022-11-12 - c6aa7e8 - III\Kristy Google Photos from 2013\IMG_20130522_193539.jpg>
// LastWriteTimeChanged <F:\Tmp\Phares\Compare\Images 2022-11-12 - c6aa7e8 - III\Herman Family Reunion 2008\Herman Family Reunion (160).jpg>
// LastWriteTimeChanged <F:\Tmp\Phares\Compare\Images 2022-11-12 - c6aa7e8 - III\Herman Family Reunion 2008\Herman Family Reunion (213).jpg>
// LastWriteTimeChanged <F:\Tmp\Phares\Compare\Images 2022-11-12 - c6aa7e8 - III\Herman Family Reunion 2008\Herman Family Reunion (215).jpg>
// LastWriteTimeChanged <F:\Tmp\Phares\Compare\Images 2022-11-12 - c6aa7e8 - III\Herman Family Reunion 2008\Herman Family Reunion (218).jpg>
// LastWriteTimeChanged <F:\Tmp\Phares\Compare\Images 2022-11-12 - c6aa7e8 - III\Herman Family Reunion 2008\Herman Family Reunion (225).jpg>
// LastWriteTimeChanged <F:\Tmp\Phares\Compare\Images 2022-11-12 - c6aa7e8 - III\Herman Family Reunion 2008\Herman Family Reunion (226).jpg>
// LastWriteTimeChanged <F:\Tmp\Phares\Compare\Images 2022-11-12 - c6aa7e8 - III\Herman Family Reunion 2008\Herman Family Reunion (231).jpg>
// LastWriteTimeChanged <F:\Tmp\Phares\Compare\Images 2022-11-12 - c6aa7e8 - III\Herman Family Reunion 2008\Herman Family Reunion (232).jpg>
// LastWriteTimeChanged <F:\Tmp\Phares\Compare\Images 2022-11-12 - c6aa7e8 - III\Herman Family Reunion 2008\Herman Family Reunion (234).jpg>
// FileSizeChanged <F:\Tmp\Phares\Compare\Images 2022-11-12 - c6aa7e8\Kristy Google Photos from 2012\2012-10-19 12.00.31.jpg>
// FileSizeChanged <F:\Tmp\Phares\Compare\Images 2022-11-12 - c6aa7e8\Kristy Google Photos from 2012\2012-10-20 15.41.37.jpg>
// FileSizeChanged <F:\Tmp\Phares\Compare\Images 2022-11-12 - c6aa7e8\Kristy Google Photos from 2012\2012-10-23 09.57.51.jpg>
// FileSizeChanged <F:\Tmp\Phares\Compare\Images 2022-11-12 - c6aa7e8\Kristy Google Photos from 2012\2012-10-25 13.46.09.jpg>
// FileSizeChanged <F:\Tmp\Phares\Compare\Images 2022-11-12 - c6aa7e8\Kristy Google Photos from 2012\2012-10-30 21.47.53.jpg>
// FileSizeChanged <F:\Tmp\Phares\Compare\Images 2022-11-12 - c6aa7e8\Kristy Google Photos from 2012\2012-10-31 11.33.13.jpg>
// FileSizeChanged <F:\Tmp\Phares\Compare\Images 2022-11-12 - c6aa7e8\Kristy Google Photos from 2012\2012-11-05 10.28.25.jpg>
// FileSizeChanged <F:\Tmp\Phares\Compare\Images 2022-11-12 - c6aa7e8\Kristy Google Photos from 2012\2012-11-11 19.57.27.jpg>
// FileSizeChanged <F:\Tmp\Phares\Compare\Images 2022-11-12 - c6aa7e8\Kristy Google Photos from 2012\2012-11-12 14.15.39.jpg>
// FileSizeChanged <F:\Tmp\Phares\Compare\Images 2022-11-12 - c6aa7e8\Kristy Google Photos from 2012\2012-11-13 09.49.09.jpg>
// FileSizeChanged <F:\Tmp\Phares\Compare\Images 2022-11-12 - c6aa7e8\Kristy Google Photos from 2012\2012-11-15 08.55.19.jpg>
// FileSizeChanged <F:\Tmp\Phares\Compare\Images 2022-11-12 - c6aa7e8\Kristy Google Photos from 2012\2012-12-01 18.03.13.jpg>
// FileSizeChanged <F:\Tmp\Phares\Compare\Images 2022-11-12 - c6aa7e8\Kristy Google Photos from 2012\2012-12-04 08.44.23.jpg>
// FileSizeChanged <F:\Tmp\Phares\Compare\Images 2022-11-12 - c6aa7e8\Kristy Google Photos from 2012\2012-12-10 21.20.31.jpg>
// FileSizeChanged <F:\Tmp\Phares\Compare\Images 2022-11-12 - c6aa7e8\Kristy Google Photos from 2012\2012-12-16 18.17.53.jpg>
// FileSizeChanged <F:\Tmp\Phares\Compare\Images 2022-11-12 - c6aa7e8\Kristy Google Photos from 2013\IMG_20130317_113053.jpg>
// FileSizeChanged <F:\Tmp\Phares\Compare\Images 2022-11-12 - c6aa7e8\Kristy Google Photos from 2013\IMG_20130324_133916.jpg>
// FileSizeChanged <F:\Tmp\Phares\Compare\Images 2022-11-12 - c6aa7e8\Kristy Google Photos from 2013\IMG_20130330_114757.jpg>
// FileSizeChanged <F:\Tmp\Phares\Compare\Images 2022-11-12 - c6aa7e8\Kristy Google Photos from 2013\IMG_20130418_175845.jpg>
// FileSizeChanged <F:\Tmp\Phares\Compare\Images 2022-11-12 - c6aa7e8\Kristy Google Photos from 2013\IMG_20130418_175934.jpg>
// FileSizeChanged <F:\Tmp\Phares\Compare\Images 2022-11-12 - c6aa7e8\Kristy Google Photos from 2013\IMG_20130424_202523.jpg>
// FileSizeChanged <F:\Tmp\Phares\Compare\Images 2022-11-12 - c6aa7e8\Kristy Google Photos from 2013\IMG_20130424_202634.jpg>
// FileSizeChanged <F:\Tmp\Phares\Compare\Images 2022-11-12 - c6aa7e8\Kristy Google Photos from 2013\IMG_20130514_190936.jpg>
// LastWriteTimeChanged <F:\Tmp\Phares\Compare\Images 2022-11-12 - c6aa7e8\Kristy Google Photos from 2013\IMG_20130516_104450.jpg>
// LastWriteTimeChanged <F:\Tmp\Phares\Compare\Images 2022-11-12 - c6aa7e8\Kristy Google Photos from 2013\IMG_20130522_193539.jpg>
// LastWriteTimeChanged <F:\Tmp\Phares\Compare\Images 2022-11-12 - c6aa7e8\Herman Family Reunion 2008\Herman Family Reunion (160).jpg>
// LastWriteTimeChanged <F:\Tmp\Phares\Compare\Images 2022-11-12 - c6aa7e8\Herman Family Reunion 2008\Herman Family Reunion (213).jpg>
// LastWriteTimeChanged <F:\Tmp\Phares\Compare\Images 2022-11-12 - c6aa7e8\Herman Family Reunion 2008\Herman Family Reunion (215).jpg>
// LastWriteTimeChanged <F:\Tmp\Phares\Compare\Images 2022-11-12 - c6aa7e8\Herman Family Reunion 2008\Herman Family Reunion (218).jpg>
// LastWriteTimeChanged <F:\Tmp\Phares\Compare\Images 2022-11-12 - c6aa7e8\Herman Family Reunion 2008\Herman Family Reunion (225).jpg>
// LastWriteTimeChanged <F:\Tmp\Phares\Compare\Images 2022-11-12 - c6aa7e8\Herman Family Reunion 2008\Herman Family Reunion (226).jpg>
// LastWriteTimeChanged <F:\Tmp\Phares\Compare\Images 2022-11-12 - c6aa7e8\Herman Family Reunion 2008\Herman Family Reunion (231).jpg>
// LastWriteTimeChanged <F:\Tmp\Phares\Compare\Images 2022-11-12 - c6aa7e8\Herman Family Reunion 2008\Herman Family Reunion (232).jpg>
// LastWriteTimeChanged <F:\Tmp\Phares\Compare\Images 2022-11-12 - c6aa7e8\Herman Family Reunion 2008\Herman Family Reunion (234).jpg>
// - Device Videos 2_0_0_3 - Current - Kristy Google
// - Device Videos 2_0_0_3 - Current - Mike Google
// - Device Videos 2_0_0_3 - Current - Tracy
// Chester & Linores ?Pearson?
// Distance face files date time?
// If not Hog and Original image size resize face
// New json file with known locations at original image size
// Add person to metadata when saving to SaveResizedImagesByPersonKeyFormattedForOutputResolutions maybe SaveMappedForOutputResolutions
// GetFaceLocations

View File

@ -35,8 +35,8 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Hosting" Version="7.0.0" />
<PackageReference Include="Microsoft.AspNetCore.Cryptography.KeyDerivation" Version="7.0.0" />
<PackageReference Include="Microsoft.Extensions.Identity.Core" Version="7.0.0" />
<PackageReference Include="Microsoft.AspNetCore.Cryptography.KeyDerivation" Version="7.0.1" />
<PackageReference Include="Microsoft.Extensions.Identity.Core" Version="7.0.1" />
<PackageReference Include="Microsoft.Extensions.Options" Version="7.0.0" />
<PackageReference Include="Serilog.Settings.Configuration" Version="3.4.0" />
<PackageReference Include="Serilog.Sinks.Console" Version="4.1.0" />
@ -45,7 +45,7 @@
<PackageReference Include="ShellProgressBar" Version="5.2.0" />
<PackageReference Include="WindowsShortcutFactory" Version="1.1.0" />
<PackageReference Include="System.Drawing.Common" Version="7.0.0" />
<PackageReference Include="System.Text.Json" Version="7.0.0" />
<PackageReference Include="System.Text.Json" Version="7.0.1" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Map\Map.csproj" />

View File

@ -87,14 +87,14 @@
"Pattern": "[^ABCDEFGHIJKLMNOPQRSTUVWXYZbcdfghjklmnpqrstvwxyz0-9]",
"PopulatePropertyId": true,
"PropertiesChangedForProperty": false,
"RootDirectory": "C:/Tmp/Phares/Compare/Images 2022-11-12 - c6aa7e8 - III",
"RootDirectory": "C:/Tmp/Phares/Compare/Images 2022-11-12 - c6aa7e8",
"WriteBitmapDataBytes": false,
"IgnoreExtensions": [
".gif",
".GIF"
],
"PropertyContentCollectionFiles": [
"/Images 2022-11-12 - c6aa7e8 - III - Results/A) Property/2022-11-12/[()]/637869381676042455.json",
"/Images 2022-11-12 - c6aa7e8 - Results/A) Property/2022-11-12/[()]/637869381676042455.json",
"/Not-Copy-Copy/Images 2019-06-08 - 34a9240ac28b52da97428d7725153a80a757ee6b - Not-Copy-Copy - Results/A) Property/2022-11-12/[()]/637869733124119330.json",
"/Not-Copy-Copy/Images 2018-12-25 - 34a9240ac28b52da97428d7725153a80a757ee6b - Not-Copy-Copy - Results/A) Property/2022-11-12/[()]/637869734240700328.json",
"/Not-Copy-Copy/Images 2018-05-12 - b01d4763d8853b6d6057a3870b2723449726da75 - Not-Copy-Copy - Results/A) Property/2022-11-12/[()]/637869734970730630.json",

View File

@ -94,7 +94,7 @@
".GIF"
],
"PropertyContentCollectionFiles": [
"/Images 2022-11-12 - c6aa7e8 - III - Results/A) Property/2022-11-12/[()]/637869381676042455.json",
"/Images 2022-11-12 - c6aa7e8 - Results/A) Property/2022-11-12/[()]/637869381676042455.json",
"/Not-Copy-Copy/Images 2019-06-08 - 34a9240ac28b52da97428d7725153a80a757ee6b - Not-Copy-Copy - Results/A) Property/2022-11-12/[()]/637869733124119330.json",
"/Not-Copy-Copy/Images 2018-12-25 - 34a9240ac28b52da97428d7725153a80a757ee6b - Not-Copy-Copy - Results/A) Property/2022-11-12/[()]/637869734240700328.json",
"/Not-Copy-Copy/Images 2018-05-12 - b01d4763d8853b6d6057a3870b2723449726da75 - Not-Copy-Copy - Results/A) Property/2022-11-12/[()]/637869734970730630.json",

View File

@ -34,9 +34,9 @@
<SupportedPlatform Include="browser" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Cryptography.KeyDerivation" Version="7.0.0" />
<PackageReference Include="Microsoft.AspNetCore.Cryptography.KeyDerivation" Version="7.0.1" />
<PackageReference Include="Microsoft.Extensions.Hosting" Version="7.0.0" />
<PackageReference Include="Microsoft.Extensions.Identity.Core" Version="7.0.0" />
<PackageReference Include="Microsoft.Extensions.Identity.Core" Version="7.0.1" />
<PackageReference Include="Microsoft.Extensions.Options" Version="7.0.0" />
<PackageReference Include="MetadataExtractor" Version="2.7.2" />
<PackageReference Include="Serilog.Settings.Configuration" Version="3.4.0" />
@ -46,13 +46,16 @@
<PackageReference Include="ShellProgressBar" Version="5.2.0" />
<PackageReference Include="WindowsShortcutFactory" Version="1.1.0" />
<PackageReference Include="System.Drawing.Common" Version="7.0.0" />
<PackageReference Include="System.Text.Json" Version="7.0.0" />
<PackageReference Include="System.Text.Json" Version="7.0.1" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Shared\View-by-Distance.Shared.csproj" />
<ProjectReference Include="..\Property\Property.csproj" />
</ItemGroup>
<ItemGroup>
<None Include="appsettings.json">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Include="appsettings.Development.json">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>

View File

@ -36,8 +36,9 @@ public class DateGroup
_FileKeyValuePairs = new List<KeyValuePair<string, string>>();
_FilePropertiesKeyValuePairs = new Dictionary<string, List<Tuple<string, Shared.Models.Property>>>();
Property.Models.Configuration propertyConfiguration = Property.Models.Binder.Configuration.Get(isEnvironment, configurationRoot);
Property.Models.Configuration.Verify(propertyConfiguration, requireExist: true);
Models.Configuration configuration = Models.Binder.Configuration.Get(isEnvironment, configurationRoot, propertyConfiguration);
_Log.Information(propertyConfiguration.RootDirectory);
Property.Models.Configuration.Verify(propertyConfiguration, requireExist: true);
Verify(configuration);
bool reverse = false;
_Configuration = configuration;
@ -141,8 +142,6 @@ public class DateGroup
check += 1;
if (configuration.ByHash)
check += 1;
if (configuration.ByNone)
check += 1;
if (configuration.BySeason)
check += 1;
if (configuration.ByWeek)
@ -256,18 +255,15 @@ public class DateGroup
if (matches is not null && matches.Any())
break;
}
matches ??= Array.Empty<string>();
foreach (Item item in filteredItems)
{
if (item.Property is null || (_Configuration.PropertyConfiguration.PopulatePropertyId && item.Property.Id is null))
continue;
directoryNames.Clear();
destinationCollection = new();
_ = destinationDirectoryName.Clear();
minimumDateTime = Shared.Models.Stateless.Methods.IProperty.GetMinimumDateTime(item.Property);
day = minimumDateTime.Value.ToString("MM-dd");
month = minimumDateTime.Value.ToString("MMMM");
if (item.Property.Id is null)
if (item.Property?.Id is null)
{
flag = '#';
isWrongYear = null;
@ -294,6 +290,8 @@ public class DateGroup
seasonValue = $".{season}";
if (isWrongYear is null || !isWrongYear.Value)
year = $"{flag}{minimumDateTime.Value:yyyy}{seasonValue}";
else if (matches is null || matches.Length < 3)
year = "----";
else
{
if (matches[0][0] != '~')
@ -303,9 +301,7 @@ public class DateGroup
}
topDirectoryName = Path.GetFileName(topDirectory);
weekOfYear = calendar.GetWeekOfYear(minimumDateTime.Value, CalendarWeekRule.FirstDay, DayOfWeek.Sunday).ToString("00");
if (_Configuration.ByNone)
directoryNames.Clear();
else if (_Configuration.ByHash)
if (_Configuration.ByHash)
directoryNames.Add($"{year} {seasonName}");
else if (_Configuration.BySeason && topDirectoryName.Length == 1 && topDirectoryName[0] == '_')
directoryNames.Add($"{year} {seasonName}");
@ -328,7 +324,7 @@ public class DateGroup
{
foreach (string sourceDirectoryNameSegment in topDirectorySegments)
{
if (matches.Contains(sourceDirectoryNameSegment))
if (matches is not null && matches.Contains(sourceDirectoryNameSegment))
_ = destinationDirectoryName.Append(year);
else
_ = destinationDirectoryName.Append(sourceDirectoryNameSegment);
@ -343,14 +339,19 @@ public class DateGroup
throw new Exception();
}
}
if (!_Configuration.ByHash || item.Property.Id is null)
if (!_Configuration.ByHash || item.Property?.Id is null)
fileName = item.ImageFileHolder.Name;
else
fileName = $"{item.Property.Id.Value}{item.ImageFileHolder.ExtensionLowered}";
destinationCollection.Add(destinationDirectory);
destinationCollection.AddRange(directoryNames);
destinationCollection.Add(fileName);
if (item.ImageFileHolder.LastWriteTime is null)
continue;
if (item.Property is not null)
results.Add(new(item, item.Property.LastWriteTime.Ticks, minimumDateTime.Value.Ticks, destinationCollection.ToArray()));
else
results.Add(new(item, item.ImageFileHolder.LastWriteTime.Value.Ticks, minimumDateTime.Value.Ticks, destinationCollection.ToArray()));
}
return results;
}
@ -419,11 +420,12 @@ public class DateGroup
{
if (_Log is null)
throw new NullReferenceException(nameof(_Log));
string checkDirectory;
bool hasDuplicate;
string fullFileName;
string directoryName;
WindowsShortcut windowsShortcut;
string duplicate = "-Duplicate";
string duplicate = "-Duplicates";
List<string> filesDistinct = new();
List<string> filesDuplicate = new();
List<string> directoriesDistinct = new();
@ -440,12 +442,17 @@ public class DateGroup
directoriesDistinct.Add(directoryName);
if (!Directory.Exists(directoryName))
_ = Directory.CreateDirectory(directoryName);
if (!Directory.Exists(string.Concat(directoryName, duplicate, " I")))
_ = Directory.CreateDirectory(string.Concat(directoryName, duplicate, " I"));
if (!Directory.Exists(string.Concat(directoryName, duplicate, " II")))
_ = Directory.CreateDirectory(string.Concat(directoryName, duplicate, " II"));
checkDirectory = Path.Combine(string.Concat(directoryName, duplicate), "I");
if (!Directory.Exists(checkDirectory))
_ = Directory.CreateDirectory(checkDirectory);
for (int i = 0; i < 200 - checkDirectory.Length; i++)
{
checkDirectory = string.Concat(checkDirectory, "I");
if (!Directory.Exists(checkDirectory))
_ = Directory.CreateDirectory(checkDirectory);
}
_Log.Information("Ready to move files?");
}
_Log.Information($"Ready to move {fileMoveCollectionAll.Length} file(s)?");
for (int y = 0; y < int.MaxValue; y++)
{
_Log.Information("Press \"Y\" key to move file(s) or close console to not move files");
@ -460,16 +467,16 @@ public class DateGroup
hasDuplicate = filesDuplicate.Contains(fullFileName);
if (hasDuplicate)
{
destination[1] = string.Concat(destination[1], duplicate, " I");
destination[0] = Path.Combine(string.Concat(destination[0], duplicate), "I");
fullFileName = Path.Combine(destination);
}
for (int i = 0; i < 256 - destination[1].Length; i++)
for (int i = 0; i < 200 - destination[0].Length; i++)
{
if (!File.Exists(fullFileName))
break;
else
{
destination[1] = string.Concat(destination[1], "I");
destination[0] = string.Concat(destination[0], "I");
fullFileName = Path.Combine(destination);
if (File.Exists(fullFileName))
continue;

View File

@ -13,7 +13,6 @@ public class Configuration
[Display(Name = "By Create Date Shortcut"), Required] public bool? ByCreateDateShortcut { get; set; }
[Display(Name = "By Date"), Required] public bool? ByDay { get; set; }
[Display(Name = "By Hash"), Required] public bool? ByHash { get; set; }
[Display(Name = "By None"), Required] public bool? ByNone { get; set; }
[Display(Name = "By Season"), Required] public bool? BySeason { get; set; }
[Display(Name = "By Week"), Required] public bool? ByWeek { get; set; }
[Display(Name = "Ignore Subdirectories for Rename"), Required] public bool? KeepFullPath { get; set; }
@ -38,15 +37,20 @@ public class Configuration
throw new NullReferenceException(nameof(configuration.ByDay));
if (configuration.ByHash is null)
throw new NullReferenceException(nameof(configuration.ByHash));
if (configuration.ByNone is null)
throw new NullReferenceException(nameof(configuration.ByNone));
if (configuration.BySeason is null)
throw new NullReferenceException(nameof(configuration.BySeason));
if (configuration.ByWeek is null)
throw new NullReferenceException(nameof(configuration.ByWeek));
if (configuration.KeepFullPath is null)
throw new NullReferenceException(nameof(configuration.KeepFullPath));
result = new(configuration.PropertyConfiguration, configuration.ByCreateDateShortcut.Value, configuration.ByDay.Value, configuration.ByHash.Value, configuration.ByNone.Value, configuration.BySeason.Value, configuration.ByWeek.Value, configuration.KeepFullPath.Value);
result = new(
configuration.PropertyConfiguration,
configuration.ByCreateDateShortcut.Value,
configuration.ByDay.Value,
configuration.ByHash.Value,
configuration.BySeason.Value,
configuration.ByWeek.Value,
configuration.KeepFullPath.Value);
return result;
}
@ -66,7 +70,7 @@ public class Configuration
result = Get(configuration);
if (configuration is null)
throw new NullReferenceException(nameof(configuration));
result.SetAndUpdate(propertyConfiguration, numberOfJitters: null, numberOfTimesToUpsample: null, modelName: null, predictorModelName: null);
result.SetAndUpdate(propertyConfiguration);
return result;
}

View File

@ -12,17 +12,15 @@ public class Configuration
public bool ByCreateDateShortcut { init; get; }
public bool ByDay { init; get; }
public bool ByHash { init; get; }
public bool ByNone { init; get; }
public bool BySeason { init; get; }
public bool ByWeek { init; get; }
public bool KeepFullPath { init; get; }
[JsonConstructor]
public Configuration(Property.Models.Configuration propertyConfiguration, bool byCreateDateShortcut, bool byDay, bool byHash, bool byNone, bool bySeason, bool byWeek, bool keepFullPath)
public Configuration(Property.Models.Configuration propertyConfiguration, bool byCreateDateShortcut, bool byDay, bool byHash, bool bySeason, bool byWeek, bool keepFullPath)
{
ByDay = byDay;
ByHash = byHash;
ByNone = byNone;
ByWeek = byWeek;
BySeason = bySeason;
KeepFullPath = keepFullPath;
@ -36,10 +34,10 @@ public class Configuration
return result;
}
public void SetAndUpdate(Property.Models.Configuration configuration, int? numberOfJitters, int? numberOfTimesToUpsample, string? modelName, string? predictorModelName)
public void SetAndUpdate(Property.Models.Configuration configuration)
{
_PropertyConfiguration = configuration;
_PropertyConfiguration.Update(numberOfJitters, numberOfTimesToUpsample, modelName, predictorModelName);
_PropertyConfiguration.Update();
}
}

View File

@ -19,6 +19,7 @@ public class Program
IsEnvironment isEnvironment = new(processesCount: null, nullASPNetCoreEnvironmentIsDevelopment: debuggerWasAttachedAtLineZero, nullASPNetCoreEnvironmentIsProduction: !debuggerWasAttachedAtLineZero);
IConfigurationBuilder configurationBuilder = new ConfigurationBuilder()
.AddEnvironmentVariables()
.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
.AddJsonFile(isEnvironment.AppSettingsFileName, optional: false, reloadOnChange: true);
IConfigurationRoot configurationRoot = configurationBuilder.Build();
AppSettings appSettings = Models.Binder.AppSettings.Get(configurationRoot);

View File

@ -53,8 +53,7 @@
"ByCreateDateShortcut": false,
"ByDay": false,
"ByHash": false,
"ByNone": false,
"BySeason": true,
"BySeason": false,
"ByWeek": false,
"DateGroup": "2022-11-12",
"FileNameDirectorySeparator": ".Z.",
@ -69,10 +68,10 @@
"ResultContent": "()",
"ResultSingleton": "{}",
"xRootDirectory": "C:/Tmp/phares/Pictures",
"xxRootDirectory": "C:/Tmp/Phares/Compare/Images 2022-11-12 - c6aa7e8 - III",
"xxxRootDirectory": "F:/Tmp/Phares/Compare/Images 2022-11-12 - c6aa7e8 - III",
"xxRootDirectory": "C:/Tmp/Phares/Compare/Images 2022-11-12 - c6aa7e8",
"xxxRootDirectory": "F:/Tmp/Phares/Compare/Not-Copy-Copy-All",
"RootDirectory": "C:/Tmp/Phares/Compare/Not-Copy-Copy-All",
"xxxxRootDirectory": "F:/Tmp/Phares/2022-11-03-DCIM/DCIM/100D3400 2022",
"RootDirectory": "F:/Tmp/Phares/Compare/Images 2022-11-12 - c6aa7e8 - III/D",
"WriteBitmapDataBytes": false,
"IgnoreExtensions": [
".gif",

348
Date-Group/appsettings.json Normal file
View File

@ -0,0 +1,348 @@
{
"Company": "Mike Phares",
"Linux": {},
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Log4netProvider": "Debug",
"Microsoft.Hosting.Lifetime": "Information"
}
},
"MaxDegreeOfParallelism": 6,
"Serilog": {
"Using": [
"Serilog.Sinks.Console",
"Serilog.Sinks.File"
],
"MinimumLevel": "Debug",
"WriteTo": [
{
"Name": "Debug",
"Args": {
"outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz} [{Level}] ({SourceContext}.{MethodName}) ({InstanceId}) ({RemoteIpAddress}) {Message}{NewLine}{Exception}"
}
},
{
"Name": "Console",
"Args": {
"outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz} [{Level}] ({SourceContext}.{MethodName}) ({InstanceId}) ({RemoteIpAddress}) {Message}{NewLine}{Exception}"
}
},
{
"Name": "File",
"Args": {
"path": "%workingDirectory% - Log/log-.txt",
"outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz} [{Level}] ({SourceContext}.{MethodName}) ({InstanceId}) ({RemoteIpAddress}) {Message}{NewLine}{Exception}",
"rollingInterval": "Hour"
}
}
],
"Enrich": [
"FromLogContext",
"WithMachineName",
"WithThreadId"
],
"Properties": {
"Application": "Sample"
}
},
"WorkingDirectoryName": "PharesApps",
"Windows": {
"Configuration": {
"ByCreateDateShortcut": false,
"ByDay": false,
"ByHash": false,
"BySeason": false,
"ByWeek": false,
"DateGroup": "2022-11-12",
"FileNameDirectorySeparator": ".Z.",
"ForcePropertyLastWriteTimeToCreationTime": false,
"KeepFullPath": false,
"MaxImagesInDirectoryForTopLevelFirstPass": 10,
"Pattern": "[^ABCDEFGHIJKLMNOPQRSTUVWXYZbcdfghjklmnpqrstvwxyz0-9]",
"PopulatePropertyId": false,
"PropertiesChangedForProperty": false,
"ResultAllInOne": "_ _ _",
"ResultCollection": "[]",
"ResultContent": "()",
"ResultSingleton": "{}",
"xRootDirectory": "C:/Tmp/phares/Pictures",
"xxRootDirectory": "C:/Tmp/Phares/Compare/Images 2022-11-12 - c6aa7e8",
"RootDirectory": "F:/Tmp/Phares/Compare/Not-Copy-Copy-All",
"xxxxRootDirectory": "F:/Tmp/Phares/2022-11-03-DCIM/DCIM/100D3400 2022",
"WriteBitmapDataBytes": false,
"IgnoreExtensions": [
".gif",
".GIF"
],
"PropertyContentCollectionFiles": [],
"ValidImageFormatExtensions": [
".bmp",
".BMP",
".gif",
".GIF",
".jpeg",
".JPEG",
".jpg",
".JPG",
".png",
".PNG",
".tiff",
".TIFF"
],
"ValidMetadataExtensions": [
".3gp",
".3GP",
".avi",
".AVI",
".bmp",
".BMP",
".gif",
".GIF",
".ico",
".ICO",
".jpeg",
".JPEG",
".jpg",
".JPG",
".m4v",
".M4V",
".mov",
".MOV",
".mp4",
".MP4",
".mta",
".MTA",
".png",
".PNG",
".tiff",
".TIFF"
],
"VerifyToSeason": [
". 2000",
". 2001",
". 2002",
". 2003",
". 2004",
". 2005",
". 2006",
". 2007",
". 2008",
". 2009",
". 2010",
". 2011",
". 2012",
". 2013",
". 2014",
". 2015",
". 2016",
". 2017",
". 2018",
". 2019",
". 2020",
". 2021",
". 2022",
". 2023",
". 2024",
". 2025",
". 2026",
". 2027",
". 2028",
". 2029",
"=2000.0 Winter",
"=2002.1 Spring",
"=2002.4 Winter",
"=2003.0 Winter",
"=2003.1 Spring",
"=2003.3 Fall",
"=2003.4 Winter",
"=2004.0 Winter",
"=2005.1 Spring",
"=2005.2 Summer",
"=2005.3 Fall",
"=2005.4 Winter",
"=2006.0 Winter",
"=2006.1 Spring",
"=2006.3 Fall",
"=2007.0 Winter",
"=2007.2 Summer Logan Michael",
"=2007.2 Summer",
"=2007.3 Fall Logan Michael",
"=2007.4 Winter Logan Michael",
"=2008.0 Winter Logan Michael",
"=2008.1 Spring Logan Michael",
"=2008.2 Summer Logan Michael",
"=2008.2 Summer",
"=2008.3 Fall Logan Michael",
"=2009.0 Winter Logan Michael",
"=2009.0 Winter",
"=2009.1 Spring Logan Michael",
"=2009.1 Spring",
"=2009.2 Summer Logan Michael",
"=2009.2 Summer",
"=2009.3 Fall Logan Michael",
"=2009.3 Fall",
"=2009.4 Winter Logan Michael",
"=2009.4 Winter",
"=2010.0 Winter Logan Michael",
"=2010.0 Winter",
"=2010.1 Spring Logan Michael",
"=2010.1 Spring",
"=2010.2 Summer",
"=2010.3 Fall Logan Michael",
"=2010.3 Fall",
"=2010.4 Winter",
"=2011.0 Winter",
"=2011.1 Spring",
"=2011.2 Summer",
"=2011.3 Fall",
"=2011.4 Winter",
"=2012.0 Winter Chelsea 2012",
"=2012.0 Winter Chelsea",
"=2012.0 Winter",
"=2012.1 Spring Chelsea",
"=2012.1 Spring",
"=2012.2 Summer Chelsea",
"=2012.2 Summer",
"=2012.3 Fall Chelsea",
"=2012.3 Fall",
"=2012.4 Winter Chelsea",
"=2012.4 Winter",
"=2013.0 Winter Chelsea 2013",
"=2013.0 Winter Chelsea",
"=2013.0 Winter",
"=2013.1 Spring",
"=2013.2 Summer Chelsea",
"=2013.2 Summer",
"=2013.3 Fall Chelsea",
"=2013.3 Fall",
"=2013.4 Winter",
"=2014.0 Winter",
"=2014.1 Spring",
"=2014.2 Summer",
"=2014.3 Fall",
"=2014.4 Winter",
"=2015.0 Winter",
"=2015.1 Spring",
"=2015.2 Summer",
"=2015.3 Fall",
"=2015.4 Winter",
"=2016.0 Winter",
"=2016.1 Spring",
"=2016.2 Summer",
"=2016.3 Fall",
"=2016.4 Winter",
"=2017.1 Spring",
"=2017.2 Summer",
"=2017.3 Fall",
"=2017.4 Winter",
"=2018.0 Winter",
"=2018.1 Spring",
"=2018.3 Fall",
"=2018.4 Winter",
"=2019.0 Winter",
"=2019.1 Spring",
"=2019.2 Summer",
"=2019.3 Fall",
"=2019.4 Winter",
"=2020.0 Winter",
"=2020.1 Spring",
"=2020.2 Summer",
"=2020.3 Fall",
"=2020.4 Winter",
"=2021.1 Spring",
"=2021.2 Summer",
"=2021.3 Fall",
"=2021.4 Winter",
"=2022.0 Winter",
"=2022.1 Spring",
"Anthem 2015",
"April 2010",
"April 2013",
"December 2006",
"December 2010",
"Fall 2005",
"Fall 2015",
"Fall 2016",
"Fall 2017",
"Fall 2018",
"Fall 2019",
"Fall 2020",
"Fall 2021",
"February 2010",
"January 2015",
"July 2010",
"June 2010",
"Kids 2005",
"March 2013",
"May 2010",
"May 2011",
"May 2013",
"October 2005",
"October 2014",
"Spring 2013",
"Spring 2014",
"Spring 2016",
"Spring 2018",
"Spring 2019",
"Spring 2020",
"Summer 2011",
"Summer 2012",
"Summer 2013",
"Summer 2014",
"Summer 2015",
"Summer 2016",
"Summer 2017",
"Summer 2018",
"Summer 2020",
"Summer 2021",
"Winter 2015",
"Winter 2016",
"Winter 2017",
"Winter 2018",
"Winter 2019-2020",
"Winter 2020",
"zzz =2005.0 Winter Tracy Pictures",
"zzz =2005.1 Spring Tracy Pictures",
"zzz =2005.2 Summer Tracy Pictures",
"zzz =2005.3 Fall Tracy Pictures",
"zzz =2005.4 Winter Tracy Pictures",
"zzz =2006.1 Spring Tracy Pictures",
"zzz =2007.0 Winter Tracy Pictures",
"zzz =2007.2 Summer Tracy Pictures",
"zzz =2008.0 Winter Tracy Pictures",
"zzz =2008.2 Summer Tracy Pictures",
"zzz =2009.0 Winter Tracy Pictures",
"zzz =2009.2 Summer Tracy Pictures",
"zzz =2009.3 Fall Tracy Pictures",
"zzz =2009.4 Winter Tracy Pictures",
"zzz =2010.0 Winter Tracy Pictures",
"zzz =2010.1 Spring Tracy Pictures",
"zzz =2010.2 Summer Tracy Pictures",
"zzz =2010.3 Fall Tracy Pictures",
"zzz =2011.0 Winter Tracy Pictures",
"zzz =2011.1 Spring Tracy Pictures",
"zzz =2011.2 Summer Tracy Pictures",
"zzz =2011.3 Fall Tracy Pictures",
"zzz =2011.4 Winter Tracy Pictures",
"zzz =2012.0 Winter Tracy Pictures",
"zzz =2012.1 Spring Tracy Pictures",
"zzz =2012.2 Summer Tracy Pictures",
"zzz =2012.3 Fall Tracy Pictures",
"zzz =2012.4 Winter Tracy Pictures",
"zzz =2013.0 Winter Tracy Pictures",
"zzz =2013.1 Spring Tracy Pictures",
"zzz =2013.2 Summer Tracy Pictures",
"zzz =2013.3 Fall Tracy Pictures",
"zzz =2013.4 Winter Tracy Pictures",
"zzz =2014.0 Winter Tracy Pictures",
"zzz =2014.1 Spring Tracy Pictures",
"zzz =2014.2 Summer Tracy Pictures",
"zzz =2014.3 Fall Tracy Pictures",
"zzz =2014.4 Winter Tracy Pictures",
"zzz =2015.0 Winter Tracy Pictures"
]
}
}
}

View File

@ -0,0 +1 @@
[]

32
Delete-By-Relative/.vscode/launch.json vendored Normal file
View File

@ -0,0 +1,32 @@
{
"version": "0.2.0",
"configurations": [
{
// Use IntelliSense to find out which attributes exist for C# debugging
// Use hover for the description of the existing attributes
// For further information visit https://github.com/OmniSharp/omnisharp-vscode/blob/master/debugger-launchjson.md
"name": ".NET Core Launch (console)",
"type": "coreclr",
"request": "launch",
"preLaunchTask": "build",
// If you have changed target frameworks, make sure to update the program path.
"program": "${workspaceFolder}/bin/Debug/net6.0/win-x64/Duplicate-Search.dll",
"args": [
"s"
],
"env": {
"ASPNETCORE_ENVIRONMENT": "Development",
},
"cwd": "${workspaceFolder}",
// For more information about the 'console' field, see https://aka.ms/VSCode-CS-LaunchJson-Console
"console": "externalTerminal",
"stopAtEntry": false
},
{
"name": ".NET Core Attach",
"type": "coreclr",
"request": "attach",
"processName": "Duplicate-Search"
}
]
}

View File

@ -0,0 +1,14 @@
{
"cSpell.words": [
"Barrick",
"bcdfghjklmnpqrstvwxyz",
"Beichler",
"Bohdi",
"Dlib",
"exif",
"nosj",
"Phares",
"Serilog",
"Vericruz"
]
}

42
Delete-By-Relative/.vscode/tasks.json vendored Normal file
View File

@ -0,0 +1,42 @@
{
"version": "2.0.0",
"tasks": [
{
"label": "build",
"command": "dotnet",
"type": "process",
"args": [
"build",
"${workspaceFolder}/Duplicate-Search.csproj",
"/property:GenerateFullPaths=true",
"/consoleloggerparameters:NoSummary"
],
"problemMatcher": "$msCompile"
},
{
"label": "publish",
"command": "dotnet",
"type": "process",
"args": [
"publish",
"${workspaceFolder}/Duplicate-Search.csproj",
"/property:GenerateFullPaths=true",
"/consoleloggerparameters:NoSummary"
],
"problemMatcher": "$msCompile"
},
{
"label": "watch",
"command": "dotnet",
"type": "process",
"args": [
"watch",
"run",
"${workspaceFolder}/Duplicate-Search.csproj",
"/property:GenerateFullPaths=true",
"/consoleloggerparameters:NoSummary"
],
"problemMatcher": "$msCompile"
}
]
}

View File

@ -0,0 +1,62 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<ImplicitUsings>enable</ImplicitUsings>
<LangVersion>10.0</LangVersion>
<Nullable>enable</Nullable>
<OutputType>Exe</OutputType>
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
<TargetFramework>net7.0</TargetFramework>
</PropertyGroup>
<PropertyGroup>
<PackageId>Phares.View.by.Distance.Delete.By.Relative</PackageId>
<GeneratePackageOnBuild>false</GeneratePackageOnBuild>
<Version>6.0.100.1</Version>
<Authors>Mike Phares</Authors>
<Company>Phares</Company>
<IncludeSymbols>true</IncludeSymbols>
<SymbolPackageFormat>snupkg</SymbolPackageFormat>
</PropertyGroup>
<PropertyGroup>
<IsWindows Condition="'$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::Windows)))' == 'true'">true</IsWindows>
<IsOSX Condition="'$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::OSX)))' == 'true'">true</IsOSX>
<IsLinux Condition="'$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::Linux)))' == 'true'">true</IsLinux>
</PropertyGroup>
<PropertyGroup Condition="'$(IsWindows)'=='true'">
<DefineConstants>Windows</DefineConstants>
</PropertyGroup>
<PropertyGroup Condition="'$(IsOSX)'=='true'">
<DefineConstants>OSX</DefineConstants>
</PropertyGroup>
<PropertyGroup Condition="'$(IsLinux)'=='true'">
<DefineConstants>Linux</DefineConstants>
</PropertyGroup>
<ItemGroup Condition="'$(RuntimeIdentifier)' == 'browser-wasm'">
<SupportedPlatform Include="browser" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Hosting" Version="7.0.0" />
<PackageReference Include="Microsoft.AspNetCore.Cryptography.KeyDerivation" Version="7.0.1" />
<PackageReference Include="Microsoft.Extensions.Identity.Core" Version="7.0.1" />
<PackageReference Include="Microsoft.Extensions.Options" Version="7.0.0" />
<PackageReference Include="Serilog.Settings.Configuration" Version="3.4.0" />
<PackageReference Include="Serilog.Sinks.Console" Version="4.1.0" />
<PackageReference Include="Serilog.Sinks.File" Version="5.0.0" />
<PackageReference Include="Serilog" Version="2.12.0" />
<PackageReference Include="ShellProgressBar" Version="5.2.0" />
<PackageReference Include="WindowsShortcutFactory" Version="1.1.0" />
<PackageReference Include="System.Drawing.Common" Version="7.0.0" />
<PackageReference Include="System.Text.Json" Version="7.0.1" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Property\Property.csproj" />
<ProjectReference Include="..\Shared\View-by-Distance.Shared.csproj" />
</ItemGroup>
<ItemGroup>
<None Include="appsettings.Development.json">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Include="appsettings.json">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
</ItemGroup>
</Project>

View File

@ -0,0 +1,82 @@
using Microsoft.Extensions.Configuration;
using Phares.Shared;
using Serilog;
using View_by_Distance.Delete.By.Relative.Models;
using View_by_Distance.Property.Models;
using View_by_Distance.Shared.Models.Methods;
namespace View_by_Distance.Delete.By.Relative;
public class DeleteByRelative
{
public DeleteByRelative(List<string> args, IsEnvironment isEnvironment, IConfigurationRoot configurationRoot, AppSettings appSettings, string workingDirectory, bool isSilent, IConsole console)
{
if (isSilent)
{ }
if (console is null)
{ }
string relativePath;
string checkFileName;
string searchPattern = "*";
long ticks = DateTime.Now.Ticks;
ILogger? log = Log.ForContext<DeleteByRelative>();
Configuration configuration = Property.Models.Binder.Configuration.Get(isEnvironment, configurationRoot);
configuration.Update();
log.Information(configuration.RootDirectory);
int length = configuration.RootDirectory.Length;
if (string.IsNullOrEmpty(appSettings.CompareRootDirectory) || Path.GetFullPath(appSettings.CompareRootDirectory) == Path.GetFullPath(configuration.RootDirectory))
throw new Exception("Check AppSettings file!");
IEnumerable<(string directory, string[] files)> leftCollection = Shared.Models.Stateless.Methods.IFileHolder.GetFiles(configuration.RootDirectory, searchPattern);
List<string> leftRelativeFiles = new();
foreach ((_, string[] files) in leftCollection)
{
foreach (string file in files)
{
relativePath = Shared.Models.Stateless.Methods.IPath.GetRelativePath(file, length);
leftRelativeFiles.Add(Path.GetFullPath(string.Concat(appSettings.CompareRootDirectory, relativePath)));
}
}
List<string> deleteFiles = new();
IEnumerable<(string, string[])> rightCollection = Shared.Models.Stateless.Methods.IFileHolder.GetFiles(appSettings.CompareRootDirectory, searchPattern);
foreach ((_, string[] files) in rightCollection)
{
foreach (string file in files)
{
checkFileName = Path.GetFullPath(file);
if (!leftRelativeFiles.Contains(checkFileName))
continue;
deleteFiles.Add(checkFileName);
}
}
string? alongSideDirectory;
string directoryName = Path.GetFileName(appSettings.CompareRootDirectory);
if (Path.GetPathRoot(appSettings.CompareRootDirectory) == appSettings.CompareRootDirectory)
alongSideDirectory = appSettings.CompareRootDirectory;
else
alongSideDirectory = Path.GetDirectoryName(appSettings.CompareRootDirectory);
if (alongSideDirectory is null)
throw new NullReferenceException(nameof(alongSideDirectory));
string deleteLog = Path.Combine(alongSideDirectory, $"{directoryName}-{ticks}.tsv");
File.WriteAllLines(deleteLog, deleteFiles);
log.Information($"Ready to delete {deleteFiles.Count} file(s)? See <{deleteLog}>");
for (int y = 0; y < int.MaxValue; y++)
{
log.Information("Press \"Y\" key to delete file(s) or close console to not delete files");
if (Console.ReadKey().Key == ConsoleKey.Y)
break;
}
log.Information(". . .");
foreach (string deleteFile in deleteFiles)
{
File.Delete(deleteFile);
checkFileName = $"{deleteFile}.id";
if (!File.Exists(checkFileName))
continue;
File.Delete(checkFileName);
}
for (int i = 1; i < 5; i++)
_ = Shared.Models.Stateless.Methods.IPath.DeleteEmptyDirectories(appSettings.CompareRootDirectory);
}
}

View File

@ -0,0 +1,31 @@
using System.Text.Json;
using System.Text.Json.Serialization;
namespace View_by_Distance.Delete.By.Relative.Models;
public class AppSettings
{
public string Company { init; get; }
public string CompareRootDirectory { init; get; }
public int MaxDegreeOfParallelism { init; get; }
public string OutputExtension { init; get; }
public string WorkingDirectoryName { init; get; }
[JsonConstructor]
public AppSettings(string company, string compareRootDirectory, int maxDegreeOfParallelism, string outputExtension, string workingDirectoryName)
{
Company = company;
CompareRootDirectory = compareRootDirectory;
MaxDegreeOfParallelism = maxDegreeOfParallelism;
OutputExtension = outputExtension;
WorkingDirectoryName = workingDirectoryName;
}
public override string ToString()
{
string result = JsonSerializer.Serialize(this, new JsonSerializerOptions() { WriteIndented = true });
return result;
}
}

View File

@ -0,0 +1,48 @@
using Microsoft.Extensions.Configuration;
using System.Text.Json;
namespace View_by_Distance.Delete.By.Relative.Models.Binder;
public class AppSettings
{
#nullable disable
public string Company { get; set; }
public string CompareRootDirectory { get; set; }
public int? MaxDegreeOfParallelism { get; set; }
public string OutputExtension { get; set; }
public string WorkingDirectoryName { get; set; }
#nullable restore
public override string ToString()
{
string result = JsonSerializer.Serialize(this, new JsonSerializerOptions() { WriteIndented = true });
return result;
}
private static Models.AppSettings Get(AppSettings? appSettings)
{
Models.AppSettings result;
if (appSettings?.MaxDegreeOfParallelism is null)
throw new NullReferenceException(nameof(appSettings.MaxDegreeOfParallelism));
result = new(
appSettings.Company,
appSettings.CompareRootDirectory,
appSettings.MaxDegreeOfParallelism.Value,
appSettings.OutputExtension,
appSettings.WorkingDirectoryName
);
return result;
}
public static Models.AppSettings Get(IConfigurationRoot configurationRoot)
{
Models.AppSettings result;
AppSettings? appSettings = configurationRoot.Get<AppSettings>();
result = Get(appSettings);
return result;
}
}

View File

@ -0,0 +1,10 @@
namespace View_by_Distance.Delete.By.Relative.Models.Stateless;
public static class SerilogExtensionMethods
{
internal static void Warn(this Serilog.ILogger log, string messageTemplate) => log.Warning(messageTemplate);
internal static void Info(this Serilog.ILogger log, string messageTemplate) => log.Information(messageTemplate);
}

View File

@ -0,0 +1,70 @@
using Microsoft.Extensions.Configuration;
using Phares.Shared;
using Serilog;
using System.Diagnostics;
using System.Reflection;
using View_by_Distance.Delete.By.Relative.Models;
using View_by_Distance.Shared.Models.Stateless.Methods;
namespace View_by_Distance.Delete.By.Relative;
public class Program
{
public static void Secondary(List<string> args)
{
LoggerConfiguration loggerConfiguration = new();
Assembly assembly = Assembly.GetExecutingAssembly();
bool debuggerWasAttachedAtLineZero = Debugger.IsAttached || assembly.Location.Contains(@"\bin\Debug");
IsEnvironment isEnvironment = new(processesCount: null, nullASPNetCoreEnvironmentIsDevelopment: debuggerWasAttachedAtLineZero, nullASPNetCoreEnvironmentIsProduction: !debuggerWasAttachedAtLineZero);
IConfigurationBuilder configurationBuilder = new ConfigurationBuilder()
.AddEnvironmentVariables()
.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
.AddJsonFile(isEnvironment.AppSettingsFileName, optional: false, reloadOnChange: true);
IConfigurationRoot configurationRoot = configurationBuilder.Build();
AppSettings appSettings = Models.Binder.AppSettings.Get(configurationRoot);
if (appSettings.MaxDegreeOfParallelism > Environment.ProcessorCount)
throw new Exception("MaxDegreeOfParallelism must be =< Environment.ProcessorCount!");
if (string.IsNullOrEmpty(appSettings.WorkingDirectoryName))
throw new Exception("Working directory name must have a value!");
string workingDirectory = IWorkingDirectory.GetWorkingDirectory(assembly.GetName().Name, appSettings.WorkingDirectoryName);
Environment.SetEnvironmentVariable(nameof(workingDirectory), workingDirectory);
_ = ConfigurationLoggerConfigurationExtensions.Configuration(loggerConfiguration.ReadFrom, configurationRoot);
Log.Logger = loggerConfiguration.CreateLogger();
ILogger log = Log.ForContext<Program>();
int silentIndex = args.IndexOf("s");
if (silentIndex > -1)
args.RemoveAt(silentIndex);
try
{
if (args is null)
throw new Exception("args is null!");
Shared.Models.Console console = new();
_ = new DeleteByRelative(args, isEnvironment, configurationRoot, appSettings, workingDirectory, silentIndex > -1, console);
}
catch (Exception ex)
{
log.Fatal(string.Concat(ex.Message, Environment.NewLine, ex.StackTrace));
}
finally
{
Log.CloseAndFlush();
}
if (silentIndex > -1)
log.Debug("Done. Bye");
else
{
log.Debug("Done. Press 'Enter' to end");
_ = Console.ReadLine();
}
}
public static void Main(string[] args)
{
if (args is not null)
Secondary(args.ToList());
else
Secondary(new List<string>());
}
}

View File

@ -0,0 +1,245 @@
{
"xCompareRootDirectory": "D:/Tmp/Phares/Not-Copy-Copy-All",
"xxCompareRootDirectory": "E:/www/Images - Results/C) Resize/2021-11-03/2256 x 1496/()",
"xxxCompareRootDirectory": "C:/Tmp/Phares/Compare/.Delete-Not-Copy-Copy-All",
"CompareRootDirectory": "C:/Tmp/Phares/Compare/Not-Copy-Copy-Duplicates",
"Logging": {
"LogLevel": {
"Log4netProvider": "Debug"
}
},
"MaxDegreeOfParallelism": 6,
"Serilog": {
"MinimumLevel": "Debug"
},
"Windows": {
"Configuration": {
"RootDirectory": "F:/Tmp/Phares/Compare/Images 2022-11-12 - c6aa7e8 - Results/A) Property/2022-11-12/{}",
"xRootDirectory": "F:/Tmp/Phares/Compare/Not-Copy-Copy-All - Results/A) Property/2022-11-12/{}",
"VerifyToSeason": [
". 2000",
". 2001",
". 2002",
". 2003",
". 2004",
". 2005",
". 2006",
". 2007",
". 2008",
". 2009",
". 2010",
". 2011",
". 2012",
". 2013",
". 2014",
". 2015",
". 2016",
". 2017",
". 2018",
". 2019",
". 2020",
". 2021",
". 2022",
". 2023",
". 2024",
". 2025",
". 2026",
". 2027",
". 2028",
". 2029",
"=2000.0 Winter",
"=2002.1 Spring",
"=2002.4 Winter",
"=2003.0 Winter",
"=2003.1 Spring",
"=2003.3 Fall",
"=2003.4 Winter",
"=2004.0 Winter",
"=2005.1 Spring",
"=2005.2 Summer",
"=2005.3 Fall",
"=2005.4 Winter",
"=2006.0 Winter",
"=2006.1 Spring",
"=2006.3 Fall",
"=2007.0 Winter",
"=2007.2 Summer Logan Michael",
"=2007.2 Summer",
"=2007.3 Fall Logan Michael",
"=2007.4 Winter Logan Michael",
"=2008.0 Winter Logan Michael",
"=2008.1 Spring Logan Michael",
"=2008.2 Summer Logan Michael",
"=2008.2 Summer",
"=2008.3 Fall Logan Michael",
"=2009.0 Winter Logan Michael",
"=2009.0 Winter",
"=2009.1 Spring Logan Michael",
"=2009.1 Spring",
"=2009.2 Summer Logan Michael",
"=2009.2 Summer",
"=2009.3 Fall Logan Michael",
"=2009.3 Fall",
"=2009.4 Winter Logan Michael",
"=2009.4 Winter",
"=2010.0 Winter Logan Michael",
"=2010.0 Winter",
"=2010.1 Spring Logan Michael",
"=2010.1 Spring",
"=2010.2 Summer",
"=2010.3 Fall Logan Michael",
"=2010.3 Fall",
"=2010.4 Winter",
"=2011.0 Winter",
"=2011.1 Spring",
"=2011.2 Summer",
"=2011.3 Fall",
"=2011.4 Winter",
"=2012.0 Winter Chelsea 2012",
"=2012.0 Winter Chelsea",
"=2012.0 Winter",
"=2012.1 Spring Chelsea",
"=2012.1 Spring",
"=2012.2 Summer Chelsea",
"=2012.2 Summer",
"=2012.3 Fall Chelsea",
"=2012.3 Fall",
"=2012.4 Winter Chelsea",
"=2012.4 Winter",
"=2013.0 Winter Chelsea 2013",
"=2013.0 Winter Chelsea",
"=2013.0 Winter",
"=2013.1 Spring",
"=2013.2 Summer Chelsea",
"=2013.2 Summer",
"=2013.3 Fall Chelsea",
"=2013.3 Fall",
"=2013.4 Winter",
"=2014.0 Winter",
"=2014.1 Spring",
"=2014.2 Summer",
"=2014.3 Fall",
"=2014.4 Winter",
"=2015.0 Winter",
"=2015.1 Spring",
"=2015.2 Summer",
"=2015.3 Fall",
"=2015.4 Winter",
"=2016.0 Winter",
"=2016.1 Spring",
"=2016.2 Summer",
"=2016.3 Fall",
"=2016.4 Winter",
"=2017.1 Spring",
"=2017.2 Summer",
"=2017.3 Fall",
"=2017.4 Winter",
"=2018.0 Winter",
"=2018.1 Spring",
"=2018.3 Fall",
"=2018.4 Winter",
"=2019.0 Winter",
"=2019.1 Spring",
"=2019.2 Summer",
"=2019.3 Fall",
"=2019.4 Winter",
"=2020.0 Winter",
"=2020.1 Spring",
"=2020.2 Summer",
"=2020.3 Fall",
"=2020.4 Winter",
"=2021.1 Spring",
"=2021.2 Summer",
"=2021.3 Fall",
"=2021.4 Winter",
"=2022.0 Winter",
"=2022.1 Spring",
"Anthem 2015",
"April 2010",
"April 2013",
"December 2006",
"December 2010",
"Fall 2005",
"Fall 2015",
"Fall 2016",
"Fall 2017",
"Fall 2018",
"Fall 2019",
"Fall 2020",
"Fall 2021",
"February 2010",
"January 2015",
"July 2010",
"June 2010",
"Kids 2005",
"March 2013",
"May 2010",
"May 2011",
"May 2013",
"October 2005",
"October 2014",
"Spring 2013",
"Spring 2014",
"Spring 2016",
"Spring 2018",
"Spring 2019",
"Spring 2020",
"Summer 2011",
"Summer 2012",
"Summer 2013",
"Summer 2014",
"Summer 2015",
"Summer 2016",
"Summer 2017",
"Summer 2018",
"Summer 2020",
"Summer 2021",
"Winter 2015",
"Winter 2016",
"Winter 2017",
"Winter 2018",
"Winter 2019-2020",
"Winter 2020",
"zzz =2005.0 Winter Tracy Pictures",
"zzz =2005.1 Spring Tracy Pictures",
"zzz =2005.2 Summer Tracy Pictures",
"zzz =2005.3 Fall Tracy Pictures",
"zzz =2005.4 Winter Tracy Pictures",
"zzz =2006.1 Spring Tracy Pictures",
"zzz =2007.0 Winter Tracy Pictures",
"zzz =2007.2 Summer Tracy Pictures",
"zzz =2008.0 Winter Tracy Pictures",
"zzz =2008.2 Summer Tracy Pictures",
"zzz =2009.0 Winter Tracy Pictures",
"zzz =2009.2 Summer Tracy Pictures",
"zzz =2009.3 Fall Tracy Pictures",
"zzz =2009.4 Winter Tracy Pictures",
"zzz =2010.0 Winter Tracy Pictures",
"zzz =2010.1 Spring Tracy Pictures",
"zzz =2010.2 Summer Tracy Pictures",
"zzz =2010.3 Fall Tracy Pictures",
"zzz =2011.0 Winter Tracy Pictures",
"zzz =2011.1 Spring Tracy Pictures",
"zzz =2011.2 Summer Tracy Pictures",
"zzz =2011.3 Fall Tracy Pictures",
"zzz =2011.4 Winter Tracy Pictures",
"zzz =2012.0 Winter Tracy Pictures",
"zzz =2012.1 Spring Tracy Pictures",
"zzz =2012.2 Summer Tracy Pictures",
"zzz =2012.3 Fall Tracy Pictures",
"zzz =2012.4 Winter Tracy Pictures",
"zzz =2013.0 Winter Tracy Pictures",
"zzz =2013.1 Spring Tracy Pictures",
"zzz =2013.2 Summer Tracy Pictures",
"zzz =2013.3 Fall Tracy Pictures",
"zzz =2013.4 Winter Tracy Pictures",
"zzz =2014.0 Winter Tracy Pictures",
"zzz =2014.1 Spring Tracy Pictures",
"zzz =2014.2 Summer Tracy Pictures",
"zzz =2014.3 Fall Tracy Pictures",
"zzz =2014.4 Winter Tracy Pictures",
"zzz =2015.0 Winter Tracy Pictures"
]
}
}
}

View File

@ -0,0 +1,117 @@
{
"CompareRootDirectory": "",
"Company": "Mike Phares",
"Linux": {},
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Log4netProvider": "Debug",
"Microsoft.Hosting.Lifetime": "Information"
}
},
"MaxDegreeOfParallelism": 6,
"Serilog": {
"Using": [
"Serilog.Sinks.Console",
"Serilog.Sinks.File"
],
"MinimumLevel": "Information",
"WriteTo": [
{
"Name": "Debug",
"Args": {
"outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz} [{Level}] ({SourceContext}.{MethodName}) ({InstanceId}) ({RemoteIpAddress}) {Message}{NewLine}{Exception}"
}
},
{
"Name": "Console",
"Args": {
"outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz} [{Level}] ({SourceContext}.{MethodName}) ({InstanceId}) ({RemoteIpAddress}) {Message}{NewLine}{Exception}"
}
},
{
"Name": "File",
"Args": {
"path": "%workingDirectory% - Log/log-.txt",
"outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz} [{Level}] ({SourceContext}.{MethodName}) ({InstanceId}) ({RemoteIpAddress}) {Message}{NewLine}{Exception}",
"rollingInterval": "Hour"
}
}
],
"Enrich": [
"FromLogContext",
"WithMachineName",
"WithThreadId"
],
"Properties": {
"Application": "Sample"
}
},
"WorkingDirectoryName": "PharesApps",
"Windows": {
"Configuration": {
"DateGroup": "2022-11-12",
"DiffPropertyDirectory": "",
"FileNameDirectorySeparator": ".Z.",
"ForcePropertyLastWriteTimeToCreationTime": false,
"MaxImagesInDirectoryForTopLevelFirstPass": 10,
"OutputExtension": ".jpg",
"Pattern": "[^ABCDEFGHIJKLMNOPQRSTUVWXYZbcdfghjklmnpqrstvwxyz0-9]",
"PopulatePropertyId": true,
"PropertiesChangedForProperty": false,
"ResultAllInOne": "_ _ _",
"ResultCollection": "[]",
"ResultContent": "()",
"ResultSingleton": "{}",
"RootDirectory": "C:/Tmp/Phares/Compare/Images 2022-11-12 - c6aa7e8",
"WriteBitmapDataBytes": false,
"IgnoreExtensions": [
".gif",
".GIF"
],
"ValidImageFormatExtensions": [
".bmp",
".BMP",
".gif",
".GIF",
".jpeg",
".JPEG",
".jpg",
".JPG",
".png",
".PNG",
".tiff",
".TIFF"
],
"ValidMetadataExtensions": [
".3gp",
".3GP",
".avi",
".AVI",
".bmp",
".BMP",
".gif",
".GIF",
".ico",
".ICO",
".jpeg",
".JPEG",
".jpg",
".JPG",
".m4v",
".M4V",
".mov",
".MOV",
".mp4",
".MP4",
".mta",
".MTA",
".png",
".PNG",
".tiff",
".TIFF"
]
}
}
}

View File

@ -39,7 +39,7 @@
<PackageReference Include="Serilog" Version="2.12.0" />
<PackageReference Include="ShellProgressBar" Version="5.2.0" />
<PackageReference Include="WindowsShortcutFactory" Version="1.1.0" />
<PackageReference Include="System.Text.Json" Version="7.0.0" />
<PackageReference Include="System.Text.Json" Version="7.0.1" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\FaceRecognitionDotNet\FaceRecognitionDotNet.csproj" />

View File

@ -135,7 +135,7 @@ public class MapLogicSupport : Shared.Models.Methods.IMapLogicSupport
}
foreach (Sorting sorting in collection)
{
if (face.Mapping is null || faceDistanceEncoding.NormalizedPixelPercentage is null)
if (face.Mapping is null || faceDistanceEncoding.NormalizedRectangle is null)
throw new NotSupportedException();
if (sorting.DaysDelta > rangeDaysDeltaTolerance)
{
@ -165,12 +165,10 @@ public class MapLogicSupport : Shared.Models.Methods.IMapLogicSupport
return results;
}
private static List<Sorting> GetSortingCollection(MapLogic mapLogic, List<FaceDistance> faceDistanceEncodings, int faceDistanceContainersLength, int i, FaceDistance faceDistanceEncoding)
private static List<Sorting> GetSortingCollection(MapLogic mapLogic, List<FaceDistance> faceDistanceEncodings, int i, FaceDistance faceDistanceEncoding)
{
List<Sorting> results;
List<FaceDistance> faceDistanceLengths = FaceRecognition.FaceDistances(faceDistanceEncodings, faceDistanceEncoding);
if (faceDistanceLengths.Count != faceDistanceContainersLength)
throw new NotSupportedException();
results = mapLogic.GetSortingCollection(i, faceDistanceEncoding, faceDistanceLengths);
return results;
}
@ -187,7 +185,7 @@ public class MapLogicSupport : Shared.Models.Methods.IMapLogicSupport
throw new NotSupportedException();
if (face.FaceDistance?.Encoding is not FaceRecognitionDotNet.FaceEncoding faceEncoding)
continue;
faceDistance = new(face.Mapping.MappingFromLocation.ConfidencePercent, faceEncoding, face.Mapping.MappingFromItem.Id, face.Mapping.MappingFromItem.IsWrongYear, face.Mapping.MappingFromItem.MinimumDateTime, face.Mapping.MappingFromLocation.NormalizedPixelPercentage);
faceDistance = new(face.Mapping.MappingFromLocation.ConfidencePercent, faceEncoding, face.Mapping.MappingFromItem.Id, face.Mapping.MappingFromItem.IsWrongYear, face.Mapping.MappingFromItem.MinimumDateTime, face.Mapping.MappingFromLocation.NormalizedRectangle);
faceDistanceContainer = new(face, faceDistance);
collection.Add(faceDistanceContainer);
}
@ -195,7 +193,7 @@ public class MapLogicSupport : Shared.Models.Methods.IMapLogicSupport
return results;
}
private static List<FaceDistance> GetFaceDistanceEncodings(FaceDistanceContainer[] faceDistanceContainers)
private static List<FaceDistance> GetFaceDistanceEncodings(FaceDistanceContainer[] faceDistanceContainers, List<FaceDistanceContainer> missingFaceDistanceContainers)
{
List<FaceDistance> faceDistanceEncodings = new();
foreach (FaceDistanceContainer faceDistanceContainer in faceDistanceContainers)
@ -204,30 +202,36 @@ public class MapLogicSupport : Shared.Models.Methods.IMapLogicSupport
continue;
faceDistanceEncodings.Add(faceDistanceContainer.FaceDistance);
}
foreach (FaceDistanceContainer faceDistanceContainer in missingFaceDistanceContainers)
{
if (faceDistanceContainer.FaceDistance.Encoding is null)
continue;
faceDistanceEncodings.Add(faceDistanceContainer.FaceDistance);
}
return faceDistanceEncodings;
}
public SortingContainer[] SetFaceMappingSortingCollectionThenGetSortingContainers(int maxDegreeOfParallelism, long ticks, MapLogic mapLogic, Face[] distinctFilteredFaces, int? useFiltersCounter)
public SortingContainer[] SetFaceMappingSortingCollectionThenGetSortingContainers(int maxDegreeOfParallelism, long ticks, MapLogic mapLogic, Face[] distinctFilteredFaces, List<FaceDistanceContainer> missingFaceDistanceContainers, int? useFiltersCounter)
{
SortingContainer[] results;
List<SortingContainer> collection = new();
int totalSeconds = (int)Math.Floor(new TimeSpan(DateTime.Now.Ticks - ticks).TotalSeconds);
ParallelOptions parallelOptions = new() { MaxDegreeOfParallelism = maxDegreeOfParallelism };
FaceDistanceContainer[] faceDistanceContainers = GetFaceDistanceContainers(distinctFilteredFaces);
List<FaceDistance> faceDistanceEncodings = GetFaceDistanceEncodings(faceDistanceContainers);
List<FaceDistance> faceDistanceEncodings = GetFaceDistanceEncodings(faceDistanceContainers, missingFaceDistanceContainers);
string message = $") {faceDistanceContainers.Length:000} Get Sorting Containers Then Set Face Mapping Sorting Collection - {totalSeconds} total second(s)";
ProgressBarOptions options = new() { ProgressCharacter = '─', ProgressBarOnBottom = true, DisableBottomPercentage = true };
using ProgressBar progressBar = new(faceDistanceContainers.Length, message, options);
_ = Parallel.For(0, faceDistanceContainers.Length, parallelOptions, (i, state) =>
{
progressBar.Tick();
Face face = faceDistanceContainers[i].Face;
if (face.Mapping is null)
throw new NotSupportedException();
FaceDistance faceDistanceEncoding = faceDistanceContainers[i].FaceDistance;
if (mapLogic.Used(faceDistanceEncoding))
return;
List<Sorting> sortingCollection = GetSortingCollection(mapLogic, faceDistanceEncodings, faceDistanceContainers.Length, i, faceDistanceEncoding);
Face face = faceDistanceContainers[i].Face;
if (face.Mapping is null)
throw new NotSupportedException();
List<Sorting> sortingCollection = GetSortingCollection(mapLogic, faceDistanceEncodings, i, faceDistanceEncoding);
if (!sortingCollection.Any())
return;
List<SortingContainer> sortingContainers = GetSortingContainers(face, faceDistanceEncoding, sortingCollection, useFiltersCounter);
@ -268,7 +272,7 @@ public class MapLogicSupport : Shared.Models.Methods.IMapLogicSupport
return;
progressBar.Tick();
faceEncoding = FaceRecognition.LoadFaceEncoding(face.FaceEncoding.RawEncoding);
FaceDistance faceDistance = new(face.Mapping.MappingFromLocation.ConfidencePercent, faceEncoding, face.Mapping.MappingFromItem.Id, face.Mapping.MappingFromItem.IsWrongYear, face.Mapping.MappingFromItem.MinimumDateTime, face.Mapping.MappingFromLocation.NormalizedPixelPercentage);
FaceDistance faceDistance = new(face.Mapping.MappingFromLocation.ConfidencePercent, faceEncoding, face.Mapping.MappingFromItem.Id, face.Mapping.MappingFromItem.IsWrongYear, face.Mapping.MappingFromItem.MinimumDateTime, face.Mapping.MappingFromLocation.NormalizedRectangle);
lock (face)
face.SetFaceDistance(faceDistance);
});
@ -325,7 +329,7 @@ public class MapLogicSupport : Shared.Models.Methods.IMapLogicSupport
}
}
public static Dictionary<int, Dictionary<int, Mapping>> GetIdToNormalizedPixelPercentageToFace(Mapping[] mappingCollection)
public static Dictionary<int, Dictionary<int, Mapping>> GetIdToNormalizedRectangleToFace(Mapping[] mappingCollection)
{
Dictionary<int, Dictionary<int, Mapping>> results = new();
Dictionary<int, Mapping> keyValuePairs;
@ -334,9 +338,9 @@ public class MapLogicSupport : Shared.Models.Methods.IMapLogicSupport
if (!results.ContainsKey(mapping.MappingFromItem.Id))
results.Add(mapping.MappingFromItem.Id, new());
keyValuePairs = results[mapping.MappingFromItem.Id];
if (keyValuePairs.ContainsKey(mapping.MappingFromLocation.NormalizedPixelPercentage))
throw new NotSupportedException();
keyValuePairs.Add(mapping.MappingFromLocation.NormalizedPixelPercentage, mapping);
if (keyValuePairs.ContainsKey(mapping.MappingFromLocation.NormalizedRectangle))
continue;
keyValuePairs.Add(mapping.MappingFromLocation.NormalizedRectangle, mapping);
}
return results;
}

View File

@ -1,3 +1,4 @@
using ShellProgressBar;
using System.Text.Json;
using View_by_Distance.Distance.Models.Stateless;
using View_by_Distance.FaceRecognitionDotNet;
@ -18,11 +19,10 @@ public partial class E_Distance
private readonly bool _DistanceMoveUnableToMatch;
private readonly List<string> _AllMappedFaceFiles;
private readonly double[] _RangeDistanceTolerance;
private readonly int _DistancePixelDistanceTolerance;
private readonly List<string> _AllMappedFaceFileNames;
private readonly List<string> _DuplicateMappedFaceFiles;
public E_Distance(bool distanceMoveUnableToMatch, int distancePixelDistanceTolerance, bool distanceRenameToMatch, int faceConfidencePercent, double[] rangeDistanceTolerance, double[] rangeFaceConfidence)
public E_Distance(bool distanceMoveUnableToMatch, bool distanceRenameToMatch, int faceConfidencePercent, double[] rangeDistanceTolerance, double[] rangeFaceConfidence)
{
_Debug = new();
_Moved = new();
@ -36,7 +36,6 @@ public partial class E_Distance
_FaceConfidencePercent = faceConfidencePercent;
_RangeDistanceTolerance = rangeDistanceTolerance;
_DistanceMoveUnableToMatch = distanceMoveUnableToMatch;
_DistancePixelDistanceTolerance = distancePixelDistanceTolerance;
}
private void MoveUnableToMatch(string eDistanceContentDirectory, string mappedFaceFile, string mappedFaceFileName)
@ -85,12 +84,12 @@ public partial class E_Distance
_Moved.Add(mappedFaceFile);
}
private FaceDistanceContainer[] GetFaceDistanceContainers(MappingFromItem mappingFromItem, Face[] filteredFaces)
private FaceDistanceContainer[] GetFaceDistanceContainers(MappingFromItem mappingFromItem, List<Face> filteredFaces)
{
FaceDistanceContainer[] results;
int confidencePercent;
int normalizedRectangle;
FaceDistance faceDistance;
int normalizedPixelPercentage;
FaceDistanceContainer faceDistanceContainer;
List<FaceDistanceContainer> collection = new();
foreach (Face face in filteredFaces)
@ -98,13 +97,13 @@ public partial class E_Distance
if (face.FaceEncoding is null || face.Location is null || face.OutputResolution is null)
throw new NotSupportedException();
confidencePercent = Shared.Models.Stateless.Methods.ILocation.GetConfidencePercent(_FaceConfidencePercent, _RangeFaceConfidence, face.Location.Confidence);
normalizedPixelPercentage = Shared.Models.Stateless.Methods.ILocation.GetNormalizedPixelPercentage(face.Location, Shared.Models.Stateless.ILocation.Digits, Shared.Models.Stateless.ILocation.Factor, face.OutputResolution);
normalizedRectangle = Shared.Models.Stateless.Methods.ILocation.GetNormalizedRectangle(face.Location, Shared.Models.Stateless.ILocation.Digits, face.OutputResolution);
if (face.FaceDistance?.Encoding is not null && face.FaceDistance.Encoding is FaceRecognitionDotNet.FaceEncoding faceEncoding)
faceDistance = new(confidencePercent, faceEncoding, mappingFromItem.Id, mappingFromItem.IsWrongYear, mappingFromItem.MinimumDateTime, normalizedPixelPercentage);
faceDistance = new(confidencePercent, faceEncoding, mappingFromItem.Id, mappingFromItem.IsWrongYear, mappingFromItem.MinimumDateTime, normalizedRectangle);
else
{
faceEncoding = FaceRecognition.LoadFaceEncoding(face.FaceEncoding.RawEncoding);
faceDistance = new(confidencePercent, faceEncoding, mappingFromItem.Id, mappingFromItem.IsWrongYear, mappingFromItem.MinimumDateTime, normalizedPixelPercentage);
faceDistance = new(confidencePercent, faceEncoding, mappingFromItem.Id, mappingFromItem.IsWrongYear, mappingFromItem.MinimumDateTime, normalizedRectangle);
lock (filteredFaces)
face.SetFaceDistance(faceDistance);
}
@ -127,27 +126,27 @@ public partial class E_Distance
return faceDistanceEncodings;
}
private List<(Face Face, double? Length)> GetValues(MappingFromItem mappingFromItem, Face[] filteredFaces, string json)
private List<(Face Face, double? Length)> GetValues(MappingFromItem mappingFromItem, Face[] faces, Shared.Models.FaceEncoding modelsFaceEncoding, int normalizedRectangle)
{
List<(Face Face, double? Length)> results = new();
Face face;
FaceDistance faceDistanceLength;
Shared.Models.FaceEncoding? modelsFaceEncoding = JsonSerializer.Deserialize<Shared.Models.FaceEncoding>(json);
if (modelsFaceEncoding is null)
throw new NotSupportedException();
List<Face> filteredFaces = FilterByIntersect(faces, normalizedRectangle);
if (filteredFaces.Any())
{
FaceRecognitionDotNet.FaceEncoding faceRecognitionDotNetFaceEncoding = FaceRecognition.LoadFaceEncoding(modelsFaceEncoding.RawEncoding);
FaceDistance faceDistanceEncoding = new(faceRecognitionDotNetFaceEncoding);
FaceDistanceContainer[] faceDistanceContainers = GetFaceDistanceContainers(mappingFromItem, filteredFaces);
int faceDistanceContainersLength = faceDistanceContainers.Length;
if (faceDistanceContainersLength != filteredFaces.Length)
if (faceDistanceContainersLength != filteredFaces.Count)
throw new NotSupportedException();
List<FaceDistance> faceDistanceEncodings = GetFaceDistanceEncodings(faceDistanceContainers);
if (faceDistanceEncodings.Count != filteredFaces.Length)
if (faceDistanceEncodings.Count != filteredFaces.Count)
throw new NotSupportedException();
List<FaceDistance> faceDistanceLengths = FaceRecognition.FaceDistances(faceDistanceEncodings, faceDistanceEncoding);
if (faceDistanceLengths.Count != faceDistanceContainersLength)
throw new NotSupportedException();
for (int i = 0; i < filteredFaces.Length; i++)
for (int i = 0; i < filteredFaces.Count; i++)
{
face = filteredFaces[i];
faceDistanceLength = faceDistanceLengths[i];
@ -155,94 +154,20 @@ public partial class E_Distance
throw new NotSupportedException();
results.Add(new(face, faceDistanceLength.Length.Value));
}
}
return results;
}
private (Face, double?)[] GetClosestFaceByDistanceIgnoringTolerance(MappingFromItem mappingFromItem, Face[] filteredFaces, string json)
private (Face, double?)[] GetClosestFaceByDistanceIgnoringTolerance(MappingFromItem mappingFromItem, int normalizedRectangle, Face[] filteredFaces, Shared.Models.FaceEncoding modelsFaceEncoding)
{
(Face, double?)[] results;
List<(Face Face, double? Length)> collection = GetValues(mappingFromItem, filteredFaces, json);
List<(Face Face, double? Length)> collection = GetValues(mappingFromItem, filteredFaces, modelsFaceEncoding, normalizedRectangle);
results = (from l in collection orderby l.Length select l).Take(1).ToArray();
(Face face, double? length) = results.First();
lock (_Debug)
(Face _, double? length) = results.First();
_Debug.Add(length);
return results;
}
private static (int?, int?) GetXY(int normalizedPixelPercentage, OutputResolution? outputResolution)
{
int? x;
int? y;
if (outputResolution is null)
{
x = null;
y = null;
}
else
{
string normalizedPixelPercentagePadded = Shared.Models.Stateless.Methods.ILocation.GetLeftPadded(Shared.Models.Stateless.ILocation.Digits, normalizedPixelPercentage);
(x, y) = Shared.Models.Stateless.Methods.ILocation.GetXY(Shared.Models.Stateless.ILocation.Digits, Shared.Models.Stateless.ILocation.Factor, outputResolution.Width, outputResolution.Height, normalizedPixelPercentagePadded);
}
return new(x, y);
}
private (Face, double?)[] GetClosestFaceByPixel(Face[] filteredFaces, int? x1, int? y1)
{
(Face, double?)[] results;
int? x2;
int? y2;
double distance;
int normalizedPixelPercentageLoop;
string normalizedPixelPercentagePadded;
List<(Face Face, double? Order)> collection = new();
if (x1 is null || y1 is null)
throw new NotSupportedException();
foreach (Face face in filteredFaces)
{
if (face.Location is null || face.OutputResolution is null)
throw new NotSupportedException();
normalizedPixelPercentageLoop = Shared.Models.Stateless.Methods.ILocation.GetNormalizedPixelPercentage(face.Location, Shared.Models.Stateless.ILocation.Digits, Shared.Models.Stateless.ILocation.Factor, face.OutputResolution);
normalizedPixelPercentagePadded = Shared.Models.Stateless.Methods.ILocation.GetLeftPadded(Shared.Models.Stateless.ILocation.Digits, normalizedPixelPercentageLoop);
(x2, y2) = Shared.Models.Stateless.Methods.ILocation.GetXY(Shared.Models.Stateless.ILocation.Digits, Shared.Models.Stateless.ILocation.Factor, face.OutputResolution.Width, face.OutputResolution.Height, normalizedPixelPercentagePadded);
if (x2 is null || y2 is null)
throw new NotSupportedException();
distance = Math.Sqrt(Math.Pow(x1.Value - x2.Value, 2) + Math.Pow(y1.Value - y2.Value, 2));
collection.Add(new(face, distance));
}
results = (from l in collection orderby l.Order where l.Order < _DistancePixelDistanceTolerance select l).Take(1).ToArray();
return results;
}
private (Face, double?)[] GetClosestFaceByPixel(Face[] filteredFaces, int normalizedPixelPercentage)
{
if (!filteredFaces.Any())
throw new NotSupportedException();
(Face, double?)[] results;
const int zero = 0;
OutputResolution? outputResolution = filteredFaces[zero].OutputResolution;
(int? x1, int? y1) = GetXY(normalizedPixelPercentage, outputResolution);
results = GetClosestFaceByPixel(filteredFaces, x1, y1);
return results;
}
private (Face, double?)[] GetClosestFaceByPixel(Face[] filteredFaces, string json)
{
if (!filteredFaces.Any())
throw new NotSupportedException();
(Face, double?)[] results;
const int zero = 0;
OutputResolution? outputResolution = filteredFaces[zero].OutputResolution;
if (outputResolution is null)
throw new NullReferenceException(nameof(outputResolution));
Location? location = JsonSerializer.Deserialize<Location>(json);
if (location is null)
throw new NullReferenceException(nameof(location));
int normalizedPixelPercentage = Shared.Models.Stateless.Methods.ILocation.GetNormalizedPixelPercentage(location, Shared.Models.Stateless.ILocation.Digits, Shared.Models.Stateless.ILocation.Factor, outputResolution);
(int? x1, int? y1) = GetXY(normalizedPixelPercentage, outputResolution);
results = GetClosestFaceByPixel(filteredFaces, x1, y1);
return results;
}
private static List<(Face, double?)> GetMatchingFacesByFaceEncoding(Face[] filteredFaces, string? json)
{
List<(Face, double?)> results = new();
@ -276,7 +201,7 @@ public partial class E_Distance
mappedFaceDirectory = Path.GetDirectoryName(mappedFaceFile);
if (mappedFaceDirectory is null)
throw new NotSupportedException();
deterministicHashCodeKey = Shared.Models.Stateless.Methods.IMapping.GetDeterministicHashCodeKey(mappingFromItem.Id, face.Location, Shared.Models.Stateless.ILocation.Digits, Shared.Models.Stateless.ILocation.Factor, face.OutputResolution);
deterministicHashCodeKey = Shared.Models.Stateless.Methods.IMapping.GetDeterministicHashCodeKey(mappingFromItem.Id, face.Location, Shared.Models.Stateless.ILocation.Digits, face.OutputResolution);
checkFile = Path.Combine(mappedFaceDirectory, $"{deterministicHashCodeKey}{mappingFromItem.ImageFileHolder.ExtensionLowered}{facesFileNameExtension}");
if (checkFile == mappedFaceFile)
continue;
@ -312,17 +237,44 @@ public partial class E_Distance
}
}
public void LookForMatchFacesAndPossiblyRename(string facesFileNameExtension, string? eDistanceContentDirectory, MappingFromItem mappingFromItem, List<Face> faces, List<(string MappedFaceFile, int normalizedPixelPercentage)> collection)
private static List<Face> FilterByIntersect(Face[] faces, int normalizedRectangle)
{
List<Face> results = new();
results.AddRange(faces);
// double? percent;
// System.Drawing.Rectangle checkRectangle;
// System.Drawing.Rectangle sourceRectangle;
// System.Drawing.Rectangle intersectRectangle;
// string npp = normalizedRectangle.ToString();
// foreach (Face face in faces)
// {
// if (face.Location is null || face.OutputResolution is null)
// continue;
// sourceRectangle = new(npp, npp, npp, npp);
// checkRectangle = new(face.Location.Left, face.Location.Top, face.Location.Right - face.Location.Left, face.Location.Bottom - face.Location.Top);
// intersectRectangle = System.Drawing.Rectangle.Intersect(sourceRectangle, checkRectangle);
// if (intersectRectangle.Width == 0 || intersectRectangle.Height == 0)
// continue;
// percent = (double)intersectRectangle.Width * intersectRectangle.Height / (checkRectangle.Width * checkRectangle.Height);
// if (percent < 0.000001)
// continue;
// results.Add(face);
// }
return results;
}
public void LookForMatchFacesAndPossiblyRename(string facesFileNameExtension, string? eDistanceContentDirectory, MappingFromItem mappingFromItem, List<Face> faces, List<(string MappedFaceFile, int normalizedRectangle)> collection)
{
string? json;
string[] matches;
FileInfo? fileInfo;
string mappedFaceFileName;
List<(Face, double?)> checkFaces = new();
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();
if (filteredFaces.Length != faces.Count)
checkFaces.Clear();
foreach ((string mappedFaceFile, int normalizedPixelPercentage) in collection)
foreach ((string mappedFaceFile, int normalizedRectangle) in collection)
{
if (!filteredFaces.Any())
break;
@ -343,19 +295,10 @@ public partial class E_Distance
if (checkFaces.Count != 1 && !string.IsNullOrEmpty(json))
{
checkFaces.Clear();
if (json is null)
modelsFaceEncoding = JsonSerializer.Deserialize<Shared.Models.FaceEncoding>(json);
if (modelsFaceEncoding is null)
throw new NotSupportedException();
checkFaces.AddRange(GetClosestFaceByDistanceIgnoringTolerance(mappingFromItem, filteredFaces, json));
}
if (checkFaces.Count != 1 && _DistancePixelDistanceTolerance > 0)
{
checkFaces.Clear();
json = Metadata.Models.Stateless.IMetadata.GetFaceLocation(mappedFaceFile);
if (json is not null)
checkFaces.AddRange(GetClosestFaceByPixel(filteredFaces, json));
else
checkFaces.AddRange(GetClosestFaceByPixel(filteredFaces, normalizedPixelPercentage));
throw new NotImplementedException("Without a tolerance this should not ever occur!");
checkFaces.AddRange(GetClosestFaceByDistanceIgnoringTolerance(mappingFromItem, normalizedRectangle, filteredFaces, modelsFaceEncoding));
}
if (!checkFaces.Any())
{
@ -415,4 +358,57 @@ public partial class E_Distance
_DuplicateMappedFaceFiles.Clear();
}
public List<FaceDistanceContainer> GetMissingFaceDistanceContainer(int maxDegreeOfParallelism, long ticks, string dFacesCollectionDirectory, Dictionary<int, Dictionary<int, PersonContainer[]>> missingIdThenNormalizedRectangleToPersonContainers)
{
List<FaceDistanceContainer> results = new();
string[] files;
List<Face>? faces;
int confidencePercent;
int normalizedRectangle;
bool? isWrongYear = null;
FaceDistance faceDistance;
List<(int id, string json)> collection = new();
FaceDistanceContainer faceDistanceContainer;
foreach (KeyValuePair<int, Dictionary<int, PersonContainer[]>> keyValuePair in missingIdThenNormalizedRectangleToPersonContainers)
{
files = Directory.GetFiles(dFacesCollectionDirectory, $"{keyValuePair.Key}*.json", SearchOption.TopDirectoryOnly);
if (files.Length != 1)
continue;
collection.Add(new(keyValuePair.Key, Shared.Models.Stateless.Methods.IFace.GetJson(files[0])));
}
int totalSeconds = (int)Math.Floor(new TimeSpan(DateTime.Now.Ticks - ticks).TotalSeconds);
ParallelOptions parallelOptions = new() { MaxDegreeOfParallelism = maxDegreeOfParallelism };
string message = $") {collection.Count:000} Setting missing distance containers - {totalSeconds} total second(s)";
ProgressBarOptions options = new() { ProgressCharacter = '─', ProgressBarOnBottom = true, DisableBottomPercentage = true };
using ProgressBar progressBar = new(collection.Count, message, options);
_ = Parallel.For(0, collection.Count, parallelOptions, (i, state) =>
{
progressBar.Tick();
int id = collection[i].id;
string json = collection[i].json;
faces = JsonSerializer.Deserialize<List<Face>>(json);
if (faces is null)
throw new NullReferenceException(nameof(faces));
foreach (Face face in faces)
{
if (face.FaceEncoding is null || face.Location is null || face.OutputResolution is null)
continue;
confidencePercent = Shared.Models.Stateless.Methods.ILocation.GetConfidencePercent(_FaceConfidencePercent, _RangeFaceConfidence, face.Location.Confidence);
normalizedRectangle = Shared.Models.Stateless.Methods.ILocation.GetNormalizedRectangle(face.Location, Shared.Models.Stateless.ILocation.Digits, face.OutputResolution);
if (face.FaceDistance?.Encoding is not null && face.FaceDistance.Encoding is FaceRecognitionDotNet.FaceEncoding faceEncoding)
faceDistance = new(confidencePercent, faceEncoding, id, isWrongYear, face.DateTime, normalizedRectangle);
else
{
faceEncoding = FaceRecognition.LoadFaceEncoding(face.FaceEncoding.RawEncoding);
faceDistance = new(confidencePercent, faceEncoding, id, isWrongYear, face.DateTime, normalizedRectangle);
face.SetFaceDistance(faceDistance);
}
faceDistanceContainer = new(face, faceDistance);
lock (results)
results.Add(faceDistanceContainer);
}
});
return results;
}
}

View File

@ -48,9 +48,12 @@ public partial class Form : System.Windows.Forms.Form
isEnvironment = new(processesCount: null, nullASPNetCoreEnvironmentIsDevelopment: debuggerWasAttachedAtLineZero, nullASPNetCoreEnvironmentIsProduction: !debuggerWasAttachedAtLineZero);
IConfigurationBuilder configurationBuilder = new ConfigurationBuilder()
.AddEnvironmentVariables()
.AddJsonFile(isEnvironment.AppSettingsFileName);
.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
.AddJsonFile(isEnvironment.AppSettingsFileName, optional: false, reloadOnChange: true);
configurationRoot = configurationBuilder.Build();
appSettings = Models.Binder.AppSettings.Get(configurationRoot);
if (string.IsNullOrEmpty(appSettings.WorkingDirectoryName))
throw new Exception("Working directory name must have a value!");
workingDirectory = IWorkingDirectory.GetWorkingDirectory(assembly.GetName().Name, appSettings.WorkingDirectoryName);
Environment.SetEnvironmentVariable(nameof(workingDirectory), workingDirectory);
_ = ConfigurationLoggerConfigurationExtensions.Configuration(loggerConfiguration.ReadFrom, configurationRoot);
@ -176,6 +179,7 @@ public partial class Form : System.Windows.Forms.Form
_ProgressBar.Step = 1;
bool isIgnoreExtension;
_ProgressBar.Value = 0;
bool skipOneAllAreNumbers;
DateTime? minimumDateTime;
_ProgressBar.Visible = true;
bool isValidImageFormatExtension;
@ -187,14 +191,18 @@ public partial class Form : System.Windows.Forms.Form
_ProgressBar.PerformStep();
fileHolder = new(file);
_Lines.Add(fileHolder.NameWithoutExtension);
if (fileHolder.ExtensionLowered == ".id" || fileHolder.DirectoryName is null)
continue;
if (files.Contains($"{fileHolder.FullName}.id"))
continue;
isValidImageFormatExtension = _Configuration.PropertyConfiguration.ValidImageFormatExtensions.Contains(fileHolder.ExtensionLowered);
isIgnoreExtension = isValidImageFormatExtension && _Configuration.IgnoreExtensions.Contains(fileHolder.ExtensionLowered);
if (fileHolder.CreationTime is null || fileHolder.Name.Contains(fileHolder.CreationTime.Value.ToString("yy")))
continue;
if (fileHolder.LastWriteTime is null || fileHolder.Name.Contains(fileHolder.LastWriteTime.Value.ToString("yy")))
continue;
if (fileHolder.NameWithoutExtension.Length == 1 || fileHolder.NameWithoutExtension[1..].All(l => char.IsNumber(l)))
if (fileHolder.NameWithoutExtension.Length > 4)
{
skipOneAllAreNumbers = fileHolder.NameWithoutExtension[1..].All(l => char.IsNumber(l));
if ((skipOneAllAreNumbers && fileHolder.NameWithoutExtension[0] == '-') || (skipOneAllAreNumbers && char.IsNumber(fileHolder.NameWithoutExtension[0])))
continue;
}
if (!isIgnoreExtension && isValidImageFormatExtension)
extraLargeBitmapThumbnail = null;
else
@ -210,16 +218,19 @@ public partial class Form : System.Windows.Forms.Form
}
if (fileHolder.DirectoryName is null)
continue;
dateTime = IProperty.GetDateTimeFromName(fileHolder);
if (dateTime is not null && fileHolder.Name.Contains(dateTime.Value.ToString("yy")))
continue;
(minimumDateTime, id, message) = IProperty.Get(fileHolder);
if (id is null)
continue;
if (minimumDateTime is not null && fileHolder.Name.Contains(minimumDateTime.Value.ToString("yy")))
dateTime = IProperty.GetDateTimeFromName(fileHolder);
if (dateTime is not null && minimumDateTime is not null && new TimeSpan(Math.Abs(minimumDateTime.Value.Ticks - dateTime.Value.Ticks)).TotalMinutes > 2)
{
checkFile = Path.Combine(fileHolder.DirectoryName, $"{dateTime.Value:yyyy-MM-dd}.{dateTime.Value.Ticks}{fileHolder.ExtensionLowered}");
if (checkFile == fileHolder.FullName || File.Exists(checkFile))
continue;
if (dateTime is not null && minimumDateTime is not null && minimumDateTime.Value != dateTime.Value)
File.Move(fileHolder.FullName, checkFile);
File.WriteAllText($"{checkFile}.id", $"{id.Value}{Environment.NewLine}{fileHolder.Name}");
continue;
}
if (extraLargeBitmapThumbnail is not null)
{
File.Delete(fileHolder.FullName);
@ -228,9 +239,10 @@ public partial class Form : System.Windows.Forms.Form
continue;
}
checkFile = Path.Combine(fileHolder.DirectoryName, $"{id.Value}{fileHolder.ExtensionLowered}");
if (File.Exists(checkFile))
if (checkFile == fileHolder.FullName || File.Exists(checkFile))
continue;
File.Move(fileHolder.FullName, checkFile);
File.WriteAllText($"{checkFile}.id", $"{id.Value}{Environment.NewLine}{fileHolder.Name}");
}
_ProgressBar.Visible = false;
}

View File

@ -190,7 +190,7 @@ public class Configuration
configuration = configurationSection.Get<Configuration>();
}
result = Get(configuration);
result.SetAndUpdate(propertyConfiguration, null, null, null, null);
result.SetAndUpdate(propertyConfiguration);
return result;
}

View File

@ -145,10 +145,10 @@ public class Configuration
return result;
}
public void SetAndUpdate(Property.Models.Configuration configuration, int? numberOfJitters, int? numberOfTimesToUpsample, string? modelName, string? predictorModelName)
public void SetAndUpdate(Property.Models.Configuration configuration)
{
_PropertyConfiguration = configuration;
_PropertyConfiguration.Update(numberOfJitters, numberOfTimesToUpsample, modelName, predictorModelName);
_PropertyConfiguration.Update();
}
}

View File

@ -0,0 +1 @@
[]

32
Duplicate-Search/.vscode/launch.json vendored Normal file
View File

@ -0,0 +1,32 @@
{
"version": "0.2.0",
"configurations": [
{
// Use IntelliSense to find out which attributes exist for C# debugging
// Use hover for the description of the existing attributes
// For further information visit https://github.com/OmniSharp/omnisharp-vscode/blob/master/debugger-launchjson.md
"name": ".NET Core Launch (console)",
"type": "coreclr",
"request": "launch",
"preLaunchTask": "build",
// If you have changed target frameworks, make sure to update the program path.
"program": "${workspaceFolder}/bin/Debug/net6.0/win-x64/Duplicate-Search.dll",
"args": [
"s"
],
"env": {
"ASPNETCORE_ENVIRONMENT": "Development",
},
"cwd": "${workspaceFolder}",
// For more information about the 'console' field, see https://aka.ms/VSCode-CS-LaunchJson-Console
"console": "externalTerminal",
"stopAtEntry": false
},
{
"name": ".NET Core Attach",
"type": "coreclr",
"request": "attach",
"processName": "Duplicate-Search"
}
]
}

14
Duplicate-Search/.vscode/settings.json vendored Normal file
View File

@ -0,0 +1,14 @@
{
"cSpell.words": [
"Barrick",
"bcdfghjklmnpqrstvwxyz",
"Beichler",
"Bohdi",
"Dlib",
"exif",
"nosj",
"Phares",
"Serilog",
"Vericruz"
]
}

42
Duplicate-Search/.vscode/tasks.json vendored Normal file
View File

@ -0,0 +1,42 @@
{
"version": "2.0.0",
"tasks": [
{
"label": "build",
"command": "dotnet",
"type": "process",
"args": [
"build",
"${workspaceFolder}/Duplicate-Search.csproj",
"/property:GenerateFullPaths=true",
"/consoleloggerparameters:NoSummary"
],
"problemMatcher": "$msCompile"
},
{
"label": "publish",
"command": "dotnet",
"type": "process",
"args": [
"publish",
"${workspaceFolder}/Duplicate-Search.csproj",
"/property:GenerateFullPaths=true",
"/consoleloggerparameters:NoSummary"
],
"problemMatcher": "$msCompile"
},
{
"label": "watch",
"command": "dotnet",
"type": "process",
"args": [
"watch",
"run",
"${workspaceFolder}/Duplicate-Search.csproj",
"/property:GenerateFullPaths=true",
"/consoleloggerparameters:NoSummary"
],
"problemMatcher": "$msCompile"
}
]
}

View File

@ -0,0 +1,62 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<ImplicitUsings>enable</ImplicitUsings>
<LangVersion>10.0</LangVersion>
<Nullable>enable</Nullable>
<OutputType>Exe</OutputType>
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
<TargetFramework>net7.0</TargetFramework>
</PropertyGroup>
<PropertyGroup>
<PackageId>Phares.View.by.Distance.Duplicate-Search</PackageId>
<GeneratePackageOnBuild>false</GeneratePackageOnBuild>
<Version>6.0.100.1</Version>
<Authors>Mike Phares</Authors>
<Company>Phares</Company>
<IncludeSymbols>true</IncludeSymbols>
<SymbolPackageFormat>snupkg</SymbolPackageFormat>
</PropertyGroup>
<PropertyGroup>
<IsWindows Condition="'$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::Windows)))' == 'true'">true</IsWindows>
<IsOSX Condition="'$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::OSX)))' == 'true'">true</IsOSX>
<IsLinux Condition="'$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::Linux)))' == 'true'">true</IsLinux>
</PropertyGroup>
<PropertyGroup Condition="'$(IsWindows)'=='true'">
<DefineConstants>Windows</DefineConstants>
</PropertyGroup>
<PropertyGroup Condition="'$(IsOSX)'=='true'">
<DefineConstants>OSX</DefineConstants>
</PropertyGroup>
<PropertyGroup Condition="'$(IsLinux)'=='true'">
<DefineConstants>Linux</DefineConstants>
</PropertyGroup>
<ItemGroup Condition="'$(RuntimeIdentifier)' == 'browser-wasm'">
<SupportedPlatform Include="browser" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Hosting" Version="7.0.0" />
<PackageReference Include="Microsoft.AspNetCore.Cryptography.KeyDerivation" Version="7.0.1" />
<PackageReference Include="Microsoft.Extensions.Identity.Core" Version="7.0.1" />
<PackageReference Include="Microsoft.Extensions.Options" Version="7.0.0" />
<PackageReference Include="Serilog.Settings.Configuration" Version="3.4.0" />
<PackageReference Include="Serilog.Sinks.Console" Version="4.1.0" />
<PackageReference Include="Serilog.Sinks.File" Version="5.0.0" />
<PackageReference Include="Serilog" Version="2.12.0" />
<PackageReference Include="ShellProgressBar" Version="5.2.0" />
<PackageReference Include="WindowsShortcutFactory" Version="1.1.0" />
<PackageReference Include="System.Drawing.Common" Version="7.0.0" />
<PackageReference Include="System.Text.Json" Version="7.0.1" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Property\Property.csproj" />
<ProjectReference Include="..\Shared\View-by-Distance.Shared.csproj" />
</ItemGroup>
<ItemGroup>
<None Include="appsettings.Development.json">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Include="appsettings.json">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
</ItemGroup>
</Project>

View File

@ -0,0 +1,255 @@
using Microsoft.Extensions.Configuration;
using Phares.Shared;
using Serilog;
using ShellProgressBar;
using System.Text;
using System.Text.Json;
using View_by_Distance.Duplicate.Search.Models;
using View_by_Distance.Property.Models;
using View_by_Distance.Shared.Models;
using View_by_Distance.Shared.Models.Methods;
namespace View_by_Distance.Duplicate.Search;
public class DuplicateSearch
{
public DuplicateSearch(List<string> args, IsEnvironment isEnvironment, IConfigurationRoot configurationRoot, AppSettings appSettings, string workingDirectory, bool isSilent, IConsole console)
{
if (isSilent)
{ }
if (console is null)
{ }
string searchPattern = "*";
long ticks = DateTime.Now.Ticks;
ILogger? log = Log.ForContext<DuplicateSearch>();
Configuration configuration = Property.Models.Binder.Configuration.Get(isEnvironment, configurationRoot);
configuration.Update();
log.Information(configuration.RootDirectory);
if (appSettings.IndexOnly)
WriteIndexData(ticks, configuration, searchPattern);
else
{
Configuration.Verify(configuration, requireExist: false);
string argZero = args.Count > 0 ? Path.GetFullPath(args[0]) : Path.GetFullPath(configuration.RootDirectory);
bool argZeroIsConfigurationRootDirectory = configuration.RootDirectory == argZero;
Container[] containers = GetContainers(appSettings, ticks, argZero, configuration, argZeroIsConfigurationRootDirectory);
string destinationRoot = Property.Models.Stateless.IResult.GetResultsGroupDirectory(configuration, "Z) Moved");
List<int> preloadIds = GetPreloadIds(destinationRoot);
Dictionary<int, List<MappingFromItem?>> idToCollection = GetIdToCollection(appSettings, argZero, configuration, argZeroIsConfigurationRootDirectory, containers, destinationRoot, preloadIds);
int duplicates = (from l in idToCollection where l.Value.Count > 1 select 1).Sum();
if (duplicates == 0)
log.Information($"Found {duplicates} duplicate file(s)");
else
QuestionMove(ticks, log, destinationRoot, idToCollection, duplicates);
}
}
private static void WriteIndexData(long ticks, Configuration configuration, string searchPattern)
{
string? alongSideDirectory;
string directoryName = Path.GetFileName(configuration.RootDirectory);
if (Path.GetPathRoot(configuration.RootDirectory) == configuration.RootDirectory)
alongSideDirectory = configuration.RootDirectory;
else
alongSideDirectory = Path.GetDirectoryName(configuration.RootDirectory);
if (alongSideDirectory is null)
throw new NullReferenceException(nameof(alongSideDirectory));
IEnumerable<(string, string[])> files = Shared.Models.Stateless.Methods.IFileHolder.GetFiles(configuration.RootDirectory, searchPattern);
List<FileHolder> fileHolders = Shared.Models.Stateless.Methods.IFileHolder.GetFileHolders(files.ToArray());
File.WriteAllLines(Path.Combine(alongSideDirectory, $"{directoryName}-{ticks}.tsv"), fileHolders.Select(l => l.FullName));
string json = JsonSerializer.Serialize(fileHolders);
File.WriteAllText(Path.Combine(alongSideDirectory, $"{directoryName}-{ticks}.json"), json);
}
private static void Move(ILogger log, long ticks, string destinationRoot, List<(FileHolder ImageFileHolder, string Destination)> collection)
{
StringBuilder stringBuilder = new();
foreach ((FileHolder fileHolder, string destination) in collection)
{
_ = stringBuilder.AppendLine(fileHolder.FullName);
_ = stringBuilder.AppendLine(destination);
}
_ = Shared.Models.Stateless.Methods.IPath.WriteAllText(Path.Combine(destinationRoot, $"{ticks}file(s).lsv"), stringBuilder.ToString(), updateDateWhenMatches: false, compareBeforeWrite: true, updateToWhenMatches: null);
log.Information($"Ready to move {collection.Count} file(s)?");
for (int y = 0; y < int.MaxValue; y++)
{
log.Information("Press \"Y\" key to move file(s) or close console to not move files");
if (System.Console.ReadKey().Key == ConsoleKey.Y)
break;
}
log.Information(". . .");
foreach ((FileHolder fileHolder, string destination) in collection)
{
try
{ File.Move(fileHolder.FullName, destination); }
catch (Exception exception)
{ log.Error(exception, $"Failed to move <{fileHolder.FullName}>"); }
}
log.Information($"{collection.Count} file(s) moved");
for (int y = 0; y < int.MaxValue; y++)
{
log.Information("Press \"Y\" key to move file(s) back or close console to leave them moved");
if (System.Console.ReadKey().Key != ConsoleKey.Y)
continue;
log.Information(". . .");
foreach ((FileHolder fileHolder, string destination) in collection)
{
if (!File.Exists(destination))
continue;
if (File.Exists(fileHolder.FullName))
continue;
try
{ File.Move(destination, fileHolder.FullName); }
catch (Exception exception)
{ log.Error(exception, $"Failed to move <{destination}>"); }
}
}
log.Information(". . .");
}
private static void QuestionMove(long ticks, ILogger log, string destinationRoot, Dictionary<int, List<MappingFromItem?>> idToCollection, int duplicates)
{
int[] ids = (from l in idToCollection orderby l.Key where l.Value.Any(m => m is not null) select l.Key).ToArray();
_ = Shared.Models.Stateless.Methods.IPath.WriteAllText(Path.Combine(destinationRoot, $"{ticks}-id(s).lsv"), string.Join(Environment.NewLine, ids), updateDateWhenMatches: false, compareBeforeWrite: true, updateToWhenMatches: null);
string json = JsonSerializer.Serialize(idToCollection, new JsonSerializerOptions { WriteIndented = true });
_ = Shared.Models.Stateless.Methods.IPath.WriteAllText(Path.Combine(destinationRoot, $"{ticks}.json"), json, updateDateWhenMatches: false, compareBeforeWrite: true, updateToWhenMatches: null);
log.Information($"Found {duplicates} duplicate file(s)");
for (int y = 0; y < int.MaxValue; y++)
{
log.Information("Press \"Y\" key to continue or close console to leave them moved");
if (System.Console.ReadKey().Key != ConsoleKey.Y)
continue;
log.Information(". . .");
List<(FileHolder ImageFileHolder, string Destination)> collection = GetCollectionAndCreateDirectories(idToCollection);
Move(log, ticks, destinationRoot, collection);
}
}
private static Container[] GetContainers(AppSettings appSettings, long ticks, string argZero, Configuration configuration, bool argZeroIsConfigurationRootDirectory)
{
int j;
int f;
int t;
Container[] containers;
int totalSeconds = (int)Math.Floor(new TimeSpan(DateTime.Now.Ticks - ticks).TotalSeconds);
string message = $") Building Container(s) - {totalSeconds} total second(s)";
A_Property propertyLogic = new(appSettings.MaxDegreeOfParallelism, configuration, appSettings.OutputExtension, appSettings.Reverse);
ProgressBarOptions options = new() { ProgressCharacter = '─', ProgressBarOnBottom = true, DisableBottomPercentage = true };
using (ProgressBar progressBar = new(1, message, options))
{
progressBar.Tick();
(j, f, t, containers) = Property.Models.Stateless.Container.GetContainers(configuration, propertyLogic);
}
if (appSettings.SortContainers)
containers = Shared.Models.Stateless.Methods.IContainer.SortContainers(configuration, appSettings.IgnoreRelativePaths, argZeroIsConfigurationRootDirectory, argZero, containers);
return containers;
}
private static Dictionary<int, List<MappingFromItem?>> GetIdToCollection(AppSettings appSettings, string argZero, Configuration configuration, bool argZeroIsConfigurationRootDirectory, Container[] containers, string destinationRoot, List<int> preloadIds)
{
Dictionary<int, List<MappingFromItem?>> results = new();
string directory;
const int zero = 0;
Item[] filteredItems;
bool isIgnoreRelativePath;
FileHolder resizedFileHolder;
DateTime[] containerDateTimes;
MappingFromItem? mappingFromItem;
List<MappingFromItem?>? collection;
const string duplicates = "-Duplicate(s)";
if (containers.Any())
{
foreach (int id in preloadIds)
results.Add(id, new() { null });
}
foreach (Container container in containers)
{
if (!container.Items.Any())
continue;
if (!argZeroIsConfigurationRootDirectory && !container.SourceDirectory.StartsWith(argZero))
continue;
filteredItems = Shared.Models.Stateless.Methods.IContainer.GetFilterItems(configuration, container);
if (!filteredItems.Any())
continue;
isIgnoreRelativePath = appSettings.IgnoreRelativePaths.Any(l => container.SourceDirectory.Contains(l)) && Shared.Models.Stateless.Methods.IContainer.IsIgnoreRelativePath(configuration, appSettings.IgnoreRelativePaths, container.SourceDirectory);
containerDateTimes = Shared.Models.Stateless.Methods.IContainer.GetContainerDateTimes(filteredItems);
foreach (Item item in filteredItems)
{
if (item.Property?.Id is null)
{
if (int.TryParse(item.ImageFileHolder.NameWithoutExtension, out int id))
continue;
continue;
}
if (!results.TryGetValue(item.Property.Id.Value, out collection))
results.Add(item.Property.Id.Value, new());
if (collection is null && !results.TryGetValue(item.Property.Id.Value, out collection))
continue;
if (collection.Count == 0)
directory = $"0{duplicates}";
else
directory = $"{collection.Count + 1}{duplicates}";
if (collection.Count == 1)
{
mappingFromItem = collection[zero];
if (mappingFromItem is not null)
{
resizedFileHolder = new(mappingFromItem.ResizedFileHolder.FullName.Replace($"0{duplicates}", $"1{duplicates}"));
collection[0] = new(mappingFromItem.ContainerDateTimes, mappingFromItem.Id, mappingFromItem.ImageFileHolder, mappingFromItem.IsWrongYear, mappingFromItem.MinimumDateTime, mappingFromItem.RelativePath, resizedFileHolder);
}
}
resizedFileHolder = new(string.Concat(Path.Combine(destinationRoot, directory), item.RelativePath));
mappingFromItem = Shared.Models.Stateless.Methods.IMappingFromItem.GetMappingFromItem(containerDateTimes, item, resizedFileHolder);
collection.Add(mappingFromItem);
}
}
return results;
}
private static List<(FileHolder ImageFileHolder, string Destination)> GetCollectionAndCreateDirectories(Dictionary<int, List<MappingFromItem?>> idToCollection)
{
List<(FileHolder ImageFileHolder, string Destination)> results = new();
List<string> collection = new();
foreach (KeyValuePair<int, List<MappingFromItem?>> keyValuePair in idToCollection)
{
foreach (MappingFromItem? mappingFromItem in keyValuePair.Value)
{
if (mappingFromItem?.ResizedFileHolder.DirectoryName is null)
continue;
if (!mappingFromItem.ImageFileHolder.Exists || mappingFromItem.ResizedFileHolder.Exists)
continue;
collection.Add(mappingFromItem.ResizedFileHolder.DirectoryName);
results.Add(new(mappingFromItem.ImageFileHolder, mappingFromItem.ResizedFileHolder.FullName));
}
}
foreach (string directory in collection.Distinct())
{
if (!Directory.Exists(directory))
_ = Directory.CreateDirectory(directory);
}
return results;
}
private static List<int> GetPreloadIds(string destinationRoot)
{
List<int> results = new();
string[] lines;
string preloadDirectory = Path.Combine(destinationRoot, "Preload");
if (!Directory.Exists(preloadDirectory))
_ = Directory.CreateDirectory(preloadDirectory);
string[] files = Directory.GetFiles(preloadDirectory, "*.lsv", SearchOption.TopDirectoryOnly);
foreach (string file in files)
{
lines = File.ReadAllLines(file);
foreach (string line in lines)
{
if (string.IsNullOrEmpty(line) || !int.TryParse(line, out int id) || id == 0)
continue;
results.Add(id);
}
}
return results;
}
}

View File

@ -0,0 +1,37 @@
using System.Text.Json;
using System.Text.Json.Serialization;
namespace View_by_Distance.Duplicate.Search.Models;
public class AppSettings
{
public string Company { init; get; }
public bool IndexOnly { init; get; }
public string[] IgnoreRelativePaths { init; get; }
public int MaxDegreeOfParallelism { init; get; }
public string OutputExtension { init; get; }
public bool SortContainers { init; get; }
public bool Reverse { init; get; }
public string WorkingDirectoryName { init; get; }
[JsonConstructor]
public AppSettings(string company, bool indexOnly, string[] ignoreRelativePaths, int maxDegreeOfParallelism, string outputExtension, bool sortContainers, bool reverse, string workingDirectoryName)
{
Company = company;
IndexOnly = indexOnly;
IgnoreRelativePaths = ignoreRelativePaths;
MaxDegreeOfParallelism = maxDegreeOfParallelism;
OutputExtension = outputExtension;
SortContainers = sortContainers;
Reverse = reverse;
WorkingDirectoryName = workingDirectoryName;
}
public override string ToString()
{
string result = JsonSerializer.Serialize(this, new JsonSerializerOptions() { WriteIndented = true });
return result;
}
}

View File

@ -0,0 +1,62 @@
using Microsoft.Extensions.Configuration;
using System.Text.Json;
namespace View_by_Distance.Duplicate.Search.Models.Binder;
public class AppSettings
{
#nullable disable
public string Company { get; set; }
public bool? IndexOnly { get; set; }
public string[] IgnoreRelativePaths { get; set; }
public int? MaxDegreeOfParallelism { get; set; }
public string OutputExtension { get; set; }
public bool? SortContainers { get; set; }
public bool? Reverse { get; set; }
public string WorkingDirectoryName { get; set; }
#nullable restore
public override string ToString()
{
string result = JsonSerializer.Serialize(this, new JsonSerializerOptions() { WriteIndented = true });
return result;
}
private static Models.AppSettings Get(AppSettings? appSettings)
{
Models.AppSettings result;
if (appSettings?.IndexOnly is null)
throw new NullReferenceException(nameof(appSettings.IndexOnly));
if (appSettings?.IgnoreRelativePaths is null)
throw new NullReferenceException(nameof(appSettings.IgnoreRelativePaths));
if (appSettings?.MaxDegreeOfParallelism is null)
throw new NullReferenceException(nameof(appSettings.MaxDegreeOfParallelism));
if (appSettings?.SortContainers is null)
throw new NullReferenceException(nameof(appSettings.SortContainers));
if (appSettings?.Reverse is null)
throw new NullReferenceException(nameof(appSettings.Reverse));
result = new(
appSettings.Company,
appSettings.IndexOnly.Value,
appSettings.IgnoreRelativePaths,
appSettings.MaxDegreeOfParallelism.Value,
appSettings.OutputExtension,
appSettings.SortContainers.Value,
appSettings.Reverse.Value,
appSettings.WorkingDirectoryName
);
return result;
}
public static Models.AppSettings Get(IConfigurationRoot configurationRoot)
{
Models.AppSettings result;
AppSettings? appSettings = configurationRoot.Get<AppSettings>();
result = Get(appSettings);
return result;
}
}

View File

@ -0,0 +1,10 @@
namespace View_by_Distance.Duplicate.Search.Models.Stateless;
public static class SerilogExtensionMethods
{
internal static void Warn(this Serilog.ILogger log, string messageTemplate) => log.Warning(messageTemplate);
internal static void Info(this Serilog.ILogger log, string messageTemplate) => log.Information(messageTemplate);
}

View File

@ -0,0 +1,70 @@
using Microsoft.Extensions.Configuration;
using Phares.Shared;
using Serilog;
using System.Diagnostics;
using System.Reflection;
using View_by_Distance.Duplicate.Search.Models;
using View_by_Distance.Shared.Models.Stateless.Methods;
namespace View_by_Distance.Duplicate.Search;
public class Program
{
public static void Secondary(List<string> args)
{
LoggerConfiguration loggerConfiguration = new();
Assembly assembly = Assembly.GetExecutingAssembly();
bool debuggerWasAttachedAtLineZero = Debugger.IsAttached || assembly.Location.Contains(@"\bin\Debug");
IsEnvironment isEnvironment = new(processesCount: null, nullASPNetCoreEnvironmentIsDevelopment: debuggerWasAttachedAtLineZero, nullASPNetCoreEnvironmentIsProduction: !debuggerWasAttachedAtLineZero);
IConfigurationBuilder configurationBuilder = new ConfigurationBuilder()
.AddEnvironmentVariables()
.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
.AddJsonFile(isEnvironment.AppSettingsFileName, optional: false, reloadOnChange: true);
IConfigurationRoot configurationRoot = configurationBuilder.Build();
AppSettings appSettings = Models.Binder.AppSettings.Get(configurationRoot);
if (appSettings.MaxDegreeOfParallelism > Environment.ProcessorCount)
throw new Exception("MaxDegreeOfParallelism must be =< Environment.ProcessorCount!");
if (string.IsNullOrEmpty(appSettings.WorkingDirectoryName))
throw new Exception("Working directory name must have a value!");
string workingDirectory = IWorkingDirectory.GetWorkingDirectory(assembly.GetName().Name, appSettings.WorkingDirectoryName);
Environment.SetEnvironmentVariable(nameof(workingDirectory), workingDirectory);
_ = ConfigurationLoggerConfigurationExtensions.Configuration(loggerConfiguration.ReadFrom, configurationRoot);
Log.Logger = loggerConfiguration.CreateLogger();
ILogger log = Log.ForContext<Program>();
int silentIndex = args.IndexOf("s");
if (silentIndex > -1)
args.RemoveAt(silentIndex);
try
{
if (args is null)
throw new Exception("args is null!");
Shared.Models.Console console = new();
_ = new DuplicateSearch(args, isEnvironment, configurationRoot, appSettings, workingDirectory, silentIndex > -1, console);
}
catch (Exception ex)
{
log.Fatal(string.Concat(ex.Message, Environment.NewLine, ex.StackTrace));
}
finally
{
Log.CloseAndFlush();
}
if (silentIndex > -1)
log.Debug("Done. Bye");
else
{
log.Debug("Done. Press 'Enter' to end");
_ = Console.ReadLine();
}
}
public static void Main(string[] args)
{
if (args is not null)
Secondary(args.ToList());
else
Secondary(new List<string>());
}
}

View File

@ -0,0 +1,356 @@
{
"IndexOnly": false,
"Logging": {
"LogLevel": {
"Log4netProvider": "Debug"
}
},
"MaxDegreeOfParallelism": 6,
"Serilog": {
"MinimumLevel": "Debug"
},
"SortContainers": false,
"IgnoreRelativePaths": [
"3757 W Whitman 2017",
"501 Playful Meadows 2006",
"501 Playful Meadows 2007",
"501 Playful Meadows 2008",
"501 Playful Meadows 2009",
"501 Playful Meadows 2010",
"501 Playful Meadows 2013",
"501 Playful Meadows 2015",
"6309 Evesham 2003",
"6309 Evesham 2004",
"Crystal's Wedding 2003",
"Danny's Wedding 2009",
"Door images 2019",
"Family Pictures 2006",
"Family Pictures 2007",
"Family Pictures 2011",
"Family Pictures 2013",
"GrandPrix 2004",
"Kids School Pictures 2004",
"Kristy 2002",
"Kristy Parents Wedding 2005",
"Logan Ultrasound 2007",
"Mandy's Dogs 2008",
"Motorcycles 2010",
"Motorcycles 2013",
"Motorcycles 2014",
"Phares Slides",
"Portrait Innovations April 2008",
"Portrait Innovations December 2007",
"Portrait Innovations June 2008",
"Portrait Innovations March 2012",
"The guys house 2000",
"Tracy Pictures 2005",
"Tracy Pictures 2006",
"Tracy Pictures 2007",
"Tracy Pictures 2008",
"Tracy Pictures 2009",
"Tracy Pictures 2010",
"Tracy Pictures 2011",
"Tracy Pictures 2012",
"Tracy Pictures 2013 Jan-July",
"Tracy Pictures 2013 July- Dec",
"Tracy Pictures 2014",
"Tracy Pictures 2015",
"Tracy Took The Kids 2006",
"Tracy's Bday 2012",
"Tracy's Wedding 2002",
"Trip to Colorado 10 2002",
"Trip to Colorado June 2002",
"Tub 2002",
"Vericruz 2011",
"zzz =2005.1 Spring Tracy Pictures",
"zzz =2005.2 Summer Tracy Pictures",
"zzz =2005.3 Fall Tracy Pictures",
"zzz =2005.4 Winter Tracy Pictures",
"zzz =2006.1 Spring Tracy Pictures",
"zzz =2007.0 Winter Tracy Pictures",
"zzz =2007.2 Summer Tracy Pictures",
"zzz =2008.2 Summer Tracy Pictures",
"zzz =2009.0 Winter Tracy Pictures",
"zzz =2009.2 Summer Tracy Pictures",
"zzz =2009.3 Fall Tracy Pictures",
"zzz =2009.4 Winter Tracy Pictures",
"zzz =2010.0 Winter Tracy Pictures",
"zzz =2010.1 Spring Tracy Pictures",
"zzz =2010.2 Summer Tracy Pictures",
"zzz =2010.3 Fall Tracy Pictures",
"zzz =2011.0 Winter Tracy Pictures",
"zzz =2011.1 Spring Tracy Pictures",
"zzz =2011.2 Summer Tracy Pictures",
"zzz =2011.3 Fall Tracy Pictures",
"zzz =2011.4 Winter Tracy Pictures",
"zzz =2012.0 Winter Tracy Pictures",
"zzz =2012.1 Spring Tracy Pictures",
"zzz =2012.2 Summer Tracy Pictures",
"zzz =2012.3 Fall Tracy Pictures",
"zzz =2012.4 Winter Tracy Pictures",
"zzz =2013.0 Winter Tracy Pictures",
"zzz =2013.1 Spring Tracy Pictures",
"zzz =2013.2 Summer Tracy Pictures",
"zzz =2013.3 Fall Tracy Pictures",
"zzz =2013.4 Winter Tracy Pictures",
"zzz =2014.0 Winter Tracy Pictures",
"zzz =2014.1 Spring Tracy Pictures",
"zzz =2014.2 Summer Tracy Pictures",
"zzz =2014.3 Fall Tracy Pictures",
"zzz =2014.4 Winter Tracy Pictures",
"zzz =2015.0 Winter Tracy Pictures",
"zzz Family Pictures",
"zzz Family Pictures",
"zzz Family Pictures",
"zzz Family Pictures",
"zzz GrandPrix",
"zzz Motorcycles",
"zzz Motorcycles",
"zzz Motorcycles",
"zzz Parents Yard",
"zzz Phares Family Pictures",
"zzz Phares Slides ####",
"zzz Portrait Innovations April",
"zzz Portrait Innovations Files",
"zzz Portrait Innovations June",
"zzz Portrait Innovations March",
"zzz Rex Memorial ####",
"zzz Scanned Grandma's Quilt ####",
"zzz Scanned Pictures Of Kids ####",
"zzz Scanned Prints ####",
"zzz Slide in Name Order Originals (622) ####",
"zzz Tub",
"zzz Vericruz"
],
"Windows": {
"Configuration": {
"xRootDirectory": "F:/Tmp/Phares/Compare/Images 2022-11-12 - c6aa7e8",
"xxRootDirectory": "F:/Tmp/Phares/Compare/Not-Copy-Copy-All",
"RootDirectory": "E:/",
"VerifyToSeason": [
". 2000",
". 2001",
". 2002",
". 2003",
". 2004",
". 2005",
". 2006",
". 2007",
". 2008",
". 2009",
". 2010",
". 2011",
". 2012",
". 2013",
". 2014",
". 2015",
". 2016",
". 2017",
". 2018",
". 2019",
". 2020",
". 2021",
". 2022",
". 2023",
". 2024",
". 2025",
". 2026",
". 2027",
". 2028",
". 2029",
"=2000.0 Winter",
"=2002.1 Spring",
"=2002.4 Winter",
"=2003.0 Winter",
"=2003.1 Spring",
"=2003.3 Fall",
"=2003.4 Winter",
"=2004.0 Winter",
"=2005.1 Spring",
"=2005.2 Summer",
"=2005.3 Fall",
"=2005.4 Winter",
"=2006.0 Winter",
"=2006.1 Spring",
"=2006.3 Fall",
"=2007.0 Winter",
"=2007.2 Summer Logan Michael",
"=2007.2 Summer",
"=2007.3 Fall Logan Michael",
"=2007.4 Winter Logan Michael",
"=2008.0 Winter Logan Michael",
"=2008.1 Spring Logan Michael",
"=2008.2 Summer Logan Michael",
"=2008.2 Summer",
"=2008.3 Fall Logan Michael",
"=2009.0 Winter Logan Michael",
"=2009.0 Winter",
"=2009.1 Spring Logan Michael",
"=2009.1 Spring",
"=2009.2 Summer Logan Michael",
"=2009.2 Summer",
"=2009.3 Fall Logan Michael",
"=2009.3 Fall",
"=2009.4 Winter Logan Michael",
"=2009.4 Winter",
"=2010.0 Winter Logan Michael",
"=2010.0 Winter",
"=2010.1 Spring Logan Michael",
"=2010.1 Spring",
"=2010.2 Summer",
"=2010.3 Fall Logan Michael",
"=2010.3 Fall",
"=2010.4 Winter",
"=2011.0 Winter",
"=2011.1 Spring",
"=2011.2 Summer",
"=2011.3 Fall",
"=2011.4 Winter",
"=2012.0 Winter Chelsea 2012",
"=2012.0 Winter Chelsea",
"=2012.0 Winter",
"=2012.1 Spring Chelsea",
"=2012.1 Spring",
"=2012.2 Summer Chelsea",
"=2012.2 Summer",
"=2012.3 Fall Chelsea",
"=2012.3 Fall",
"=2012.4 Winter Chelsea",
"=2012.4 Winter",
"=2013.0 Winter Chelsea 2013",
"=2013.0 Winter Chelsea",
"=2013.0 Winter",
"=2013.1 Spring",
"=2013.2 Summer Chelsea",
"=2013.2 Summer",
"=2013.3 Fall Chelsea",
"=2013.3 Fall",
"=2013.4 Winter",
"=2014.0 Winter",
"=2014.1 Spring",
"=2014.2 Summer",
"=2014.3 Fall",
"=2014.4 Winter",
"=2015.0 Winter",
"=2015.1 Spring",
"=2015.2 Summer",
"=2015.3 Fall",
"=2015.4 Winter",
"=2016.0 Winter",
"=2016.1 Spring",
"=2016.2 Summer",
"=2016.3 Fall",
"=2016.4 Winter",
"=2017.1 Spring",
"=2017.2 Summer",
"=2017.3 Fall",
"=2017.4 Winter",
"=2018.0 Winter",
"=2018.1 Spring",
"=2018.3 Fall",
"=2018.4 Winter",
"=2019.0 Winter",
"=2019.1 Spring",
"=2019.2 Summer",
"=2019.3 Fall",
"=2019.4 Winter",
"=2020.0 Winter",
"=2020.1 Spring",
"=2020.2 Summer",
"=2020.3 Fall",
"=2020.4 Winter",
"=2021.1 Spring",
"=2021.2 Summer",
"=2021.3 Fall",
"=2021.4 Winter",
"=2022.0 Winter",
"=2022.1 Spring",
"Anthem 2015",
"April 2010",
"April 2013",
"December 2006",
"December 2010",
"Fall 2005",
"Fall 2015",
"Fall 2016",
"Fall 2017",
"Fall 2018",
"Fall 2019",
"Fall 2020",
"Fall 2021",
"February 2010",
"January 2015",
"July 2010",
"June 2010",
"Kids 2005",
"March 2013",
"May 2010",
"May 2011",
"May 2013",
"October 2005",
"October 2014",
"Spring 2013",
"Spring 2014",
"Spring 2016",
"Spring 2018",
"Spring 2019",
"Spring 2020",
"Summer 2011",
"Summer 2012",
"Summer 2013",
"Summer 2014",
"Summer 2015",
"Summer 2016",
"Summer 2017",
"Summer 2018",
"Summer 2020",
"Summer 2021",
"Winter 2015",
"Winter 2016",
"Winter 2017",
"Winter 2018",
"Winter 2019-2020",
"Winter 2020",
"zzz =2005.0 Winter Tracy Pictures",
"zzz =2005.1 Spring Tracy Pictures",
"zzz =2005.2 Summer Tracy Pictures",
"zzz =2005.3 Fall Tracy Pictures",
"zzz =2005.4 Winter Tracy Pictures",
"zzz =2006.1 Spring Tracy Pictures",
"zzz =2007.0 Winter Tracy Pictures",
"zzz =2007.2 Summer Tracy Pictures",
"zzz =2008.0 Winter Tracy Pictures",
"zzz =2008.2 Summer Tracy Pictures",
"zzz =2009.0 Winter Tracy Pictures",
"zzz =2009.2 Summer Tracy Pictures",
"zzz =2009.3 Fall Tracy Pictures",
"zzz =2009.4 Winter Tracy Pictures",
"zzz =2010.0 Winter Tracy Pictures",
"zzz =2010.1 Spring Tracy Pictures",
"zzz =2010.2 Summer Tracy Pictures",
"zzz =2010.3 Fall Tracy Pictures",
"zzz =2011.0 Winter Tracy Pictures",
"zzz =2011.1 Spring Tracy Pictures",
"zzz =2011.2 Summer Tracy Pictures",
"zzz =2011.3 Fall Tracy Pictures",
"zzz =2011.4 Winter Tracy Pictures",
"zzz =2012.0 Winter Tracy Pictures",
"zzz =2012.1 Spring Tracy Pictures",
"zzz =2012.2 Summer Tracy Pictures",
"zzz =2012.3 Fall Tracy Pictures",
"zzz =2012.4 Winter Tracy Pictures",
"zzz =2013.0 Winter Tracy Pictures",
"zzz =2013.1 Spring Tracy Pictures",
"zzz =2013.2 Summer Tracy Pictures",
"zzz =2013.3 Fall Tracy Pictures",
"zzz =2013.4 Winter Tracy Pictures",
"zzz =2014.0 Winter Tracy Pictures",
"zzz =2014.1 Spring Tracy Pictures",
"zzz =2014.2 Summer Tracy Pictures",
"zzz =2014.3 Fall Tracy Pictures",
"zzz =2014.4 Winter Tracy Pictures",
"zzz =2015.0 Winter Tracy Pictures"
]
}
}
}

View File

@ -0,0 +1,119 @@
{
"Company": "Mike Phares",
"IndexOnly": false,
"Linux": {},
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Log4netProvider": "Debug",
"Microsoft.Hosting.Lifetime": "Information"
}
},
"MaxDegreeOfParallelism": 6,
"Reverse": false,
"SortContainers": true,
"Serilog": {
"Using": [
"Serilog.Sinks.Console",
"Serilog.Sinks.File"
],
"MinimumLevel": "Information",
"WriteTo": [
{
"Name": "Debug",
"Args": {
"outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz} [{Level}] ({SourceContext}.{MethodName}) ({InstanceId}) ({RemoteIpAddress}) {Message}{NewLine}{Exception}"
}
},
{
"Name": "Console",
"Args": {
"outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz} [{Level}] ({SourceContext}.{MethodName}) ({InstanceId}) ({RemoteIpAddress}) {Message}{NewLine}{Exception}"
}
},
{
"Name": "File",
"Args": {
"path": "%workingDirectory% - Log/log-.txt",
"outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz} [{Level}] ({SourceContext}.{MethodName}) ({InstanceId}) ({RemoteIpAddress}) {Message}{NewLine}{Exception}",
"rollingInterval": "Hour"
}
}
],
"Enrich": [
"FromLogContext",
"WithMachineName",
"WithThreadId"
],
"Properties": {
"Application": "Sample"
}
},
"WorkingDirectoryName": "PharesApps",
"Windows": {
"Configuration": {
"DateGroup": "2022-11-12",
"DiffPropertyDirectory": "",
"FileNameDirectorySeparator": ".Z.",
"ForcePropertyLastWriteTimeToCreationTime": false,
"MaxImagesInDirectoryForTopLevelFirstPass": 10,
"OutputExtension": ".jpg",
"Pattern": "[^ABCDEFGHIJKLMNOPQRSTUVWXYZbcdfghjklmnpqrstvwxyz0-9]",
"PopulatePropertyId": true,
"PropertiesChangedForProperty": false,
"ResultAllInOne": "_ _ _",
"ResultCollection": "[]",
"ResultContent": "()",
"ResultSingleton": "{}",
"RootDirectory": "C:/Tmp/Phares/Compare/Images 2022-11-12 - c6aa7e8",
"WriteBitmapDataBytes": false,
"IgnoreExtensions": [
".gif",
".GIF"
],
"ValidImageFormatExtensions": [
".bmp",
".BMP",
".gif",
".GIF",
".jpeg",
".JPEG",
".jpg",
".JPG",
".png",
".PNG",
".tiff",
".TIFF"
],
"ValidMetadataExtensions": [
".3gp",
".3GP",
".avi",
".AVI",
".bmp",
".BMP",
".gif",
".GIF",
".ico",
".ICO",
".jpeg",
".JPEG",
".jpg",
".JPG",
".m4v",
".M4V",
".mov",
".MOV",
".mp4",
".MP4",
".mta",
".MTA",
".png",
".PNG",
".tiff",
".TIFF"
]
}
}
}

View File

@ -35,7 +35,7 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="Serilog" Version="2.12.0" />
<PackageReference Include="System.Text.Json" Version="7.0.0" />
<PackageReference Include="System.Text.Json" Version="7.0.1" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\FaceRecognitionDotNet\FaceRecognitionDotNet.csproj" />

View File

@ -31,12 +31,9 @@ public class D_Face
private readonly Model _Model;
private readonly string _ArgZero;
private readonly int _NumberOfJitters;
private readonly Serilog.ILogger? _Log;
private readonly bool _OverrideForFaceImages;
private readonly Configuration _Configuration;
private readonly int _NumberOfTimesToUpsample;
private readonly bool _RetryImagesWithoutAFace;
private readonly ImageCodecInfo _ImageCodecInfo;
private readonly ModelParameter _ModelParameter;
private readonly PredictorModel _PredictorModel;
@ -46,6 +43,7 @@ public class D_Face
private readonly int _FaceDistanceHiddenImageFactor;
private readonly EncoderParameters _EncoderParameters;
private readonly ImageCodecInfo _HiddenImageCodecInfo;
private readonly bool _RetryImagesWithoutAFaceLocation;
private readonly bool _ForceFaceLastWriteTimeToCreationTime;
private readonly EncoderParameters _HiddenEncoderParameters;
private readonly JsonSerializerOptions _WriteIndentedAndWhenWritingNull;
@ -64,30 +62,26 @@ public class D_Face
ImageCodecInfo imageCodecInfo,
string modelDirectory,
string modelName,
int numberOfJitters,
int numberOfTimesToUpsample,
bool overrideForFaceImages,
bool retryImagesWithoutAFace,
bool retryImagesWithoutAFaceLocation,
string predictorModelName,
bool propertiesChangedForFaces)
{
_ArgZero = argZero;
_Configuration = configuration;
_ImageCodecInfo = imageCodecInfo;
_NumberOfJitters = numberOfJitters;
_EncoderParameters = encoderParameters;
_FileNameExtension = filenameExtension;
_Log = Serilog.Log.ForContext<D_Face>();
AngleBracketCollection = new List<string>();
_HiddenImageCodecInfo = hiddenImageCodecInfo;
_OverrideForFaceImages = overrideForFaceImages;
_RetryImagesWithoutAFace = retryImagesWithoutAFace;
_HiddenEncoderParameters = hiddenEncoderParameters;
_HiddenFileNameExtension = hiddenFileNameExtension;
_NumberOfTimesToUpsample = numberOfTimesToUpsample;
_CheckDFaceAndUpWriteDates = checkDFaceAndUpWriteDates;
_PropertiesChangedForFaces = propertiesChangedForFaces;
_FaceDistanceHiddenImageFactor = faceDistanceHiddenImageFactor;
_RetryImagesWithoutAFaceLocation = retryImagesWithoutAFaceLocation;
_ForceFaceLastWriteTimeToCreationTime = forceFaceLastWriteTimeToCreationTime;
(Model model, PredictorModel predictorModel, ModelParameter modelParameter) = GetModel(modelDirectory, modelName, predictorModelName);
_Model = model;
@ -149,19 +143,10 @@ public class D_Face
#pragma warning disable CA1416
private static byte[] GetBytes(string value)
{
byte[] results = new byte[value.Length + 1];
for (int i = 0; i < value.Length; i++)
results[i] = (byte)value[i];
results[value.Length] = 0x00;
return results;
}
private PropertyItem GetPropertyItem(int id, string value)
{
PropertyItem result = (PropertyItem)_ConstructorInfo.Invoke(null);
byte[] bytes = GetBytes(value);
byte[] bytes = C_Resize.GetBytes(value);
result.Id = id;
result.Len = value.Length + 1;
result.Type = 2;
@ -234,6 +219,10 @@ public class D_Face
{
if (_Log is null)
throw new NullReferenceException(nameof(_Log));
if (_Configuration.NumberOfJitters is null)
throw new NullReferenceException(nameof(_Configuration.NumberOfJitters));
if (_Configuration.NumberOfTimesToUpsample is null)
throw new NullReferenceException(nameof(_Configuration.NumberOfTimesToUpsample));
List<Shared.Models.Face> results = new();
FaceRecognitionDotNet.Image? unknownImage;
if (!mappingFromItem.ResizedFileHolder.Exists)
@ -253,7 +242,7 @@ public class D_Face
else
{
List<(Location Location, FaceRecognitionDotNet.FaceEncoding? FaceEncoding, Dictionary<FacePart, FacePoint[]>? FaceParts)> collection;
FaceRecognition faceRecognition = new(_NumberOfTimesToUpsample, _NumberOfJitters, _PredictorModel, _Model, _ModelParameter);
FaceRecognition faceRecognition = new(_Configuration.NumberOfJitters.Value, _Configuration.NumberOfTimesToUpsample.Value, _Model, _ModelParameter, _PredictorModel);
collection = faceRecognition.GetCollection(unknownImage, includeFaceEncoding: true, includeFaceParts: true);
if (!collection.Any())
results.Add(new(property, outputResolutionWidth, outputResolutionHeight, outputResolutionOrientation, location: null));
@ -306,9 +295,9 @@ public class D_Face
throw new NullReferenceException(nameof(item.ImageFileHolder.DirectoryName));
SetAngleBracketCollection(dResultsFullGroupDirectory, item.ImageFileHolder.DirectoryName);
}
result = Path.Combine(AngleBracketCollection[0].Replace("<>", "()"), item.ImageFileHolder.NameWithoutExtension);
if (!angleBracketCollectionAny)
AngleBracketCollection.Clear();
result = Path.Combine(AngleBracketCollection[0].Replace("<>", "()"), item.ImageFileHolder.NameWithoutExtension);
return result;
}
@ -324,17 +313,6 @@ public class D_Face
List<DateTime> dateTimes = (from l in subFileTuples where changesFrom.Contains(l.Item1) select l.Item2).ToList();
string dCollectionFile = Path.Combine(dResultsFullGroupDirectory, "[]", _Configuration.ResultAllInOne, $"{mappingFromItem.Id}{mappingFromItem.ImageFileHolder.ExtensionLowered}.json");
FileInfo fileInfo = new(dCollectionFile);
if (!fileInfo.FullName.Contains(_Configuration.ResultAllInOne) && !fileInfo.Exists)
{
if (fileInfo.Directory?.Parent is null)
throw new Exception();
string parentCheck = Path.Combine(fileInfo.Directory.Parent.FullName, fileInfo.Name);
if (File.Exists(parentCheck))
{
File.Move(parentCheck, fileInfo.FullName);
fileInfo.Refresh();
}
}
if (_ForceFaceLastWriteTimeToCreationTime && !fileInfo.Exists && File.Exists(Path.ChangeExtension(fileInfo.FullName, ".delete")))
{
File.Move(Path.ChangeExtension(fileInfo.FullName, ".delete"), fileInfo.FullName);
@ -367,32 +345,148 @@ public class D_Face
parseExceptions.Add(nameof(D_Face));
}
}
if (results is null || (_RetryImagesWithoutAFace && results.Count == 1 && results[0].FaceEncoding is null))
if (results is null || (_RetryImagesWithoutAFaceLocation && results.Count == 1 && results[0].Location is null))
{
bool wasNull = results is null;
results = GetFaces(property, mappingFromItem, outputResolutionWidth, outputResolutionHeight, outputResolutionOrientation);
if (wasNull || (!wasNull && results.Any(l => l.FaceEncoding is not null)))
if (wasNull || (!wasNull && results.Any(l => l.Location is not null)))
{
json = JsonSerializer.Serialize(results, _WriteIndentedAndWhenWritingNull);
bool updateDateWhenMatches = dateTimes.Any() && fileInfo.Exists && dateTimes.Max() > fileInfo.LastWriteTime;
DateTime? dateTime = !updateDateWhenMatches ? null : dateTimes.Max();
if (Shared.Models.Stateless.Methods.IPath.WriteAllText(fileInfo.FullName, json, updateDateWhenMatches, compareBeforeWrite: true, updateToWhenMatches: dateTime))
{
if (!_ForceFaceLastWriteTimeToCreationTime && (!fileInfo.Exists || fileInfo.LastWriteTime == fileInfo.CreationTime))
subFileTuples.Add(new Tuple<string, DateTime>(nameof(D_Face), DateTime.Now));
}
}
if (_ForceFaceLastWriteTimeToCreationTime)
{
results = (from l in results select new Shared.Models.Face(ILocation.Digits, ILocation.Factor, results.Count, l)).ToList();
json = JsonSerializer.Serialize(results, _WriteIndentedAndWhenWritingNull);
bool updateDateWhenMatches = dateTimes.Any() && fileInfo.Exists && dateTimes.Max() > fileInfo.LastWriteTime;
DateTime? dateTime = !updateDateWhenMatches ? null : dateTimes.Max();
if (Shared.Models.Stateless.Methods.IPath.WriteAllText(fileInfo.FullName, json, updateDateWhenMatches, compareBeforeWrite: true, updateToWhenMatches: dateTime))
else
{
File.SetLastWriteTime(fileInfo.FullName, fileInfo.CreationTime);
fileInfo.Refresh();
subFileTuples.Add(new Tuple<string, DateTime>(nameof(D_Face), fileInfo.CreationTime));
}
}
}
}
return results;
}
private void WriteAllText(Dictionary<string, List<RelativeLocation>>? results, List<DateTime> dateTimes, FileInfo fileInfo)
{
string json = JsonSerializer.Serialize(results, _WriteIndentedAndWhenWritingNull);
bool updateDateWhenMatches = dateTimes.Any() && fileInfo.Exists && dateTimes.Max() > fileInfo.LastWriteTime;
DateTime? dateTime = !updateDateWhenMatches ? null : dateTimes.Max();
if (Shared.Models.Stateless.Methods.IPath.WriteAllText(fileInfo.FullName, json, updateDateWhenMatches, compareBeforeWrite: true, updateToWhenMatches: dateTime))
{
if (!_ForceFaceLastWriteTimeToCreationTime && (!fileInfo.Exists || fileInfo.LastWriteTime == fileInfo.CreationTime))
; // subFileTuples.Add(new Tuple<string, DateTime>(nameof(D_Face), DateTime.Now));
else
{
File.SetLastWriteTime(fileInfo.FullName, fileInfo.CreationTime);
fileInfo.Refresh();
// subFileTuples.Add(new Tuple<string, DateTime>(nameof(D_Face), fileInfo.CreationTime));
}
}
}
public Dictionary<string, List<RelativeLocation>> GetRelativeLocations(string outputResolution, string dResultsDateGroupDirectory, List<Tuple<string, DateTime>> subFileTuples, List<string> parseExceptions, Shared.Models.Property property, MappingFromItem mappingFromItem, int outputResolutionWidth, int outputResolutionHeight, int outputResolutionOrientation, string original, Dictionary<string, int[]> imageResizeKeyValuePairs, List<Shared.Models.Face> faces)
{
Dictionary<string, List<RelativeLocation>>? results;
if (string.IsNullOrEmpty(dResultsDateGroupDirectory))
throw new NullReferenceException(nameof(dResultsDateGroupDirectory));
if (!imageResizeKeyValuePairs.ContainsKey(original))
throw new Exception();
if (!imageResizeKeyValuePairs.ContainsKey(outputResolution))
throw new Exception();
string json;
decimal? h, l, t, w;
RelativeLocation relativeLocation;
List<RelativeLocation> relativeLocations = new();
int[] resize = imageResizeKeyValuePairs[outputResolution];
string key = $"{resize[0].ToString().PadLeft(6, '0')}.{resize[1].ToString().PadLeft(6, '0')}";
string[] changesFrom = new string[] { nameof(A_Property), nameof(B_Metadata), nameof(C_Resize), nameof(D_Face) };
List<DateTime> dateTimes = (from d in subFileTuples where changesFrom.Contains(d.Item1) select d.Item2).ToList();
string dCollectionDirectory = Path.Combine(dResultsDateGroupDirectory, "[]", _Configuration.ResultAllInOne);
string dCollectionFile = Path.Combine(dCollectionDirectory, $"{mappingFromItem.Id}{mappingFromItem.ImageFileHolder.ExtensionLowered}.json");
if (!Directory.Exists(dCollectionDirectory))
_ = Directory.CreateDirectory(dCollectionDirectory);
FileInfo fileInfo = new(dCollectionFile);
if (_ForceFaceLastWriteTimeToCreationTime && !fileInfo.Exists && File.Exists(Path.ChangeExtension(fileInfo.FullName, ".delete")))
{
File.Move(Path.ChangeExtension(fileInfo.FullName, ".delete"), fileInfo.FullName);
fileInfo.Refresh();
}
if (_ForceFaceLastWriteTimeToCreationTime && fileInfo.Exists && fileInfo.LastWriteTime != fileInfo.CreationTime)
{
File.SetLastWriteTime(fileInfo.FullName, fileInfo.CreationTime);
fileInfo.Refresh();
}
if (_PropertiesChangedForFaces)
results = null;
else if (!fileInfo.Exists)
results = null;
else if (_CheckDFaceAndUpWriteDates && dateTimes.Any() && dateTimes.Max() > fileInfo.LastWriteTime)
results = null;
else
{
json = Shared.Models.Stateless.Methods.IFace.GetJson(fileInfo.FullName);
try
{
results = JsonSerializer.Deserialize<Dictionary<string, List<RelativeLocation>>>(json);
if (results is null)
throw new NullReferenceException(nameof(results));
bool added = false;
relativeLocations.Clear();
foreach (KeyValuePair<string, List<RelativeLocation>> keyValuePair in results)
relativeLocations.AddRange(keyValuePair.Value);
if (!results.ContainsKey(key))
results.Add(key, new());
foreach (Shared.Models.Face face in faces)
{
if (face.Location is null || face.OutputResolution is null)
continue;
(h, l, t, w) = Shared.Models.Stateless.Methods.ILocation.GetHeightLeftTopWidth(face.Location, face.OutputResolution);
if (h is null || l is null || t is null || w is null)
continue;
relativeLocation = new(face.Location.Confidence, h.Value.ToString(), l.Value.ToString(), t.Value.ToString(), w.Value.ToString());
if (relativeLocations.Any(r => r.Match(h, l, t, w)))
continue;
if (!added)
added = true;
results[key].Add(relativeLocation);
}
if (added)
{
List<(string Key, List<RelativeLocation> Value)> sort = new();
foreach (KeyValuePair<string, List<RelativeLocation>> keyValuePair in results)
sort.Add(new(keyValuePair.Key, keyValuePair.Value));
results.Clear();
foreach ((string k, List<RelativeLocation> v) in sort.OrderBy(l => l.Key))
results.Add(k, v.OrderByDescending(l => l.Confidence).ToList());
WriteAllText(results, dateTimes, fileInfo);
}
// subFileTuples.Add(new Tuple<string, DateTime>(nameof(D_Face), fileInfo.LastWriteTime));
}
catch (Exception)
{
results = null;
parseExceptions.Add(nameof(D_Face));
}
}
if (results is null)
{
results = new() { { key, new() } };
foreach (Shared.Models.Face face in faces)
{
if (face.Location is null || face.OutputResolution is null)
continue;
(h, l, t, w) = Shared.Models.Stateless.Methods.ILocation.GetHeightLeftTopWidth(face.Location, face.OutputResolution);
if (h is null || l is null || t is null || w is null)
continue;
relativeLocation = new(face.Location.Confidence, h.Value.ToString(), l.Value.ToString(), t.Value.ToString(), w.Value.ToString());
results[key].Add(relativeLocation);
}
WriteAllText(results, dateTimes, fileInfo);
}
return results;
}
@ -400,7 +494,6 @@ public class D_Face
{
FileInfo fileInfo;
bool result = false;
string parentCheck;
string deterministicHashCodeKey;
List<(Shared.Models.Face, FileInfo?, string)> collection = new();
string[] changesFrom = new string[] { nameof(A_Property), nameof(B_Metadata), nameof(C_Resize) };
@ -414,16 +507,8 @@ public class D_Face
collection.Add(new(face, null, string.Empty));
continue;
}
deterministicHashCodeKey = Shared.Models.Stateless.Methods.IMapping.GetDeterministicHashCodeKey(mappingFromItem.Id, face.Location, ILocation.Digits, ILocation.Factor, face.OutputResolution);
deterministicHashCodeKey = Shared.Models.Stateless.Methods.IMapping.GetDeterministicHashCodeKey(mappingFromItem.Id, face.Location, ILocation.Digits, face.OutputResolution);
fileInfo = new FileInfo(Path.Combine(facesDirectory, $"{deterministicHashCodeKey}{mappingFromItem.ImageFileHolder.ExtensionLowered}{_FileNameExtension}"));
if (!fileInfo.FullName.Contains(_Configuration.ResultAllInOne) && !fileInfo.Exists)
{
if (fileInfo.Directory?.Parent is null)
throw new Exception();
parentCheck = Path.Combine(fileInfo.Directory.Parent.FullName, fileInfo.Name);
if (File.Exists(parentCheck))
File.Delete(parentCheck);
}
collection.Add(new(face, fileInfo, Path.Combine(facesDirectory, $"{deterministicHashCodeKey}{mappingFromItem.ImageFileHolder.ExtensionLowered}{_HiddenFileNameExtension}")));
if (_OverrideForFaceImages)
result = true;

View File

@ -35,7 +35,7 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="Serilog" Version="2.12.0" />
<PackageReference Include="System.Text.Json" Version="7.0.0" />
<PackageReference Include="System.Text.Json" Version="7.0.1" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\FaceRecognitionDotNet\FaceRecognitionDotNet.csproj" />

View File

@ -4,6 +4,7 @@ using System.Drawing.Imaging;
using System.Text.Json;
using View_by_Distance.Face.Models;
using View_by_Distance.Metadata.Models;
using View_by_Distance.Property.Models.Stateless;
using View_by_Distance.Resize.Models;
using View_by_Distance.Shared.Models;
using View_by_Distance.Shared.Models.Properties;
@ -25,12 +26,14 @@ public class D2_FaceParts
private readonly bool _CheckDFaceAndUpWriteDates;
private readonly bool _OverrideForFaceLandmarkImages;
private readonly EncoderParameters _EncoderParameters;
private readonly List<string> _AngleBracketCollection;
public D2_FaceParts(ImageCodecInfo imageCodecInfo, EncoderParameters encoderParameters, string filenameExtension, bool checkDFaceAndUpWriteDates, bool overrideForFaceLandmarkImages)
{
_ImageCodecInfo = imageCodecInfo;
_EncoderParameters = encoderParameters;
_FileNameExtension = filenameExtension;
_AngleBracketCollection = new List<string>();
_Log = Serilog.Log.ForContext<D2_FaceParts>();
_CheckDFaceAndUpWriteDates = checkDFaceAndUpWriteDates;
_OverrideForFaceLandmarkImages = overrideForFaceLandmarkImages;
@ -42,6 +45,34 @@ public class D2_FaceParts
return result;
}
public void SetAngleBracketCollection(Property.Models.Configuration configuration, string d2ResultsFullGroupDirectory, string sourceDirectory)
{
_AngleBracketCollection.Clear();
_AngleBracketCollection.AddRange(IResult.GetDirectoryInfoCollection(configuration,
sourceDirectory,
d2ResultsFullGroupDirectory,
contentDescription: "n gif file(s) for each face found",
singletonDescription: string.Empty,
collectionDescription: string.Empty,
converted: true));
}
public string GetFacePartsDirectory(Property.Models.Configuration configuration, string dResultsFullGroupDirectory, Item item)
{
string result;
bool angleBracketCollectionAny = _AngleBracketCollection.Any();
if (!angleBracketCollectionAny)
{
if (item.ImageFileHolder.DirectoryName is null)
throw new NullReferenceException(nameof(item.ImageFileHolder.DirectoryName));
SetAngleBracketCollection(configuration, dResultsFullGroupDirectory, item.ImageFileHolder.DirectoryName);
}
result = Path.Combine(_AngleBracketCollection[0].Replace("<>", "()"), item.ImageFileHolder.NameWithoutExtension);
if (!angleBracketCollectionAny)
_AngleBracketCollection.Clear();
return result;
}
private static void GetPointBounds(PointF[] points, out float xMinimum, out float xMaximum, out float yMinimum, out float yMaximum)
{
xMinimum = points[0].X;
@ -166,7 +197,7 @@ public class D2_FaceParts
{
if (face.Location is null)
continue;
graphic.DrawEllipse(Pens.GreenYellow, face.Location.Left + facePoint.X - pointSize, face.Location.Top + facePoint.Y - pointSize, pointSize * 2, pointSize * 2);
graphic.DrawEllipse(Pens.GreenYellow, facePoint.X - pointSize, facePoint.Y - pointSize, pointSize * 2, pointSize * 2);
}
if (facePart == FacePart.Chin)
continue;
@ -176,7 +207,7 @@ public class D2_FaceParts
y = (int)(from l in facePoints select l.Y).Average();
if (face.Location is null)
continue;
graphic.DrawEllipse(Pens.Purple, face.Location.Left + x - pointSize, face.Location.Top + y - pointSize, pointSize * 2, pointSize * 2);
graphic.DrawEllipse(Pens.Purple, x - pointSize, y - pointSize, pointSize * 2, pointSize * 2);
}
}
image.Save(fileName, _ImageCodecInfo, _EncoderParameters);
@ -201,11 +232,10 @@ public class D2_FaceParts
#pragma warning restore CA1416
public void SaveFaceLandmarkImages(Property.Models.Configuration configuration, string facesDirectory, List<Tuple<string, DateTime>> subFileTuples, List<string> parseExceptions, MappingFromItem mappingFromItem, List<Shared.Models.Face> faceCollection, bool saveRotated)
public void SaveFaceLandmarkImages(Property.Models.Configuration configuration, string facePartsDirectory, List<Tuple<string, DateTime>> subFileTuples, List<string> parseExceptions, MappingFromItem mappingFromItem, List<Shared.Models.Face> faces, bool saveRotated)
{
FileInfo fileInfo;
bool check = false;
string parentCheck;
const int pointSize = 2;
FileInfo rotatedFileInfo;
DateTime? dateTime = null;
@ -215,25 +245,17 @@ public class D2_FaceParts
List<(Shared.Models.Face, string, string)> collection = new();
string[] changesFrom = new string[] { nameof(Property.Models.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();
if (!Directory.Exists(facesDirectory))
_ = Directory.CreateDirectory(facesDirectory);
foreach (Shared.Models.Face face in faceCollection)
if (!Directory.Exists(facePartsDirectory))
_ = Directory.CreateDirectory(facePartsDirectory);
foreach (Shared.Models.Face face in faces)
{
if (face.FaceEncoding is null || face.Location is null || face.OutputResolution is null)
{
collection.Add(new(face, string.Empty, string.Empty));
continue;
}
deterministicHashCodeKey = Shared.Models.Stateless.Methods.IMapping.GetDeterministicHashCodeKey(mappingFromItem.Id, face.Location, Shared.Models.Stateless.ILocation.Digits, Shared.Models.Stateless.ILocation.Factor, face.OutputResolution);
fileInfo = new FileInfo(Path.Combine(facesDirectory, $"{deterministicHashCodeKey}{mappingFromItem.ImageFileHolder.ExtensionLowered}{_FileNameExtension}"));
if (!fileInfo.FullName.Contains(configuration.ResultAllInOne) && !fileInfo.Exists)
{
if (fileInfo.Directory?.Parent is null)
throw new Exception();
parentCheck = Path.Combine(fileInfo.Directory.Parent.FullName, fileInfo.Name);
if (File.Exists(parentCheck))
File.Delete(parentCheck);
}
deterministicHashCodeKey = Shared.Models.Stateless.Methods.IMapping.GetDeterministicHashCodeKey(mappingFromItem.Id, face.Location, Shared.Models.Stateless.ILocation.Digits, face.OutputResolution);
fileInfo = new FileInfo(Path.Combine(facePartsDirectory, $"{deterministicHashCodeKey}{mappingFromItem.ImageFileHolder.ExtensionLowered}{_FileNameExtension}"));
if (string.IsNullOrEmpty(fileInfo.DirectoryName))
continue;
rotatedFileInfo = new FileInfo(Path.Combine(fileInfo.DirectoryName, $"{deterministicHashCodeKey} - R{mappingFromItem.ImageFileHolder.ExtensionLowered}{_FileNameExtension}"));

View File

@ -26,7 +26,7 @@ public class FaceRecognition : DisposableObject
private readonly ShapePredictor _PosePredictor5Point;
private readonly ShapePredictor _PosePredictor68Point;
public FaceRecognition(int numberOfTimesToUpsample, int numberOfJitters, PredictorModel predictorModel, Model model, ModelParameter modelParameter)
public FaceRecognition(int numberOfJitters, int numberOfTimesToUpsample, Model model, ModelParameter modelParameter, PredictorModel predictorModel)
{
if (modelParameter is null)
throw new NullReferenceException(nameof(modelParameter));
@ -284,6 +284,23 @@ public class FaceRecognition : DisposableObject
return new FaceEncoding(matrix);
}
public static FaceEncoding LoadBFaceEncoding(double[] encoding)
{
if (encoding is null)
throw new NullReferenceException(nameof(encoding));
if (encoding.Length != 512)
{
string message = $"{nameof(encoding)}.{nameof(encoding.Length)} must be 512.";
throw new ArgumentOutOfRangeException(message);
}
#pragma warning disable
Matrix<double>? matrix = Matrix<double>.CreateTemplateParameterizeMatrix(0, 1);
#pragma warning restore
matrix.SetSize(512);
matrix.Assign(encoding);
return new FaceEncoding(matrix);
}
public static Image LoadImageFile(string file, Mode mode = Mode.Rgb)
{
if (!File.Exists(file))

View File

@ -47,7 +47,6 @@ public partial class DlibDotNet
IConsole console)
{
_Console = console;
string argZero;
string message;
_AppSettings = appSettings;
_IsEnvironment = isEnvironment;
@ -56,9 +55,9 @@ public partial class DlibDotNet
PersonContainer[] personContainers;
_Log = Serilog.Log.ForContext<DlibDotNet>();
Property.Models.Configuration propertyConfiguration = Property.Models.Binder.Configuration.Get(isEnvironment, configurationRoot);
Models.Configuration configuration = Models.Binder.Configuration.Get(isEnvironment, configurationRoot, propertyConfiguration);
_Log.Information(propertyConfiguration.RootDirectory);
Property.Models.Configuration.Verify(propertyConfiguration, requireExist: false);
Models.Configuration configuration = Models.Binder.Configuration.Get(isEnvironment, configurationRoot, propertyConfiguration);
Verify(configuration);
VerifyExtra(args, propertyConfiguration, configuration);
_Configuration = configuration;
@ -69,8 +68,13 @@ public partial class DlibDotNet
throw new NullReferenceException(nameof(configuration.IgnoreExtensions));
string propertyRoot = Property.Models.Stateless.IResult.GetResultsGroupDirectory(propertyConfiguration, nameof(A_Property), create: false);
_PropertyRootExistedBefore = !Directory.Exists(propertyRoot);
argZero = args.Count > 0 ? Path.GetFullPath(args[0]) : Path.GetFullPath(propertyConfiguration.RootDirectory);
string argZero = args.Count > 0 ? Path.GetFullPath(args[0]) : Path.GetFullPath(propertyConfiguration.RootDirectory);
_ArgZeroIsConfigurationRootDirectory = propertyConfiguration.RootDirectory == argZero;
if (!Directory.Exists(argZero))
_ = Directory.CreateDirectory(argZero);
_ = Shared.Models.Stateless.Methods.IPath.DeleteEmptyDirectories(argZero);
if (!Directory.Exists(argZero))
_ = Directory.CreateDirectory(argZero);
_Log.Information(configuration.ModelDirectory);
{
(ImageCodecInfo imageCodecInfo, EncoderParameters encoderParameters, string filenameExtension) = C_Resize.GetPngLowQuality();
@ -89,10 +93,8 @@ public partial class DlibDotNet
imageCodecInfo,
configuration.ModelDirectory,
configuration.ModelName,
configuration.NumberOfJitters,
configuration.NumberOfTimesToUpsample,
configuration.OverrideForFaceImages,
configuration.RetryImagesWithoutAFace,
configuration.RetryImagesWithoutAFaceLocation,
configuration.PredictorModelName,
configuration.PropertiesChangedForFaces);
}
@ -102,7 +104,7 @@ public partial class DlibDotNet
}
_Metadata = new(configuration.ForceMetadataLastWriteTimeToCreationTime, configuration.PropertiesChangedForMetadata);
_MapConfiguration = Get(configuration, _Faces.FileNameExtension, _Faces.HiddenFileNameExtension, _FaceParts.FileNameExtension);
_Distance = new(configuration.DistanceMoveUnableToMatch, configuration.DistancePixelDistanceTolerance, configuration.DistanceRenameToMatch, _Configuration.FaceConfidencePercent, configuration.RangeDistanceTolerance, configuration.RangeFaceConfidence);
_Distance = new(configuration.DistanceMoveUnableToMatch, configuration.DistanceRenameToMatch, _Configuration.FaceConfidencePercent, configuration.RangeDistanceTolerance, configuration.RangeFaceConfidence);
if (_PropertyRootExistedBefore || !_ArgZeroIsConfigurationRootDirectory)
personContainers = Array.Empty<PersonContainer>();
else
@ -268,6 +270,7 @@ public partial class DlibDotNet
configuration.MappingDefaultName,
configuration.PersonBirthdayFirstYear,
configuration.PersonBirthdayFormat,
configuration.PhotoPrismDirectory,
configuration.RangeDaysDeltaTolerance,
configuration.RangeDistanceTolerance,
configuration.SortingMaximumPerKey,
@ -278,7 +281,7 @@ public partial class DlibDotNet
return result;
}
private void FullParallelForWork(A_Property propertyLogic, Dictionary<int, List<(string, int)>> idToMappedFaceFilesCollection, string outputResolution, string bResultsFullGroupDirectory, string cResultsFullGroupDirectory, string dResultsFullGroupDirectory, string? eDistanceContentDirectory, List<Tuple<string, DateTime>> sourceDirectoryChanges, List<FileHolder?> propertyFileHolderCollection, List<Shared.Models.Property?> propertyCollection, List<List<KeyValuePair<string, string>>> metadataCollections, List<Dictionary<string, int[]>> resizeKeyValuePairs, List<List<Shared.Models.Face>> imageFaceCollections, Container container, int index, Item item)
private void FullParallelForWork(A_Property propertyLogic, Dictionary<int, List<(string, int)>> idToMappedFaceFilesCollection, string outputResolution, string bResultsFullGroupDirectory, string cResultsFullGroupDirectory, string dResultsDateGroupDirectory, string dResultsFullGroupDirectory, string? eDistanceContentDirectory, List<Tuple<string, DateTime>> sourceDirectoryChanges, List<FileHolder?> propertyFileHolderCollection, List<Shared.Models.Property?> propertyCollection, List<List<KeyValuePair<string, string>>> metadataCollections, List<Dictionary<string, int[]>> resizeKeyValuePairs, List<List<Shared.Models.Face>> imageFaceCollections, Container container, int index, Item item, DateTime[] containerDateTimes)
{
if (_Log is null)
throw new NullReferenceException(nameof(_Log));
@ -291,19 +294,18 @@ public partial class DlibDotNet
Dictionary<string, int[]> imageResizeKeyValuePairs;
List<Tuple<string, DateTime>> subFileTuples = new();
List<KeyValuePair<string, string>> metadataCollection;
if (item.Property is null || item.Property.Id is null)
Dictionary<string, List<RelativeLocation>> relativeLocations;
if (item.Property is not null && item.Property.Id is not null && !item.Any())
{
property = propertyLogic.GetProperty(item, subFileTuples, parseExceptions);
item.Update(property);
if (subFileTuples.Any())
{
lock (sourceDirectoryChanges)
sourceDirectoryChanges.Add(new Tuple<string, DateTime>(nameof(A_Property), (from l in subFileTuples select l.Item2).Max()));
}
property = item.Property;
if (item.SourceDirectoryFileHolder.LastWriteTime is not null)
subFileTuples.Add(new Tuple<string, DateTime>(nameof(A_Property), item.SourceDirectoryFileHolder.LastWriteTime.Value));
else
subFileTuples.Add(new Tuple<string, DateTime>(nameof(A_Property), new FileInfo(item.SourceDirectoryFileHolder.FullName).LastWriteTime));
}
else
{
property = item.Property;
int? propertyHashCode = item.Property?.GetHashCode();
if (item.Abandoned.HasValue && item.Abandoned.Value)
_Log.Information(string.Concat("Abandoned <", item.ImageFileHolder.FullName, '>'));
else if (item.FileSizeChanged.HasValue && item.FileSizeChanged.Value)
@ -312,13 +314,26 @@ public partial class DlibDotNet
_Log.Information(string.Concat("LastWriteTimeChanged <", item.ImageFileHolder.FullName, '>'));
else if (item.Moved.HasValue && item.Moved.Value)
_Log.Information(string.Concat("Moved <", item.ImageFileHolder.FullName, '>'));
property = propertyLogic.GetProperty(item, subFileTuples, parseExceptions);
item.Update(property);
if (propertyHashCode is null)
{
lock (sourceDirectoryChanges)
sourceDirectoryChanges.Add(new Tuple<string, DateTime>(nameof(A_Property), DateTime.Now));
}
else if (propertyHashCode.Value != property.GetHashCode())
{
lock (sourceDirectoryChanges)
sourceDirectoryChanges.Add(new Tuple<string, DateTime>(nameof(A_Property), DateTime.Now));
}
}
if (property is null || item.Property is null)
throw new NullReferenceException(nameof(property));
FileHolder resizedFileHolder = _Resize.GetResizedFileHolder(item);
item.SetResizedFileHolder(_Resize.FileNameExtension, resizedFileHolder);
string facesDirectory = _Faces.GetFacesDirectory(dResultsFullGroupDirectory, item);
MappingFromItem mappingFromItem = Shared.Models.Stateless.Methods.IMappingFromItem.GetMappingFromItem(item, resizedFileHolder);
string facesDirectory = _Configuration.LoadOrCreateThenSaveImageFacesResultsForOutputResolutions.Contains(outputResolution) ? _Faces.GetFacesDirectory(dResultsFullGroupDirectory, item) : string.Empty;
string facePartsDirectory = _Configuration.SaveFaceLandmarkForOutputResolutions.Contains(outputResolution) ? _FaceParts.GetFacePartsDirectory(_Configuration.PropertyConfiguration, dResultsFullGroupDirectory, item) : string.Empty;
MappingFromItem mappingFromItem = Shared.Models.Stateless.Methods.IMappingFromItem.GetMappingFromItem(containerDateTimes, item, resizedFileHolder);
(int metadataGroups, metadataCollection) = _Metadata.GetMetadataCollection(_Configuration.PropertyConfiguration, bResultsFullGroupDirectory, subFileTuples, parseExceptions, mappingFromItem);
if (_AppSettings.MaxDegreeOfParallelism < 2)
ticks = LogDelta(ticks, nameof(B_Metadata.GetMetadataCollection));
@ -343,28 +358,29 @@ public partial class DlibDotNet
faces = new();
else
{
List<(string, int)>? collection;
int[] outputResolutionCollection = imageResizeKeyValuePairs[outputResolution];
int outputResolutionWidth = outputResolutionCollection[0];
int outputResolutionHeight = outputResolutionCollection[1];
int outputResolutionOrientation = outputResolutionCollection[2];
faces = _Faces.GetFaces(dResultsFullGroupDirectory, subFileTuples, parseExceptions, property, mappingFromItem, outputResolutionWidth, outputResolutionHeight, outputResolutionOrientation);
relativeLocations = _Faces.GetRelativeLocations(outputResolution, dResultsDateGroupDirectory, subFileTuples, parseExceptions, property, mappingFromItem, outputResolutionWidth, outputResolutionHeight, outputResolutionOrientation, original, imageResizeKeyValuePairs, faces);
if (_AppSettings.MaxDegreeOfParallelism < 2)
ticks = LogDelta(ticks, nameof(D_Face.GetFaces));
bool anyFacesSaved = _Faces.SaveFaces(dResultsFullGroupDirectory, subFileTuples, parseExceptions, mappingFromItem, facesDirectory, faces);
if (_AppSettings.MaxDegreeOfParallelism < 2)
ticks = LogDelta(ticks, nameof(D_Face.SaveFaces));
if (!anyFacesSaved && item.Property?.Id is not null
&& idToMappedFaceFilesCollection.TryGetValue(item.Property.Id.Value, out List<(string, int)>? collection))
if (_Configuration.LoadOrCreateThenSaveDistanceResultsForOutputResolutions.Contains(outputResolution)
&& !anyFacesSaved && item.Property?.Id is not null
&& idToMappedFaceFilesCollection.TryGetValue(item.Property.Id.Value, out collection))
_Distance.LookForMatchFacesAndPossiblyRename(_Faces.FileNameExtension, eDistanceContentDirectory, mappingFromItem, faces, collection);
if (_Configuration.SaveFaceLandmarkForOutputResolutions.Contains(outputResolution))
{
throw new NotImplementedException();
// bool saveRotated = _Configuration.SaveFaceLandmarkForOutputResolutions.Contains(outputResolution);
// string sourceDirectorySegment = Property.Models.Stateless.IResult.GetRelativePath(_Configuration.PropertyConfiguration, container.SourceDirectory);
// string facePartsDirectoryX = Path.GetFullPath(Path.Combine($"{Path.Combine(d2FacePartsContentDirectory, "()")}{sourceDirectorySegment}", item.ImageFileHolder.NameWithoutExtension));
// _FaceParts.SaveFaceLandmarkImages(facesDirectory, subFileTuples, parseExceptions, item, faceCollection, saveRotated);
// if (_AppSettings.MaxDegreeOfParallelism < 2)
// ticks = LogDelta(ticks, nameof(D2_FaceParts.SaveFaceLandmarkImages));
bool saveRotated = !_Configuration.SaveFaceLandmarkForOutputResolutions.Contains(outputResolution);
string sourceDirectorySegment = Property.Models.Stateless.IResult.GetRelativePath(_Configuration.PropertyConfiguration, container.SourceDirectory);
_FaceParts.SaveFaceLandmarkImages(_Configuration.PropertyConfiguration, facePartsDirectory, subFileTuples, parseExceptions, mappingFromItem, faces, saveRotated);
if (_AppSettings.MaxDegreeOfParallelism < 2)
ticks = LogDelta(ticks, nameof(D2_FaceParts.SaveFaceLandmarkImages));
}
}
lock (sourceDirectoryChanges)
@ -384,6 +400,7 @@ public partial class DlibDotNet
string outputResolution,
string bResultsFullGroupDirectory,
string cResultsFullGroupDirectory,
string dResultsDateGroupDirectory,
string dResultsFullGroupDirectory,
string? eDistanceContentDirectory,
List<Tuple<string, DateTime>> sourceDirectoryChanges,
@ -415,6 +432,7 @@ public partial class DlibDotNet
propertyFileHolderCollection.Add(null);
}
}
DateTime[] containerDateTimes = Shared.Models.Stateless.Methods.IContainer.GetContainerDateTimes(filteredItems);
using ProgressBar progressBar = new(filteredItems.Length, message, options);
_ = Parallel.For(0, filteredItems.Length, parallelOptions, (i, state) =>
{
@ -426,6 +444,7 @@ public partial class DlibDotNet
outputResolution,
bResultsFullGroupDirectory,
cResultsFullGroupDirectory,
dResultsDateGroupDirectory,
dResultsFullGroupDirectory,
eDistanceContentDirectory,
sourceDirectoryChanges,
@ -436,7 +455,8 @@ public partial class DlibDotNet
imageFaceCollections,
container,
index: i,
filteredItems[i]);
filteredItems[i],
containerDateTimes);
if (i == 0 || sourceDirectoryChanges.Any())
progressBar.Tick();
}
@ -559,7 +579,7 @@ public partial class DlibDotNet
}
}
private (string, string, string, string) GetResultsFullGroupDirectories(string outputResolution)
private (string, string, string, string, string) GetResultsFullGroupDirectories(string outputResolution)
{
string aResultsFullGroupDirectory = Property.Models.Stateless.IResult.GetResultsFullGroupDirectory(
_Configuration.PropertyConfiguration,
@ -589,7 +609,14 @@ public partial class DlibDotNet
includeResizeGroup: true,
includeModel: true,
includePredictorModel: true);
return new(aResultsFullGroupDirectory, bResultsFullGroupDirectory, cResultsFullGroupDirectory, dResultsFullGroupDirectory);
string d2ResultsFullGroupDirectory = Property.Models.Stateless.IResult.GetResultsFullGroupDirectory(
_Configuration.PropertyConfiguration,
nameof(D2_FaceParts),
outputResolution,
includeResizeGroup: true,
includeModel: true,
includePredictorModel: true);
return new(aResultsFullGroupDirectory, bResultsFullGroupDirectory, cResultsFullGroupDirectory, dResultsFullGroupDirectory, d2ResultsFullGroupDirectory);
}
private void SetAngleBracketCollections(A_Property propertyLogic, Container container, string aResultsFullGroupDirectory, string bResultsFullGroupDirectory, string cResultsFullGroupDirectory)
@ -599,20 +626,6 @@ public partial class DlibDotNet
_Metadata.SetAngleBracketCollection(_Configuration.PropertyConfiguration, bResultsFullGroupDirectory, container.SourceDirectory);
}
private Item[] GetFilterItems(Container container)
{
List<Item> results = new();
foreach (Item item in container.Items)
{
if (item.ImageFileHolder is not null
&& (item.Abandoned is null || !item.Abandoned.Value)
&& item.ValidImageFormatExtension
&& !_Configuration.IgnoreExtensions.Contains(item.ImageFileHolder.ExtensionLowered))
results.Add(item);
}
return results.ToArray();
}
private void FullDoWork(string argZero, string propertyRoot, long ticks, A_Property propertyLogic, int t, Container[] containers, string? eDistanceContentDirectory, Dictionary<int, List<(string, int)>> idToMappedFaceFilesCollection)
{
if (_Log is null)
@ -627,6 +640,7 @@ public partial class DlibDotNet
string bResultsFullGroupDirectory;
string cResultsFullGroupDirectory;
string dResultsFullGroupDirectory;
string d2ResultsFullGroupDirectory;
int containersLength = containers.Length;
Shared.Models.Property[] propertyCollection;
List<FileHolder?> propertyFileHolderCollection = new();
@ -636,10 +650,12 @@ public partial class DlibDotNet
int maxDegreeOfParallelism = _AppSettings.MaxDegreeOfParallelism;
List<Shared.Models.Property?> nullablePropertyCollection = new();
List<List<KeyValuePair<string, string>>> metadataCollection = new();
string dResultsDateGroupDirectory = Property.Models.Stateless.IResult.GetResultsDateGroupDirectory(_Configuration.PropertyConfiguration, nameof(D_Face));
foreach (string outputResolution in _Configuration.OutputResolutions)
{
total = 0;
(aResultsFullGroupDirectory, bResultsFullGroupDirectory, cResultsFullGroupDirectory, dResultsFullGroupDirectory) = GetResultsFullGroupDirectories(outputResolution);
(aResultsFullGroupDirectory, bResultsFullGroupDirectory, cResultsFullGroupDirectory, dResultsFullGroupDirectory, d2ResultsFullGroupDirectory) = GetResultsFullGroupDirectories(outputResolution);
// _ = Shared.Models.Stateless.Methods.IPath.DeleteEmptyDirectories(dResultsFullGroupDirectory);
for (int i = 0; i < containers.Length; i++)
{
container = containers[i];
@ -647,7 +663,7 @@ public partial class DlibDotNet
continue;
if (!_ArgZeroIsConfigurationRootDirectory && !container.SourceDirectory.StartsWith(argZero))
continue;
filteredItems = GetFilterItems(container);
filteredItems = Shared.Models.Stateless.Methods.IContainer.GetFilterItems(_Configuration.PropertyConfiguration, container);
if (!filteredItems.Any())
continue;
metadataCollection.Clear();
@ -660,6 +676,8 @@ public partial class DlibDotNet
message = $"{i + 1:000}.{container.G} [{filteredItems.Length:000} files] / {containersLength:000} - {total} / {t} total files - {totalSeconds} total second(s) - {outputResolution} - {container.SourceDirectory}";
if (_Configuration.LoadOrCreateThenSaveImageFacesResultsForOutputResolutions.Contains(outputResolution))
_Faces.SetAngleBracketCollection(dResultsFullGroupDirectory, container.SourceDirectory);
if (_Configuration.SaveFaceLandmarkForOutputResolutions.Contains(outputResolution))
_FaceParts.SetAngleBracketCollection(_Configuration.PropertyConfiguration, d2ResultsFullGroupDirectory, container.SourceDirectory);
SetAngleBracketCollections(propertyLogic, container, aResultsFullGroupDirectory, bResultsFullGroupDirectory, cResultsFullGroupDirectory);
exceptionCount = FullParallelWork(
maxDegreeOfParallelism,
@ -668,6 +686,7 @@ public partial class DlibDotNet
outputResolution,
bResultsFullGroupDirectory,
cResultsFullGroupDirectory,
dResultsDateGroupDirectory,
dResultsFullGroupDirectory,
eDistanceContentDirectory,
sourceDirectoryChanges,
@ -718,37 +737,56 @@ public partial class DlibDotNet
}
}
private bool IsIgnoreRelativePath(string directory)
private void SetMapping(string argZero, Container[] containers)
{
bool result = false;
string? checkDirectory = Path.GetFullPath(directory);
for (int i = 0; i < int.MaxValue; i++)
{
if (_Configuration.IgnoreRelativePaths.Contains(Path.GetFileName(checkDirectory)))
{
result = true;
break;
}
checkDirectory = Path.GetDirectoryName(checkDirectory);
if (string.IsNullOrEmpty(checkDirectory) || checkDirectory == _Configuration.PropertyConfiguration.RootDirectory)
break;
}
return result;
}
private (List<Item>, Shared.Models.Face[]) SetMappingThenGetDistinctFilteredFacesWithMapping(string argZero, Container[] containers)
{
List<Item> items = new();
Shared.Models.Face[] faces;
Mapping mapping;
int faceAreaPermille;
Item[] filteredItems;
int confidencePercent;
List<int> distinct = new();
int normalizedPixelPercentage;
int normalizedRectangle;
bool isIgnoreRelativePath;
DateTime[] containerDateTimes;
string deterministicHashCodeKey;
MappingFromItem mappingFromItem;
MappingFromLocation mappingFromLocation;
foreach (Container container in containers)
{
if (!container.Items.Any())
continue;
if (!_ArgZeroIsConfigurationRootDirectory && !container.SourceDirectory.StartsWith(argZero))
continue;
filteredItems = Shared.Models.Stateless.Methods.IContainer.GetFilterItems(_Configuration.PropertyConfiguration, container);
if (!filteredItems.Any())
continue;
containerDateTimes = Shared.Models.Stateless.Methods.IContainer.GetContainerDateTimes(filteredItems);
isIgnoreRelativePath = _Configuration.IgnoreRelativePaths.Any(l => container.SourceDirectory.Contains(l)) && Shared.Models.Stateless.Methods.IContainer.IsIgnoreRelativePath(_Configuration.PropertyConfiguration, _Configuration.IgnoreRelativePaths, container.SourceDirectory);
foreach (Item item in filteredItems)
{
if (item.Property?.Id is null || item.ResizedFileHolder is null)
continue;
mappingFromItem = Shared.Models.Stateless.Methods.IMappingFromItem.GetMappingFromItem(containerDateTimes, item);
foreach (Shared.Models.Face face in item.Faces)
{
if (face.FaceEncoding is null || face.Location is null || face.OutputResolution is null)
continue;
confidencePercent = Shared.Models.Stateless.Methods.ILocation.GetConfidencePercent(_Configuration.FaceConfidencePercent, _Configuration.RangeFaceConfidence, face.Location.Confidence);
faceAreaPermille = Shared.Models.Stateless.Methods.IMapping.GetAreaPermille(_Configuration.FaceAreaPermille, face.Location, face.OutputResolution);
normalizedRectangle = Shared.Models.Stateless.Methods.ILocation.GetNormalizedRectangle(face.Location, Shared.Models.Stateless.ILocation.Digits, face.OutputResolution);
deterministicHashCodeKey = Shared.Models.Stateless.Methods.IMapping.GetDeterministicHashCodeKey(item.Property.Id.Value, face.Location, Shared.Models.Stateless.ILocation.Digits, face.OutputResolution);
mappingFromLocation = new(faceAreaPermille, confidencePercent, deterministicHashCodeKey, normalizedRectangle);
mapping = new(mappingFromItem, mappingFromLocation);
face.SetMapping(mapping);
}
}
}
}
private Shared.Models.Face[] GetFilteredDistinctFaces(string argZero, Container[] containers)
{
Shared.Models.Face[] results;
Item[] filteredItems;
bool isIgnoreRelativePath;
List<int> distinct = new();
List<Shared.Models.Face> collection = new();
foreach (Container container in containers)
{
@ -756,11 +794,10 @@ public partial class DlibDotNet
continue;
if (!_ArgZeroIsConfigurationRootDirectory && !container.SourceDirectory.StartsWith(argZero))
continue;
if (_Configuration.IgnoreRelativePaths.Any(l => container.SourceDirectory.Contains(l)) && IsIgnoreRelativePath(container.SourceDirectory))
continue;
filteredItems = GetFilterItems(container);
filteredItems = Shared.Models.Stateless.Methods.IContainer.GetFilterItems(_Configuration.PropertyConfiguration, container);
if (!filteredItems.Any())
continue;
isIgnoreRelativePath = _Configuration.IgnoreRelativePaths.Any(l => container.SourceDirectory.Contains(l)) && Shared.Models.Stateless.Methods.IContainer.IsIgnoreRelativePath(_Configuration.PropertyConfiguration, _Configuration.IgnoreRelativePaths, container.SourceDirectory);
foreach (Item item in filteredItems)
{
if (item.Property?.Id is null || item.ResizedFileHolder is null)
@ -768,38 +805,55 @@ public partial class DlibDotNet
if (distinct.Contains(item.Property.Id.Value))
continue;
distinct.Add(item.Property.Id.Value);
if (!item.Faces.Any(l => l.FaceEncoding is not null && l.Location is not null && l.OutputResolution is not null))
{
items.Add(item);
if (isIgnoreRelativePath)
continue;
}
mappingFromItem = Shared.Models.Stateless.Methods.IMappingFromItem.GetMappingFromItem(item);
foreach (Shared.Models.Face face in item.Faces)
{
if (face.FaceEncoding is null || face.Location is null || face.OutputResolution is null)
continue;
confidencePercent = Shared.Models.Stateless.Methods.ILocation.GetConfidencePercent(_Configuration.FaceConfidencePercent, _Configuration.RangeFaceConfidence, face.Location.Confidence);
faceAreaPermille = Shared.Models.Stateless.Methods.IMapping.GetAreaPermille(_Configuration.FaceAreaPermille, face.Location, face.OutputResolution);
normalizedPixelPercentage = Shared.Models.Stateless.Methods.ILocation.GetNormalizedPixelPercentage(face.Location, Shared.Models.Stateless.ILocation.Digits, Shared.Models.Stateless.ILocation.Factor, face.OutputResolution);
deterministicHashCodeKey = Shared.Models.Stateless.Methods.IMapping.GetDeterministicHashCodeKey(item.Property.Id.Value, face.Location, Shared.Models.Stateless.ILocation.Digits, Shared.Models.Stateless.ILocation.Factor, face.OutputResolution);
mappingFromLocation = new(faceAreaPermille, confidencePercent, deterministicHashCodeKey, normalizedPixelPercentage);
mapping = new(mappingFromItem, mappingFromLocation);
face.SetMapping(mapping);
collection.Add(face);
}
}
}
faces = (from l in collection orderby l.Mapping?.MappingFromItem.Id select l).ToArray();
return new(items, faces);
results = (from l in collection orderby l.Mapping?.MappingFromItem.Id select l).ToArray();
return results;
}
private void MapLogic(string argZero, long ticks, PersonContainer[] personContainers, Container[] containers, string a2PeopleSingletonDirectory, string dResultsFullGroupDirectory, string d2FacePartsContentDirectory, string eDistanceContentDirectory, string outputResolution)
private List<Item> GetItems(string argZero, Container[] containers)
{
List<Item> items = new();
Item[] filteredItems;
bool isIgnoreRelativePath;
List<Shared.Models.Face> collection = new();
foreach (Container container in containers)
{
if (!container.Items.Any())
continue;
if (!_ArgZeroIsConfigurationRootDirectory && !container.SourceDirectory.StartsWith(argZero))
continue;
filteredItems = Shared.Models.Stateless.Methods.IContainer.GetFilterItems(_Configuration.PropertyConfiguration, container);
if (!filteredItems.Any())
continue;
isIgnoreRelativePath = _Configuration.IgnoreRelativePaths.Any(l => container.SourceDirectory.Contains(l)) && Shared.Models.Stateless.Methods.IContainer.IsIgnoreRelativePath(_Configuration.PropertyConfiguration, _Configuration.IgnoreRelativePaths, container.SourceDirectory);
foreach (Item item in filteredItems)
{
if (item.Property?.Id is null || item.ResizedFileHolder is null)
continue;
items.Add(item);
}
}
return items;
}
private void MapLogic(string argZero, long ticks, PersonContainer[] personContainers, Container[] containers, string a2PeopleSingletonDirectory, string dResultsFullGroupDirectory, string d2ResultsFullGroupDirectory, string eDistanceContentDirectory, string outputResolution)
{
int? useFiltersCounter = null;
SortingContainer[] sortingContainers;
string dFacesContentDirectory = Path.Combine(dResultsFullGroupDirectory, "()");
(List<Item> filteredItems, Shared.Models.Face[] distinctFilteredFaces) = SetMappingThenGetDistinctFilteredFacesWithMapping(argZero, containers);
string d2FacePartsContentDirectory = Path.Combine(d2ResultsFullGroupDirectory, "()");
Shared.Models.Face[] distinctFilteredFaces = GetFilteredDistinctFaces(argZero, containers);
Mapping[] mappingCollection = MapLogicSupport.GetSelectedMappingCollection(distinctFilteredFaces);
string dFacesCollectionDirectory = Path.Combine(dResultsFullGroupDirectory, "[]", _Configuration.PropertyConfiguration.ResultAllInOne);
MapLogicSupport mapLogicSupport = new(
_Configuration.FaceConfidencePercent,
_Configuration.FaceDistancePermyriad,
@ -816,33 +870,50 @@ public partial class DlibDotNet
eDistanceContentDirectory,
mappingCollection,
mapLogicSupport);
Dictionary<int, Dictionary<int, Mapping>> idToNormalizedPixelPercentageToMapping = MapLogicSupport.GetIdToNormalizedPixelPercentageToFace(mappingCollection);
mapLogic.CopyManualFiles(dFacesContentDirectory, idToNormalizedPixelPercentageToMapping);
if (_Configuration.SaveNotMappedForOutputResolutions.Contains(outputResolution))
mapLogic.CopyNotMappedFaces(_Configuration.RangeFaceAreaPermilleTolerance, dFacesContentDirectory, idToNormalizedPixelPercentageToMapping);
(Dictionary<long, int> personKeyToCount, int totalNotMapped) = mapLogic.AddToMapping(mappingCollection);
if (_Configuration.SaveMappedForOutputResolutions.Contains(outputResolution))
mapLogic.SaveMapped(dFacesContentDirectory, d2FacePartsContentDirectory, mappingCollection, idToNormalizedPixelPercentageToMapping, personKeyToCount, totalNotMapped);
if (_Configuration.SaveShortcutsForOutputResolutions.Contains(outputResolution) || (!string.IsNullOrEmpty(_Configuration.PhotoPrismDirectory) && Directory.Exists(_Configuration.PhotoPrismDirectory)))
{
List<Item> filteredItems = GetItems(argZero, containers);
if (!string.IsNullOrEmpty(_Configuration.PhotoPrismDirectory))
{
mapLogic.SaveMarkers();
mapLogic.FindMatch(filteredItems);
mapLogic.LoadMatches();
}
if (_Configuration.SaveShortcutsForOutputResolutions.Contains(outputResolution))
mapLogic.SaveShortcuts(a2PeopleSingletonDirectory, personContainers, filteredItems, mappingCollection, personKeyToCount);
mapLogic.SaveShortcutsForOutputResolutions(filteredItems, mappingCollection, personKeyToCount);
}
Dictionary<int, Dictionary<int, Mapping>> idToNormalizedRectangleToMapping = MapLogicSupport.GetIdToNormalizedRectangleToFace(mappingCollection);
mapLogic.CopyManualFiles(dFacesContentDirectory, idToNormalizedRectangleToMapping);
if (_Configuration.SaveNotMappedForOutputResolutions.Contains(outputResolution))
mapLogic.CopyNotMappedFaces(_Configuration.RangeFaceAreaPermilleTolerance, dFacesContentDirectory, idToNormalizedRectangleToMapping);
if (_Configuration.SaveMappedForOutputResolutions.Contains(outputResolution))
mapLogic.SaveMapped(dFacesContentDirectory, d2FacePartsContentDirectory, mappingCollection, idToNormalizedRectangleToMapping, personKeyToCount, totalNotMapped);
if (_Configuration.SaveResizedImagesByPersonKeyFormattedForOutputResolutions.Contains(outputResolution))
mapLogic.SaveResizedImagesByPersonKeyFormatted(_Configuration.JLinks, a2PeopleSingletonDirectory, personContainers, mappingCollection, personKeyToCount, totalNotMapped);
if (_Configuration.SaveFaceDistancesForOutputResolutions.Contains(outputResolution))
{
MapLogicSupport.SetFaceDistances(_AppSettings.MaxDegreeOfParallelism, ticks, distinctFilteredFaces);
sortingContainers = mapLogicSupport.SetFaceMappingSortingCollectionThenGetSortingContainers(_AppSettings.MaxDegreeOfParallelism, ticks, mapLogic, distinctFilteredFaces, useFiltersCounter);
Dictionary<int, Dictionary<int, PersonContainer[]>> missingIdThenNormalizedRectangleToPersonContainers = mapLogic.GetMissing(idToNormalizedRectangleToMapping);
List<FaceDistanceContainer> missingFaceDistanceContainers = _Distance.GetMissingFaceDistanceContainer(_AppSettings.MaxDegreeOfParallelism, ticks, dFacesCollectionDirectory, missingIdThenNormalizedRectangleToPersonContainers);
sortingContainers = mapLogicSupport.SetFaceMappingSortingCollectionThenGetSortingContainers(_AppSettings.MaxDegreeOfParallelism, ticks, mapLogic, distinctFilteredFaces, missingFaceDistanceContainers, useFiltersCounter);
if (!sortingContainers.Any())
{
for (useFiltersCounter = 1; useFiltersCounter < 17; useFiltersCounter++)
{
sortingContainers = mapLogicSupport.SetFaceMappingSortingCollectionThenGetSortingContainers(_AppSettings.MaxDegreeOfParallelism, ticks, mapLogic, distinctFilteredFaces, useFiltersCounter);
sortingContainers = mapLogicSupport.SetFaceMappingSortingCollectionThenGetSortingContainers(_AppSettings.MaxDegreeOfParallelism, ticks, mapLogic, distinctFilteredFaces, missingFaceDistanceContainers, useFiltersCounter);
if (sortingContainers.Any())
break;
}
}
MapLogicSupport.SaveFaceDistances(_Configuration.PropertyConfiguration, sortingContainers);
if (totalNotMapped > 0)
mapLogic.UpdateFromSortingContainersThenSaveContainers(dFacesContentDirectory, d2FacePartsContentDirectory, mappingCollection, idToNormalizedPixelPercentageToMapping, useFiltersCounter, sortingContainers, totalNotMapped);
{
bool saveNullPerson = !personKeyToCount.Any();
int updated = mapLogic.UpdateFromSortingContainers(sortingContainers, saveNullPerson);
List<SaveContainer> saveContainers = mapLogic.GetSaveContainers(dFacesContentDirectory, d2FacePartsContentDirectory, mappingCollection, idToNormalizedRectangleToMapping, useFiltersCounter, saveNullPerson);
mapLogic.SaveContainers(totalNotMapped, updated, saveContainers);
}
}
if (_Configuration.SaveNotMappedForOutputResolutions.Contains(outputResolution))
mapLogic.SaveNotMappedTicks();
@ -886,6 +957,7 @@ public partial class DlibDotNet
string fileName;
Task<byte[]> task;
string relativePath;
FileHolder fileHolder;
string extensionLowered;
string sourceDirectoryFile;
int length = result.Length;
@ -907,7 +979,8 @@ public partial class DlibDotNet
extensionLowered = Path.GetExtension(uri.LocalPath);
relativePath = Shared.Models.Stateless.Methods.IPath.GetRelativePath(sourceDirectoryFile, length, forceExtensionToLower: true);
isValidImageFormatExtension = _Configuration.PropertyConfiguration.ValidImageFormatExtensions.Contains(extensionLowered);
item = new(sourceDirectoryFile, relativePath, isValidImageFormatExtension);
fileHolder = new(sourceDirectoryFile);
item = new(fileHolder, relativePath, isValidImageFormatExtension);
container.Items.Add(item);
}
_Log.Information(". . .");
@ -918,21 +991,23 @@ public partial class DlibDotNet
{
List<MappingFromItem> results = new();
Item[] filteredItems;
DateTime[] containerDateTimes;
MappingFromItem mappingFromItem;
foreach (Container container in containers)
{
if (!container.Items.Any())
continue;
if (_Configuration.IgnoreRelativePaths.Any(l => container.SourceDirectory.Contains(l)) && IsIgnoreRelativePath(container.SourceDirectory))
if (_Configuration.IgnoreRelativePaths.Any(l => container.SourceDirectory.Contains(l)) && Shared.Models.Stateless.Methods.IContainer.IsIgnoreRelativePath(_Configuration.PropertyConfiguration, _Configuration.IgnoreRelativePaths, container.SourceDirectory))
continue;
filteredItems = GetFilterItems(container);
filteredItems = Shared.Models.Stateless.Methods.IContainer.GetFilterItems(_Configuration.PropertyConfiguration, container);
if (!filteredItems.Any())
continue;
containerDateTimes = Shared.Models.Stateless.Methods.IContainer.GetContainerDateTimes(filteredItems);
foreach (Item item in filteredItems)
{
if (item.Property?.Id is null)
continue;
mappingFromItem = Shared.Models.Stateless.Methods.IMappingFromItem.GetMappingFromItem(item);
mappingFromItem = Shared.Models.Stateless.Methods.IMappingFromItem.GetMappingFromItem(containerDateTimes, item);
results.Add(mappingFromItem);
}
}
@ -951,8 +1026,8 @@ public partial class DlibDotNet
string cResultsFullGroupDirectory;
string dResultsFullGroupDirectory;
string? eDistanceContentDirectory;
string d2ResultsFullGroupDirectory;
string a2PeopleSingletonDirectory = Property.Models.Stateless.IResult.GetResultsDateGroupDirectory(_Configuration.PropertyConfiguration, nameof(A2_People), "{}");
string d2FacePartsContentDirectory = Property.Models.Stateless.IResult.GetResultsDateGroupDirectory(_Configuration.PropertyConfiguration, nameof(D2_FaceParts), "()");
int totalSeconds = (int)Math.Floor(new TimeSpan(DateTime.Now.Ticks - ticks).TotalSeconds);
string message = $") Building Container(s) - {totalSeconds} total second(s)";
A_Property propertyLogic = new(_AppSettings.MaxDegreeOfParallelism, _Configuration.PropertyConfiguration, _Resize.FileNameExtension, _Configuration.Reverse);
@ -970,24 +1045,29 @@ public partial class DlibDotNet
}
else
{
string resultsGroupDirectory;
a2PeopleContentDirectory = null;
eDistanceContentDirectory = null;
string? newRootDirectory = SaveUrlAndGetNewRootDirectory(container);
for (int i = 1; i < 10; i++)
_ = Shared.Models.Stateless.Methods.IPath.DeleteEmptyDirectories(Property.Models.Stateless.IResult.GetResultsGroupDirectory(_Configuration.PropertyConfiguration, string.Empty, create: true));
{
resultsGroupDirectory = Property.Models.Stateless.IResult.GetResultsGroupDirectory(_Configuration.PropertyConfiguration, string.Empty, create: true);
_ = Shared.Models.Stateless.Methods.IPath.DeleteEmptyDirectories(resultsGroupDirectory);
}
argZero = newRootDirectory;
_Configuration.PropertyConfiguration.ChangeRootDirectory(newRootDirectory);
propertyRoot = Property.Models.Stateless.IResult.GetResultsGroupDirectory(_Configuration.PropertyConfiguration, nameof(A_Property), create: false);
propertyLogic = new(_AppSettings.MaxDegreeOfParallelism, _Configuration.PropertyConfiguration, _Resize.FileNameExtension, _Configuration.Reverse);
}
Dictionary<int, List<(string, int)>> idToMappedFaceFilesCollection = Map.Models.Stateless.Methods.IMapLogic.DeleteEmptyDirectoriesAndGetMappedFaceFiles(_MapConfiguration, ticks, a2PeopleContentDirectory, eDistanceContentDirectory, personContainers);
containers = Shared.Models.Stateless.Methods.IContainer.SortContainers(_Configuration.PropertyConfiguration, _Configuration.IgnoreRelativePaths, _ArgZeroIsConfigurationRootDirectory, argZero, containers);
FullDoWork(argZero, propertyRoot, ticks, propertyLogic, t, containers, eDistanceContentDirectory, idToMappedFaceFilesCollection);
_Distance.Clear();
foreach (string outputResolution in _Configuration.OutputResolutions)
{
if (_PropertyRootExistedBefore || container is not null)
break;
(aResultsFullGroupDirectory, bResultsFullGroupDirectory, cResultsFullGroupDirectory, dResultsFullGroupDirectory) = GetResultsFullGroupDirectories(outputResolution);
(aResultsFullGroupDirectory, bResultsFullGroupDirectory, cResultsFullGroupDirectory, dResultsFullGroupDirectory, d2ResultsFullGroupDirectory) = GetResultsFullGroupDirectories(outputResolution);
if (_Configuration.SaveResizedImagesByPersonKeyFormattedForOutputResolutions.Contains(outputResolution))
MapLogicSupport.BeforeSaveResizedImagesByPersonKeyFormatted(_Configuration.JLinks, a2PeopleSingletonDirectory);
if (_ArgZeroIsConfigurationRootDirectory
@ -999,7 +1079,8 @@ public partial class DlibDotNet
{
if (!_Configuration.LoadOrCreateThenSaveImageFacesResultsForOutputResolutions.Any())
break;
MapLogic(argZero, ticks, personContainers, containers, a2PeopleSingletonDirectory, dResultsFullGroupDirectory, d2FacePartsContentDirectory, eDistanceContentDirectory, outputResolution);
SetMapping(argZero, containers);
MapLogic(argZero, ticks, personContainers, containers, a2PeopleSingletonDirectory, dResultsFullGroupDirectory, d2ResultsFullGroupDirectory, eDistanceContentDirectory, outputResolution);
if (_IsEnvironment.Development)
continue;
List<MappingFromItem> mappingFromItemCollection = GetMappingFromItemCollection(containers);

View File

@ -34,12 +34,12 @@
<SupportedPlatform Include="browser" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Cryptography.KeyDerivation" Version="7.0.0" />
<PackageReference Include="Microsoft.AspNetCore.Cryptography.KeyDerivation" Version="7.0.1" />
<PackageReference Include="Microsoft.Extensions.Hosting" Version="7.0.0" />
<PackageReference Include="Microsoft.Extensions.Identity.Core" Version="7.0.0" />
<PackageReference Include="Microsoft.Extensions.Identity.Core" Version="7.0.1" />
<PackageReference Include="Microsoft.Extensions.Options" Version="7.0.0" />
<PackageReference Include="System.Drawing.Common" Version="7.0.0" />
<PackageReference Include="System.Text.Json" Version="7.0.0" />
<PackageReference Include="System.Text.Json" Version="7.0.1" />
<PackageReference Include="MetadataExtractor" Version="2.7.2" />
<PackageReference Include="Serilog.Settings.Configuration" Version="3.4.0" />
<PackageReference Include="Serilog.Sinks.Console" Version="4.1.0" />

View File

@ -50,6 +50,7 @@ public class Configuration
[Display(Name = "Person Birthday First Year"), Required] public int? PersonBirthdayFirstYear { get; set; }
[Display(Name = "Person Birthday Format"), Required] public string PersonBirthdayFormat { get; set; }
[Display(Name = "PersonKey Format"), Required] public string PersonKeyFormat { get; set; }
[Display(Name = "Photo-Prism Directory"), Required] public string PhotoPrismDirectory { get; set; }
[Display(Name = "Predictor Model Name"), Required] public string PredictorModelName { get; set; }
[Display(Name = "Properties Changed For Distance"), Required] public bool? PropertiesChangedForDistance { get; set; }
[Display(Name = "Properties Changed For Faces"), Required] public bool? PropertiesChangedForFaces { get; set; }
@ -58,10 +59,10 @@ public class Configuration
[Display(Name = "Properties Changed For Resize"), Required] public bool? PropertiesChangedForResize { get; set; }
[Display(Name = "Property Configuration"), Required] public Property.Models.Configuration PropertyConfiguration { get; set; }
[Display(Name = "Sorting Days Delta Tolerance"), Required] public int[] RangeDaysDeltaTolerance { get; set; }
[Display(Name = "Face Distance Tolerance"), Required] public double[] RangeDistanceTolerance { get; set; }
[Display(Name = "Face Area Permille Tolerance"), Required] public int[] RangeFaceAreaPermilleTolerance { get; set; }
[Display(Name = "Location Minimum Confidence"), Required] public double[] RangeFaceConfidence { get; set; }
[Display(Name = "Face Distance Tolerance"), Required] public double[] RangeDistanceTolerance { get; set; }
[Display(Name = "Retry Images Without a Face"), Required] public bool? RetryImagesWithoutAFace { get; set; }
[Display(Name = "Retry Images Without a Face"), Required] public bool? RetryImagesWithoutAFaceLocation { get; set; }
[Display(Name = "Reverse"), Required] public bool? Reverse { get; set; }
[Display(Name = "Save Face Distances"), Required] public string[] SaveFaceDistancesForOutputResolutions { get; set; }
[Display(Name = "Save Face Landmark For Output Resolutions"), Required] public string[] SaveFaceLandmarkForOutputResolutions { get; set; }
@ -159,6 +160,8 @@ public class Configuration
throw new NullReferenceException(nameof(configuration.PersonBirthdayFormat));
if (configuration.PersonKeyFormat is null)
throw new NullReferenceException(nameof(configuration.PersonKeyFormat));
if (configuration.PhotoPrismDirectory is null)
throw new NullReferenceException(nameof(configuration.PhotoPrismDirectory));
if (configuration.PropertiesChangedForDistance is null)
throw new NullReferenceException(nameof(configuration.PropertiesChangedForDistance));
if (configuration.PropertiesChangedForFaces is null)
@ -177,8 +180,8 @@ public class Configuration
throw new NullReferenceException(nameof(configuration.RangeFaceConfidence));
if (configuration.RangeDistanceTolerance is null || configuration.RangeDistanceTolerance.Length != 3)
throw new NullReferenceException(nameof(configuration.RangeDistanceTolerance));
if (configuration.RetryImagesWithoutAFace is null)
throw new NullReferenceException(nameof(configuration.RetryImagesWithoutAFace));
if (configuration.RetryImagesWithoutAFaceLocation is null)
throw new NullReferenceException(nameof(configuration.RetryImagesWithoutAFaceLocation));
if (configuration.Reverse is null)
throw new NullReferenceException(nameof(configuration.Reverse));
configuration.SaveFaceDistancesForOutputResolutions ??= Array.Empty<string>();
@ -235,8 +238,6 @@ public class Configuration
configuration.MixedYearRelativePaths,
configuration.ModelDirectory,
configuration.ModelName,
configuration.NumberOfJitters.Value,
configuration.NumberOfTimesToUpsample.Value,
configuration.OutputExtension,
configuration.OutputQuality.Value,
configuration.OutputResolutions,
@ -246,6 +247,7 @@ public class Configuration
configuration.PersonBirthdayFirstYear.Value,
configuration.PersonBirthdayFormat,
configuration.PersonKeyFormat,
configuration.PhotoPrismDirectory,
configuration.PredictorModelName,
configuration.PropertiesChangedForDistance.Value,
configuration.PropertiesChangedForFaces.Value,
@ -256,7 +258,7 @@ public class Configuration
configuration.RangeFaceAreaPermilleTolerance,
configuration.RangeFaceConfidence,
configuration.RangeDistanceTolerance,
configuration.RetryImagesWithoutAFace.Value,
configuration.RetryImagesWithoutAFaceLocation.Value,
configuration.Reverse.Value,
configuration.SaveFaceDistancesForOutputResolutions,
configuration.SaveFaceLandmarkForOutputResolutions,
@ -289,9 +291,7 @@ public class Configuration
configuration = configurationSection.Get<Configuration>();
}
result = Get(configuration);
if (configuration is null)
throw new NullReferenceException(nameof(configuration));
result.SetAndUpdate(propertyConfiguration, configuration.NumberOfJitters, configuration.NumberOfTimesToUpsample, configuration.ModelName, configuration.PredictorModelName);
result.SetAndUpdate(propertyConfiguration, configuration?.NumberOfJitters, configuration?.NumberOfTimesToUpsample, configuration?.ModelName, configuration?.PredictorModelName);
return result;
}

View File

@ -38,8 +38,6 @@ public class Configuration
public string[] MixedYearRelativePaths { init; get; }
public string ModelDirectory { init; get; }
public string ModelName { init; get; }
public int NumberOfJitters { init; get; }
public int NumberOfTimesToUpsample { init; get; }
public string OutputExtension { init; get; }
public int OutputQuality { init; get; }
public string[] OutputResolutions { init; get; }
@ -49,6 +47,7 @@ public class Configuration
public int PersonBirthdayFirstYear { init; get; }
public string PersonBirthdayFormat { init; get; }
public string PersonKeyFormat { init; get; }
public string PhotoPrismDirectory { init; get; }
public string PredictorModelName { init; get; }
public bool PropertiesChangedForDistance { init; get; }
public bool PropertiesChangedForFaces { init; get; }
@ -59,7 +58,7 @@ public class Configuration
public int[] RangeFaceAreaPermilleTolerance { init; get; }
public double[] RangeFaceConfidence { init; get; }
public double[] RangeDistanceTolerance { init; get; }
public bool RetryImagesWithoutAFace { init; get; }
public bool RetryImagesWithoutAFaceLocation { init; get; }
public bool Reverse { init; get; }
public string[] SaveFaceDistancesForOutputResolutions { init; get; }
public string[] SaveFaceLandmarkForOutputResolutions { init; get; }
@ -107,8 +106,6 @@ public class Configuration
string[] mixedYearRelativePaths,
string modelDirectory,
string modelName,
int numberOfJitters,
int numberOfTimesToUpsample,
string outputExtension,
int outputQuality,
string[] outputResolutions,
@ -118,6 +115,7 @@ public class Configuration
int personBirthdayFirstYear,
string personBirthdayFormat,
string personKeyFormat,
string photoPrismDirectory,
string predictorModelName,
bool propertiesChangedForDistance,
bool propertiesChangedForFaces,
@ -128,7 +126,7 @@ public class Configuration
int[] rangeFaceAreaPermilleTolerance,
double[] rangeFaceConfidence,
double[] rangeDistanceTolerance,
bool retryImagesWithoutAFace,
bool retryImagesWithoutAFaceLocation,
bool reverse,
string[] saveFaceDistancesForOutputResolutions,
string[] saveFaceLandmarkForOutputResolutions,
@ -175,8 +173,6 @@ public class Configuration
MixedYearRelativePaths = mixedYearRelativePaths;
ModelDirectory = modelDirectory;
ModelName = modelName;
NumberOfJitters = numberOfJitters;
NumberOfTimesToUpsample = numberOfTimesToUpsample;
OutputExtension = outputExtension;
OutputQuality = outputQuality;
OutputResolutions = outputResolutions;
@ -186,6 +182,7 @@ public class Configuration
PersonBirthdayFirstYear = personBirthdayFirstYear;
PersonBirthdayFormat = personBirthdayFormat;
PersonKeyFormat = personKeyFormat;
PhotoPrismDirectory = photoPrismDirectory;
PredictorModelName = predictorModelName;
PropertiesChangedForDistance = propertiesChangedForDistance;
PropertiesChangedForFaces = propertiesChangedForFaces;
@ -196,7 +193,7 @@ public class Configuration
RangeFaceAreaPermilleTolerance = rangeFaceAreaPermilleTolerance;
RangeFaceConfidence = rangeFaceConfidence;
RangeDistanceTolerance = rangeDistanceTolerance;
RetryImagesWithoutAFace = retryImagesWithoutAFace;
RetryImagesWithoutAFaceLocation = retryImagesWithoutAFaceLocation;
Reverse = reverse;
SaveFaceDistancesForOutputResolutions = saveFaceDistancesForOutputResolutions;
SaveFaceLandmarkForOutputResolutions = saveFaceLandmarkForOutputResolutions;

View File

@ -145,7 +145,6 @@ public class G_Index : Shared.Models.Properties.IIndex, IIndex
Dictionary<string, List<Tuple<string, Shared.Models.Property>>> filePropertiesKeyValuePairs = new();
FileInfo fileInfo;
G_Index indexInfo;
string parentCheck;
List<int> indices = new();
Dictionary<int, G_Index> valuePairs;
List<string> directoryInfoCollection;
@ -170,14 +169,6 @@ public class G_Index : Shared.Models.Properties.IIndex, IIndex
foreach (Tuple<string, Shared.Models.Property> tuple in tuples.Value)
{
fileInfo = new FileInfo(Path.Combine(directoryInfoCollection[0].Replace("<>", "{}"), string.Concat(Path.GetFileNameWithoutExtension(tuple.Item1), ".json")));
if (!fileInfo.FullName.Contains(configuration.ResultAllInOne) && !fileInfo.Exists)
{
if (fileInfo.Directory?.Parent is null)
throw new Exception();
parentCheck = Path.Combine(fileInfo.Directory.Parent.FullName, fileInfo.Name);
if (File.Exists(parentCheck))
File.Delete(parentCheck);
}
if (_Configuration.PropertiesChangedForIndex)
indexInfo = null;
else if (!fileInfo.Exists)

View File

@ -18,6 +18,7 @@ public class Program
IsEnvironment isEnvironment = new(processesCount: null, nullASPNetCoreEnvironmentIsDevelopment: debuggerWasAttachedAtLineZero, nullASPNetCoreEnvironmentIsProduction: !debuggerWasAttachedAtLineZero);
IConfigurationBuilder configurationBuilder = new ConfigurationBuilder()
.AddEnvironmentVariables()
.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
.AddJsonFile(isEnvironment.AppSettingsFileName, optional: false, reloadOnChange: true);
IConfigurationRoot configurationRoot = configurationBuilder.Build();
AppSettings appSettings = Models.Binder.AppSettings.Get(configurationRoot);

View File

@ -1,129 +1,23 @@
{
"Company": "Mike Phares",
"Linux": {},
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Log4netProvider": "Debug",
"Microsoft.Hosting.Lifetime": "Information"
"Log4netProvider": "Debug"
}
},
"MaxDegreeOfParallelism": 6,
"Serilog": {
"Using": [
"Serilog.Sinks.Console",
"Serilog.Sinks.File"
],
"MinimumLevel": "Debug",
"WriteTo": [
{
"Name": "Debug",
"Args": {
"outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz} [{Level}] ({SourceContext}.{MethodName}) ({InstanceId}) ({RemoteIpAddress}) {Message}{NewLine}{Exception}"
}
"MinimumLevel": "Debug"
},
{
"Name": "Console",
"Args": {
"outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz} [{Level}] ({SourceContext}.{MethodName}) ({InstanceId}) ({RemoteIpAddress}) {Message}{NewLine}{Exception}"
}
},
{
"Name": "File",
"Args": {
"path": "%workingDirectory% - Log/log-.txt",
"outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz} [{Level}] ({SourceContext}.{MethodName}) ({InstanceId}) ({RemoteIpAddress}) {Message}{NewLine}{Exception}",
"rollingInterval": "Hour"
}
}
],
"Enrich": [
"FromLogContext",
"WithMachineName",
"WithThreadId"
],
"Properties": {
"Application": "Sample"
}
},
"WorkingDirectoryName": "PharesApps",
"Windows": {
"Configuration": {
"CheckDFaceAndUpWriteDates": true,
"CheckJsonForDistanceResults": false,
"CrossDirectoryMaxItemsInDistanceCollection": 7,
"DateGroup": "2022-11-12",
"DistanceFactor": 8,
"DistanceMoveUnableToMatch": false,
"DistancePixelDistanceTolerance": 1,
"DistanceRenameToMatch": false,
"FaceAreaPermille": 1000,
"FaceDistanceHiddenImageFactor": 2,
"FaceConfidencePercent": 100,
"FaceDistancePermyriad": 10000,
"FileNameDirectorySeparator": ".Z.",
"ForceFaceLastWriteTimeToCreationTime": false,
"ForceMetadataLastWriteTimeToCreationTime": false,
"ForcePropertyLastWriteTimeToCreationTime": false,
"ForceResizeLastWriteTimeToCreationTime": false,
"LoadOrCreateThenSaveIndex": false,
"LocationDigits": 9,
"LocationFactor": 10000,
"MappedMaxIndex": 1034720,
"MappingDefaultName": "John Doe~25",
"MappingUseDeterministicHashCodeUnknownFaceKeyValuePairsForAddToMapping": false,
"MappingUseDeterministicHashCodeUnknownFaceKeyValuePairsForSaveMapping": false,
"MaxImagesInDirectoryForTopLevelFirstPass": 10,
"ModelDirectory": "C:/GitHub/dlib-models",
"ModelName": "Hog",
"NumberOfJitters": 0,
"NumberOfTimesToUpsample": 0,
"OutputExtension": ".jpg",
"OutputQuality": 95,
"OverrideForFaceImages": false,
"OverrideForFaceLandmarkImages": false,
"OverrideForResizeImages": false,
"Pattern": "[^ABCDEFGHIJKLMNOPQRSTUVWXYZbcdfghjklmnpqrstvwxyz0-9]",
"PersonBirthdayFirstYear": 1500,
"PersonBirthdayFormat": "yyyy-MM-dd_HH",
"PersonKeyFormat": "yyyy-MM-dd_HH",
"PersonRequirePeopleFile": true,
"PopulatePropertyId": true,
"PredictorModelName": "Large",
"PropertiesChangedForDistance": false,
"PropertiesChangedForFaces": false,
"PropertiesChangedForIndex": false,
"PropertiesChangedForMetadata": false,
"PropertiesChangedForProperty": false,
"PropertiesChangedForResize": false,
"ResultAllInOne": "_ _ _",
"ResultCollection": "[]",
"ResultContent": "()",
"ResultSingleton": "{}",
"RetryImagesWithoutAFace": false,
"Reverse": false,
"PhotoPrismDirectory": "G:/photo-prism/Not-Copy-Copy-All/phpMyAdmin/export",
"xRootDirectory": "C:/Tmp/phares/Pictures",
"RootDirectory": "F:/Tmp/Phares/Compare/Images 2022-11-12 - c6aa7e8 - III",
"xxRootDirectory": "F:/Tmp/Phares/Compare/Images 2022-11-12 - c6aa7e8 - III/Facebook/=2022.3 Facebook",
"SaveFullYearOfRandomFiles": true,
"SaveResizedSubFiles": true,
"SkipSearch": false,
"SortingMaximumPerFaceShouldBeHigh": 3000,
"SortingMaximumPerKey": 7,
"SortingMinimumToUseSigma": 10,
"TestDistanceResults": true,
"WriteBitmapDataBytes": false,
"IgnoreExtensions": [
".gif",
".GIF"
],
"xxRootDirectory": "F:/Tmp/Phares/Compare/Not-Copy-Copy-All",
"RootDirectory": "F:/Tmp/Phares/Compare/Images 2022-11-12 - c6aa7e8",
"xxxxRootDirectory": "F:/Tmp/Phares/Compare/Images 2022-11-12 - c6aa7e8/Facebook/=2022.3 Facebook",
"JLinks": [
"Julie"
],
"LoadOrCreateThenSaveDirectoryDistanceResultsForOutputResolutions": [
"7680 x 4320"
],
"LoadOrCreateThenSaveDistanceResultsForOutputResolutions": [
"7680 x 4320"
],
@ -136,17 +30,17 @@
"PropertyContentCollectionFiles": [],
"RangeDaysDeltaTolerance": [
0,
700,
2100,
123456
],
"RangeDistanceTolerance": [
0,
0.4,
0.6,
0.6
],
"RangeFaceAreaPermilleTolerance": [
0,
10,
3,
1000
],
"RangeFaceConfidence": [
@ -154,72 +48,135 @@
0.2,
100
],
"SaveFaceLandmarkForOutputResolutions": [
"176 x 176",
"256 x 256"
"SaveFaceDistancesForOutputResolutions": [
"7680 x 4320"
],
"SaveFaceDistancesForOutputResolutions": [],
"SaveFaceLandmarkForOutputResolutions": [],
"SaveMappedForOutputResolutions": [],
"SaveNotMappedForOutputResolutions": [],
"SaveResizedImagesByPersonKeyFormattedForOutputResolutions": [],
"SaveShortcutsForOutputResolutions": [
"7680 x 4320"
"SaveShortcutsForOutputResolutions": [],
"IgnoreRelativePaths": [
"3757 W Whitman 2017",
"501 Playful Meadows 2006",
"501 Playful Meadows 2007",
"501 Playful Meadows 2008",
"501 Playful Meadows 2009",
"501 Playful Meadows 2010",
"501 Playful Meadows 2013",
"501 Playful Meadows 2015",
"6309 Evesham 2003",
"6309 Evesham 2004",
"Crystal's Wedding 2003",
"Danny's Wedding 2009",
"Door images 2019",
"Family Pictures 2006",
"Family Pictures 2007",
"Family Pictures 2011",
"Family Pictures 2013",
"GrandPrix 2004",
"Kids School Pictures 2004",
"Kristy 2002",
"Kristy Parents Wedding 2005",
"Logan Ultrasound 2007",
"Mandy's Dogs 2008",
"Motorcycles 2010",
"Motorcycles 2013",
"Motorcycles 2014",
"Phares Slides",
"Portrait Innovations April 2008",
"Portrait Innovations December 2007",
"Portrait Innovations June 2008",
"Portrait Innovations March 2012",
"The guys house 2000",
"Tracy Pictures 2005",
"Tracy Pictures 2006",
"Tracy Pictures 2007",
"Tracy Pictures 2008",
"Tracy Pictures 2009",
"Tracy Pictures 2010",
"Tracy Pictures 2011",
"Tracy Pictures 2012",
"Tracy Pictures 2013 Jan-July",
"Tracy Pictures 2013 July- Dec",
"Tracy Pictures 2014",
"Tracy Pictures 2015",
"Tracy Took The Kids 2006",
"Tracy's Bday 2012",
"Tracy's Wedding 2002",
"Trip to Colorado 10 2002",
"Trip to Colorado June 2002",
"Tub 2002",
"Vericruz 2011",
"zzz =2005.1 Spring Tracy Pictures",
"zzz =2005.2 Summer Tracy Pictures",
"zzz =2005.3 Fall Tracy Pictures",
"zzz =2005.4 Winter Tracy Pictures",
"zzz =2006.1 Spring Tracy Pictures",
"zzz =2007.0 Winter Tracy Pictures",
"zzz =2007.2 Summer Tracy Pictures",
"zzz =2008.2 Summer Tracy Pictures",
"zzz =2009.0 Winter Tracy Pictures",
"zzz =2009.2 Summer Tracy Pictures",
"zzz =2009.3 Fall Tracy Pictures",
"zzz =2009.4 Winter Tracy Pictures",
"zzz =2010.0 Winter Tracy Pictures",
"zzz =2010.1 Spring Tracy Pictures",
"zzz =2010.2 Summer Tracy Pictures",
"zzz =2010.3 Fall Tracy Pictures",
"zzz =2011.0 Winter Tracy Pictures",
"zzz =2011.1 Spring Tracy Pictures",
"zzz =2011.2 Summer Tracy Pictures",
"zzz =2011.3 Fall Tracy Pictures",
"zzz =2011.4 Winter Tracy Pictures",
"zzz =2012.0 Winter Tracy Pictures",
"zzz =2012.1 Spring Tracy Pictures",
"zzz =2012.2 Summer Tracy Pictures",
"zzz =2012.3 Fall Tracy Pictures",
"zzz =2012.4 Winter Tracy Pictures",
"zzz =2013.0 Winter Tracy Pictures",
"zzz =2013.1 Spring Tracy Pictures",
"zzz =2013.2 Summer Tracy Pictures",
"zzz =2013.3 Fall Tracy Pictures",
"zzz =2013.4 Winter Tracy Pictures",
"zzz =2014.0 Winter Tracy Pictures",
"zzz =2014.1 Spring Tracy Pictures",
"zzz =2014.2 Summer Tracy Pictures",
"zzz =2014.3 Fall Tracy Pictures",
"zzz =2014.4 Winter Tracy Pictures",
"zzz =2015.0 Winter Tracy Pictures",
"zzz Family Pictures",
"zzz Family Pictures",
"zzz Family Pictures",
"zzz Family Pictures",
"zzz GrandPrix",
"zzz Motorcycles",
"zzz Motorcycles",
"zzz Motorcycles",
"zzz Parents Yard",
"zzz Phares Family Pictures",
"zzz Phares Slides ####",
"zzz Portrait Innovations April",
"zzz Portrait Innovations Files",
"zzz Portrait Innovations June",
"zzz Portrait Innovations March",
"zzz Rex Memorial ####",
"zzz Scanned Grandma's Quilt ####",
"zzz Scanned Pictures Of Kids ####",
"zzz Scanned Prints ####",
"zzz Slide in Name Order Originals (622) ####",
"zzz Tub",
"zzz Vericruz"
],
"ValidImageFormatExtensions": [
".bmp",
".BMP",
".gif",
".GIF",
".jpeg",
".JPEG",
".jpg",
".JPG",
".png",
".PNG",
".tiff",
".TIFF"
],
"ValidMetadataExtensions": [
".3gp",
".3GP",
".avi",
".AVI",
".bmp",
".BMP",
".gif",
".GIF",
".ico",
".ICO",
".jpeg",
".JPEG",
".jpg",
".JPG",
".m4v",
".M4V",
".mov",
".MOV",
".mp4",
".MP4",
".mta",
".MTA",
".png",
".PNG",
".tiff",
".TIFF"
],
"ValidResolutions": [
"176 x 176",
"256 x 256",
"353 x 353",
"1024 x 768",
"1280 x 720",
"1280 x 800",
"1376 x 768",
"1600 x 1200",
"1920 x 1080",
"2256 x 1496",
"3840 x 2160",
"7680 x 4320"
"MixedYearRelativePaths": [
"Edited",
"Phares Slides",
"Rex Memorial",
"Scanned Grandma's Quilt",
"Scanned Pictures Of Kids",
"Scanned Prints",
"Slide in Name Order Originals (622)",
"Slides Pictures"
],
"VerifyToSeason": [
". 2000",
@ -444,128 +401,6 @@
"zzz =2014.3 Fall Tracy Pictures",
"zzz =2014.4 Winter Tracy Pictures",
"zzz =2015.0 Winter Tracy Pictures"
],
"MixedYearRelativePaths": [
"Edited",
"Phares Slides",
"Rex Memorial",
"Scanned Grandma's Quilt",
"Scanned Pictures Of Kids",
"Scanned Prints",
"Slide in Name Order Originals (622)",
"Slides Pictures"
],
"IgnoreRelativePaths": [
"3757 W Whitman 2017",
"501 Playful Meadows 2006",
"501 Playful Meadows 2007",
"501 Playful Meadows 2008",
"501 Playful Meadows 2009",
"501 Playful Meadows 2010",
"501 Playful Meadows 2013",
"501 Playful Meadows 2015",
"6309 Evesham 2003",
"6309 Evesham 2004",
"Crystal's Wedding 2003",
"Danny's Wedding 2009",
"Door images 2019",
"Family Pictures 2006",
"Family Pictures 2007",
"Family Pictures 2011",
"Family Pictures 2013",
"GrandPrix 2004",
"Kids School Pictures 2004",
"Kristy 2002",
"Kristy Parents Wedding 2005",
"Logan Ultrasound 2007",
"Mandy's Dogs 2008",
"Motorcycles 2010",
"Motorcycles 2013",
"Motorcycles 2014",
"Phares Slides",
"Portrait Innovations April 2008",
"Portrait Innovations December 2007",
"Portrait Innovations June 2008",
"Portrait Innovations March 2012",
"The guys house 2000",
"Tracy Pictures 2005",
"Tracy Pictures 2006",
"Tracy Pictures 2007",
"Tracy Pictures 2008",
"Tracy Pictures 2009",
"Tracy Pictures 2010",
"Tracy Pictures 2011",
"Tracy Pictures 2012",
"Tracy Pictures 2013 Jan-July",
"Tracy Pictures 2013 July- Dec",
"Tracy Pictures 2014",
"Tracy Pictures 2015",
"Tracy Took The Kids 2006",
"Tracy's Bday 2012",
"Tracy's Wedding 2002",
"Trip to Colorado 10 2002",
"Trip to Colorado June 2002",
"Tub 2002",
"Vericruz 2011",
"zzz =2005.1 Spring Tracy Pictures",
"zzz =2005.2 Summer Tracy Pictures",
"zzz =2005.3 Fall Tracy Pictures",
"zzz =2005.4 Winter Tracy Pictures",
"zzz =2006.1 Spring Tracy Pictures",
"zzz =2007.0 Winter Tracy Pictures",
"zzz =2007.2 Summer Tracy Pictures",
"zzz =2008.2 Summer Tracy Pictures",
"zzz =2009.0 Winter Tracy Pictures",
"zzz =2009.2 Summer Tracy Pictures",
"zzz =2009.3 Fall Tracy Pictures",
"zzz =2009.4 Winter Tracy Pictures",
"zzz =2010.0 Winter Tracy Pictures",
"zzz =2010.1 Spring Tracy Pictures",
"zzz =2010.2 Summer Tracy Pictures",
"zzz =2010.3 Fall Tracy Pictures",
"zzz =2011.0 Winter Tracy Pictures",
"zzz =2011.1 Spring Tracy Pictures",
"zzz =2011.2 Summer Tracy Pictures",
"zzz =2011.3 Fall Tracy Pictures",
"zzz =2011.4 Winter Tracy Pictures",
"zzz =2012.0 Winter Tracy Pictures",
"zzz =2012.1 Spring Tracy Pictures",
"zzz =2012.2 Summer Tracy Pictures",
"zzz =2012.3 Fall Tracy Pictures",
"zzz =2012.4 Winter Tracy Pictures",
"zzz =2013.0 Winter Tracy Pictures",
"zzz =2013.1 Spring Tracy Pictures",
"zzz =2013.2 Summer Tracy Pictures",
"zzz =2013.3 Fall Tracy Pictures",
"zzz =2013.4 Winter Tracy Pictures",
"zzz =2014.0 Winter Tracy Pictures",
"zzz =2014.1 Spring Tracy Pictures",
"zzz =2014.2 Summer Tracy Pictures",
"zzz =2014.3 Fall Tracy Pictures",
"zzz =2014.4 Winter Tracy Pictures",
"zzz =2015.0 Winter Tracy Pictures",
"zzz Family Pictures",
"zzz Family Pictures",
"zzz Family Pictures",
"zzz Family Pictures",
"zzz GrandPrix",
"zzz Motorcycles",
"zzz Motorcycles",
"zzz Motorcycles",
"zzz Parents Yard",
"zzz Phares Family Pictures",
"zzz Phares Slides ####",
"zzz Portrait Innovations April",
"zzz Portrait Innovations Files",
"zzz Portrait Innovations June",
"zzz Portrait Innovations March",
"zzz Rex Memorial ####",
"zzz Scanned Grandma's Quilt ####",
"zzz Scanned Pictures Of Kids ####",
"zzz Scanned Prints ####",
"zzz Slide in Name Order Originals (622) ####",
"zzz Tub",
"zzz Vericruz"
]
}
}

View File

@ -1,505 +1 @@
{
"Company": "Mike Phares",
"Linux": {},
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Log4netProvider": "Information",
"Microsoft.Hosting.Lifetime": "Information"
}
},
"MaxDegreeOfParallelism": 12,
"Serilog": {
"Using": [
"Serilog.Sinks.Console",
"Serilog.Sinks.File"
],
"MinimumLevel": "Debug",
"WriteTo": [
{
"Name": "Debug",
"Args": {
"outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz} [{Level}] ({SourceContext}.{MethodName}) ({InstanceId}) ({RemoteIpAddress}) {Message}{NewLine}{Exception}"
}
},
{
"Name": "Console",
"Args": {
"outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz} [{Level}] ({SourceContext}.{MethodName}) ({InstanceId}) ({RemoteIpAddress}) {Message}{NewLine}{Exception}"
}
},
{
"Name": "File",
"Args": {
"path": "%workingDirectory% - Log/log-.txt",
"outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz} [{Level}] ({SourceContext}.{MethodName}) ({InstanceId}) ({RemoteIpAddress}) {Message}{NewLine}{Exception}",
"rollingInterval": "Hour"
}
}
],
"Enrich": [
"FromLogContext",
"WithMachineName",
"WithThreadId"
],
"Properties": {
"Application": "Sample"
}
},
"WorkingDirectoryName": "PharesApps",
"Windows": {
"Configuration": {
"CheckDFaceAndUpWriteDates": true,
"CheckJsonForDistanceResults": false,
"CrossDirectoryMaxItemsInDistanceCollection": 7,
"DateGroup": "2022-11-12",
"DistanceFactor": 8,
"DistanceMoveUnableToMatch": false,
"DistancePixelDistanceTolerance": 1,
"DistanceRenameToMatch": false,
"FaceAreaPermille": 1000,
"FaceDistanceHiddenImageFactor": 2,
"FaceConfidencePercent": 100,
"FaceDistancePermyriad": 10000,
"FileNameDirectorySeparator": ".Z.",
"ForceFaceLastWriteTimeToCreationTime": false,
"ForceMetadataLastWriteTimeToCreationTime": false,
"ForcePropertyLastWriteTimeToCreationTime": false,
"ForceResizeLastWriteTimeToCreationTime": false,
"LoadOrCreateThenSaveIndex": false,
"LocationDigits": 9,
"LocationFactor": 10000,
"MappedMaxIndex": 1034720,
"MappingDefaultName": "John Doe~25",
"MappingUseDeterministicHashCodeUnknownFaceKeyValuePairsForAddToMapping": false,
"MappingUseDeterministicHashCodeUnknownFaceKeyValuePairsForSaveMapping": false,
"MaxImagesInDirectoryForTopLevelFirstPass": 10,
"ModelDirectory": "L:/GitHub/dlib-models",
"ModelName": "Hog",
"NumberOfJitters": 0,
"NumberOfTimesToUpsample": 0,
"OutputExtension": ".jpg",
"OutputQuality": 95,
"OverrideForFaceImages": false,
"OverrideForFaceLandmarkImages": false,
"OverrideForResizeImages": false,
"Pattern": "[^ABCDEFGHIJKLMNOPQRSTUVWXYZbcdfghjklmnpqrstvwxyz0-9]",
"PersonBirthdayFirstYear": 1500,
"PersonBirthdayFormat": "yyyy-MM-dd_HH",
"PersonKeyFormat": "yyyy-MM-dd_HH",
"PersonRequirePeopleFile": false,
"PopulatePropertyId": true,
"PredictorModelName": "Large",
"PropertiesChangedForDistance": false,
"PropertiesChangedForFaces": false,
"PropertiesChangedForIndex": false,
"PropertiesChangedForMetadata": false,
"PropertiesChangedForProperty": false,
"PropertiesChangedForResize": false,
"ResultAllInOne": "_ _ _",
"ResultCollection": "[]",
"ResultContent": "()",
"ResultSingleton": "{}",
"RetryImagesWithoutAFace": false,
"Reverse": false,
"RootDirectory": "E:/Images",
"SaveFullYearOfRandomFiles": true,
"SaveResizedSubFiles": true,
"SkipSearch": false,
"SortingMaximumPerFaceShouldBeHigh": 3000,
"SortingMaximumPerKey": 7,
"SortingMinimumToUseSigma": 10,
"TestDistanceResults": true,
"WriteBitmapDataBytes": false,
"IgnoreExtensions": [
".gif",
".GIF"
],
"OutputResolutions": [
"176 x 176",
"256 x 256",
"353 x 353",
"1024 x 768",
"1920 x 1080"
],
"PropertyContentCollectionFiles": [],
"RangeDaysDeltaTolerance": [
0,
700,
123456
],
"RangeDistanceTolerance": [
0,
0.4,
0.6
],
"RangeFaceAreaPermilleTolerance": [
0,
10,
1000
],
"RangeFaceConfidence": [
0.8,
0.2,
100
],
"SaveFaceDistancesForOutputResolutions": [],
"SaveFaceLandmarkForOutputResolutions": [
"176 x 176",
"256 x 256"
],
"SaveMappedForOutputResolutions": [],
"SaveNotMappedForOutputResolutions": [],
"SaveResizedImagesByPersonKeyFormattedForOutputResolutions": [
"1920 x 1080"
],
"SaveShortcutsForOutputResolutions": [
"1920 x 1080"
],
"ValidImageFormatExtensions": [
".bmp",
".BMP",
".gif",
".GIF",
".jpeg",
".JPEG",
".jpg",
".JPG",
".png",
".PNG",
".tiff",
".TIFF"
],
"ValidMetadataExtensions": [
".3gp",
".3GP",
".avi",
".AVI",
".bmp",
".BMP",
".gif",
".GIF",
".ico",
".ICO",
".jpeg",
".JPEG",
".jpg",
".JPG",
".m4v",
".M4V",
".mov",
".MOV",
".mp4",
".MP4",
".mta",
".MTA",
".png",
".PNG",
".tiff",
".TIFF"
],
"ValidResolutions": [
"176 x 176",
"256 x 256",
"353 x 353",
"1024 x 768",
"1280 x 720",
"1280 x 800",
"1376 x 768",
"1600 x 1200",
"1920 x 1080",
"2256 x 1496",
"3840 x 2160",
"7680 x 4320"
],
"VerifyToSeason": [
". 2000",
". 2001",
". 2002",
". 2003",
". 2004",
". 2005",
". 2006",
". 2007",
". 2008",
". 2009",
". 2010",
". 2011",
". 2012",
". 2013",
". 2014",
". 2015",
". 2016",
". 2017",
". 2018",
". 2019",
". 2020",
". 2021",
". 2022",
". 2023",
". 2024",
". 2025",
". 2026",
". 2027",
". 2028",
". 2029",
"=2000.0 Winter",
"=2002.1 Spring",
"=2002.4 Winter",
"=2003.0 Winter",
"=2003.1 Spring",
"=2003.3 Fall",
"=2003.4 Winter",
"=2004.0 Winter",
"=2005.1 Spring",
"=2005.2 Summer",
"=2005.3 Fall",
"=2005.4 Winter",
"=2006.0 Winter",
"=2006.1 Spring",
"=2006.3 Fall",
"=2007.0 Winter",
"=2007.2 Summer Logan Michael",
"=2007.2 Summer",
"=2007.3 Fall Logan Michael",
"=2007.4 Winter Logan Michael",
"=2008.0 Winter Logan Michael",
"=2008.1 Spring Logan Michael",
"=2008.2 Summer Logan Michael",
"=2008.2 Summer",
"=2008.3 Fall Logan Michael",
"=2009.0 Winter Logan Michael",
"=2009.0 Winter",
"=2009.1 Spring Logan Michael",
"=2009.1 Spring",
"=2009.2 Summer Logan Michael",
"=2009.2 Summer",
"=2009.3 Fall Logan Michael",
"=2009.3 Fall",
"=2009.4 Winter Logan Michael",
"=2009.4 Winter",
"=2010.0 Winter Logan Michael",
"=2010.0 Winter",
"=2010.1 Spring Logan Michael",
"=2010.1 Spring",
"=2010.2 Summer",
"=2010.3 Fall Logan Michael",
"=2010.3 Fall",
"=2010.4 Winter",
"=2011.0 Winter",
"=2011.1 Spring",
"=2011.2 Summer",
"=2011.3 Fall",
"=2011.4 Winter",
"=2012.0 Winter Chelsea 2012",
"=2012.0 Winter Chelsea",
"=2012.0 Winter",
"=2012.1 Spring Chelsea",
"=2012.1 Spring",
"=2012.2 Summer Chelsea",
"=2012.2 Summer",
"=2012.3 Fall Chelsea",
"=2012.3 Fall",
"=2012.4 Winter Chelsea",
"=2012.4 Winter",
"=2013.0 Winter Chelsea 2013",
"=2013.0 Winter Chelsea",
"=2013.0 Winter",
"=2013.1 Spring",
"=2013.2 Summer Chelsea",
"=2013.2 Summer",
"=2013.3 Fall Chelsea",
"=2013.3 Fall",
"=2013.4 Winter",
"=2014.0 Winter",
"=2014.1 Spring",
"=2014.2 Summer",
"=2014.3 Fall",
"=2014.4 Winter",
"=2015.0 Winter",
"=2015.1 Spring",
"=2015.2 Summer",
"=2015.3 Fall",
"=2015.4 Winter",
"=2016.0 Winter",
"=2016.1 Spring",
"=2016.2 Summer",
"=2016.3 Fall",
"=2016.4 Winter",
"=2017.1 Spring",
"=2017.2 Summer",
"=2017.3 Fall",
"=2017.4 Winter",
"=2018.0 Winter",
"=2018.1 Spring",
"=2018.3 Fall",
"=2018.4 Winter",
"=2019.0 Winter",
"=2019.1 Spring",
"=2019.2 Summer",
"=2019.3 Fall",
"=2019.4 Winter",
"=2020.0 Winter",
"=2020.1 Spring",
"=2020.2 Summer",
"=2020.3 Fall",
"=2020.4 Winter",
"=2021.1 Spring",
"=2021.2 Summer",
"=2021.3 Fall",
"=2021.4 Winter",
"=2022.0 Winter",
"=2022.1 Spring",
"Anthem 2015",
"April 2010",
"April 2013",
"December 2006",
"December 2010",
"Fall 2005",
"Fall 2015",
"Fall 2016",
"Fall 2017",
"Fall 2018",
"Fall 2019",
"Fall 2020",
"Fall 2021",
"February 2010",
"January 2015",
"July 2010",
"June 2010",
"Kids 2005",
"March 2013",
"May 2010",
"May 2011",
"May 2013",
"October 2005",
"October 2014",
"Spring 2013",
"Spring 2014",
"Spring 2016",
"Spring 2018",
"Spring 2019",
"Spring 2020",
"Summer 2011",
"Summer 2012",
"Summer 2013",
"Summer 2014",
"Summer 2015",
"Summer 2016",
"Summer 2017",
"Summer 2018",
"Summer 2020",
"Summer 2021",
"Winter 2015",
"Winter 2016",
"Winter 2017",
"Winter 2018",
"Winter 2019-2020",
"Winter 2020",
"zzz =2005.0 Winter Tracy Pictures",
"zzz =2005.1 Spring Tracy Pictures",
"zzz =2005.2 Summer Tracy Pictures",
"zzz =2005.3 Fall Tracy Pictures",
"zzz =2005.4 Winter Tracy Pictures",
"zzz =2006.1 Spring Tracy Pictures",
"zzz =2007.0 Winter Tracy Pictures",
"zzz =2007.2 Summer Tracy Pictures",
"zzz =2008.0 Winter Tracy Pictures",
"zzz =2008.2 Summer Tracy Pictures",
"zzz =2009.0 Winter Tracy Pictures",
"zzz =2009.2 Summer Tracy Pictures",
"zzz =2009.3 Fall Tracy Pictures",
"zzz =2009.4 Winter Tracy Pictures",
"zzz =2010.0 Winter Tracy Pictures",
"zzz =2010.1 Spring Tracy Pictures",
"zzz =2010.2 Summer Tracy Pictures",
"zzz =2010.3 Fall Tracy Pictures",
"zzz =2011.0 Winter Tracy Pictures",
"zzz =2011.1 Spring Tracy Pictures",
"zzz =2011.2 Summer Tracy Pictures",
"zzz =2011.3 Fall Tracy Pictures",
"zzz =2011.4 Winter Tracy Pictures",
"zzz =2012.0 Winter Tracy Pictures",
"zzz =2012.1 Spring Tracy Pictures",
"zzz =2012.2 Summer Tracy Pictures",
"zzz =2012.3 Fall Tracy Pictures",
"zzz =2012.4 Winter Tracy Pictures",
"zzz =2013.0 Winter Tracy Pictures",
"zzz =2013.1 Spring Tracy Pictures",
"zzz =2013.2 Summer Tracy Pictures",
"zzz =2013.3 Fall Tracy Pictures",
"zzz =2013.4 Winter Tracy Pictures",
"zzz =2014.0 Winter Tracy Pictures",
"zzz =2014.1 Spring Tracy Pictures",
"zzz =2014.2 Summer Tracy Pictures",
"zzz =2014.3 Fall Tracy Pictures",
"zzz =2014.4 Winter Tracy Pictures",
"zzz =2015.0 Winter Tracy Pictures"
],
"MixedYearRelativePaths": [
"Edited",
"Phares Slides",
"Rex Memorial",
"Scanned Grandma's Quilt",
"Scanned Pictures Of Kids",
"Scanned Prints",
"Slide in Name Order Originals (622)",
"Slides Pictures"
],
"IgnoreRelativePaths": [
"3757 W Whitman 2017",
"501 Playful Meadows 2006",
"501 Playful Meadows 2007",
"501 Playful Meadows 2008",
"501 Playful Meadows 2009",
"501 Playful Meadows 2010",
"501 Playful Meadows 2013",
"501 Playful Meadows 2015",
"6309 Evesham 2003",
"6309 Evesham 2004",
"Crystal's Wedding 2003",
"Danny's Wedding 2009",
"Door images 2019",
"Family Pictures 2006",
"Family Pictures 2007",
"Family Pictures 2011",
"Family Pictures 2013",
"GrandPrix 2004",
"Kids School Pictures 2004",
"Kristy 2002",
"Kristy Parents Wedding 2005",
"Logan Ultrasound 2007",
"Mandy's Dogs 2008",
"Motorcycles 2010",
"Motorcycles 2013",
"Motorcycles 2014",
"Phares Slides",
"Portrait Innovations April 2008",
"Portrait Innovations December 2007",
"Portrait Innovations June 2008",
"Portrait Innovations March 2012",
"The guys house 2000",
"Tracy Pictures 2005",
"Tracy Pictures 2006",
"Tracy Pictures 2007",
"Tracy Pictures 2008",
"Tracy Pictures 2009",
"Tracy Pictures 2010",
"Tracy Pictures 2011",
"Tracy Pictures 2012",
"Tracy Pictures 2013 Jan-July",
"Tracy Pictures 2013 July- Dec",
"Tracy Pictures 2014",
"Tracy Pictures 2015",
"Tracy Took The Kids 2006",
"Tracy's Bday 2012",
"Tracy's Wedding 2002",
"Trip to Colorado 10 2002",
"Trip to Colorado June 2002",
"Tub 2002",
"Vericruz 2011"
]
}
}
}
{}

View File

@ -50,7 +50,7 @@
"WorkingDirectoryName": "PharesApps",
"Windows": {
"Configuration": {
"CheckDFaceAndUpWriteDates": true,
"CheckDFaceAndUpWriteDates": false,
"CheckJsonForDistanceResults": false,
"CrossDirectoryMaxItemsInDistanceCollection": 7,
"DateGroup": "2022-11-12",
@ -88,7 +88,7 @@
"PersonBirthdayFirstYear": 1500,
"PersonBirthdayFormat": "yyyy-MM-dd_HH",
"PersonKeyFormat": "yyyy-MM-dd_HH",
"PersonRequirePeopleFile": false,
"PhotoPrismDirectory": "",
"PopulatePropertyId": true,
"PredictorModelName": "Large",
"PropertiesChangedForDistance": false,
@ -101,7 +101,7 @@
"ResultCollection": "[]",
"ResultContent": "()",
"ResultSingleton": "{}",
"RetryImagesWithoutAFace": false,
"RetryImagesWithoutAFaceLocation": false,
"Reverse": false,
"RootDirectory": "D:/Images",
"SaveFullYearOfRandomFiles": true,
@ -114,24 +114,18 @@
"WriteBitmapDataBytes": false,
"IgnoreExtensions": [
".gif",
".GIF"
],
"JLinks": [
"Julie"
],
"LoadOrCreateThenSaveDistanceResultsForOutputResolutions": [
"1920 x 1080"
],
"LoadOrCreateThenSaveImageFacesResultsForOutputResolutions": [
"1920 x 1080"
],
"OutputResolutions": [
"176 x 176",
"256 x 256",
"353 x 353",
"1024 x 768",
"1920 x 1080"
".GIF",
".json",
".JOSN",
".txt",
".TXT",
".ico",
".ICO"
],
"JLinks": [],
"LoadOrCreateThenSaveDistanceResultsForOutputResolutions": [],
"LoadOrCreateThenSaveImageFacesResultsForOutputResolutions": [],
"OutputResolutions": [],
"PropertyContentCollectionFiles": [],
"RangeDaysDeltaTolerance": [
0,
@ -154,18 +148,14 @@
100
],
"SaveFaceDistancesForOutputResolutions": [],
"SaveFaceLandmarkForOutputResolutions": [
"176 x 176",
"256 x 256"
],
"SaveFaceLandmarkForOutputResolutions": [],
"SaveMappedForOutputResolutions": [],
"SaveNotMappedForOutputResolutions": [],
"SaveResizedImagesByPersonKeyFormattedForOutputResolutions": [
"1920 x 1080"
],
"SaveShortcutsForOutputResolutions": [
"1920 x 1080"
],
"SaveResizedImagesByPersonKeyFormattedForOutputResolutions": [],
"SaveShortcutsForOutputResolutions": [],
"IgnoreRelativePaths": [],
"MixedYearRelativePaths": [],
"VerifyToSeason": [],
"ValidImageFormatExtensions": [
".bmp",
".BMP",
@ -221,293 +211,6 @@
"2256 x 1496",
"3840 x 2160",
"7680 x 4320"
],
"VerifyToSeason": [
". 2000",
". 2001",
". 2002",
". 2003",
". 2004",
". 2005",
". 2006",
". 2007",
". 2008",
". 2009",
". 2010",
". 2011",
". 2012",
". 2013",
". 2014",
". 2015",
". 2016",
". 2017",
". 2018",
". 2019",
". 2020",
". 2021",
". 2022",
". 2023",
". 2024",
". 2025",
". 2026",
". 2027",
". 2028",
". 2029",
"=2000.0 Winter",
"=2002.1 Spring",
"=2002.4 Winter",
"=2003.0 Winter",
"=2003.1 Spring",
"=2003.3 Fall",
"=2003.4 Winter",
"=2004.0 Winter",
"=2005.1 Spring",
"=2005.2 Summer",
"=2005.3 Fall",
"=2005.4 Winter",
"=2006.0 Winter",
"=2006.1 Spring",
"=2006.3 Fall",
"=2007.0 Winter",
"=2007.2 Summer Logan Michael",
"=2007.2 Summer",
"=2007.3 Fall Logan Michael",
"=2007.4 Winter Logan Michael",
"=2008.0 Winter Logan Michael",
"=2008.1 Spring Logan Michael",
"=2008.2 Summer Logan Michael",
"=2008.2 Summer",
"=2008.3 Fall Logan Michael",
"=2009.0 Winter Logan Michael",
"=2009.0 Winter",
"=2009.1 Spring Logan Michael",
"=2009.1 Spring",
"=2009.2 Summer Logan Michael",
"=2009.2 Summer",
"=2009.3 Fall Logan Michael",
"=2009.3 Fall",
"=2009.4 Winter Logan Michael",
"=2009.4 Winter",
"=2010.0 Winter Logan Michael",
"=2010.0 Winter",
"=2010.1 Spring Logan Michael",
"=2010.1 Spring",
"=2010.2 Summer",
"=2010.3 Fall Logan Michael",
"=2010.3 Fall",
"=2010.4 Winter",
"=2011.0 Winter",
"=2011.1 Spring",
"=2011.2 Summer",
"=2011.3 Fall",
"=2011.4 Winter",
"=2012.0 Winter Chelsea 2012",
"=2012.0 Winter Chelsea",
"=2012.0 Winter",
"=2012.1 Spring Chelsea",
"=2012.1 Spring",
"=2012.2 Summer Chelsea",
"=2012.2 Summer",
"=2012.3 Fall Chelsea",
"=2012.3 Fall",
"=2012.4 Winter Chelsea",
"=2012.4 Winter",
"=2013.0 Winter Chelsea 2013",
"=2013.0 Winter Chelsea",
"=2013.0 Winter",
"=2013.1 Spring",
"=2013.2 Summer Chelsea",
"=2013.2 Summer",
"=2013.3 Fall Chelsea",
"=2013.3 Fall",
"=2013.4 Winter",
"=2014.0 Winter",
"=2014.1 Spring",
"=2014.2 Summer",
"=2014.3 Fall",
"=2014.4 Winter",
"=2015.0 Winter",
"=2015.1 Spring",
"=2015.2 Summer",
"=2015.3 Fall",
"=2015.4 Winter",
"=2016.0 Winter",
"=2016.1 Spring",
"=2016.2 Summer",
"=2016.3 Fall",
"=2016.4 Winter",
"=2017.1 Spring",
"=2017.2 Summer",
"=2017.3 Fall",
"=2017.4 Winter",
"=2018.0 Winter",
"=2018.1 Spring",
"=2018.3 Fall",
"=2018.4 Winter",
"=2019.0 Winter",
"=2019.1 Spring",
"=2019.2 Summer",
"=2019.3 Fall",
"=2019.4 Winter",
"=2020.0 Winter",
"=2020.1 Spring",
"=2020.2 Summer",
"=2020.3 Fall",
"=2020.4 Winter",
"=2021.1 Spring",
"=2021.2 Summer",
"=2021.3 Fall",
"=2021.4 Winter",
"=2022.0 Winter",
"=2022.1 Spring",
"Anthem 2015",
"April 2010",
"April 2013",
"December 2006",
"December 2010",
"Fall 2005",
"Fall 2015",
"Fall 2016",
"Fall 2017",
"Fall 2018",
"Fall 2019",
"Fall 2020",
"Fall 2021",
"February 2010",
"January 2015",
"July 2010",
"June 2010",
"Kids 2005",
"March 2013",
"May 2010",
"May 2011",
"May 2013",
"October 2005",
"October 2014",
"Spring 2013",
"Spring 2014",
"Spring 2016",
"Spring 2018",
"Spring 2019",
"Spring 2020",
"Summer 2011",
"Summer 2012",
"Summer 2013",
"Summer 2014",
"Summer 2015",
"Summer 2016",
"Summer 2017",
"Summer 2018",
"Summer 2020",
"Summer 2021",
"Winter 2015",
"Winter 2016",
"Winter 2017",
"Winter 2018",
"Winter 2019-2020",
"Winter 2020",
"zzz =2005.0 Winter Tracy Pictures",
"zzz =2005.1 Spring Tracy Pictures",
"zzz =2005.2 Summer Tracy Pictures",
"zzz =2005.3 Fall Tracy Pictures",
"zzz =2005.4 Winter Tracy Pictures",
"zzz =2006.1 Spring Tracy Pictures",
"zzz =2007.0 Winter Tracy Pictures",
"zzz =2007.2 Summer Tracy Pictures",
"zzz =2008.0 Winter Tracy Pictures",
"zzz =2008.2 Summer Tracy Pictures",
"zzz =2009.0 Winter Tracy Pictures",
"zzz =2009.2 Summer Tracy Pictures",
"zzz =2009.3 Fall Tracy Pictures",
"zzz =2009.4 Winter Tracy Pictures",
"zzz =2010.0 Winter Tracy Pictures",
"zzz =2010.1 Spring Tracy Pictures",
"zzz =2010.2 Summer Tracy Pictures",
"zzz =2010.3 Fall Tracy Pictures",
"zzz =2011.0 Winter Tracy Pictures",
"zzz =2011.1 Spring Tracy Pictures",
"zzz =2011.2 Summer Tracy Pictures",
"zzz =2011.3 Fall Tracy Pictures",
"zzz =2011.4 Winter Tracy Pictures",
"zzz =2012.0 Winter Tracy Pictures",
"zzz =2012.1 Spring Tracy Pictures",
"zzz =2012.2 Summer Tracy Pictures",
"zzz =2012.3 Fall Tracy Pictures",
"zzz =2012.4 Winter Tracy Pictures",
"zzz =2013.0 Winter Tracy Pictures",
"zzz =2013.1 Spring Tracy Pictures",
"zzz =2013.2 Summer Tracy Pictures",
"zzz =2013.3 Fall Tracy Pictures",
"zzz =2013.4 Winter Tracy Pictures",
"zzz =2014.0 Winter Tracy Pictures",
"zzz =2014.1 Spring Tracy Pictures",
"zzz =2014.2 Summer Tracy Pictures",
"zzz =2014.3 Fall Tracy Pictures",
"zzz =2014.4 Winter Tracy Pictures",
"zzz =2015.0 Winter Tracy Pictures"
],
"MixedYearRelativePaths": [
"Edited",
"Phares Slides",
"Rex Memorial",
"Scanned Grandma's Quilt",
"Scanned Pictures Of Kids",
"Scanned Prints",
"Slide in Name Order Originals (622)",
"Slides Pictures"
],
"IgnoreRelativePaths": [
"3757 W Whitman 2017",
"501 Playful Meadows 2006",
"501 Playful Meadows 2007",
"501 Playful Meadows 2008",
"501 Playful Meadows 2009",
"501 Playful Meadows 2010",
"501 Playful Meadows 2013",
"501 Playful Meadows 2015",
"6309 Evesham 2003",
"6309 Evesham 2004",
"Crystal's Wedding 2003",
"Danny's Wedding 2009",
"Door images 2019",
"Family Pictures 2006",
"Family Pictures 2007",
"Family Pictures 2011",
"Family Pictures 2013",
"GrandPrix 2004",
"Kids School Pictures 2004",
"Kristy 2002",
"Kristy Parents Wedding 2005",
"Logan Ultrasound 2007",
"Mandy's Dogs 2008",
"Motorcycles 2010",
"Motorcycles 2013",
"Motorcycles 2014",
"Phares Slides",
"Portrait Innovations April 2008",
"Portrait Innovations December 2007",
"Portrait Innovations June 2008",
"Portrait Innovations March 2012",
"The guys house 2000",
"Tracy Pictures 2005",
"Tracy Pictures 2006",
"Tracy Pictures 2007",
"Tracy Pictures 2008",
"Tracy Pictures 2009",
"Tracy Pictures 2010",
"Tracy Pictures 2011",
"Tracy Pictures 2012",
"Tracy Pictures 2013 Jan-July",
"Tracy Pictures 2013 July- Dec",
"Tracy Pictures 2014",
"Tracy Pictures 2015",
"Tracy Took The Kids 2006",
"Tracy's Bday 2012",
"Tracy's Wedding 2002",
"Trip to Colorado 10 2002",
"Trip to Colorado June 2002",
"Tub 2002",
"Vericruz 2011"
]
}
}

View File

@ -39,7 +39,7 @@
<PackageReference Include="Serilog" Version="2.12.0" />
<PackageReference Include="ShellProgressBar" Version="5.2.0" />
<PackageReference Include="WindowsShortcutFactory" Version="1.1.0" />
<PackageReference Include="System.Text.Json" Version="7.0.0" />
<PackageReference Include="System.Text.Json" Version="7.0.1" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Shared\View-by-Distance.Shared.csproj" />

View File

@ -14,6 +14,7 @@ public class Configuration
public string MappingDefaultName { init; get; }
public int PersonBirthdayFirstYear { init; get; }
public string PersonBirthdayFormat { init; get; }
public string PhotoPrismDirectory { init; get; }
public int RangeDaysDeltaTolerance { init; get; }
public double RangeDistanceTolerance { init; get; }
public int SortingMaximumPerKey { init; get; }
@ -25,6 +26,7 @@ public class Configuration
string mappingDefaultName,
int personBirthdayFirstYear,
string personBirthdayFormat,
string photoPrismDirectory,
int[] rangeDaysDeltaTolerance,
double[] rangeDistanceTolerance,
int sortingMaximumPerKey,
@ -34,6 +36,7 @@ public class Configuration
string facePartsFileNameExtension)
{
MappingDefaultName = mappingDefaultName;
PhotoPrismDirectory = photoPrismDirectory;
PersonBirthdayFormat = personBirthdayFormat;
SortingMaximumPerKey = sortingMaximumPerKey;
FaceConfidencePercent = faceConfidencePercent;

View File

@ -0,0 +1,54 @@
using System.Text.Json.Serialization;
namespace View_by_Distance.Map.Models;
public record DatabaseFile(
[property: JsonPropertyName("id")] int Id,
[property: JsonPropertyName("photo_id")] int PhotoId,
[property: JsonPropertyName("photo_uid")] string PhotoUid,
[property: JsonPropertyName("photo_taken_at")] string PhotoTakenAt,
[property: JsonPropertyName("time_index")] string TimeIndex,
[property: JsonPropertyName("media_id")] string MediaId,
[property: JsonPropertyName("media_utc")] object MediaUtc,
[property: JsonPropertyName("instance_id")] string InstanceId,
[property: JsonPropertyName("file_uid")] string FileUid,
[property: JsonPropertyName("file_name")] string FileName,
[property: JsonPropertyName("file_root")] string FileRoot,
[property: JsonPropertyName("original_name")] string OriginalName,
[property: JsonPropertyName("file_hash")] string FileHash,
[property: JsonPropertyName("file_size")] int FileSize,
[property: JsonPropertyName("file_codec")] string FileCodec,
[property: JsonPropertyName("file_type")] string FileType,
[property: JsonPropertyName("media_type")] string MediaType,
[property: JsonPropertyName("file_mime")] string FileMime,
[property: JsonPropertyName("file_primary")] long FilePrimary,
[property: JsonPropertyName("file_sidecar")] long FileSidecar,
[property: JsonPropertyName("file_missing")] long FileMissing,
[property: JsonPropertyName("file_portrait")] long FilePortrait,
[property: JsonPropertyName("file_video")] long FileVideo,
[property: JsonPropertyName("file_duration")] long FileDuration,
[property: JsonPropertyName("file_fps")] object FileFps,
[property: JsonPropertyName("file_frames")] object FileFrames,
[property: JsonPropertyName("file_width")] int FileWidth,
[property: JsonPropertyName("file_height")] int FileHeight,
[property: JsonPropertyName("file_orientation")] int FileOrientation,
[property: JsonPropertyName("file_projection")] string FileProjection,
[property: JsonPropertyName("file_aspect_ratio")] double FileAspectRatio,
[property: JsonPropertyName("file_hdr")] long FileHdr,
[property: JsonPropertyName("file_watermark")] long FileWatermark,
[property: JsonPropertyName("file_color_profile")] string FileColorProfile,
[property: JsonPropertyName("file_main_color")] string FileMainColor,
[property: JsonPropertyName("file_colors")] string FileColors,
[property: JsonPropertyName("file_luminance")] string FileLuminance,
[property: JsonPropertyName("file_diff")] long FileDiff,
[property: JsonPropertyName("file_chroma")] long FileChroma,
[property: JsonPropertyName("file_software")] string FileSoftware,
[property: JsonPropertyName("file_error")] string FileError,
[property: JsonPropertyName("mod_time")] long ModTime,
[property: JsonPropertyName("created_at")] string CreatedAt,
[property: JsonPropertyName("created_in")] long CreatedIn,
[property: JsonPropertyName("updated_at")] string UpdatedAt,
[property: JsonPropertyName("updated_in")] long UpdatedIn,
[property: JsonPropertyName("published_at")] object PublishedAt,
[property: JsonPropertyName("deleted_at")] object DeletedAt
);

View File

@ -0,0 +1,8 @@
using System.Text.Json.Serialization;
namespace View_by_Distance.Map.Models;
public record DatabaseFileRoot(
[property: JsonPropertyName("table")] string Table,
[property: JsonPropertyName("rows")] IReadOnlyList<DatabaseFile> Files
);

View File

@ -1,5 +1,6 @@
using Humanizer;
using ShellProgressBar;
using System.Text;
using System.Text.Json;
using View_by_Distance.Map.Models.Stateless;
using View_by_Distance.Shared.Models;
@ -15,7 +16,7 @@ public class MapLogic
protected readonly List<PersonContainer> _NotMappedPersonContainers;
protected readonly Dictionary<long, PersonContainer> _PersonKeyToPersonContainer;
protected readonly Dictionary<long, (long LCL, long Minimum, long Maximum, long UCL)> _PersonKeyToRanges;
protected readonly Dictionary<int, Dictionary<int, PersonContainer[]>> _IdThenNormalizedPixelPercentageToPersonContainers;
protected readonly Dictionary<int, Dictionary<int, PersonContainer[]>> _IdThenNormalizedRectangleToPersonContainers;
public Dictionary<int, int[]> KeyValuePairs => throw new NotImplementedException();
public Dictionary<int, int[]> IndicesFromNew => throw new NotImplementedException();
@ -51,7 +52,7 @@ public class MapLogic
string? rootDirectoryParent = Path.GetDirectoryName(propertyConfiguration.RootDirectory);
Dictionary<long, (long LCL, long Minimum, long Maximum, long UCL)> personKeyToRanges = new();
string eDistanceContentTicksDirectory = Path.Combine(eDistanceContentDirectory, $"({ticks})");
Dictionary<int, Dictionary<int, PersonContainer[]>> idThenNormalizedPixelPercentageToPersonContainers = new();
Dictionary<int, Dictionary<int, PersonContainer[]>> idThenNormalizedRectangleToPersonContainers = new();
for (int i = 1; i < 5; i++)
_ = IPath.DeleteEmptyDirectories(eDistanceContentDirectory);
_ = IPath.DeleteEmptyDirectories(eDistanceContentDirectory);
@ -76,7 +77,7 @@ public class MapLogic
personKeyToRanges,
notMappedPersonContainers,
skipCollection,
idThenNormalizedPixelPercentageToPersonContainers);
idThenNormalizedRectangleToPersonContainers);
if (personContainerCollection.Count == personContainers.Length)
throw new NotSupportedException();
}
@ -97,7 +98,7 @@ public class MapLogic
_NotMappedPersonContainers = notMappedPersonContainers;
_PersonKeyToPersonContainer = personKeyToPersonContainer;
_EDistanceContentTicksDirectory = eDistanceContentTicksDirectory;
_IdThenNormalizedPixelPercentageToPersonContainers = idThenNormalizedPixelPercentageToPersonContainers;
_IdThenNormalizedRectangleToPersonContainers = idThenNormalizedRectangleToPersonContainers;
}
public MapLogic(int maxDegreeOfParallelism, Shared.Models.Properties.IPropertyConfiguration propertyConfiguration, Configuration? configuration, long ticks, PersonContainer[] personContainers, string a2PeopleSingletonDirectory, string eDistanceContentDirectory) :
@ -123,15 +124,15 @@ public class MapLogic
PersonContainer[]? collection;
List<PersonContainer> personContainers = new();
Dictionary<long, int> personKeyToCount = new();
Dictionary<int, PersonContainer[]>? normalizedPixelPercentageToPersonContainers;
Dictionary<int, PersonContainer[]>? normalizedRectangleToPersonContainers;
foreach (Mapping mapping in mappingCollection)
{
personContainers.Clear();
if (!_IdThenNormalizedPixelPercentageToPersonContainers.TryGetValue(mapping.MappingFromItem.Id, out normalizedPixelPercentageToPersonContainers))
if (!_IdThenNormalizedRectangleToPersonContainers.TryGetValue(mapping.MappingFromItem.Id, out normalizedRectangleToPersonContainers))
result += 1;
else
{
if (!normalizedPixelPercentageToPersonContainers.TryGetValue(mapping.MappingFromLocation.NormalizedPixelPercentage, out collection))
if (!normalizedRectangleToPersonContainers.TryGetValue(mapping.MappingFromLocation.NormalizedRectangle, out collection))
result += 1;
else
personContainers.AddRange(collection);
@ -152,7 +153,7 @@ public class MapLogic
return new(personKeyToCount, result);
}
private void SaveContainers(int totalNotMapped, int? updated, List<SaveContainer> saveContainers)
public void SaveContainers(int totalNotMapped, int? updated, List<SaveContainer> saveContainers)
{
if (_Configuration is null)
throw new NullReferenceException(nameof(_Configuration));
@ -342,7 +343,7 @@ public class MapLogic
string personKeyFormatted;
PersonBirthday personBirthday;
PersonContainer personContainer;
result = Path.Combine(_EDistanceContentTicksDirectory, by, sortingContainer.Sorting.Id.ToString(), sortingContainer.Sorting.NormalizedPixelPercentage.ToString());
result = Path.Combine(_EDistanceContentTicksDirectory, by, sortingContainer.Sorting.Id.ToString(), sortingContainer.Sorting.NormalizedRectangle.ToString());
for (int i = 0; i < _NotMappedPersonContainers.Count; i++)
{
personContainer = _NotMappedPersonContainers[i];
@ -358,7 +359,7 @@ public class MapLogic
return result;
}
private List<SaveContainer> GetSaveContainers(string dFacesContentDirectory, string d2FacePartsContentDirectory, Mapping[] mappingCollection, Dictionary<int, Dictionary<int, Mapping>> idToNormalizedPixelPercentageToMapping, Dictionary<long, int> personKeyToCount, int? useFiltersCounter, bool saveMapped)
private List<SaveContainer> GetSaveContainers(string dFacesContentDirectory, string d2FacePartsContentDirectory, Mapping[] mappingCollection, Dictionary<int, Dictionary<int, Mapping>> idToNormalizedRectangleToMapping, Dictionary<long, int> personKeyToCount, int? useFiltersCounter, bool saveNullPerson, bool saveMapped)
{
if (_Configuration is null)
throw new NullReferenceException(nameof(_Configuration));
@ -379,7 +380,7 @@ public class MapLogic
SaveContainer? saveContainer;
FileHolder facePartsFileHolder;
FileHolder hiddenFaceFileHolder;
Dictionary<int, Mapping>? normalizedPixelPercentageToMapping;
Dictionary<int, Mapping>? normalizedRectangleToMapping;
string forceSingleImageHumanized = nameof(IMapLogic.ForceSingleImage).Humanize(LetterCasing.Title);
foreach (Mapping mapping in mappingCollection)
{
@ -391,6 +392,8 @@ public class MapLogic
continue;
if (mapping.MappingFromPerson is null)
{
if (!saveNullPerson)
continue;
if (mapping.SortingContainer is null)
continue;
directory = GetDirectory(by, mapping.MappingFromItem, mapping.SortingContainer);
@ -404,7 +407,10 @@ public class MapLogic
throw new NotSupportedException();
personKey = mapping.MappingFromPerson.PersonBirthday.Value.Ticks;
personKeyFormatted = IPersonBirthday.GetFormatted(_Configuration.PersonBirthdayFormat, mapping.MappingFromPerson.PersonBirthday);
if (string.IsNullOrEmpty(mapping.SegmentC))
directory = Path.Combine(_EDistanceContentTicksDirectory, by, personKeyFormatted, mapping.MappingFromPerson.SegmentB);
else
directory = Path.Combine(_EDistanceContentTicksDirectory, by, personKeyFormatted, mapping.MappingFromPerson.SegmentB, mapping.SegmentC);
if (isByMapping)
personDirectory = Path.Combine(directory, mapping.MappingFromPerson.DisplayDirectoryName);
else if (mapping.By is not null)
@ -435,7 +441,10 @@ public class MapLogic
facePartsDirectory = GetFacePartsDirectory(d2FacePartsContentDirectory, mapping.MappingFromItem);
if (facePartsDirectory is null)
continue;
if (!isBySorting || mapping.MappingFromPerson is not null)
checkFile = Path.Combine(directory, $"{mapping.MappingFromLocation.DeterministicHashCodeKey}{mapping.MappingFromItem.ImageFileHolder.ExtensionLowered}");
else
checkFile = Path.Combine(directory, $"{mapping.MappingFromLocation.DeterministicHashCodeKey}-Source{mapping.MappingFromItem.ImageFileHolder.ExtensionLowered}");
shortcutFile = Path.Combine(personDirectory, $"{mapping.MappingFromLocation.DeterministicHashCodeKey}{mapping.MappingFromItem.ImageFileHolder.ExtensionLowered}.lnk");
hiddenFaceFileHolder = new(Path.Combine(facesDirectory, $"{mapping.MappingFromLocation.DeterministicHashCodeKey}{mapping.MappingFromItem.ImageFileHolder.ExtensionLowered}{_Configuration.FacesHiddenFileNameExtension}"));
facePartsFileHolder = new(Path.Combine(facePartsDirectory, $"{mapping.MappingFromLocation.DeterministicHashCodeKey}{mapping.MappingFromItem.ImageFileHolder.ExtensionLowered}{_Configuration.FacePartsFileNameExtension}"));
@ -444,43 +453,43 @@ public class MapLogic
results.Add(saveContainer);
if (!isBySorting || mapping.SortingContainer is null)
continue;
if (!idToNormalizedPixelPercentageToMapping.TryGetValue(mapping.SortingContainer.Sorting.Id, out normalizedPixelPercentageToMapping))
if (!idToNormalizedRectangleToMapping.TryGetValue(mapping.SortingContainer.Sorting.Id, out normalizedRectangleToMapping))
continue;
if (!normalizedPixelPercentageToMapping.ContainsKey(mapping.SortingContainer.Sorting.NormalizedPixelPercentage))
if (!normalizedRectangleToMapping.ContainsKey(mapping.SortingContainer.Sorting.NormalizedRectangle))
continue;
if (isBySorting && mapping.MappingFromPerson is null)
{
saveContainer = GetMatchSaveContainer(dFacesContentDirectory, d2FacePartsContentDirectory, directory, normalizedPixelPercentageToMapping[mapping.SortingContainer.Sorting.NormalizedPixelPercentage]);
saveContainer = GetMatchSaveContainer(dFacesContentDirectory, d2FacePartsContentDirectory, directory, normalizedRectangleToMapping[mapping.SortingContainer.Sorting.NormalizedRectangle]);
if (saveContainer is not null)
results.Add(saveContainer);
}
saveContainer = Stateless.MapLogic.GetDebugSaveContainer(directory, mapping.SortingContainer, normalizedPixelPercentageToMapping[mapping.SortingContainer.Sorting.NormalizedPixelPercentage]);
saveContainer = Stateless.MapLogic.GetDebugSaveContainer(directory, mapping.SortingContainer, normalizedRectangleToMapping[mapping.SortingContainer.Sorting.NormalizedRectangle]);
results.Add(saveContainer);
}
return results;
}
public void UpdateFromSortingContainersThenSaveContainers(string dFacesContentDirectory, string d2FacePartsContentDirectory, Mapping[] mappingCollection, Dictionary<int, Dictionary<int, Mapping>> idToNormalizedPixelPercentageToMapping, int? useFiltersCounter, SortingContainer[] sortingContainers, int totalNotMapped)
public List<SaveContainer> GetSaveContainers(string dFacesContentDirectory, string d2FacePartsContentDirectory, Mapping[] mappingCollection, Dictionary<int, Dictionary<int, Mapping>> idToNormalizedRectangleToMapping, int? useFiltersCounter, bool saveNullPerson)
{
if (_MapLogicSupport is not null)
{
string counts = _MapLogicSupport.GetCounts();
_ = Directory.CreateDirectory(Path.Combine(_EDistanceContentTicksDirectory, counts));
}
if (_Configuration is null)
throw new NullReferenceException(nameof(_Configuration));
List<SaveContainer> results;
bool saveMapped = false;
Dictionary<long, int> personKeyToCount = new();
int updated = UpdateFromSortingContainers(sortingContainers);
List<SaveContainer> saveContainers = GetSaveContainers(dFacesContentDirectory, d2FacePartsContentDirectory, mappingCollection, idToNormalizedPixelPercentageToMapping, personKeyToCount, useFiltersCounter, saveMapped: false);
SaveContainers(totalNotMapped, updated, saveContainers);
results = GetSaveContainers(dFacesContentDirectory, d2FacePartsContentDirectory, mappingCollection, idToNormalizedRectangleToMapping, personKeyToCount, useFiltersCounter, saveNullPerson, saveMapped);
return results;
}
public void SaveMapped(string dFacesContentDirectory, string d2FacePartsContentDirectory, Mapping[] mappingCollection, Dictionary<int, Dictionary<int, Mapping>> idToNormalizedPixelPercentageToMapping, Dictionary<long, int> personKeyToCount, int totalNotMapped)
public void SaveMapped(string dFacesContentDirectory, string d2FacePartsContentDirectory, Mapping[] mappingCollection, Dictionary<int, Dictionary<int, Mapping>> idToNormalizedRectangleToMapping, Dictionary<long, int> personKeyToCount, int totalNotMapped)
{
if (_Configuration is null)
throw new NullReferenceException(nameof(_Configuration));
int? updated = null;
bool saveMapped = true;
bool saveNullPerson = false;
int? useFiltersCounter = null;
string mappingDirectory = Path.Combine(_EDistanceContentTicksDirectory, nameof(IMapLogic.Mapping));
List<SaveContainer> saveContainers = GetSaveContainers(dFacesContentDirectory, d2FacePartsContentDirectory, mappingCollection, idToNormalizedPixelPercentageToMapping, personKeyToCount, useFiltersCounter, saveMapped: true);
List<SaveContainer> saveContainers = GetSaveContainers(dFacesContentDirectory, d2FacePartsContentDirectory, mappingCollection, idToNormalizedRectangleToMapping, personKeyToCount, useFiltersCounter, saveNullPerson, saveMapped);
SaveContainers(totalNotMapped, updated, saveContainers);
if (!string.IsNullOrEmpty(_EDistanceContentTicksDirectory) && Directory.Exists(mappingDirectory))
Stateless.MapLogic.SaveMappingShortcuts(mappingDirectory);
@ -504,18 +513,18 @@ public class MapLogic
public bool Used(FaceDistance faceDistanceEncoding)
{
bool result = false;
if (faceDistanceEncoding.NormalizedPixelPercentage is null)
if (faceDistanceEncoding.NormalizedRectangle is null)
throw new NotSupportedException();
List<int>? normalizedPixelPercentages;
Dictionary<int, PersonContainer[]>? normalizedPixelPercentageToPersonContainers;
if (_SkipCollection.TryGetValue(faceDistanceEncoding.Id, out normalizedPixelPercentages))
List<int>? normalizedRectangles;
Dictionary<int, PersonContainer[]>? normalizedRectangleToPersonContainers;
if (_SkipCollection.TryGetValue(faceDistanceEncoding.Id, out normalizedRectangles))
{
if (normalizedPixelPercentages.Contains(faceDistanceEncoding.NormalizedPixelPercentage.Value))
if (normalizedRectangles.Contains(faceDistanceEncoding.NormalizedRectangle.Value))
result = true;
}
if (!result && _IdThenNormalizedPixelPercentageToPersonContainers.TryGetValue(faceDistanceEncoding.Id, out normalizedPixelPercentageToPersonContainers))
if (!result && _IdThenNormalizedRectangleToPersonContainers.TryGetValue(faceDistanceEncoding.Id, out normalizedRectangleToPersonContainers))
{
if (normalizedPixelPercentageToPersonContainers.ContainsKey(faceDistanceEncoding.NormalizedPixelPercentage.Value))
if (normalizedRectangleToPersonContainers.ContainsKey(faceDistanceEncoding.NormalizedRectangle.Value))
result = true;
}
return result;
@ -528,45 +537,45 @@ public class MapLogic
List<Sorting> results = new();
Sorting sorting;
FaceDistance faceDistanceLength;
List<int>? normalizedPixelPercentages;
Dictionary<int, PersonContainer[]>? normalizedPixelPercentageToPersonContainers;
List<int>? normalizedRectangles;
Dictionary<int, PersonContainer[]>? normalizedRectangleToPersonContainers;
List<(long lcl, long minimum, long maximum, long ucl)> personKeysRangesCollection;
for (int j = 0; j < faceDistanceLengths.Count; j++)
{
if (faceDistanceEncoding.NormalizedPixelPercentage is null)
if (faceDistanceEncoding.NormalizedRectangle is null)
throw new NotSupportedException();
if (j == i)
continue;
if (_SkipCollection.TryGetValue(faceDistanceEncoding.Id, out normalizedPixelPercentages))
if (_SkipCollection.TryGetValue(faceDistanceEncoding.Id, out normalizedRectangles))
{
if (normalizedPixelPercentages.Contains(faceDistanceEncoding.NormalizedPixelPercentage.Value))
if (normalizedRectangles.Contains(faceDistanceEncoding.NormalizedRectangle.Value))
continue;
}
if (_IdThenNormalizedPixelPercentageToPersonContainers.TryGetValue(faceDistanceEncoding.Id, out normalizedPixelPercentageToPersonContainers))
if (_IdThenNormalizedRectangleToPersonContainers.TryGetValue(faceDistanceEncoding.Id, out normalizedRectangleToPersonContainers))
{
if (normalizedPixelPercentageToPersonContainers.ContainsKey(faceDistanceEncoding.NormalizedPixelPercentage.Value))
if (normalizedRectangleToPersonContainers.ContainsKey(faceDistanceEncoding.NormalizedRectangle.Value))
continue;
}
faceDistanceLength = faceDistanceLengths[j];
if (faceDistanceLength.NormalizedPixelPercentage is null || faceDistanceLength.Length is null)
if (faceDistanceLength.NormalizedRectangle is null || faceDistanceLength.Length is null)
throw new NotSupportedException();
if (faceDistanceLength.Length == 0)
continue;
if (!_IdThenNormalizedPixelPercentageToPersonContainers.TryGetValue(faceDistanceLength.Id, out normalizedPixelPercentageToPersonContainers))
if (!_IdThenNormalizedRectangleToPersonContainers.TryGetValue(faceDistanceLength.Id, out normalizedRectangleToPersonContainers))
personKeysRangesCollection = new();
else
{
if (!normalizedPixelPercentageToPersonContainers.ContainsKey(faceDistanceLength.NormalizedPixelPercentage.Value))
if (!normalizedRectangleToPersonContainers.ContainsKey(faceDistanceLength.NormalizedRectangle.Value))
personKeysRangesCollection = new();
else
personKeysRangesCollection = GetPersonKeysRangesCollection(normalizedPixelPercentageToPersonContainers[faceDistanceLength.NormalizedPixelPercentage.Value]);
personKeysRangesCollection = GetPersonKeysRangesCollection(normalizedRectangleToPersonContainers[faceDistanceLength.NormalizedRectangle.Value]);
}
sorting = ISorting.Get(_Configuration.FaceDistancePermyriad, _Configuration.RangeDistanceTolerance, faceDistanceEncoding, faceDistanceLength, personKeysRangesCollection);
if (sorting.DistancePermyriad == 0)
continue;
if (sorting.Id == faceDistanceEncoding.Id)
{
if (sorting.NormalizedPixelPercentage == faceDistanceEncoding.NormalizedPixelPercentage.Value)
if (sorting.NormalizedRectangle == faceDistanceEncoding.NormalizedRectangle.Value)
throw new NotSupportedException();
continue;
}
@ -575,10 +584,15 @@ public class MapLogic
return results;
}
public int UpdateFromSortingContainers(SortingContainer[] sortingContainers)
public int UpdateFromSortingContainers(SortingContainer[] sortingContainers, bool saveNullPerson)
{
if (_Configuration is null)
throw new NullReferenceException(nameof(_Configuration));
if (_MapLogicSupport is not null)
{
string counts = _MapLogicSupport.GetCounts();
_ = Directory.CreateDirectory(Path.Combine(_EDistanceContentTicksDirectory, counts));
}
int result = 0;
string key;
const int zero = 0;
@ -587,12 +601,13 @@ public class MapLogic
PersonBirthday personBirthday;
const int by = IMapLogic.Sorting;
PersonContainer[] personContainers;
List<int> normalizedPixelPercentageCollectionForA;
List<int> normalizedPixelPercentageCollectionForB;
Dictionary<string, int> checkKeyValuePairs = new();
Dictionary<int, List<int>> idToNormalizedPixelPercentageCollectionForA = new();
Dictionary<int, List<int>> idToNormalizedPixelPercentageCollectionForB = new();
Dictionary<int, PersonContainer[]>? normalizedPixelPercentageToPersonContainers;
Dictionary<string, int> keyToCount = new();
Dictionary<string, string> keyToSegmentC = new();
List<int> normalizedRectangleCollectionForA;
List<int> normalizedRectangleCollectionForB;
Dictionary<int, List<int>> idToNormalizedRectangleCollectionForA = new();
Dictionary<int, List<int>> idToNormalizedRectangleCollectionForB = new();
Dictionary<int, PersonContainer[]>? normalizedRectangleToPersonContainers;
int totalSeconds = (int)Math.Floor(new TimeSpan(DateTime.Now.Ticks - _Ticks).TotalSeconds);
string message = $") {sortingContainers.Length:000} Update From Sorting Container(s) - {totalSeconds} total second(s)";
ProgressBarOptions options = new() { ProgressCharacter = '─', ProgressBarOnBottom = true, DisableBottomPercentage = true };
@ -602,35 +617,39 @@ public class MapLogic
progressBar.Tick();
if (sortingContainer.Mapping is null)
throw new NotSupportedException();
if (!idToNormalizedPixelPercentageCollectionForA.ContainsKey(sortingContainer.Mapping.MappingFromItem.Id))
idToNormalizedPixelPercentageCollectionForA.Add(sortingContainer.Mapping.MappingFromItem.Id, new());
normalizedPixelPercentageCollectionForA = idToNormalizedPixelPercentageCollectionForA[sortingContainer.Mapping.MappingFromItem.Id];
if (!idToNormalizedPixelPercentageCollectionForB.ContainsKey(sortingContainer.Mapping.MappingFromItem.Id))
idToNormalizedPixelPercentageCollectionForB.Add(sortingContainer.Mapping.MappingFromItem.Id, new());
normalizedPixelPercentageCollectionForB = idToNormalizedPixelPercentageCollectionForB[sortingContainer.Mapping.MappingFromItem.Id];
if (!_IdThenNormalizedPixelPercentageToPersonContainers.TryGetValue(sortingContainer.Sorting.Id, out normalizedPixelPercentageToPersonContainers))
if (!idToNormalizedRectangleCollectionForA.ContainsKey(sortingContainer.Mapping.MappingFromItem.Id))
idToNormalizedRectangleCollectionForA.Add(sortingContainer.Mapping.MappingFromItem.Id, new());
normalizedRectangleCollectionForA = idToNormalizedRectangleCollectionForA[sortingContainer.Mapping.MappingFromItem.Id];
if (!idToNormalizedRectangleCollectionForB.ContainsKey(sortingContainer.Mapping.MappingFromItem.Id))
idToNormalizedRectangleCollectionForB.Add(sortingContainer.Mapping.MappingFromItem.Id, new());
normalizedRectangleCollectionForB = idToNormalizedRectangleCollectionForB[sortingContainer.Mapping.MappingFromItem.Id];
if (!_IdThenNormalizedRectangleToPersonContainers.TryGetValue(sortingContainer.Sorting.Id, out normalizedRectangleToPersonContainers))
{
personContainers = Array.Empty<PersonContainer>();
if (normalizedPixelPercentageCollectionForA.Contains(sortingContainer.Mapping.MappingFromLocation.NormalizedPixelPercentage))
if (!saveNullPerson)
continue;
key = string.Concat(sortingContainer.Mapping.MappingFromItem.Id, '\t', sortingContainer.Mapping.MappingFromLocation.NormalizedPixelPercentage);
if (!checkKeyValuePairs.ContainsKey(key))
checkKeyValuePairs.Add(key, new());
checkKeyValuePairs[key]++;
if (checkKeyValuePairs[key] > _Configuration.SortingMaximumPerKey)
personContainers = Array.Empty<PersonContainer>();
if (normalizedRectangleCollectionForA.Contains(sortingContainer.Mapping.MappingFromLocation.NormalizedRectangle))
continue;
key = string.Concat(sortingContainer.Mapping.MappingFromItem.Id, '\t', sortingContainer.Mapping.MappingFromLocation.NormalizedRectangle);
if (!keyToCount.ContainsKey(key))
keyToCount.Add(key, 0);
if (!keyToSegmentC.ContainsKey(key))
keyToSegmentC.Add(key, string.Empty);
keyToCount[key]++;
if (keyToCount[key] > _Configuration.SortingMaximumPerKey)
continue;
sortingContainer.Mapping.UpdateMappingFromUnknownPerson(by, sortingContainer);
normalizedPixelPercentageCollectionForA.Add(sortingContainer.Mapping.MappingFromLocation.NormalizedPixelPercentage);
normalizedRectangleCollectionForA.Add(sortingContainer.Mapping.MappingFromLocation.NormalizedRectangle);
result += 1;
}
else
{
if (normalizedPixelPercentageCollectionForB.Contains(sortingContainer.Mapping.MappingFromLocation.NormalizedPixelPercentage))
if (normalizedRectangleCollectionForB.Contains(sortingContainer.Mapping.MappingFromLocation.NormalizedRectangle))
continue;
if (!normalizedPixelPercentageToPersonContainers.ContainsKey(sortingContainer.Sorting.NormalizedPixelPercentage))
if (!normalizedRectangleToPersonContainers.ContainsKey(sortingContainer.Sorting.NormalizedRectangle))
personContainers = Array.Empty<PersonContainer>();
else
personContainers = normalizedPixelPercentageToPersonContainers[sortingContainer.Sorting.NormalizedPixelPercentage];
personContainers = normalizedRectangleToPersonContainers[sortingContainer.Sorting.NormalizedRectangle];
foreach (PersonContainer personContainer in personContainers)
{
if (personContainer.Key is null || personContainer.Birthdays is null || !personContainer.Birthdays.Any())
@ -639,13 +658,20 @@ public class MapLogic
personKeyFormatted = IPersonBirthday.GetFormatted(_Configuration.PersonBirthdayFormat, personBirthday);
mappingSegmentB = Stateless.MapLogic.GetMappingSegmentB(_Ticks, personBirthday, personContainer.ApproximateYears, sortingContainer.Mapping.MappingFromItem);
key = string.Concat(personKeyFormatted, '\t', mappingSegmentB);
if (!checkKeyValuePairs.ContainsKey(key))
checkKeyValuePairs.Add(key, new());
checkKeyValuePairs[key]++;
if (checkKeyValuePairs[key] > _Configuration.SortingMaximumPerKey)
continue;
sortingContainer.Mapping.UpdateMappingFromPerson(personContainer.ApproximateYears, by, personContainer.DisplayDirectoryName, personBirthday, mappingSegmentB, sortingContainer);
normalizedPixelPercentageCollectionForB.Add(sortingContainer.Mapping.MappingFromLocation.NormalizedPixelPercentage);
if (!keyToCount.ContainsKey(key))
keyToCount.Add(key, new());
if (!keyToCount.ContainsKey(key))
keyToCount.Add(key, 0);
if (!keyToSegmentC.ContainsKey(key))
keyToSegmentC.Add(key, string.Empty);
keyToCount[key]++;
if (keyToCount[key] > _Configuration.SortingMaximumPerKey)
{
keyToCount[key] = 0;
keyToSegmentC[key] = sortingContainer.Sorting.DistancePermyriad.ToString();
}
sortingContainer.Mapping.UpdateMappingFromPerson(personContainer.ApproximateYears, by, personContainer.DisplayDirectoryName, personBirthday, mappingSegmentB, keyToSegmentC[key], sortingContainer);
normalizedRectangleCollectionForB.Add(sortingContainer.Mapping.MappingFromLocation.NormalizedRectangle);
result += 1;
break;
}
@ -654,7 +680,7 @@ public class MapLogic
return result;
}
public void CopyManualFiles(string dFacesContentDirectory, Dictionary<int, Dictionary<int, Mapping>> idToNormalizedPixelPercentageToMapping)
public void CopyManualFiles(string dFacesContentDirectory, Dictionary<int, Dictionary<int, Mapping>> idToNormalizedRectangleToMapping)
{
if (_Configuration is null)
throw new NullReferenceException(nameof(_Configuration));
@ -675,11 +701,11 @@ public class MapLogic
string personDisplayFileName;
PersonBirthday personBirthday;
string? personDisplayDirectory;
int? normalizedPixelPercentage;
int? normalizedRectangle;
WindowsShortcut windowsShortcut;
string by = nameof(IMapLogic.ManualCopy);
Dictionary<int, Mapping>? normalizedPixelPercentageToMapping;
Dictionary<int, PersonContainer[]>? normalizedPixelPercentageToPeronContainerCollection;
Dictionary<int, Mapping>? normalizedRectangleToMapping;
Dictionary<int, PersonContainer[]>? normalizedRectangleToPeronContainerCollection;
string successfull = $"_ {nameof(IMapLogic.ManualCopy).Humanize(LetterCasing.Title)} Successfull";
foreach (KeyValuePair<long, PersonContainer> keyValuePair in _PersonKeyToPersonContainer)
{
@ -692,8 +718,8 @@ public class MapLogic
continue;
if (!personDisplayDirectoryAllFile.EndsWith(_Configuration.FacesFileNameExtension))
continue;
(id, normalizedPixelPercentage, _) = IMapping.GetReversedDeterministicHashCodeKey(_Configuration.FacesFileNameExtension, personDisplayDirectoryAllFile);
if (id is null || normalizedPixelPercentage is null)
(id, normalizedRectangle, _) = IMapping.GetConverted(_Configuration.FacesFileNameExtension, personDisplayDirectoryAllFile);
if (id is null || normalizedRectangle is null)
continue;
fileInfo = new(personDisplayDirectoryAllFile);
if (!fileInfo.Exists)
@ -704,11 +730,11 @@ public class MapLogic
mappingSegmentB = Stateless.MapLogic.GetMappingSegmentB(_Ticks, personBirthday, keyValuePair.Value.ApproximateYears, fileInfo.CreationTime, isWrongYear: null);
directory = Path.Combine(_EDistanceContentTicksDirectory, by, personKeyFormatted, mappingSegmentB);
personDirectory = Path.Combine(directory, keyValuePair.Value.DisplayDirectoryName, "lnk");
if (!idToNormalizedPixelPercentageToMapping.TryGetValue(id.Value, out normalizedPixelPercentageToMapping))
if (!idToNormalizedRectangleToMapping.TryGetValue(id.Value, out normalizedRectangleToMapping))
continue;
if (!normalizedPixelPercentageToMapping.ContainsKey(normalizedPixelPercentage.Value))
if (!normalizedRectangleToMapping.ContainsKey(normalizedRectangle.Value))
continue;
mapping = normalizedPixelPercentageToMapping[normalizedPixelPercentage.Value];
mapping = normalizedRectangleToMapping[normalizedRectangle.Value];
if (string.IsNullOrEmpty(personDisplayDirectory))
throw new NotSupportedException();
directoryName = Path.GetDirectoryName(mapping.MappingFromItem.RelativePath);
@ -720,7 +746,7 @@ public class MapLogic
continue;
faceFileName = $"{mapping.MappingFromLocation.DeterministicHashCodeKey}{mapping.MappingFromItem.ImageFileHolder.ExtensionLowered}{_Configuration.FacesFileNameExtension}";
checkFile = Path.Combine(directory, fileInfo.Name);
if (!_IdThenNormalizedPixelPercentageToPersonContainers.TryGetValue(id.Value, out normalizedPixelPercentageToPeronContainerCollection) || !normalizedPixelPercentageToPeronContainerCollection.ContainsKey(normalizedPixelPercentage.Value))
if (!_IdThenNormalizedRectangleToPersonContainers.TryGetValue(id.Value, out normalizedRectangleToPeronContainerCollection) || !normalizedRectangleToPeronContainerCollection.ContainsKey(normalizedRectangle.Value))
{
if (!Directory.Exists(personDirectory))
_ = Directory.CreateDirectory(personDirectory);
@ -946,7 +972,7 @@ public class MapLogic
SaveContainers(totalNotMapped, null, saveContainers);
}
private List<(string, string, string, string)> GetCollectionForSaveShortcuts(string[] jLinks, string a2PeopleSingletonDirectory, PersonContainer[] personContainers, List<Item> filteredItems, Mapping[] mappingCollection, Dictionary<long, int> personKeyToCount)
private (List<(string, DateTime[])>, List<(string, string, string, string)>) GetCollectionForSaveShortcutsForOutputResolutions(List<Item> filteredItems, Mapping[] mappingCollection, Dictionary<long, int> personKeyToCount)
{
if (_Configuration is null)
throw new NullReferenceException(nameof(_Configuration));
@ -956,19 +982,44 @@ public class MapLogic
string? directoryName;
string personDirectory;
string personKeyFormatted;
List<string> distinct = new();
List<(string, string, string, string)> collection = new();
List<string> personKeyFormattedCollection = GetPersonKeyFormattedCollection(jLinks, a2PeopleSingletonDirectory, personContainers, personKeyToCount);
List<(string, DateTime[])> directoriesAndDateTimes = new();
foreach (Item item in filteredItems)
{
directoryName = Path.GetDirectoryName(item.RelativePath);
if (item.ResizedFileHolder is null)
continue;
foreach (Face face in item.Faces)
{
if (face.FaceEncoding is null || face.Location is null || face.OutputResolution is null || face.Mapping is null)
continue;
directoryName = Path.GetDirectoryName(face.Mapping.MappingFromItem.RelativePath);
if (directoryName is null)
throw new NotSupportedException();
if (item.Property?.Id is null || item.ResizedFileHolder?.DirectoryName is null || !item.ResizedFileHolder.Exists)
if (item.ResizedFileHolder?.DirectoryName is null || !item.ResizedFileHolder.Exists)
continue;
directory = Path.Combine(item.ResizedFileHolder.DirectoryName, $"{_PropertyConfiguration.ResultAllInOne}Shortcuts", _PropertyConfiguration.ResultAllInOne);
personDirectory = Path.Combine(directory, "No Faces");
fileName = Path.Combine(personDirectory, $"{item.ResizedFileHolder.Name}.lnk");
collection.Add(new(item.ResizedFileHolder.FullName, personDirectory, fileName, item.Property.Id.Value.ToString()));
collection.Add(new(item.ResizedFileHolder.FullName, personDirectory, fileName, face.Mapping.MappingFromItem.Id.ToString()));
if (face.Mapping.MappingFromItem.ContainerDateTimes.Any() && !distinct.Contains(item.ResizedFileHolder.DirectoryName))
{
distinct.Add(item.ResizedFileHolder.DirectoryName);
directoriesAndDateTimes.Add(new(item.ResizedFileHolder.DirectoryName, face.Mapping.MappingFromItem.ContainerDateTimes));
}
}
}
foreach (Mapping mapping in mappingCollection)
{
if (mapping.MappingFromItem.ResizedFileHolder.DirectoryName is null || !mapping.MappingFromItem.ResizedFileHolder.Exists)
continue;
if (mapping.By is null or IMapLogic.Sorting || mapping.MappingFromPerson?.ApproximateYears is null)
continue;
if (string.IsNullOrEmpty(mapping.MappingFromPerson.SegmentB))
throw new NotSupportedException();
if (string.IsNullOrEmpty(mapping.MappingFromPerson.DisplayDirectoryName))
throw new NotSupportedException();
personKeyFormatted = IPersonBirthday.GetFormatted(_Configuration.PersonBirthdayFormat, mapping.MappingFromPerson.PersonBirthday);
}
foreach (Mapping mapping in mappingCollection)
{
@ -979,6 +1030,11 @@ public class MapLogic
continue;
if (mapping.By is null or IMapLogic.Sorting || mapping.MappingFromPerson?.ApproximateYears is null)
{
if (mapping.MappingFromItem.ContainerDateTimes.Any() && !distinct.Contains(mapping.MappingFromItem.ResizedFileHolder.DirectoryName))
{
distinct.Add(mapping.MappingFromItem.ResizedFileHolder.DirectoryName);
directoriesAndDateTimes.Add(new(mapping.MappingFromItem.ResizedFileHolder.DirectoryName, mapping.MappingFromItem.ContainerDateTimes));
}
directory = Path.Combine(mapping.MappingFromItem.ResizedFileHolder.DirectoryName, $"{_PropertyConfiguration.ResultAllInOne}Shortcuts", _PropertyConfiguration.ResultAllInOne);
personDirectory = Path.Combine(directory, "Unknown");
fileName = Path.Combine(personDirectory, $"{mapping.MappingFromItem.ResizedFileHolder.Name}.lnk");
@ -991,9 +1047,12 @@ public class MapLogic
if (string.IsNullOrEmpty(mapping.MappingFromPerson.DisplayDirectoryName))
throw new NotSupportedException();
personKeyFormatted = IPersonBirthday.GetFormatted(_Configuration.PersonBirthdayFormat, mapping.MappingFromPerson.PersonBirthday);
if (!personKeyFormattedCollection.Contains(personKeyFormatted))
continue;
personKey = mapping.MappingFromPerson.PersonBirthday.Value.Ticks;
if (mapping.MappingFromItem.ContainerDateTimes.Any() && !distinct.Contains(mapping.MappingFromItem.ResizedFileHolder.DirectoryName))
{
distinct.Add(mapping.MappingFromItem.ResizedFileHolder.DirectoryName);
directoriesAndDateTimes.Add(new(mapping.MappingFromItem.ResizedFileHolder.DirectoryName, mapping.MappingFromItem.ContainerDateTimes));
}
directory = Path.Combine(mapping.MappingFromItem.ResizedFileHolder.DirectoryName, $"{_PropertyConfiguration.ResultAllInOne}Shortcuts", personKeyFormatted);
if (!personKeyToCount.ContainsKey(personKey))
personDirectory = Path.Combine(directory, mapping.MappingFromPerson.DisplayDirectoryName);
@ -1003,16 +1062,17 @@ public class MapLogic
collection.Add(new(mapping.MappingFromItem.ResizedFileHolder.FullName, personDirectory, fileName, mapping.MappingFromLocation.DeterministicHashCodeKey));
}
}
return collection;
return new(directoriesAndDateTimes, collection);
}
public void SaveShortcuts(string a2PeopleSingletonDirectory, PersonContainer[] personContainers, List<Item> filteredItems, Mapping[] mappingCollection, Dictionary<long, int> personKeyToCount)
public void SaveShortcutsForOutputResolutions(List<Item> filteredItems, Mapping[] mappingCollection, Dictionary<long, int> personKeyToCount)
{
if (_Configuration is null)
throw new NullReferenceException(nameof(_Configuration));
WindowsShortcut windowsShortcut;
string[] jLinks = new string[] { "All" };
List<(string, string Directory, string, string)> collection = GetCollectionForSaveShortcuts(jLinks, a2PeopleSingletonDirectory, personContainers, filteredItems, mappingCollection, personKeyToCount);
List<(string, DateTime[])> directoriesAndDateTimes;
List<(string, string Directory, string, string)> collection;
(directoriesAndDateTimes, collection) = GetCollectionForSaveShortcutsForOutputResolutions(filteredItems, mappingCollection, personKeyToCount);
string[] directories = (from l in collection select l.Directory).Distinct().ToArray();
foreach (string directory in directories)
{
@ -1034,9 +1094,16 @@ public class MapLogic
catch (Exception)
{ }
}
foreach ((string directory, DateTime[] dateTimes) in directoriesAndDateTimes)
{
if (!dateTimes.Any())
continue;
Directory.SetCreationTime(directory, dateTimes[0]);
Directory.SetLastWriteTime(directory, dateTimes[1]);
}
}
private List<(string, FileHolder, string)> GetCollection(string dFacesContentDirectory, Dictionary<int, Dictionary<int, Mapping>> idToNormalizedPixelPercentageToMapping)
private List<(string, FileHolder, string)> GetCollection(string dFacesContentDirectory, Dictionary<int, Dictionary<int, Mapping>> idToNormalizedRectangleToMapping)
{
if (_Configuration is null)
throw new NullReferenceException(nameof(_Configuration));
@ -1047,19 +1114,19 @@ public class MapLogic
string? directoryName;
string? facesDirectory;
FileHolder faceFileHolder;
List<int>? normalizedPixelPercentages;
List<int>? normalizedRectangles;
string by = nameof(IMapLogic.CopyNotMappedFaces);
Dictionary<int, PersonContainer[]>? normalizedPixelPercentageToPersonContainers;
foreach (KeyValuePair<int, Dictionary<int, Mapping>> keyValuePair in idToNormalizedPixelPercentageToMapping)
Dictionary<int, PersonContainer[]>? normalizedRectangleToPersonContainers;
foreach (KeyValuePair<int, Dictionary<int, Mapping>> keyValuePair in idToNormalizedRectangleToMapping)
{
_ = _IdThenNormalizedPixelPercentageToPersonContainers.TryGetValue(keyValuePair.Key, out normalizedPixelPercentageToPersonContainers);
foreach (KeyValuePair<int, Mapping> normalizedPixelPercentageAndMapping in keyValuePair.Value)
_ = _IdThenNormalizedRectangleToPersonContainers.TryGetValue(keyValuePair.Key, out normalizedRectangleToPersonContainers);
foreach (KeyValuePair<int, Mapping> normalizedRectangleAndMapping in keyValuePair.Value)
{
mapping = normalizedPixelPercentageAndMapping.Value;
if (normalizedPixelPercentageToPersonContainers is not null && normalizedPixelPercentageToPersonContainers.ContainsKey(mapping.MappingFromLocation.NormalizedPixelPercentage))
mapping = normalizedRectangleAndMapping.Value;
if (normalizedRectangleToPersonContainers is not null && normalizedRectangleToPersonContainers.ContainsKey(mapping.MappingFromLocation.NormalizedRectangle))
continue;
_ = _SkipCollection.TryGetValue(keyValuePair.Key, out normalizedPixelPercentages);
if (normalizedPixelPercentages is not null && normalizedPixelPercentages.Contains(mapping.MappingFromLocation.NormalizedPixelPercentage))
_ = _SkipCollection.TryGetValue(keyValuePair.Key, out normalizedRectangles);
if (normalizedRectangles is not null && normalizedRectangles.Contains(mapping.MappingFromLocation.NormalizedRectangle))
continue;
directoryName = Path.GetDirectoryName(mapping.MappingFromItem.RelativePath);
facesDirectory = GetFacesDirectory(dFacesContentDirectory, mapping.MappingFromItem); // Path.Combine($"{dFacesContentDirectory}{directoryName}", mapping.MappingFromItem.ImageFileHolder.NameWithoutExtension);
@ -1076,11 +1143,11 @@ public class MapLogic
return results;
}
public void CopyNotMappedFaces(int[] rangeFaceAreaPermilleTolerance, string dFacesContentDirectory, Dictionary<int, Dictionary<int, Mapping>> idToNormalizedPixelPercentageToMapping)
public void CopyNotMappedFaces(int[] rangeFaceAreaPermilleTolerance, string dFacesContentDirectory, Dictionary<int, Dictionary<int, Mapping>> idToNormalizedRectangleToMapping)
{
if (_Configuration is null)
throw new NullReferenceException(nameof(_Configuration));
List<(string Directory, FileHolder FaceFileHolder, string CheckFile)> collection = GetCollection(dFacesContentDirectory, idToNormalizedPixelPercentageToMapping);
List<(string Directory, FileHolder FaceFileHolder, string CheckFile)> collection = GetCollection(dFacesContentDirectory, idToNormalizedRectangleToMapping);
string[] directories = (from l in collection select l.Directory).Distinct().ToArray();
foreach (string directory in directories)
{
@ -1097,4 +1164,249 @@ public class MapLogic
}
}
private DatabaseFileRoot GetDatabaseFileRoot()
{
if (_Configuration is null)
throw new NullReferenceException(nameof(_Configuration));
string file = Path.Combine(_Configuration.PhotoPrismDirectory, "files.json");
string json = File.ReadAllText(file);
DatabaseFileRoot? databaseFileRoot = JsonSerializer.Deserialize<DatabaseFileRoot>(json);
if (databaseFileRoot is null)
throw new NullReferenceException(nameof(databaseFileRoot));
return databaseFileRoot;
}
private Marker[] GetMarkers()
{
if (_Configuration is null)
throw new NullReferenceException(nameof(_Configuration));
string file = Path.Combine(_Configuration.PhotoPrismDirectory, "markers.json");
string json = File.ReadAllText(file);
Marker[]? markerRoot = JsonSerializer.Deserialize<Marker[]>(json);
if (markerRoot is null)
throw new NullReferenceException(nameof(markerRoot));
return markerRoot;
}
private static Dictionary<string, DatabaseFile> Get(DatabaseFileRoot databaseFileRoot)
{
Dictionary<string, DatabaseFile> fileUidToFile = new();
for (int i = 0; i < databaseFileRoot.Files.Count; i++)
fileUidToFile.Add(databaseFileRoot.Files[i].FileUid, databaseFileRoot.Files[i]);
return fileUidToFile;
}
private static MarkerWith GetMarkerWith(int? dlib, DatabaseFile databaseFile, Marker marker, int? count, double? percent, int? normalizedRectangle, long? personKey, string personKeyFormatted)
{
return new(marker.MarkerUid,
marker.FileUid,
marker.MarkerType,
marker.MarkerSrc,
marker.MarkerName,
marker.MarkerReview,
marker.MarkerInvalid,
marker.SubjUid,
marker.SubjSrc,
marker.FaceId,
marker.FaceDist,
marker.EmbeddingsJson,
marker.LandmarksJson,
marker.X,
marker.Y,
marker.W,
marker.H,
marker.Q,
marker.Size,
marker.Score,
marker.Thumb,
marker.MatchedAt,
marker.CreatedAt,
marker.UpdatedAt,
databaseFile.Id,
databaseFile.FileName,
dlib,
count,
percent,
normalizedRectangle,
personKey,
personKeyFormatted);
}
private static Dictionary<string, List<Face>> GetFacesByFileName(List<Item> filteredItems)
{
Dictionary<string, List<Face>> results = new();
string key;
foreach (Item item in filteredItems)
{
foreach (Face face in item.Faces)
{
if (face.FaceEncoding is null || face.Location is null || face.OutputResolution is null || face.Mapping is null)
continue;
key = Path.GetFileNameWithoutExtension(face.Mapping.MappingFromItem.RelativePath);
if (!results.ContainsKey(key))
results.Add(key, new());
results[key].Add(face);
}
}
return results;
}
public void FindMatch(List<Item> filteredItems)
{
if (_Configuration is null)
throw new NullReferenceException(nameof(_Configuration));
int? dlib;
double? percent;
long? personKey;
const int zero = 0;
List<Face>? matches;
MarkerWith markerWith;
int? normalizedRectangle;
string personKeyFormatted;
DatabaseFile? databaseFile;
PersonBirthday personBirthday;
Marker[] markers = GetMarkers();
string fileNameWithoutExtension;
PersonContainer[]? personContainers;
System.Drawing.Rectangle dlibRectangle;
System.Drawing.Rectangle prismRectangle;
System.Drawing.Rectangle intersectRectangle;
(Face Face, double Percent)[] sortedCollection;
List<(Face Face, double Percent)> collection = new();
DatabaseFileRoot databaseFileRoot = GetDatabaseFileRoot();
Dictionary<string, DatabaseFile> fileUidToFile = Get(databaseFileRoot);
Dictionary<int, PersonContainer[]>? normalizedRectangleToPersonContainers;
Dictionary<string, List<Face>> keyValuePairs = GetFacesByFileName(filteredItems);
foreach (Marker marker in markers)
{
dlib = null;
personKey = null;
collection.Clear();
normalizedRectangle = null;
personKeyFormatted = string.Empty;
normalizedRectangleToPersonContainers = null;
if (!fileUidToFile.TryGetValue(marker.FileUid, out databaseFile))
continue;
fileNameWithoutExtension = Path.GetFileNameWithoutExtension(Path.Combine("C:", databaseFile.FileName));
prismRectangle = new((int)(marker.X * databaseFile.FileWidth), (int)(marker.Y * databaseFile.FileHeight), (int)(marker.W * databaseFile.FileWidth), (int)(marker.H * databaseFile.FileHeight));
if (!keyValuePairs.TryGetValue(fileNameWithoutExtension, out matches) || !int.TryParse(fileNameWithoutExtension, out int id))
percent = null;
else
{
dlib = id;
_ = _IdThenNormalizedRectangleToPersonContainers.TryGetValue(dlib.Value, out normalizedRectangleToPersonContainers);
foreach (Face face in matches)
{
if (face.Location is null || face.OutputResolution is null)
continue;
dlibRectangle = new(face.Location.Left, face.Location.Top, face.Location.Right - face.Location.Left, face.Location.Bottom - face.Location.Top);
intersectRectangle = System.Drawing.Rectangle.Intersect(prismRectangle, dlibRectangle);
if (intersectRectangle.Width == 0 || intersectRectangle.Height == 0)
continue;
percent = (double)intersectRectangle.Width * intersectRectangle.Height / (dlibRectangle.Width * dlibRectangle.Height);
if (percent < 0.000001)
continue;
collection.Add(new(face, percent.Value));
}
}
if (!collection.Any())
percent = null;
else
{
sortedCollection = collection.OrderByDescending(l => l.Percent).ToArray();
percent = sortedCollection[zero].Percent;
normalizedRectangle = sortedCollection[zero].Face.Mapping?.MappingFromLocation.NormalizedRectangle;
if (normalizedRectangleToPersonContainers is null || normalizedRectangle is null || !normalizedRectangleToPersonContainers.TryGetValue(normalizedRectangle.Value, out personContainers))
personContainers = null;
else
{
foreach (PersonContainer personContainer in personContainers)
{
if (personContainer.Key is null || personContainer.Birthdays is null || !personContainer.Birthdays.Any())
continue;
personBirthday = personContainer.Birthdays[zero];
personKey = personBirthday.Value.Ticks;
personKeyFormatted = IPersonBirthday.GetFormatted(_Configuration.PersonBirthdayFormat, personBirthday);
break;
}
}
}
markerWith = GetMarkerWith(dlib, databaseFile, marker, collection.Count, percent, normalizedRectangle, personKey, personKeyFormatted);
string json = JsonSerializer.Serialize(markerWith, new JsonSerializerOptions() { WriteIndented = true });
if (IPath.WriteAllText(Path.Combine(_Configuration.PhotoPrismDirectory, "With", $"{marker.MarkerUid}.json"), json, updateDateWhenMatches: false, compareBeforeWrite: true))
continue;
}
}
public void SaveMarkers()
{
if (_Configuration is null)
throw new NullReferenceException(nameof(_Configuration));
double[]? encoding;
string file = Path.Combine(_Configuration.PhotoPrismDirectory, "markers.json");
string json = File.ReadAllText(file);
Marker[]? markers = JsonSerializer.Deserialize<Marker[]>(json);
if (markers is null)
throw new NullReferenceException(nameof(markers));
foreach (Marker marker in markers)
{
encoding = JsonSerializer.Deserialize<double[]>(marker.EmbeddingsJson[1..^1]);
File.WriteAllText(Path.Combine(_Configuration.PhotoPrismDirectory, "EmbeddingsJson", $"{marker.MarkerUid}.json"), marker.EmbeddingsJson);
if (encoding is null)
continue;
}
}
public void LoadMatches()
{
if (_Configuration is null)
throw new NullReferenceException(nameof(_Configuration));
string json;
MarkerWith? markerWith;
List<MarkerWith> collection = new();
StringBuilder stringBuilder = new();
List<(int Count, MarkerWith MarkerWith)> countCollection = new();
List<(double Percent, MarkerWith MarkerWith)> percentCollection = new();
string[] files = Directory.GetFiles(Path.Combine(_Configuration.PhotoPrismDirectory, "With"), "*.json", SearchOption.TopDirectoryOnly);
foreach (string file in files)
{
json = File.ReadAllText(file);
markerWith = JsonSerializer.Deserialize<MarkerWith>(json);
if (markerWith is null || markerWith.DlibId is null)
continue;
collection.Add(markerWith);
if (markerWith.Count is null || markerWith.Count.Value == 0)
continue;
countCollection.Add(new(markerWith.Count.Value, markerWith));
if (markerWith.Percent is null)
continue;
percentCollection.Add(new(markerWith.Percent.Value, markerWith));
if (string.IsNullOrEmpty(markerWith.PersonKeyFormatted))
continue;
_ = stringBuilder.
Append("update `markers` set subj_src = 'manual' marker_name = '").
Append(markerWith.PersonKeyFormatted).
Append("' where marker_uid = '").
Append(markerWith.MarkerUid).
AppendLine("';");
}
(int, MarkerWith)[] countSorted = countCollection.OrderByDescending(l => l.Count).ToArray();
(double, MarkerWith)[] percentSorted = percentCollection.OrderBy(l => l.Percent).ToArray();
if (collection.Any())
{ }
File.WriteAllText(Path.Combine(_Configuration.PhotoPrismDirectory, "marker_name_update.sql"), stringBuilder.ToString());
}
public Dictionary<int, Dictionary<int, PersonContainer[]>> GetMissing(Dictionary<int, Dictionary<int, Mapping>> idToNormalizedRectangleToMapping)
{
Dictionary<int, Dictionary<int, PersonContainer[]>> results = new();
foreach (KeyValuePair<int, Dictionary<int, PersonContainer[]>> normalizedRectangleToPersonContainers in _IdThenNormalizedRectangleToPersonContainers)
{
if (idToNormalizedRectangleToMapping.ContainsKey(normalizedRectangleToPersonContainers.Key))
continue;
results.Add(normalizedRectangleToPersonContainers.Key, normalizedRectangleToPersonContainers.Value);
}
return results;
}
}

View File

@ -39,7 +39,7 @@ internal abstract class MapLogic
int? id;
long personKey;
string personKeyFormatted;
int? normalizedPixelPercentage;
int? normalizedRectangle;
string newestPersonKeyFormatted;
foreach (PersonContainer personContainer in personContainers)
{
@ -47,12 +47,12 @@ internal abstract class MapLogic
{
if (!personDisplayDirectoryAllFile.EndsWith(configuration.FacesFileNameExtension))
continue;
(id, normalizedPixelPercentage, _) = IMapping.GetReversedDeterministicHashCodeKey(configuration.FacesFileNameExtension, personDisplayDirectoryAllFile);
if (id is null || normalizedPixelPercentage is null)
(id, normalizedRectangle, _) = IMapping.GetConverted(configuration.FacesFileNameExtension, personDisplayDirectoryAllFile);
if (id is null || normalizedRectangle is null)
continue;
if (!skipCollection.ContainsKey(id.Value))
skipCollection.Add(id.Value, new());
skipCollection[id.Value].Add(normalizedPixelPercentage.Value);
skipCollection[id.Value].Add(normalizedRectangle.Value);
}
if (personContainer.Person is null || personContainer.Key is null || personContainer.Birthdays is null || !personContainer.Birthdays.Any())
continue;
@ -86,7 +86,7 @@ internal abstract class MapLogic
string? personFirstInitial;
DirectoryInfo directoryInfo;
string[] personKeyDirectories;
int? normalizedPixelPercentage;
int? normalizedRectangle;
string[] personNameDirectories;
string[] personNameLinkDirectories;
string? personFirstInitialDirectory;
@ -141,6 +141,16 @@ internal abstract class MapLogic
else
{
personFirstInitial = personDisplayDirectoryNames[^1][..1];
if (personFirstInitial.All(l => char.IsDigit(l)))
{
foreach (string file in files)
File.Delete(file);
files = Directory.GetFiles(personNameDirectory, "*", SearchOption.AllDirectories);
foreach (string file in files)
File.Delete(file);
_ = IPath.DeleteEmptyDirectories(personNameDirectory);
continue;
}
personFirstInitialDirectory = Path.Combine(yearDirectory, personFirstInitial.ToString());
Directory.Move(personNameDirectory, personFirstInitialDirectory);
files = Directory.GetFiles(personFirstInitialDirectory, "*", SearchOption.TopDirectoryOnly);
@ -149,8 +159,8 @@ internal abstract class MapLogic
{
if (file.EndsWith(".lnk") || file.EndsWith(".json"))
continue;
(id, normalizedPixelPercentage, _) = IMapping.GetReversedDeterministicHashCodeKey(configuration.FacesFileNameExtension, file);
if (id is null || normalizedPixelPercentage is null)
(id, normalizedRectangle, _) = IMapping.GetConverted(configuration.FacesFileNameExtension, file);
if (id is null || normalizedRectangle is null)
continue;
results.Add(new(personKeyFormatted, personDisplayDirectoryNames, file));
}
@ -182,15 +192,15 @@ internal abstract class MapLogic
{
Dictionary<int, List<(string, int)>> results = new();
int? id;
int? normalizedPixelPercentage;
int? normalizedRectangle;
foreach ((string personKeyFormatted, string[] personDisplayDirectoryNames, string mappedFaceFile) in collection)
{
(id, normalizedPixelPercentage, _) = IMapping.GetReversedDeterministicHashCodeKey(configuration.FacesFileNameExtension, mappedFaceFile);
if (id is null || normalizedPixelPercentage is null)
(id, normalizedRectangle, _) = IMapping.GetConverted(configuration.FacesFileNameExtension, mappedFaceFile);
if (id is null || normalizedRectangle is null)
continue;
if (!results.ContainsKey(id.Value))
results.Add(id.Value, new());
results[id.Value].Add(new(mappedFaceFile, normalizedPixelPercentage.Value));
results[id.Value].Add(new(mappedFaceFile, normalizedRectangle.Value));
}
return results;
}
@ -211,7 +221,11 @@ internal abstract class MapLogic
if (!Directory.Exists(eDistanceContentDirectory))
_ = Directory.CreateDirectory(eDistanceContentDirectory);
else
{
_ = IPath.DeleteEmptyDirectories(eDistanceContentDirectory);
if (!Directory.Exists(eDistanceContentDirectory))
_ = Directory.CreateDirectory(eDistanceContentDirectory);
}
ticksDirectories = Directory.GetDirectories(eDistanceContentDirectory, "*", SearchOption.TopDirectoryOnly);
}
string message = $") {ticksDirectories.Length:000} collect from and clean ticks Director(ies) - A - {totalSeconds} total second(s)";
@ -246,23 +260,23 @@ internal abstract class MapLogic
return results.ToArray();
}
private static void SetKeyValuePairs(Configuration configuration, long ticks, List<PersonContainer> personContainers, Mapping[] mappingCollection, List<(string, string[], int, int)> personKeyFormattedIdThenNormalizedPixelPercentageCollection, List<(string, int, int)> incorrectPersonKeyFormattedIdThenNormalizedPixelPercentageCollection, Dictionary<long, PersonContainer> personKeyToPersonContainer, Dictionary<int, Dictionary<int, PersonContainer[]>> idThenNormalizedPixelPercentageToPersonContainers, List<(string[], PersonContainer)> possiblyNewPersonDisplayDirectoryNamesAndPersonContainer, Dictionary<int, Dictionary<int, PersonContainer[]>> incorrectIdThenNormalizedPixelPercentageToPersonContainers, Dictionary<long, (long LCL, long Minimum, long Maximum, long UCL)> personKeyToRanges)
private static void SetKeyValuePairs(Configuration configuration, long ticks, List<PersonContainer> personContainers, Mapping[] mappingCollection, List<(string, string[], int, int)> personKeyFormattedIdThenNormalizedRectangleCollection, List<(string, int, int)> incorrectPersonKeyFormattedIdThenNormalizedRectangleCollection, Dictionary<long, PersonContainer> personKeyToPersonContainer, Dictionary<int, Dictionary<int, PersonContainer[]>> idThenNormalizedRectangleToPersonContainers, List<(string[], PersonContainer)> possiblyNewPersonDisplayDirectoryNamesAndPersonContainer, Dictionary<int, Dictionary<int, PersonContainer[]>> incorrectIdThenNormalizedRectangleToPersonContainers, Dictionary<long, (long LCL, long Minimum, long Maximum, long UCL)> personKeyToRanges)
{
PersonBirthday? personBirthday;
PersonContainer[] distinctPersonContainers;
Dictionary<string, PersonContainer> personKeyFormattedToPersonContainer = new();
Dictionary<int, Dictionary<int, List<PersonContainer>>> idThenNormalizedPixelPercentageToPersonContainerCollection = new();
Dictionary<int, Dictionary<int, List<PersonContainer>>> incorrectIdThenNormalizedPixelPercentageToPersonContainerCollection = new();
Dictionary<int, Dictionary<int, List<PersonContainer>>> idThenNormalizedRectangleToPersonContainerCollection = new();
Dictionary<int, Dictionary<int, List<PersonContainer>>> incorrectIdThenNormalizedRectangleToPersonContainerCollection = new();
List<(long, PersonContainer)> collection = GetDistinctCollection(configuration, personContainers, personKeyFormattedToPersonContainer);
foreach ((long personKey, PersonContainer personContainer) in collection)
personKeyToPersonContainer.Add(personKey, personContainer);
if (personKeyFormattedIdThenNormalizedPixelPercentageCollection.Any())
if (personKeyFormattedIdThenNormalizedRectangleCollection.Any())
{
string personDisplayDirectory;
PersonContainer personContainer;
string personDisplayDirectoryName;
Dictionary<string, (string[], PersonContainer)> personDisplayDirectoryTo = new();
foreach ((string personKeyFormatted, string[] personDisplayDirectoryNames, int id, int normalizedPixelPercentage) in personKeyFormattedIdThenNormalizedPixelPercentageCollection)
foreach ((string personKeyFormatted, string[] personDisplayDirectoryNames, int id, int normalizedRectangle) in personKeyFormattedIdThenNormalizedRectangleCollection)
{
personBirthday = IPersonBirthday.GetPersonBirthday(configuration.PersonBirthdayFormat, personKeyFormatted);
if (personBirthday is null)
@ -276,52 +290,52 @@ internal abstract class MapLogic
}
if (personDisplayDirectoryName.Length != 1 && personDisplayDirectoryName != configuration.MappingDefaultName && !personDisplayDirectoryTo.ContainsKey(personDisplayDirectory))
personDisplayDirectoryTo.Add(personDisplayDirectory, new(personDisplayDirectoryNames, personKeyFormattedToPersonContainer[personKeyFormatted]));
if (!idThenNormalizedPixelPercentageToPersonContainerCollection.ContainsKey(id))
idThenNormalizedPixelPercentageToPersonContainerCollection.Add(id, new());
if (!idThenNormalizedPixelPercentageToPersonContainerCollection[id].ContainsKey(normalizedPixelPercentage))
idThenNormalizedPixelPercentageToPersonContainerCollection[id].Add(normalizedPixelPercentage, new());
idThenNormalizedPixelPercentageToPersonContainerCollection[id][normalizedPixelPercentage].Add(personKeyFormattedToPersonContainer[personKeyFormatted]);
if (!idThenNormalizedRectangleToPersonContainerCollection.ContainsKey(id))
idThenNormalizedRectangleToPersonContainerCollection.Add(id, new());
if (!idThenNormalizedRectangleToPersonContainerCollection[id].ContainsKey(normalizedRectangle))
idThenNormalizedRectangleToPersonContainerCollection[id].Add(normalizedRectangle, new());
idThenNormalizedRectangleToPersonContainerCollection[id][normalizedRectangle].Add(personKeyFormattedToPersonContainer[personKeyFormatted]);
}
foreach (KeyValuePair<string, (string[], PersonContainer)> keyValuePair in personDisplayDirectoryTo)
possiblyNewPersonDisplayDirectoryNamesAndPersonContainer.Add(keyValuePair.Value);
}
foreach (KeyValuePair<int, Dictionary<int, List<PersonContainer>>> keyValuePair in idThenNormalizedPixelPercentageToPersonContainerCollection)
foreach (KeyValuePair<int, Dictionary<int, List<PersonContainer>>> keyValuePair in idThenNormalizedRectangleToPersonContainerCollection)
{
idThenNormalizedPixelPercentageToPersonContainers.Add(keyValuePair.Key, new());
idThenNormalizedRectangleToPersonContainers.Add(keyValuePair.Key, new());
foreach (KeyValuePair<int, List<PersonContainer>> innerKeyValuePair in keyValuePair.Value)
{
distinctPersonContainers = GetDistinctPersonContainers(innerKeyValuePair.Value);
idThenNormalizedPixelPercentageToPersonContainers[keyValuePair.Key].Add(innerKeyValuePair.Key, distinctPersonContainers);
idThenNormalizedRectangleToPersonContainers[keyValuePair.Key].Add(innerKeyValuePair.Key, distinctPersonContainers);
}
};
SetPersonTicks(configuration, ticks, mappingCollection, personKeyToRanges, idThenNormalizedPixelPercentageToPersonContainers);
if (incorrectPersonKeyFormattedIdThenNormalizedPixelPercentageCollection.Any())
SetPersonTicks(configuration, ticks, mappingCollection, personKeyToRanges, idThenNormalizedRectangleToPersonContainers);
if (incorrectPersonKeyFormattedIdThenNormalizedRectangleCollection.Any())
{
PersonContainer personContainer;
foreach ((string personKeyFormatted, int id, int normalizedPixelPercentage) in incorrectPersonKeyFormattedIdThenNormalizedPixelPercentageCollection)
foreach ((string personKeyFormatted, int id, int normalizedRectangle) in incorrectPersonKeyFormattedIdThenNormalizedRectangleCollection)
{
personBirthday = IPersonBirthday.GetPersonBirthday(configuration.PersonBirthdayFormat, personKeyFormatted);
if (personBirthday is null)
continue;
if (!incorrectIdThenNormalizedPixelPercentageToPersonContainerCollection.ContainsKey(id))
incorrectIdThenNormalizedPixelPercentageToPersonContainerCollection.Add(id, new());
if (!incorrectIdThenNormalizedRectangleToPersonContainerCollection.ContainsKey(id))
incorrectIdThenNormalizedRectangleToPersonContainerCollection.Add(id, new());
if (!personKeyFormattedToPersonContainer.ContainsKey(personKeyFormatted))
{
personContainer = new(personBirthday, configuration.MappingDefaultName);
personKeyFormattedToPersonContainer.Add(personKeyFormatted, personContainer);
}
if (!incorrectIdThenNormalizedPixelPercentageToPersonContainerCollection[id].ContainsKey(normalizedPixelPercentage))
incorrectIdThenNormalizedPixelPercentageToPersonContainerCollection[id].Add(normalizedPixelPercentage, new());
incorrectIdThenNormalizedPixelPercentageToPersonContainerCollection[id][normalizedPixelPercentage].Add(personKeyFormattedToPersonContainer[personKeyFormatted]);
if (!incorrectIdThenNormalizedRectangleToPersonContainerCollection[id].ContainsKey(normalizedRectangle))
incorrectIdThenNormalizedRectangleToPersonContainerCollection[id].Add(normalizedRectangle, new());
incorrectIdThenNormalizedRectangleToPersonContainerCollection[id][normalizedRectangle].Add(personKeyFormattedToPersonContainer[personKeyFormatted]);
}
}
foreach (KeyValuePair<int, Dictionary<int, List<PersonContainer>>> keyValuePair in incorrectIdThenNormalizedPixelPercentageToPersonContainerCollection)
foreach (KeyValuePair<int, Dictionary<int, List<PersonContainer>>> keyValuePair in incorrectIdThenNormalizedRectangleToPersonContainerCollection)
{
incorrectIdThenNormalizedPixelPercentageToPersonContainers.Add(keyValuePair.Key, new());
incorrectIdThenNormalizedRectangleToPersonContainers.Add(keyValuePair.Key, new());
foreach (KeyValuePair<int, List<PersonContainer>> innerKeyValuePair in keyValuePair.Value)
{
distinctPersonContainers = GetDistinctPersonContainers(innerKeyValuePair.Value);
incorrectIdThenNormalizedPixelPercentageToPersonContainers[keyValuePair.Key].Add(innerKeyValuePair.Key, distinctPersonContainers);
incorrectIdThenNormalizedRectangleToPersonContainers[keyValuePair.Key].Add(innerKeyValuePair.Key, distinctPersonContainers);
}
}
}
@ -352,19 +366,19 @@ internal abstract class MapLogic
return results;
}
private static (int, int) SetCollectionsAndGetUnableToMatchCount(Configuration configuration, long ticks, Dictionary<int, List<Mapping>> idToMappingCollection, Dictionary<string, string> personKeyFormattedToNewestPersonKeyFormatted, List<(string, string[], int, int)> personKeyFormattedIdThenNormalizedPixelPercentageCollection, List<(string, int, int)> incorrectPersonKeyFormattedIdThenNormalizedPixelPercentageCollection, List<(string, string[], string)> collection)
private static (int, int) SetCollectionsAndGetUnableToMatchCount(Configuration configuration, long ticks, Dictionary<int, List<Mapping>> idToMappingCollection, Dictionary<string, string> personKeyFormattedToNewestPersonKeyFormatted, List<(string, string[], int, int)> personKeyFormattedIdThenNormalizedRectangleCollection, List<(string, int, int)> incorrectPersonKeyFormattedIdThenNormalizedRectangleCollection, List<(string, string[], string)> collection)
{
int result = 0;
int? id;
int? normalizedPixelPercentage;
int? normalizedRectangle;
string newestPersonKeyFormatted;
List<Mapping>? mappingCollection;
string personDisplayDirectoryName;
List<int> normalizedPixelPercentages;
List<int> normalizedRectangles;
List<Mapping> checkMappingCollection = new();
List<string> duplicateMappedFaceFiles = new();
bool idToMappingCollectionAny = idToMappingCollection.Any();
Dictionary<int, List<int>> idToNormalizedPixelPercentages = new();
Dictionary<int, List<int>> idToNormalizedRectangles = new();
int totalSeconds = (int)Math.Floor(new TimeSpan(DateTime.Now.Ticks - ticks).TotalSeconds);
string message = $") {collection.Count:000} join from ticks Director(ies) - C - {totalSeconds} total second(s)";
ProgressBarOptions options = new() { ProgressCharacter = '─', ProgressBarOnBottom = true, DisableBottomPercentage = true };
@ -372,26 +386,23 @@ internal abstract class MapLogic
foreach ((string personKeyFormatted, string[] personDisplayDirectoryNames, string mappedFaceFile) in collection)
{
progressBar.Tick();
(id, normalizedPixelPercentage, mappingCollection) = IMapping.GetReversedDeterministicHashCodeKey(configuration.FacesFileNameExtension, idToMappingCollectionAny, idToMappingCollection, mappedFaceFile);
if (id is null || normalizedPixelPercentage is null)
{
result++;
continue;
}
if (!idToNormalizedPixelPercentages.ContainsKey(id.Value))
idToNormalizedPixelPercentages.Add(id.Value, new());
normalizedPixelPercentages = idToNormalizedPixelPercentages[id.Value];
if (mappingCollection is null)
(id, normalizedRectangle, mappingCollection) = IMapping.GetConverted(configuration.FacesFileNameExtension, idToMappingCollectionAny, idToMappingCollection, mappedFaceFile);
if (id is null || normalizedRectangle is null)
{
result++;
continue;
}
if (!idToNormalizedRectangles.ContainsKey(id.Value))
idToNormalizedRectangles.Add(id.Value, new());
normalizedRectangles = idToNormalizedRectangles[id.Value];
checkMappingCollection.Clear();
if (mappingCollection is not null)
{
foreach (Mapping mapping in mappingCollection)
{
if (normalizedPixelPercentage.Value != mapping.MappingFromLocation.NormalizedPixelPercentage)
if (normalizedRectangle.Value != mapping.MappingFromLocation.NormalizedRectangle)
continue;
if (normalizedPixelPercentages.Contains(mapping.MappingFromLocation.NormalizedPixelPercentage))
if (normalizedRectangles.Contains(mapping.MappingFromLocation.NormalizedRectangle))
{
duplicateMappedFaceFiles.Add(mappedFaceFile);
continue;
@ -408,17 +419,18 @@ internal abstract class MapLogic
result++;
continue;
}
normalizedPixelPercentages.Add(normalizedPixelPercentage.Value);
idToNormalizedPixelPercentages[id.Value].Add(normalizedPixelPercentage.Value);
}
normalizedRectangles.Add(normalizedRectangle.Value);
idToNormalizedRectangles[id.Value].Add(normalizedRectangle.Value);
if (!personKeyFormattedToNewestPersonKeyFormatted.ContainsKey(personKeyFormatted))
newestPersonKeyFormatted = personKeyFormatted;
else
newestPersonKeyFormatted = personKeyFormattedToNewestPersonKeyFormatted[personKeyFormatted];
personDisplayDirectoryName = personDisplayDirectoryNames[^1];
if (string.IsNullOrEmpty(personDisplayDirectoryName) || personDisplayDirectoryName[0] == '!')
incorrectPersonKeyFormattedIdThenNormalizedPixelPercentageCollection.Add(new(newestPersonKeyFormatted, id.Value, normalizedPixelPercentage.Value));
incorrectPersonKeyFormattedIdThenNormalizedRectangleCollection.Add(new(newestPersonKeyFormatted, id.Value, normalizedRectangle.Value));
else
personKeyFormattedIdThenNormalizedPixelPercentageCollection.Add(new(newestPersonKeyFormatted, personDisplayDirectoryNames, id.Value, normalizedPixelPercentage.Value));
personKeyFormattedIdThenNormalizedRectangleCollection.Add(new(newestPersonKeyFormatted, personDisplayDirectoryNames, id.Value, normalizedRectangle.Value));
}
if (duplicateMappedFaceFiles.Any())
{
@ -494,7 +506,7 @@ internal abstract class MapLogic
}
}
private static void SetPersonTicks(Configuration configuration, long ticks, Mapping[] mappingCollection, Dictionary<long, (long LCL, long Minimum, long Maximum, long UCL)> personKeyToRanges, Dictionary<int, Dictionary<int, PersonContainer[]>> idThenNormalizedPixelPercentageToPersonContainers)
private static void SetPersonTicks(Configuration configuration, long ticks, Mapping[] mappingCollection, Dictionary<long, (long LCL, long Minimum, long Maximum, long UCL)> personKeyToRanges, Dictionary<int, Dictionary<int, PersonContainer[]>> idThenNormalizedRectangleToPersonContainers)
{
PersonContainer[]? personContainers;
Dictionary<int, PersonContainer[]>? keyValuePairs;
@ -506,9 +518,9 @@ internal abstract class MapLogic
foreach (Mapping mapping in mappingCollection)
{
progressBar.Tick();
if (!idThenNormalizedPixelPercentageToPersonContainers.TryGetValue(mapping.MappingFromItem.Id, out keyValuePairs))
if (!idThenNormalizedRectangleToPersonContainers.TryGetValue(mapping.MappingFromItem.Id, out keyValuePairs))
continue;
if (!keyValuePairs.TryGetValue(mapping.MappingFromLocation.NormalizedPixelPercentage, out personContainers))
if (!keyValuePairs.TryGetValue(mapping.MappingFromLocation.NormalizedRectangle, out personContainers))
continue;
foreach (PersonContainer personContainer in personContainers)
{
@ -543,14 +555,14 @@ internal abstract class MapLogic
return results;
}
private static void AppendToSkipCollection(Dictionary<int, List<int>> skipCollection, Dictionary<int, Dictionary<int, PersonContainer[]>> idThenNormalizedPixelPercentageToPersonContainers, Dictionary<int, Dictionary<int, PersonContainer[]>> incorrectIdThenNormalizedPixelPercentageToPersonContainers)
private static void AppendToSkipCollection(Dictionary<int, List<int>> skipCollection, Dictionary<int, Dictionary<int, PersonContainer[]>> idThenNormalizedRectangleToPersonContainers, Dictionary<int, Dictionary<int, PersonContainer[]>> incorrectIdThenNormalizedRectangleToPersonContainers)
{
Dictionary<int, PersonContainer[]>? keyValuePairs;
foreach (KeyValuePair<int, Dictionary<int, PersonContainer[]>> keyValuePair in incorrectIdThenNormalizedPixelPercentageToPersonContainers)
foreach (KeyValuePair<int, Dictionary<int, PersonContainer[]>> keyValuePair in incorrectIdThenNormalizedRectangleToPersonContainers)
{
if (!skipCollection.ContainsKey(keyValuePair.Key))
skipCollection.Add(keyValuePair.Key, new());
if (idThenNormalizedPixelPercentageToPersonContainers.TryGetValue(keyValuePair.Key, out keyValuePairs))
if (idThenNormalizedRectangleToPersonContainers.TryGetValue(keyValuePair.Key, out keyValuePairs))
{
if (keyValuePairs.ContainsKey(keyValuePair.Value.ElementAt(0).Key))
continue;
@ -600,7 +612,7 @@ internal abstract class MapLogic
}
}
internal static void Set(Shared.Models.Properties.IPropertyConfiguration propertyConfiguration, Configuration? configuration, long ticks, List<PersonContainer> personContainers, string? a2PeopleContentDirectory, string eDistanceContentDirectory, Mapping[] mappingCollection, Shared.Models.Methods.IMapLogicSupport mapLogicSupport, Dictionary<long, PersonContainer> personKeyToPersonContainer, Dictionary<long, (long LCL, long Minimum, long Maximum, long UCL)> personKeyToRanges, List<PersonContainer> notMappedPersonContainers, Dictionary<int, List<int>> skipCollection, Dictionary<int, Dictionary<int, PersonContainer[]>> idThenNormalizedPixelPercentageToPersonContainers)
internal static void Set(Shared.Models.Properties.IPropertyConfiguration propertyConfiguration, Configuration? configuration, long ticks, List<PersonContainer> personContainers, string? a2PeopleContentDirectory, string eDistanceContentDirectory, Mapping[] mappingCollection, Shared.Models.Methods.IMapLogicSupport mapLogicSupport, Dictionary<long, PersonContainer> personKeyToPersonContainer, Dictionary<long, (long LCL, long Minimum, long Maximum, long UCL)> personKeyToRanges, List<PersonContainer> notMappedPersonContainers, Dictionary<int, List<int>> skipCollection, Dictionary<int, Dictionary<int, PersonContainer[]>> idThenNormalizedRectangleToPersonContainers)
{
if (configuration is null)
throw new NullReferenceException(nameof(configuration));
@ -612,9 +624,9 @@ internal abstract class MapLogic
Dictionary<int, List<Mapping>> idToMappingCollection = new();
Dictionary<string, string> personKeyFormattedToNewestPersonKeyFormatted = new();
List<(string[], PersonContainer)> possiblyNewPersonDisplayDirectoryNamesAndPersonContainer = new();
List<(string, string[], int, int)> personKeyFormattedIdThenNormalizedPixelPercentageCollection = new();
List<(string, int, int)> incorrectPersonKeyFormattedIdThenNormalizedPixelPercentageCollection = new();
Dictionary<int, Dictionary<int, PersonContainer[]>> incorrectIdThenNormalizedPixelPercentageToPersonContainers = new();
List<(string, string[], int, int)> personKeyFormattedIdThenNormalizedRectangleCollection = new();
List<(string, int, int)> incorrectPersonKeyFormattedIdThenNormalizedRectangleCollection = new();
Dictionary<int, Dictionary<int, PersonContainer[]>> incorrectIdThenNormalizedRectangleToPersonContainers = new();
SetPersonCollections(configuration, personContainers, personKeys, personKeyFormattedToNewestPersonKeyFormatted, personKeyFormattedCollection, skipCollection);
personContainers.AddRange(AddToPersonKeysThenGetNonSpecificPeopleCollection(configuration, personKeys));
foreach (Mapping mapping in mappingCollection)
@ -627,14 +639,14 @@ internal abstract class MapLogic
string[] ticksDirectories = Directory.GetDirectories(eDistanceContentDirectory, "*", SearchOption.TopDirectoryOnly);
message = $") {ticksDirectories.Length:000} compile from and clean ticks Director(ies) - B - {totalSeconds} total second(s)";
List<(string, string[], string)> collection = DeleteEmptyDirectoriesAndGetCollection(configuration, personKeyFormattedCollection, ticksDirectories, message);
(int unableToMatchCount, int duplicateCount) = SetCollectionsAndGetUnableToMatchCount(configuration, ticks, idToMappingCollection, personKeyFormattedToNewestPersonKeyFormatted, personKeyFormattedIdThenNormalizedPixelPercentageCollection, incorrectPersonKeyFormattedIdThenNormalizedPixelPercentageCollection, collection);
SetKeyValuePairs(configuration, ticks, personContainers, mappingCollection, personKeyFormattedIdThenNormalizedPixelPercentageCollection, incorrectPersonKeyFormattedIdThenNormalizedPixelPercentageCollection, personKeyToPersonContainer, idThenNormalizedPixelPercentageToPersonContainers, possiblyNewPersonDisplayDirectoryNamesAndPersonContainer, incorrectIdThenNormalizedPixelPercentageToPersonContainers, personKeyToRanges);
(int unableToMatchCount, int duplicateCount) = SetCollectionsAndGetUnableToMatchCount(configuration, ticks, idToMappingCollection, personKeyFormattedToNewestPersonKeyFormatted, personKeyFormattedIdThenNormalizedRectangleCollection, incorrectPersonKeyFormattedIdThenNormalizedRectangleCollection, collection);
SetKeyValuePairs(configuration, ticks, personContainers, mappingCollection, personKeyFormattedIdThenNormalizedRectangleCollection, incorrectPersonKeyFormattedIdThenNormalizedRectangleCollection, personKeyToPersonContainer, idThenNormalizedRectangleToPersonContainers, possiblyNewPersonDisplayDirectoryNamesAndPersonContainer, incorrectIdThenNormalizedRectangleToPersonContainers, personKeyToRanges);
totalSeconds = (int)Math.Floor(new TimeSpan(DateTime.Now.Ticks - ticks).TotalSeconds);
message = $") {collection.Count:000} message from ticks Director(ies) - D - {duplicateCount} Duplicate Count {unableToMatchCount} Unable To Match Count / {collection.Count} Collection - {totalSeconds} total second(s)";
ProgressBarOptions options = new() { ProgressCharacter = '─', ProgressBarOnBottom = true, DisableBottomPercentage = true };
using (ProgressBar progressBar = new(collection.Count, message, options))
{
foreach (KeyValuePair<int, Dictionary<int, PersonContainer[]>> keyValuePair in idThenNormalizedPixelPercentageToPersonContainers)
foreach (KeyValuePair<int, Dictionary<int, PersonContainer[]>> keyValuePair in idThenNormalizedRectangleToPersonContainers)
{
progressBar.Tick();
foreach (KeyValuePair<int, PersonContainer[]> keyValue in keyValuePair.Value)
@ -644,7 +656,7 @@ internal abstract class MapLogic
long[] personKeyCollection = (from l in nullablePersonKeyCollection where l is not null select l.Value).Distinct().ToArray();
SetPersonKeyToPersonContainer(configuration, personContainers, personKeyCollection, personKeyToPersonContainer);
notMappedPersonContainers.AddRange(GetNotMappedPersonContainers(configuration, personContainers, personKeyCollection));
AppendToSkipCollection(skipCollection, idThenNormalizedPixelPercentageToPersonContainers, incorrectIdThenNormalizedPixelPercentageToPersonContainers);
AppendToSkipCollection(skipCollection, idThenNormalizedRectangleToPersonContainers, incorrectIdThenNormalizedRectangleToPersonContainers);
if (possiblyNewPersonDisplayDirectoryNamesAndPersonContainer.Any())
mapLogicSupport.SavePossiblyNewPersonContainers(propertyConfiguration, configuration.PersonBirthdayFormat, configuration.FacesFileNameExtension, a2PeopleContentDirectory, personKeyToPersonContainer, possiblyNewPersonDisplayDirectoryNamesAndPersonContainer);
}
@ -690,7 +702,7 @@ internal abstract class MapLogic
internal static SaveContainer GetDebugSaveContainer(string directory, SortingContainer sortingContainer, Mapping mapping)
{
SaveContainer result;
FileHolder faceFileHolder = new($"C:/{sortingContainer.Sorting.Id}.{sortingContainer.Sorting.NormalizedPixelPercentage}");
FileHolder faceFileHolder = new($"C:/{sortingContainer.Sorting.Id}.{sortingContainer.Sorting.NormalizedRectangle}");
string shortcutFile = Path.Combine(directory, $"{sortingContainer.Mapping.MappingFromLocation.DeterministicHashCodeKey}{sortingContainer.Mapping.MappingFromItem.ImageFileHolder.ExtensionLowered}.debug.lnk");
result = new(directory, faceFileHolder, mapping.MappingFromItem.ResizedFileHolder, shortcutFile);
return result;

View File

@ -36,7 +36,7 @@
<ItemGroup>
<PackageReference Include="MetadataExtractor" Version="2.7.2" />
<PackageReference Include="Serilog" Version="2.12.0" />
<PackageReference Include="System.Text.Json" Version="7.0.0" />
<PackageReference Include="System.Text.Json" Version="7.0.1" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Shared\View-by-Distance.Shared.csproj" />

View File

@ -95,22 +95,11 @@ public class B_Metadata
{
List<KeyValuePair<string, string>> results = new();
string json = string.Empty;
string[] changesFrom = Array.Empty<string>();
Dictionary<string, List<KeyValuePair<string, string>>>? dictionary;
string[] changesFrom = new string[] { nameof(Property.Models.A_Property) };
List<DateTime> dateTimes = (from l in subFileTuples where changesFrom.Contains(l.Item1) select l.Item2).ToList();
string bMetadataSingletonFile = Path.Combine(bResultsFullGroupDirectory, "{}", configuration.ResultAllInOne, $"{mappingFromItem.Id}{mappingFromItem.ImageFileHolder.ExtensionLowered}.json");
FileInfo fileInfo = new(bMetadataSingletonFile);
if (!fileInfo.FullName.Contains(configuration.ResultAllInOne) && !fileInfo.Exists)
{
if (fileInfo.Directory?.Parent is null)
throw new Exception();
string parentCheck = Path.Combine(fileInfo.Directory.Parent.FullName, fileInfo.Name);
if (File.Exists(parentCheck))
{
File.Move(parentCheck, fileInfo.FullName);
fileInfo.Refresh();
}
}
if (_ForceMetadataLastWriteTimeToCreationTime && !fileInfo.Exists && File.Exists(Path.ChangeExtension(fileInfo.FullName, ".delete")))
{
File.Move(Path.ChangeExtension(fileInfo.FullName, ".delete"), fileInfo.FullName);

View File

@ -8,9 +8,9 @@ public interface IMetadata
static string? GetFaceEncoding(string file) =>
Metadata.GetFaceEncoding(file);
string? TestStatic_GetFaceLocation(string file) =>
GetFaceLocation(file);
static string? GetFaceLocation(string file) =>
Metadata.GetFaceLocation(file);
string? TestStatic_GetFaceX(string file) =>
GetFaceX(file);
static string? GetFaceX(string file) =>
Metadata.GetFaceX(file);
}

View File

@ -29,7 +29,7 @@ internal class Metadata
return result;
}
internal static string? GetFaceLocation(string file)
internal static string? GetFaceX(string file)
{
string? result;
List<string> results = new();

View File

@ -32,9 +32,9 @@ public class Configuration
public void Set(Property.Models.Configuration configuration) => _PropertyConfiguration = configuration;
public void SetAndUpdate(Property.Models.Configuration configuration, int? numberOfJitters, int? numberOfTimesToUpsample, string? modelName, string? predictorModelName)
public void SetAndUpdate(Property.Models.Configuration configuration)
{
_PropertyConfiguration.Update(numberOfJitters, numberOfTimesToUpsample, modelName, predictorModelName);
_PropertyConfiguration.Update();
_CompareSource = Path.GetFullPath(_CompareSource);
_SelectedSource = Path.GetFullPath(_SelectedSource);
_EmptyDestination = Path.GetFullPath(_EmptyDestination);

View File

@ -19,7 +19,7 @@ public abstract class Configuration
if (result is null)
throw new Exception(json);
string jsonThis = result.ToString();
result.SetAndUpdate(propertyConfiguration, null, null, null, null);
result.SetAndUpdate(propertyConfiguration);
if (jsonThis != json)
{
int? check = null;

View File

@ -26,8 +26,9 @@ public class NotCopyCopy
_IsEnvironment = isEnvironment;
_Log = Serilog.Log.ForContext<NotCopyCopy>();
Property.Models.Configuration propertyConfiguration = Property.Models.Binder.Configuration.Get(isEnvironment, configurationRoot);
Property.Models.Configuration.Verify(propertyConfiguration, requireExist: true);
Models.Configuration configuration = Models.Stateless.Configuration.Get(isEnvironment, configurationRoot, workingDirectory, propertyConfiguration);
_Log.Information(propertyConfiguration.RootDirectory);
Property.Models.Configuration.Verify(propertyConfiguration, requireExist: true);
Verify(configuration);
bool reverse = false;
string outputExtension = ".jpg";

View File

@ -35,8 +35,8 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Hosting" Version="7.0.0" />
<PackageReference Include="Microsoft.AspNetCore.Cryptography.KeyDerivation" Version="7.0.0" />
<PackageReference Include="Microsoft.Extensions.Identity.Core" Version="7.0.0" />
<PackageReference Include="Microsoft.AspNetCore.Cryptography.KeyDerivation" Version="7.0.1" />
<PackageReference Include="Microsoft.Extensions.Identity.Core" Version="7.0.1" />
<PackageReference Include="Microsoft.Extensions.Options" Version="7.0.0" />
<PackageReference Include="ShellProgressBar" Version="5.2.0" />
<PackageReference Include="Serilog" Version="2.12.0" />
@ -45,7 +45,7 @@
<PackageReference Include="Serilog.Sinks.File" Version="5.0.0" />
<PackageReference Include="MetadataExtractor" Version="2.7.2" />
<PackageReference Include="System.Drawing.Common" Version="7.0.0" />
<PackageReference Include="System.Text.Json" Version="7.0.0" />
<PackageReference Include="System.Text.Json" Version="7.0.1" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Shared\View-by-Distance.Shared.csproj" />

View File

@ -19,6 +19,7 @@ public class Program
IsEnvironment isEnvironment = new(processesCount: null, nullASPNetCoreEnvironmentIsDevelopment: debuggerWasAttachedAtLineZero, nullASPNetCoreEnvironmentIsProduction: !debuggerWasAttachedAtLineZero);
IConfigurationBuilder configurationBuilder = new ConfigurationBuilder()
.AddEnvironmentVariables()
.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
.AddJsonFile(isEnvironment.AppSettingsFileName, optional: false, reloadOnChange: true);
IConfigurationRoot configurationRoot = configurationBuilder.Build();
AppSettings appSettings = Models.Binder.AppSettings.Get(configurationRoot);

View File

@ -24,10 +24,10 @@ public class Configuration
return result;
}
public void SetAndUpdate(Property.Models.Configuration configuration, int? numberOfJitters, int? numberOfTimesToUpsample, string? modelName, string? predictorModelName)
public void SetAndUpdate(Property.Models.Configuration configuration)
{
_PropertyConfiguration = configuration;
_PropertyConfiguration.Update(numberOfJitters, numberOfTimesToUpsample, modelName, predictorModelName);
_PropertyConfiguration.Update();
}
}

View File

@ -19,7 +19,7 @@ public abstract class Configuration
if (result is null)
throw new Exception(json);
string jsonThis = result.ToString();
result.SetAndUpdate(propertyConfiguration, null, null, null, null);
result.SetAndUpdate(propertyConfiguration);
if (jsonThis != json)
{
int? check = null;

File diff suppressed because it is too large Load Diff

View File

@ -41,10 +41,10 @@
<PackageReference Include="Serilog.Sinks.Console" Version="4.1.0" />
<PackageReference Include="Serilog.Sinks.File" Version="5.0.0" />
<PackageReference Include="System.Drawing.Common" Version="7.0.0" />
<PackageReference Include="System.Text.Json" Version="7.0.0" />
<PackageReference Include="System.Text.Json" Version="7.0.1" />
<PackageReference Include="MetadataExtractor" Version="2.7.2" />
<PackageReference Include="Microsoft.AspNetCore.Cryptography.KeyDerivation" Version="7.0.0" />
<PackageReference Include="Microsoft.Extensions.Identity.Core" Version="7.0.0" />
<PackageReference Include="Microsoft.AspNetCore.Cryptography.KeyDerivation" Version="7.0.1" />
<PackageReference Include="Microsoft.Extensions.Identity.Core" Version="7.0.1" />
<PackageReference Include="Microsoft.Extensions.Options" Version="7.0.0" />
</ItemGroup>
<ItemGroup>

View File

@ -19,6 +19,7 @@ public class Program
IsEnvironment isEnvironment = new(processesCount: null, nullASPNetCoreEnvironmentIsDevelopment: debuggerWasAttachedAtLineZero, nullASPNetCoreEnvironmentIsProduction: !debuggerWasAttachedAtLineZero);
IConfigurationBuilder configurationBuilder = new ConfigurationBuilder()
.AddEnvironmentVariables()
.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
.AddJsonFile(isEnvironment.AppSettingsFileName, optional: false, reloadOnChange: true);
IConfigurationRoot configurationRoot = configurationBuilder.Build();
AppSettings appSettings = Models.Binder.AppSettings.Get(configurationRoot);
@ -38,8 +39,8 @@ public class Program
{
if (args is null)
throw new Exception("args is null!");
Shared.Models.Console console = new();
PrepareForOld dlibDotNet = new(args, isEnvironment, configurationRoot, appSettings, workingDirectory, silentIndex > -1, console);
// Shared.Models.Console console = new();
// PrepareForOld dlibDotNet = new(args, isEnvironment, configurationRoot, appSettings, workingDirectory, silentIndex > -1, console);
}
catch (Exception ex)
{

View File

@ -1,29 +1,29 @@
namespace View_by_Distance.PropertyCompare.Models;
// namespace View_by_Distance.PropertyCompare.Models;
internal class PropertyCompareItem
{
// internal class PropertyCompareItem
// {
protected readonly string _ImageFileName;
protected readonly bool _IsArg;
protected readonly string _JsonFileNameWithoutExtension;
protected readonly long[] _Numbers;
protected readonly Shared.Models.Property _Property;
protected readonly string[] _Strings;
public string ImageFileName => _ImageFileName;
public bool IsArg => _IsArg;
public string JsonFileNameWithoutExtension => _JsonFileNameWithoutExtension;
public long[] Numbers => _Numbers;
public Shared.Models.Property Property => _Property;
public string[] Strings => _Strings;
// protected readonly string _ImageFileName;
// protected readonly bool _IsArg;
// protected readonly string _JsonFileNameWithoutExtension;
// protected readonly long[] _Numbers;
// protected readonly Shared.Models.Property _Property;
// protected readonly string[] _Strings;
// public string ImageFileName => _ImageFileName;
// public bool IsArg => _IsArg;
// public string JsonFileNameWithoutExtension => _JsonFileNameWithoutExtension;
// public long[] Numbers => _Numbers;
// public Shared.Models.Property Property => _Property;
// public string[] Strings => _Strings;
public PropertyCompareItem(string imageFileName, bool isArg, string jsonFileNameWithoutExtension, long[] numbers, Shared.Models.Property property, string[] strings)
{
_ImageFileName = imageFileName;
_IsArg = isArg;
_JsonFileNameWithoutExtension = jsonFileNameWithoutExtension;
_Numbers = numbers;
_Property = property;
_Strings = strings;
}
// public PropertyCompareItem(string imageFileName, bool isArg, string jsonFileNameWithoutExtension, long[] numbers, Shared.Models.Property property, string[] strings)
// {
// _ImageFileName = imageFileName;
// _IsArg = isArg;
// _JsonFileNameWithoutExtension = jsonFileNameWithoutExtension;
// _Numbers = numbers;
// _Property = property;
// _Strings = strings;
// }
}
// }

File diff suppressed because it is too large Load Diff

View File

@ -37,7 +37,7 @@
<PackageReference Include="ShellProgressBar" Version="5.2.0" />
<PackageReference Include="Serilog" Version="2.12.0" />
<PackageReference Include="System.Drawing.Common" Version="7.0.0" />
<PackageReference Include="System.Text.Json" Version="7.0.0" />
<PackageReference Include="System.Text.Json" Version="7.0.1" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Shared\View-by-Distance.Shared.csproj" />

View File

@ -64,7 +64,7 @@ public class A_Property
#pragma warning disable CA1416
private Shared.Models.Property GetImageProperty(FileHolder fileHolder, Shared.Models.Property? property, bool populateId, bool isIgnoreExtension, bool isValidImageFormatExtension, bool isValidMetadataExtensions, int? id, List<int> indices)
private Shared.Models.Property GetImageProperty(FileHolder fileHolder, Shared.Models.Property? property, bool populateId, bool isIgnoreExtension, bool isValidImageFormatExtension, bool isValidMetadataExtensions, int? id)
{
Shared.Models.Property result;
if (_Log is null)
@ -99,7 +99,7 @@ public class A_Property
try
{
using Image image = Image.FromFile(fileHolder.FullName);
if (populateId && (id is null || !indices.Any()))
if (populateId && id is null)
{
using Bitmap bitmap = new(image);
string angleBracket = AngleBracketCollection[0];
@ -225,9 +225,9 @@ public class A_Property
if (fileHolder.LastWriteTime is null && property?.LastWriteTime is null)
throw new NullReferenceException(nameof(fileHolder.LastWriteTime));
if (fileHolder.CreationTime is not null && fileHolder.LastWriteTime is not null)
result = new(fileHolder.CreationTime.Value, dateTime, dateTimeDigitized, dateTimeFromName, dateTimeOriginal, fileLength, gpsDateStamp, height, id, indices.ToArray(), fileHolder.LastWriteTime.Value, make, model, orientation, width);
result = new(fileHolder.CreationTime.Value, dateTime, dateTimeDigitized, dateTimeFromName, dateTimeOriginal, fileLength, gpsDateStamp, height, id, fileHolder.LastWriteTime.Value, make, model, orientation, width);
else if (property is not null)
result = new(property.CreationTime, dateTime, dateTimeDigitized, dateTimeFromName, dateTimeOriginal, fileLength, gpsDateStamp, height, id, indices.ToArray(), property.LastWriteTime, make, model, orientation, width);
result = new(property.CreationTime, dateTime, dateTimeDigitized, dateTimeFromName, dateTimeOriginal, fileLength, gpsDateStamp, height, id, property.LastWriteTime, make, model, orientation, width);
else
throw new NullReferenceException(nameof(property));
return result;
@ -240,9 +240,7 @@ public class A_Property
Shared.Models.Property? result;
string json;
int? id = null;
List<int> indices = new();
bool hasWrongYearProperty = false;
Shared.Models.Property? property = null;
string[] changesFrom = Array.Empty<string>();
string angleBracket = AngleBracketCollection[0];
bool populateId = _Configuration.PopulatePropertyId;
@ -254,17 +252,6 @@ public class A_Property
fileInfo.Refresh();
}
List<DateTime> dateTimes = (from l in sourceDirectoryFileTuples where changesFrom.Contains(l.Item1) select l.Item2).ToList();
if (!fileInfo.FullName.Contains(_Configuration.ResultAllInOne) && !fileInfo.Exists)
{
if (fileInfo.Directory?.Parent is null)
throw new Exception();
string parentCheck = Path.Combine(fileInfo.Directory.Parent.FullName, fileInfo.Name);
if (File.Exists(parentCheck))
{
File.Move(parentCheck, fileInfo.FullName);
fileInfo.Refresh();
}
}
if (_Configuration.ForcePropertyLastWriteTimeToCreationTime && !fileInfo.Exists && File.Exists(Path.ChangeExtension(fileInfo.FullName, ".delete")))
{
File.Move(Path.ChangeExtension(fileInfo.FullName, ".delete"), fileInfo.FullName);
@ -288,62 +275,50 @@ public class A_Property
json = File.ReadAllText(fileInfo.FullName);
try
{
bool check = true;
property = JsonSerializer.Deserialize<Shared.Models.Property>(json);
if (!isIgnoreExtension && item.ValidImageFormatExtension && ((populateId && property?.Id is null) || property?.Width is null || property?.Height is null))
if (item.Property is not null)
result = item.Property;
else
result = JsonSerializer.Deserialize<Shared.Models.Property>(json);
if (result is not null && json.Contains("WrongYear"))
{
check = false;
id = property?.Id;
if (property is not null && property.Indices.Any())
indices = property.Indices.ToList();
property = GetImageProperty(item.ImageFileHolder, property, populateId, isIgnoreExtension, item.ValidImageFormatExtension, isValidMetadataExtensions, id, indices);
id = result.Id;
hasWrongYearProperty = true;
result = null;
}
if (!isIgnoreExtension && item.ValidImageFormatExtension && populateId && property is not null && !property.Indices.Any())
if (!isIgnoreExtension && item.ValidImageFormatExtension && ((populateId && result?.Id is null) || result?.Width is null || result.Height is null))
{
check = false;
id = property?.Id;
if (property is not null && property.Indices.Any())
indices = property.Indices.ToList();
property = GetImageProperty(item.ImageFileHolder, property, populateId, isIgnoreExtension, item.ValidImageFormatExtension, isValidMetadataExtensions, id, indices);
id = result?.Id;
result = null;
}
if (!isIgnoreExtension && item.ValidImageFormatExtension && populateId && property is not null && property.LastWriteTime != item.ImageFileHolder.LastWriteTime)
if (!isIgnoreExtension && item.ValidImageFormatExtension && populateId && result is not null)
{
id = result.Id;
result = null;
}
if (!isIgnoreExtension && item.ValidImageFormatExtension && populateId && result is not null && result.LastWriteTime != item.ImageFileHolder.LastWriteTime)
{
check = false;
id = null;
indices.Clear();
property = GetImageProperty(item.ImageFileHolder, property, populateId, isIgnoreExtension, item.ValidImageFormatExtension, isValidMetadataExtensions, id, indices);
result = null;
}
if (!isIgnoreExtension && item.ValidImageFormatExtension && property?.Width is not null && property?.Height is not null && property.Width.Value == property.Height.Value && item.ImageFileHolder.Exists)
if (!isIgnoreExtension && item.ValidImageFormatExtension && result?.Width is not null && result.Height is not null && result.Width.Value == result.Height.Value && item.ImageFileHolder.Exists)
{
check = false;
id = property?.Id;
if (property is not null && property.Indices.Any())
indices = property.Indices.ToList();
property = GetImageProperty(item.ImageFileHolder, property, populateId, isIgnoreExtension, item.ValidImageFormatExtension, isValidMetadataExtensions, id, indices);
if (property?.Width is not null && property?.Height is not null && property.Width.Value != property.Height.Value)
id = result.Id;
result = null;
if (result?.Width is not null && result.Height is not null && result.Width.Value != result.Height.Value)
throw new Exception("Was square!");
}
// if (filteredSourceDirectoryFileFileInfo.CreationTime != property?.CreationTime || filteredSourceDirectoryFileFileInfo.LastWriteTime != property?.LastWriteTime)
// {
// check = false;
// id = null;
// indices.Clear();
// property = GetImagePropertyB(filteredSourceDirectoryFile, populateId, isIgnoreExtension, isValidImageFormatExtension, isValidMetadataExtensions, id, indices);
// }
if (json.Contains("WrongYear"))
if (!isIgnoreExtension && item.ValidImageFormatExtension && result is not null && result.FileSize != fileInfo.Length)
{
id = property?.Id;
hasWrongYearProperty = true;
}
if (property is null)
throw new Exception();
if (!check)
id = result.Id;
result = null;
else
{
result = property;
sourceDirectoryFileTuples.Add(new Tuple<string, DateTime>(nameof(A_Property), fileInfo.LastWriteTime));
}
// if (filteredSourceDirectoryFileFileInfo.CreationTime != result.CreationTime || filteredSourceDirectoryFileFileInfo.LastWriteTime != result?.LastWriteTime)
// {
// id = null;
// property = ;
// }
if (result is not null)
sourceDirectoryFileTuples.Add(new Tuple<string, DateTime>(nameof(A_Property), fileInfo.LastWriteTime));
}
catch (Exception)
{
@ -353,7 +328,8 @@ public class A_Property
}
if (result is null)
{
result = GetImageProperty(item.ImageFileHolder, property, populateId, isIgnoreExtension, item.ValidImageFormatExtension, isValidMetadataExtensions, id, indices);
id ??= item.ImageFileHolder.Id;
result = GetImageProperty(item.ImageFileHolder, result, populateId, isIgnoreExtension, item.ValidImageFormatExtension, isValidMetadataExtensions, id);
json = JsonSerializer.Serialize(result, _WriteIndentedJsonSerializerOptions);
if (populateId && Shared.Models.Stateless.Methods.IPath.WriteAllText(fileInfo.FullName, json, updateDateWhenMatches: true, compareBeforeWrite: true))
{

View File

@ -99,6 +99,8 @@ public class Configuration
IConfigurationSection configurationSection = configurationRoot.GetSection(section);
configuration = configurationSection.Get<Configuration>();
}
if (configuration is null)
throw new NullReferenceException(nameof(configuration));
result = Get(configuration);
return result;
}

View File

@ -92,6 +92,8 @@ public class Configuration : Shared.Models.Properties.IPropertyConfiguration
_RootDirectory = Path.GetFullPath(_RootDirectory);
}
public void Update() => Update(numberOfJitters: null, numberOfTimesToUpsample: null, modelName: null, predictorModelName: null);
public static void Verify(Configuration propertyConfiguration, bool requireExist)
{
if (propertyConfiguration is null)
@ -118,6 +120,8 @@ public class Configuration : Shared.Models.Properties.IPropertyConfiguration
throw new NullReferenceException(nameof(propertyConfiguration.Pattern));
if (string.IsNullOrEmpty(propertyConfiguration.RootDirectory) || (requireExist && !Directory.Exists(propertyConfiguration.RootDirectory)))
throw new NullReferenceException(nameof(propertyConfiguration.RootDirectory));
if (propertyConfiguration.RootDirectory != Path.GetFullPath(propertyConfiguration.RootDirectory))
throw new Exception();
}
}

View File

@ -6,126 +6,46 @@ namespace View_by_Distance.Property.Models.Stateless;
public class Container
{
public static (int t, List<(int g, string sourceDirectory, string[] sourceDirectoryFiles)>) GetGroupCollection(string rootDirectory, int maxImagesInDirectoryForTopLevelFirstPass, bool reverse, string searchPattern, List<string> topDirectories)
{
int result = 0;
List<(int g, string sourceDirectory, string[] sourceDirectoryFiles)> results = new();
string? parentDirectory;
string[] subDirectories;
string[] sourceDirectoryFiles;
List<string[]> fileCollections = new();
if (!topDirectories.Any())
{
if (!Directory.Exists(rootDirectory))
_ = Directory.CreateDirectory(rootDirectory);
topDirectories.AddRange(from l in Directory.GetDirectories(rootDirectory, "*", SearchOption.TopDirectoryOnly) select Path.GetFullPath(l));
}
for (int g = 1; g < 5; g++)
{
if (g == 4)
{
for (int i = fileCollections.Count - 1; i > -1; i--)
{
parentDirectory = Path.GetDirectoryName(fileCollections[i][0]);
if (string.IsNullOrEmpty(parentDirectory))
continue;
results.Add(new(g, parentDirectory, fileCollections[i]));
fileCollections.RemoveAt(i);
}
}
else if (g == 2)
{
for (int i = fileCollections.Count - 1; i > -1; i--)
{
if (fileCollections[i].Length > maxImagesInDirectoryForTopLevelFirstPass * g)
break;
parentDirectory = Path.GetDirectoryName(fileCollections[i][0]);
if (string.IsNullOrEmpty(parentDirectory))
continue;
results.Add(new(g, parentDirectory, fileCollections[i]));
fileCollections.RemoveAt(i);
}
}
else if (g == 3)
{
subDirectories = Directory.GetDirectories(rootDirectory, "*", SearchOption.AllDirectories);
if (reverse)
subDirectories = subDirectories.Reverse().ToArray();
foreach (string subDirectory in subDirectories)
{
sourceDirectoryFiles = Directory.GetFiles(subDirectory, "*", SearchOption.TopDirectoryOnly);
result += sourceDirectoryFiles.Length;
if (!topDirectories.Contains(subDirectory))
results.Add(new(g, subDirectory, sourceDirectoryFiles));
}
}
else if (g == 1)
{
sourceDirectoryFiles = Directory.GetFiles(rootDirectory, searchPattern, SearchOption.TopDirectoryOnly);
result += sourceDirectoryFiles.Length;
if (sourceDirectoryFiles.Length > maxImagesInDirectoryForTopLevelFirstPass)
fileCollections.Add(sourceDirectoryFiles);
else
results.Add(new(g, rootDirectory, sourceDirectoryFiles));
if (reverse)
topDirectories.Reverse();
subDirectories = topDirectories.ToArray();
foreach (string subDirectory in subDirectories)
{
sourceDirectoryFiles = Directory.GetFiles(subDirectory, searchPattern, SearchOption.TopDirectoryOnly);
result += sourceDirectoryFiles.Length;
if (sourceDirectoryFiles.Length > maxImagesInDirectoryForTopLevelFirstPass)
fileCollections.Add(sourceDirectoryFiles);
else
{
if (sourceDirectoryFiles.Any() || Directory.GetDirectories(subDirectory, "*", SearchOption.TopDirectoryOnly).Any())
results.Add(new(g, subDirectory, sourceDirectoryFiles));
else if (searchPattern == "*" && subDirectory != rootDirectory)
Directory.Delete(subDirectory);
}
}
fileCollections.Reverse();
}
else
throw new Exception();
}
return new(result, results);
}
public static (int t, List<(int g, string sourceDirectory, string[] sourceDirectoryFiles)>) GetGroupCollection(string rootDirectory, string searchPattern, List<string> topDirectories)
{
(int t, List<(int g, string sourceDirectory, string[] sourceDirectoryFiles)>) results;
int maxImagesInDirectoryForTopLevelFirstPass = 50;
bool reverse = false;
results = GetGroupCollection(rootDirectory, maxImagesInDirectoryForTopLevelFirstPass, reverse, searchPattern, topDirectories);
return results;
}
private static (int j, List<(int g, string sourceDirectory, string[] sourceDirectoryFiles)>) GetJsonGroupCollection(Configuration configuration, A_Property propertyLogic, string rootDirectory)
{
(int j, List<(int g, string sourceDirectory, string[] sourceDirectoryFiles)>) results;
string searchPattern = "*.json";
List<string> topDirectories = new();
results = GetGroupCollection(rootDirectory, configuration.MaxImagesInDirectoryForTopLevelFirstPass, propertyLogic.Reverse, searchPattern, topDirectories);
return results;
}
private static (int f, List<(int g, string sourceDirectory, FileHolder[] sourceDirectoryFiles)>) GetFileHolderGroupCollection(Configuration configuration, A_Property propertyLogic, string searchPattern, List<string> topDirectories)
{
List<(int g, string sourceDirectory, FileHolder[] sourceDirectoryFiles)> results = new();
int? id;
int parsedId;
string idFile;
string[] lines;
const int zero = 0;
List<(string File, int? Id)> files = new();
List<(int g, string sourceDirectory, string[] sourceDirectoryFiles)> collection;
(int f, collection) = GetGroupCollection(configuration.RootDirectory, configuration.MaxImagesInDirectoryForTopLevelFirstPass, propertyLogic.Reverse, searchPattern, topDirectories);
(int f, collection) = Shared.Models.Stateless.Methods.IFileHolder.GetGroupCollection(configuration.RootDirectory, configuration.MaxImagesInDirectoryForTopLevelFirstPass, propertyLogic.Reverse, searchPattern, topDirectories);
foreach ((int g, string sourceDirectory, string[] sourceDirectoryFiles) in collection)
results.Add(new(g, sourceDirectory, (from l in sourceDirectoryFiles select new FileHolder(l)).ToArray()));
{
files.Clear();
foreach (string sourceDirectoryFile in sourceDirectoryFiles)
{
if (sourceDirectoryFile.EndsWith(".id"))
continue;
id = null;
idFile = $"{sourceDirectoryFile}.id";
if (sourceDirectoryFiles.Contains(idFile))
{
lines = File.ReadAllLines(idFile);
File.Delete(idFile);
if (lines.Any() && int.TryParse(lines[zero], out parsedId))
id = parsedId;
};
files.Add(new(sourceDirectoryFile, id));
}
results.Add(new(g, sourceDirectory, (from l in files select new FileHolder(l.File, l.Id)).ToArray()));
}
return new(f, results);
}
private static void ParallelFor(List<(int, string, string[])> jsonCollection, int i, int length, List<(int, string, List<(string, Shared.Models.Property?)>)> results)
private static void ParallelFor(List<(string, string[])> jsonCollection, int i, int length, List<(string, List<(string, Shared.Models.Property?)>)> results)
{
string key;
string json;
Shared.Models.Property? property;
(int g, string sourceDirectory, string[] sourceDirectoryFiles) = jsonCollection[i];
(string sourceDirectory, string[] sourceDirectoryFiles) = jsonCollection[i];
List<(string, Shared.Models.Property?)> collection = new();
foreach (string sourceDirectoryFile in sourceDirectoryFiles)
{
@ -135,37 +55,28 @@ public class Container
collection.Add(new(sourceDirectoryFile, property));
}
lock (results)
results.Add(new(g, sourceDirectory, collection));
results.Add(new(sourceDirectory, collection));
}
private static List<(int g, string sourceDirectory, List<(string sourceDirectoryFile, Shared.Models.Property? property)> collection)> GetCollection(string rootDirectory, List<(int g, string sourceDirectory, string[] SourceDirectoryFiles)> jsonCollection)
private static List<(string sourceDirectory, List<(string sourceDirectoryFile, Shared.Models.Property? property)> collection)> GetCollection(string rootDirectory, List<(string sourceDirectory, string[] SourceDirectoryFiles)> jsonCollection)
{
List<(int, string, List<(string, Shared.Models.Property?)>)> results = new();
List<(string, List<(string, Shared.Models.Property?)>)> results = new();
int length = rootDirectory.Length;
ParallelOptions parallelOptions = new() { MaxDegreeOfParallelism = Environment.ProcessorCount };
_ = Parallel.For(0, jsonCollection.Count, parallelOptions, (i, state) => ParallelFor(jsonCollection, i, length, results));
return results;
}
private static Item GetNewItem(Configuration configuration, A_Property propertyLogic, string relativePath, FileHolder sourceDirectoryFileHolder)
private static Item GetNewItem(Configuration configuration, string relativePath, FileHolder sourceDirectoryFileHolder)
{
Item result;
Shared.Models.Property? property = null;
bool isValidImageFormatExtension = configuration.ValidImageFormatExtensions.Contains(sourceDirectoryFileHolder.ExtensionLowered);
if (configuration.PopulatePropertyId)
result = new(sourceDirectoryFileHolder.FullName, relativePath, sourceDirectoryFileHolder, isValidImageFormatExtension, property, null, null, null);
else
{
List<string> parseExceptions = new();
List<Tuple<string, DateTime>> subFileTuples = new();
Item item = new(sourceDirectoryFileHolder.FullName, relativePath, sourceDirectoryFileHolder, isValidImageFormatExtension, property, null, null, null);
property = propertyLogic.GetProperty(item, subFileTuples, parseExceptions);
result = new(sourceDirectoryFileHolder.FullName, relativePath, sourceDirectoryFileHolder, isValidImageFormatExtension, property, null, null, null);
}
result = new(sourceDirectoryFileHolder, relativePath, sourceDirectoryFileHolder, isValidImageFormatExtension, property, null, null, null);
return result;
}
private static (int, Shared.Models.Container[]) GetContainers(Configuration configuration, A_Property propertyLogic, string aPropertySingletonDirectory, List<(int, string, FileHolder[])> fileHolderGroupCollection, List<(int, string, List<(string, Shared.Models.Property?)>)> collectionFromJson)
private static (int, Shared.Models.Container[]) GetContainers(Configuration configuration, A_Property propertyLogic, string aPropertySingletonDirectory, List<(int, string, FileHolder[])> fileHolderGroupCollection, List<(string, List<(string, Shared.Models.Property?)>)> collectionFromJson)
{
int result = 0;
Shared.Models.Container[] results;
@ -174,9 +85,11 @@ public class Container
int additional;
string inferred;
List<Item> items;
const int last = 9;
string keyWithJson;
string relativePath;
bool fileSizeChanged;
FileHolder fileHolder;
FileHolder keyFileHolder;
bool lastWriteTimeChanged;
bool isValidImageFormatExtension;
@ -190,11 +103,13 @@ public class Container
foreach (FileHolder sourceDirectoryFileHolder in sourceDirectoryFileHolderCollection)
{
relativePath = Shared.Models.Stateless.Methods.IPath.GetRelativePath(sourceDirectoryFileHolder.FullName, length, forceExtensionToLower: true);
if (fileHolderKeyValuePairs.ContainsKey(relativePath))
throw new NotSupportedException();
fileHolderKeyValuePairs.Add(relativePath, new(sourceDirectory, sourceDirectoryFileHolder));
}
}
length = aPropertySingletonDirectory.Length;
foreach ((int g, string _, List<(string, Shared.Models.Property?)> collection) in collectionFromJson)
foreach ((string _, List<(string, Shared.Models.Property?)> collection) in collectionFromJson)
{
if (!collection.Any())
continue;
@ -202,6 +117,7 @@ public class Container
keySourceDirectories = new();
foreach ((string sourceDirectoryFile, Shared.Models.Property? property) in collection)
{
fileHolder = new(sourceDirectoryFile);
keyWithJson = Shared.Models.Stateless.Methods.IPath.GetRelativePath(sourceDirectoryFile, length, forceExtensionToLower: false);
relativePath = keyWithJson[..^5];
if (!fileHolderKeyValuePairs.ContainsKey(relativePath))
@ -212,7 +128,7 @@ public class Container
continue;
keySourceDirectories.Add(string.Concat(keyFileHolder.DirectoryName));
isValidImageFormatExtension = configuration.ValidImageFormatExtensions.Contains(keyFileHolder.ExtensionLowered);
item = new(sourceDirectoryFile, relativePath, keyFileHolder, isValidImageFormatExtension, property, true, null, null);
item = new(fileHolder, relativePath, keyFileHolder, isValidImageFormatExtension, property, true, null, null);
items.Add(item);
}
else
@ -225,12 +141,12 @@ public class Container
continue;
isValidImageFormatExtension = configuration.ValidImageFormatExtensions.Contains(keyFileHolder.ExtensionLowered);
if (property?.Id is null || property?.Width is null || property?.Height is null)
item = new(sourceDirectoryFile, relativePath, keyFileHolder, isValidImageFormatExtension, property, false, null, null);
item = new(fileHolder, relativePath, keyFileHolder, isValidImageFormatExtension, property, false, null, null);
else
{
fileSizeChanged = property.FileSize != keyFileHolder.Length;
lastWriteTimeChanged = configuration.PropertiesChangedForProperty || property.LastWriteTime != keyFileHolder.LastWriteTime;
item = new(sourceDirectoryFile, relativePath, keyFileHolder, isValidImageFormatExtension, property, false, fileSizeChanged, lastWriteTimeChanged);
item = new(fileHolder, relativePath, keyFileHolder, isValidImageFormatExtension, property, false, fileSizeChanged, lastWriteTimeChanged);
}
items.Add(item);
}
@ -240,7 +156,7 @@ public class Container
result += items.Count;
if (keySourceDirectories.Distinct().Count() != 1)
continue;
container = new(g, items, keySourceDirectories[0]);
container = new(last, items, keySourceDirectories[0]);
keyValuePairs.Add(keySourceDirectories[0], container);
}
}
@ -258,7 +174,7 @@ public class Container
throw new Exception();
if (sourceDirectoryFileHolder.ExtensionLowered is ".json")
continue;
item = GetNewItem(configuration, propertyLogic, relativePath, sourceDirectoryFileHolder);
item = GetNewItem(configuration, relativePath, sourceDirectoryFileHolder);
items.Add(item);
}
if (sourceDirectory == configuration.RootDirectory || items.Any())
@ -285,19 +201,54 @@ public class Container
return new(result, results);
}
private static void SetCollections(string aPropertySingletonDirectory, List<string> otherCollection, List<(string, string[])> jsonCollection)
{
string searchPattern = "*";
(string, string[])[] collection = Shared.Models.Stateless.Methods.IFileHolder.GetFiles(aPropertySingletonDirectory, searchPattern).ToArray();
foreach ((string sourceDirectory, string[] files) in collection)
{
otherCollection.AddRange(files.Where(l => !l.EndsWith(".json")));
jsonCollection.Add(new(sourceDirectory, files.Where(l => l.EndsWith(".json")).ToArray()));
}
}
private static void DeleteAbandoned(Configuration configuration, string aPropertySingletonDirectory, List<string> otherCollection, List<(int g, string sourceDirectory, FileHolder[] sourceDirectoryFiles)> fileHolderGroupCollection)
{
string relativePath;
string checkFileName;
List<string> checkCollection = new();
checkCollection.AddRange(otherCollection);
int length = configuration.RootDirectory.Length;
foreach ((int g, string sourceDirectory, FileHolder[] sourceDirectoryFiles) in fileHolderGroupCollection)
{
foreach (FileHolder fileHolder in sourceDirectoryFiles)
{
relativePath = Shared.Models.Stateless.Methods.IPath.GetRelativePath(fileHolder.FullName, length);
checkFileName = Path.GetFullPath(string.Concat(aPropertySingletonDirectory, relativePath));
if (!checkCollection.Remove(checkFileName))
File.WriteAllText(checkFileName, string.Empty);
}
}
foreach (string file in checkCollection)
File.Delete(file);
}
public static (int, int, int, Shared.Models.Container[]) GetContainers(Configuration configuration, A_Property propertyLogic)
{
Shared.Models.Container[] results;
string searchPattern = "*";
List<string> topDirectories = new();
List<(int g, string sourceDirectory, string[] sourceDirectoryFiles)> jsonCollection;
List<string> otherCollection = new();
List<(string, string[])> jsonCollection = new();
List<(int g, string sourceDirectory, FileHolder[] sourceDirectoryFiles)> fileHolderGroupCollection;
string aPropertySingletonDirectory = IResult.GetResultsDateGroupDirectory(configuration, nameof(A_Property), "{}");
List<(int g, string sourceDirectory, List<(string sourceDirectoryFile, Shared.Models.Property? property)> collection)> collectionFromJson;
(int j, jsonCollection) = GetJsonGroupCollection(configuration, propertyLogic, aPropertySingletonDirectory);
SetCollections(aPropertySingletonDirectory, otherCollection, jsonCollection);
(int f, fileHolderGroupCollection) = GetFileHolderGroupCollection(configuration, propertyLogic, searchPattern, topDirectories);
DeleteAbandoned(configuration, aPropertySingletonDirectory, otherCollection, fileHolderGroupCollection);
List<(string sourceDirectory, List<(string sourceDirectoryFile, Shared.Models.Property? property)> collection)> collectionFromJson;
collectionFromJson = GetCollection(aPropertySingletonDirectory, jsonCollection);
(int t, results) = GetContainers(configuration, propertyLogic, aPropertySingletonDirectory, fileHolderGroupCollection, collectionFromJson);
int j = jsonCollection.Select(l => l.Item2.Length).Sum();
return (j, f, t, results);
}

View File

@ -52,7 +52,7 @@ internal class Result
predictorModelName = PredictorModel.Large.ToString();
else
predictorModelName = propertyConfiguration.PredictorModelName;
string dateGroupDirectory = string.Concat(outputResolution.Replace(" ", string.Empty), " - ", modelName, " - ", predictorModelName);
string dateGroupDirectory = string.Concat(outputResolution.Replace(" ", string.Empty), "-", modelName, "-", predictorModelName, "-", propertyConfiguration.NumberOfJitters, "-", propertyConfiguration.NumberOfTimesToUpsample);
result = Path.Combine(result, dateGroupDirectory);
}
else if (includeModel)

View File

@ -45,7 +45,7 @@
<PackageReference Include="Serilog" Version="2.12.0" />
<PackageReference Include="Serilog.Settings.Configuration" Version="3.4.0" />
<PackageReference Include="System.Drawing.Common" Version="7.0.0" />
<PackageReference Include="System.Text.Json" Version="7.0.0" />
<PackageReference Include="System.Text.Json" Version="7.0.1" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Shared\View-by-Distance.Shared.csproj" />

View File

@ -313,12 +313,12 @@ public class C_Resize
return results;
}
public byte[] GetResizedBytes(string outputResolution, string cResultsFullGroupDirectory, List<Tuple<string, DateTime>> subFileTuples, Shared.Models.Property property, MappingFromItem mappingFromItem, Dictionary<string, int[]> imageResizes)
public byte[] GetResizedBytes(string outputResolution, string cResultsFullGroupDirectory, List<Tuple<string, DateTime>> subFileTuples, Shared.Models.Property property, MappingFromItem mappingFromItem, Dictionary<string, int[]> imageResizeKeyValuePairs)
{
byte[] results;
if (!imageResizes.ContainsKey(outputResolution))
if (!imageResizeKeyValuePairs.ContainsKey(outputResolution))
throw new Exception();
int[] resize = imageResizes[outputResolution];
int[] resize = imageResizeKeyValuePairs[outputResolution];
int outputResolutionWidth = resize[_OutputResolutionWidthIndex];
int outputResolutionHeight = resize[_OutputResolutionHeightIndex];
int outputResolutionOrientation = resize[_OutputResolutionOrientationIndex];
@ -327,34 +327,35 @@ public class C_Resize
return results;
}
public void SaveResizedSubfile(Property.Models.Configuration configuration, string outputResolution, string cResultsFullGroupDirectory, List<Tuple<string, DateTime>> subFileTuples, Item item, Shared.Models.Property property, MappingFromItem mappingFromItem, string original, Dictionary<string, int[]> imageResizes)
public void SaveResizedSubfile(Property.Models.Configuration configuration, string outputResolution, string cResultsFullGroupDirectory, List<Tuple<string, DateTime>> subFileTuples, Item item, Shared.Models.Property property, MappingFromItem mappingFromItem, string original, Dictionary<string, int[]> imageResizeKeyValuePairs)
{
if (mappingFromItem.ResizedFileHolder is null)
throw new NullReferenceException(nameof(mappingFromItem.ResizedFileHolder));
if (!imageResizes.ContainsKey(outputResolution))
if (!imageResizeKeyValuePairs.ContainsKey(original))
throw new Exception();
if (!imageResizeKeyValuePairs.ContainsKey(outputResolution))
throw new Exception();
FileInfo fileInfo = new(mappingFromItem.ResizedFileHolder.FullName);
if (!fileInfo.FullName.Contains(configuration.ResultAllInOne) && !fileInfo.Exists)
{
if (fileInfo.Directory?.Parent is null)
throw new Exception();
string parentCheck = Path.Combine(fileInfo.Directory.Parent.FullName, fileInfo.Name);
if (File.Exists(parentCheck))
{
File.Move(parentCheck, fileInfo.FullName);
item.SetResizedFileHolder(_FileNameExtension, Shared.Models.Stateless.Methods.IFileHolder.Refresh(mappingFromItem.ResizedFileHolder));
fileInfo.Refresh();
}
}
int[] resize = imageResizes[outputResolution];
bool check = false;
int[] resize = imageResizeKeyValuePairs[outputResolution];
int outputResolutionWidth = resize[_OutputResolutionWidthIndex];
int outputResolutionHeight = resize[_OutputResolutionHeightIndex];
int outputResolutionOrientation = resize[_OutputResolutionOrientationIndex];
int[] originalCollection = imageResizes[original];
int[] originalCollection = imageResizeKeyValuePairs[original];
string[] changesFrom = new string[] { nameof(Property.Models.A_Property), nameof(B_Metadata), nameof(C_Resize) };
List<DateTime> dateTimes = (from l in subFileTuples where changesFrom.Contains(l.Item1) select l.Item2).ToList();
if (_OverrideForResizeImages)
check = true;
else if (!fileInfo.Exists)
check = true;
if (outputResolutionWidth == originalCollection[_OutputResolutionWidthIndex] && outputResolutionHeight == originalCollection[_OutputResolutionHeightIndex] && outputResolutionOrientation == originalCollection[_OutputResolutionOrientationIndex])
{
if (!fileInfo.Exists)
if (!check && dateTimes.Any() && dateTimes.Max() > fileInfo.CreationTime.AddDays(1))
check = true;
if (check)
{
if (fileInfo.Exists)
File.Delete(fileInfo.FullName);
File.Copy(mappingFromItem.ImageFileHolder.FullName, fileInfo.FullName);
item.SetResizedFileHolder(_FileNameExtension, Shared.Models.Stateless.Methods.IFileHolder.Refresh(mappingFromItem.ResizedFileHolder));
subFileTuples.Add(new Tuple<string, DateTime>(nameof(C_Resize), DateTime.Now));
@ -362,14 +363,7 @@ public class C_Resize
}
else
{
bool check = false;
string[] changesFrom = new string[] { nameof(Property.Models.A_Property), nameof(B_Metadata), nameof(C_Resize) };
List<DateTime> dateTimes = (from l in subFileTuples where changesFrom.Contains(l.Item1) select l.Item2).ToList();
if (_OverrideForResizeImages)
check = true;
else if (!fileInfo.Exists)
check = true;
else if (dateTimes.Any() && dateTimes.Max() > fileInfo.LastWriteTime)
if (!check && dateTimes.Any() && dateTimes.Max() > fileInfo.LastWriteTime)
check = true;
if (check)
{
@ -461,17 +455,6 @@ public class C_Resize
List<DateTime> dateTimes = (from l in subFileTuples where changesFrom.Contains(l.Item1) select l.Item2).ToList();
string cResizeSingletonFile = Path.Combine(cResultsFullGroupDirectory, "{}", configuration.ResultAllInOne, $"{mappingFromItem.Id}{mappingFromItem.ImageFileHolder.ExtensionLowered}.json");
FileInfo fileInfo = new(cResizeSingletonFile);
if (!fileInfo.FullName.Contains(configuration.ResultAllInOne) && !fileInfo.Exists)
{
if (fileInfo.Directory?.Parent is null)
throw new Exception();
string parentCheck = Path.Combine(fileInfo.Directory.Parent.FullName, fileInfo.Name);
if (File.Exists(parentCheck))
{
File.Move(parentCheck, fileInfo.FullName);
fileInfo.Refresh();
}
}
if (_ForceResizeLastWriteTimeToCreationTime && !fileInfo.Exists && File.Exists(Path.ChangeExtension(fileInfo.FullName, ".delete")))
{
File.Move(Path.ChangeExtension(fileInfo.FullName, ".delete"), fileInfo.FullName);
@ -535,4 +518,13 @@ public class C_Resize
return results;
}
public static byte[] GetBytes(string value)
{
byte[] results = new byte[value.Length + 1];
for (int i = 0; i < value.Length; i++)
results[i] = (byte)value[i];
results[value.Length] = 0x00;
return results;
}
}

View File

@ -37,7 +37,7 @@
<PackageReference Include="Serilog" Version="2.12.0" />
<PackageReference Include="MetadataExtractor" Version="2.7.2" />
<PackageReference Include="System.Drawing.Common" Version="7.0.0" />
<PackageReference Include="System.Text.Json" Version="7.0.0" />
<PackageReference Include="System.Text.Json" Version="7.0.1" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Shared\View-by-Distance.Shared.csproj" />

View File

@ -12,10 +12,10 @@ public record class FaceDistance : Properties.IFaceDistance
public bool? IsWrongYear { init; get; }
public double? Length { init; get; }
public DateTime? MinimumDateTime { init; get; }
public int? NormalizedPixelPercentage { init; get; }
public int? NormalizedRectangle { init; get; }
[JsonConstructor]
public FaceDistance(int? confidencePercent, object? encoding, int id, bool? isWrongYear, double? length, DateTime? minimumDateTime, int? normalizedPixelPercentage)
public FaceDistance(int? confidencePercent, object? encoding, int id, bool? isWrongYear, double? length, DateTime? minimumDateTime, int? normalizedRectangle)
{
ConfidencePercent = confidencePercent;
Encoding = encoding;
@ -23,15 +23,15 @@ public record class FaceDistance : Properties.IFaceDistance
IsWrongYear = isWrongYear;
Length = length;
MinimumDateTime = minimumDateTime;
NormalizedPixelPercentage = normalizedPixelPercentage;
NormalizedRectangle = normalizedRectangle;
}
public FaceDistance(int? confidencePercent, object? encoding, int id, bool? isWrongYear, DateTime? minimumDateTime, int? normalizedPixelPercentage) :
this(confidencePercent, encoding, id, isWrongYear, null, minimumDateTime, normalizedPixelPercentage)
public FaceDistance(int? confidencePercent, object? encoding, int id, bool? isWrongYear, DateTime? minimumDateTime, int? normalizedRectangle) :
this(confidencePercent, encoding, id, isWrongYear, null, minimumDateTime, normalizedRectangle)
{ }
public FaceDistance(FaceDistance faceDistance, double length) :
this(faceDistance.ConfidencePercent, null, faceDistance.Id, faceDistance.IsWrongYear, length, faceDistance.MinimumDateTime, faceDistance.NormalizedPixelPercentage)
this(faceDistance.ConfidencePercent, null, faceDistance.Id, faceDistance.IsWrongYear, length, faceDistance.MinimumDateTime, faceDistance.NormalizedRectangle)
{ }
public FaceDistance(object encoding) => Encoding = encoding;

View File

@ -10,6 +10,7 @@ public class FileHolder : Properties.IFileHolder
protected readonly bool _Exists;
protected readonly string _ExtensionLowered;
protected readonly string _FullName;
protected readonly int? _Id;
protected readonly DateTime? _LastWriteTime;
protected readonly long? _Length;
protected readonly string _Name;
@ -19,25 +20,27 @@ public class FileHolder : Properties.IFileHolder
public bool Exists => _Exists;
public string ExtensionLowered => _ExtensionLowered;
public string FullName => _FullName;
public int? Id => _Id;
public DateTime? LastWriteTime => _LastWriteTime;
public long? Length => _Length;
public string Name => _Name;
public string NameWithoutExtension => _NameWithoutExtension;
public FileHolder(DateTime? creationTime, string? directoryName, bool exists, string extensionLowered, string fullName, DateTime? lastWriteTime, long? length, string name, string nameWithoutExtension)
public FileHolder(DateTime? creationTime, string? directoryName, bool exists, string extensionLowered, string fullName, int? id, DateTime? lastWriteTime, long? length, string name, string nameWithoutExtension)
{
_CreationTime = creationTime;
_DirectoryName = directoryName;
_Exists = exists;
_ExtensionLowered = extensionLowered;
_FullName = fullName;
_Id = id;
_LastWriteTime = lastWriteTime;
_Length = length;
_Name = name;
_NameWithoutExtension = nameWithoutExtension;
}
public FileHolder(FileInfo fileInfo)
public FileHolder(FileInfo fileInfo, int? id)
{
if (fileInfo.Exists)
{
@ -49,13 +52,18 @@ public class FileHolder : Properties.IFileHolder
_DirectoryName = fileInfo.DirectoryName;
_Exists = fileInfo.Exists;
_ExtensionLowered = fileInfo.Extension.ToLower();
_Id = id;
_FullName = fileInfo.FullName;
_Name = fileInfo.Name;
_NameWithoutExtension = Path.GetFileNameWithoutExtension(fileInfo.FullName);
}
public FileHolder(string fileName) :
this(new FileInfo(fileName))
this(new FileInfo(fileName), null)
{ }
public FileHolder(string fileName, int? id) :
this(new FileInfo(fileName), id)
{ }
public override string ToString()

View File

@ -16,7 +16,7 @@ public class Item : Properties.IItem
protected Property? _Property;
protected readonly string _RelativePath;
protected FileHolder? _ResizedFileHolder;
protected readonly string _SourceDirectoryFile;
protected readonly FileHolder _SourceDirectoryFileHolder;
protected bool _ValidImageFormatExtension;
public bool? Abandoned => _Abandoned;
public List<Face> Faces => _Faces;
@ -28,11 +28,11 @@ public class Item : Properties.IItem
public Property? Property => _Property;
public string RelativePath => _RelativePath;
public FileHolder? ResizedFileHolder => _ResizedFileHolder;
public string SourceDirectoryFile => _SourceDirectoryFile;
public FileHolder SourceDirectoryFileHolder => _SourceDirectoryFileHolder;
public bool ValidImageFormatExtension => _ValidImageFormatExtension;
[JsonConstructor]
public Item(bool? abandoned, List<Face> faces, bool? fileSizeChanged, FileHolder imageFileHolder, bool? lastWriteTimeChanged, bool? moved, bool? noJson, Property? property, string relativePath, FileHolder? resizedFileHolder, string sourceDirectoryFile, bool validImageFormatExtension)
public Item(bool? abandoned, List<Face> faces, bool? fileSizeChanged, FileHolder imageFileHolder, bool? lastWriteTimeChanged, bool? moved, bool? noJson, Property? property, string relativePath, FileHolder? resizedFileHolder, FileHolder sourceDirectoryFileHolder, bool validImageFormatExtension)
{
_Faces = faces;
_Moved = moved;
@ -43,13 +43,13 @@ public class Item : Properties.IItem
_FileSizeChanged = fileSizeChanged;
_ImageFileHolder = imageFileHolder;
_ResizedFileHolder = resizedFileHolder;
_SourceDirectoryFile = sourceDirectoryFile;
_SourceDirectoryFileHolder = sourceDirectoryFileHolder;
_LastWriteTimeChanged = lastWriteTimeChanged;
_ValidImageFormatExtension = validImageFormatExtension;
}
public Item(string sourceDirectoryFile, string relativePath, FileHolder imageFileInfo, bool validImageFormatExtension, Property? property, bool? abandoned, bool? fileSizeChanged, bool? lastWriteTimeChanged) :
this(abandoned, new(), fileSizeChanged, imageFileInfo, lastWriteTimeChanged, null, abandoned is null, property, relativePath, null, sourceDirectoryFile, validImageFormatExtension)
public Item(FileHolder sourceDirectoryFileHolder, string relativePath, FileHolder imageFileInfo, bool validImageFormatExtension, Property? property, bool? abandoned, bool? fileSizeChanged, bool? lastWriteTimeChanged) :
this(abandoned, new(), fileSizeChanged, imageFileInfo, lastWriteTimeChanged, null, abandoned is null, property, relativePath, null, sourceDirectoryFileHolder, validImageFormatExtension)
{
if (relativePath.EndsWith(".json"))
throw new ArgumentException("Can not be a *.json file!");
@ -57,8 +57,8 @@ public class Item : Properties.IItem
throw new ArgumentException("Can not be a *.json file!");
}
public Item(string sourceDirectoryFile, string relativePath, bool isValidImageFormatExtension) :
this(sourceDirectoryFile, relativePath, new(sourceDirectoryFile), isValidImageFormatExtension, null, null, null, null)
public Item(FileHolder sourceDirectoryFileHolder, string relativePath, bool isValidImageFormatExtension) :
this(sourceDirectoryFileHolder, relativePath, sourceDirectoryFileHolder, isValidImageFormatExtension, null, null, null, null)
{ }
public override string ToString()

View File

@ -20,7 +20,7 @@ public class Location : Properties.ILocation, IEquatable<Location>
Left = left;
Right = right;
Top = top;
Stateless.Methods.Location.Check(bottom, left, right, top, zCount: 1);
_ = Stateless.Methods.Location.Check(bottom, left, right, top, zCount: 1, throwException: true);
}
public Location(double confidence, int height, Location location, int locationDigits, int locationFactor, int width, int zCount) :
@ -30,7 +30,7 @@ public class Location : Properties.ILocation, IEquatable<Location>
location.Left,
location.Right,
location.Top) =>
Stateless.Methods.Location.Check(Bottom, height, Left, Right, Top, width, zCount);
Stateless.Methods.Location.Check(Bottom, height, Left, Right, Top, width, zCount, throwException: true);
public Location(int bottom, double confidence, int height, int left, int locationDigits, int locationFactor, int right, int top, int width, int zCount) :
this(
@ -39,7 +39,7 @@ public class Location : Properties.ILocation, IEquatable<Location>
left,
right,
top) =>
Stateless.Methods.Location.Check(Bottom, height, Left, Right, Top, width, zCount);
Stateless.Methods.Location.Check(Bottom, height, Left, Right, Top, width, zCount, throwException: true);
public Location(int height, Location location, int locationDigits, int locationFactor, int width, int zCount) :
this(
@ -48,7 +48,7 @@ public class Location : Properties.ILocation, IEquatable<Location>
location.Left,
location.Right,
location.Top) =>
Stateless.Methods.Location.Check(Bottom, height, Left, Right, Top, width, zCount);
Stateless.Methods.Location.Check(Bottom, height, Left, Right, Top, width, zCount, throwException: true);
public Location(double confidence, int factor, int height, Location location, int locationDigits, int locationFactor, int width, int zCount)
{
@ -58,7 +58,7 @@ public class Location : Properties.ILocation, IEquatable<Location>
int left = Math.Max(location.Left - x, 0);
int right = Math.Min(location.Right + x, width);
int top = Math.Max(location.Top - y, 0);
Stateless.Methods.Location.Check(Bottom, height, Left, Right, Top, width, zCount);
_ = Stateless.Methods.Location.Check(Bottom, height, Left, Right, Top, width, zCount, throwException: true);
Confidence = confidence;
Bottom = bottom;
Left = left;

View File

@ -6,6 +6,7 @@ namespace View_by_Distance.Shared.Models;
public class MappingFromItem : Properties.IMappingFromItem
{
public DateTime[] ContainerDateTimes { init; get; }
public int Id { init; get; }
public FileHolder ImageFileHolder { init; get; }
public bool? IsWrongYear { init; get; }
@ -14,8 +15,9 @@ public class MappingFromItem : Properties.IMappingFromItem
public FileHolder ResizedFileHolder { init; get; }
[JsonConstructor]
public MappingFromItem(int id, FileHolder imageFileHolder, bool? isWrongYear, DateTime minimumDateTime, string relativePath, FileHolder resizedFileHolder)
public MappingFromItem(DateTime[] containerDateTimes, int id, FileHolder imageFileHolder, bool? isWrongYear, DateTime minimumDateTime, string relativePath, FileHolder resizedFileHolder)
{
ContainerDateTimes = containerDateTimes;
Id = id;
ImageFileHolder = imageFileHolder;
IsWrongYear = isWrongYear;
@ -30,7 +32,7 @@ public class MappingFromItem : Properties.IMappingFromItem
return result;
}
internal static MappingFromItem GetMappingFromItem(Item item, FileHolder? resizedFileHolder)
internal static MappingFromItem GetMappingFromItem(DateTime[] containerDateTimes, Item item, FileHolder? resizedFileHolder)
{
MappingFromItem result;
bool? isWrongYear;
@ -41,7 +43,7 @@ public class MappingFromItem : Properties.IMappingFromItem
throw new NotSupportedException();
minimumDateTime = Stateless.Methods.IProperty.GetMinimumDateTime(item.Property);
(isWrongYear, _) = item.Property.IsWrongYear(item.ImageFileHolder, minimumDateTime);
result = new(item.Property.Id.Value, item.ImageFileHolder, isWrongYear, minimumDateTime, item.RelativePath, resizedFileHolder);
result = new(containerDateTimes, item.Property.Id.Value, item.ImageFileHolder, isWrongYear, minimumDateTime, item.RelativePath, resizedFileHolder);
return result;
}
@ -53,15 +55,15 @@ public class MappingFromLocation : Properties.IMappingFromLocation
public int AreaPermille { init; get; }
public int ConfidencePercent { init; get; }
public string DeterministicHashCodeKey { init; get; }
public int NormalizedPixelPercentage { init; get; }
public int NormalizedRectangle { init; get; }
[JsonConstructor]
public MappingFromLocation(int areaPermille, int confidencePercent, string deterministicHashCodeKey, int normalizedPixelPercentage)
public MappingFromLocation(int areaPermille, int confidencePercent, string deterministicHashCodeKey, int normalizedRectangle)
{
AreaPermille = areaPermille;
ConfidencePercent = confidencePercent;
DeterministicHashCodeKey = deterministicHashCodeKey;
NormalizedPixelPercentage = normalizedPixelPercentage;
NormalizedRectangle = normalizedRectangle;
}
public override string ToString()
@ -102,17 +104,20 @@ public class Mapping : Properties.IMapping
protected int? _By;
protected MappingFromPerson? _MappingFromPerson;
public string? _SegmentC;
protected SortingContainer? _SortingContainer;
public int? By => _By;
public MappingFromItem MappingFromItem { init; get; }
public MappingFromLocation MappingFromLocation { init; get; }
public MappingFromPerson? MappingFromPerson => _MappingFromPerson;
public string? SegmentC => _SegmentC;
public SortingContainer? SortingContainer => _SortingContainer;
[JsonConstructor]
public Mapping(int? by, MappingFromItem mappingFromItem, MappingFromLocation mappingFromLocation, MappingFromPerson? mappingFromPerson, SortingContainer? sortingContainer)
public Mapping(int? by, MappingFromItem mappingFromItem, MappingFromLocation mappingFromLocation, MappingFromPerson? mappingFromPerson, string? segmentC, SortingContainer? sortingContainer)
{
_By = by;
_SegmentC = segmentC;
MappingFromItem = mappingFromItem;
MappingFromLocation = mappingFromLocation;
_MappingFromPerson = mappingFromPerson;
@ -120,7 +125,7 @@ public class Mapping : Properties.IMapping
}
public Mapping(MappingFromItem mappingFromItem, MappingFromLocation mappingFromLocation) :
this(null, mappingFromItem, mappingFromLocation, null, null)
this(null, mappingFromItem, mappingFromLocation, null, null, null)
{ }
public override string ToString()
@ -142,9 +147,10 @@ public class Mapping : Properties.IMapping
_MappingFromPerson = new(approximateYears, displayDirectoryName, personBirthday, segmentB);
}
public void UpdateMappingFromPerson(int? approximateYears, int? by, string displayDirectoryName, PersonBirthday personBirthday, string segmentB, SortingContainer sortingContainer)
public void UpdateMappingFromPerson(int? approximateYears, int? by, string displayDirectoryName, PersonBirthday personBirthday, string segmentB, string segmentC, SortingContainer sortingContainer)
{
_By = by;
_SegmentC = segmentC;
_SortingContainer = sortingContainer;
_MappingFromPerson = new(approximateYears, displayDirectoryName, personBirthday, segmentB);
}

30
Shared/Models/Marker.cs Normal file
View File

@ -0,0 +1,30 @@
using System.Text.Json.Serialization;
namespace View_by_Distance.Shared.Models;
public record Marker(
[property: JsonPropertyName("marker_uid")] string MarkerUid,
[property: JsonPropertyName("file_uid")] string FileUid,
[property: JsonPropertyName("marker_type")] string MarkerType,
[property: JsonPropertyName("marker_src")] string MarkerSrc,
[property: JsonPropertyName("marker_name")] string MarkerName,
[property: JsonPropertyName("marker_review")] int MarkerReview,
[property: JsonPropertyName("marker_invalid")] int MarkerInvalid,
[property: JsonPropertyName("subj_uid")] string SubjUid,
[property: JsonPropertyName("subj_src")] string SubjSrc,
[property: JsonPropertyName("face_id")] string FaceId,
[property: JsonPropertyName("face_dist")] double FaceDist,
[property: JsonPropertyName("embeddings_json")] string EmbeddingsJson,
[property: JsonPropertyName("landmarks_json")] string LandmarksJson,
[property: JsonPropertyName("x")] double X,
[property: JsonPropertyName("y")] double Y,
[property: JsonPropertyName("w")] double W,
[property: JsonPropertyName("h")] double H,
[property: JsonPropertyName("q")] int Q,
[property: JsonPropertyName("size")] int Size,
[property: JsonPropertyName("score")] int Score,
[property: JsonPropertyName("thumb")] string Thumb,
[property: JsonPropertyName("matched_at")] string MatchedAt,
[property: JsonPropertyName("created_at")] string CreatedAt,
[property: JsonPropertyName("updated_at")] string UpdatedAt
);

View File

@ -0,0 +1,36 @@
namespace View_by_Distance.Shared.Models;
public record MarkerWith(
string MarkerUid,
string FileUid,
string MarkerType,
string MarkerSrc,
string MarkerName,
int MarkerReview,
int MarkerInvalid,
string SubjUid,
string SubjSrc,
string FaceId,
double FaceDist,
string EmbeddingsJson,
string LandmarksJson,
double X,
double Y,
double W,
double H,
int Q,
int Size,
int Score,
string Thumb,
string MatchedAt,
string CreatedAt,
string UpdatedAt,
int FileId,
string FileName,
int? DlibId,
int? Count,
double? Percent,
int? NormalizedRectangle,
long? PersonKey,
string PersonKeyFormatted
);

View File

@ -9,6 +9,6 @@ public interface IFaceDistance
public bool? IsWrongYear { init; get; }
public double? Length { init; get; }
public DateTime? MinimumDateTime { init; get; }
public int? NormalizedPixelPercentage { init; get; }
public int? NormalizedRectangle { init; get; }
}

View File

@ -12,7 +12,7 @@ public interface IItem
public Property? Property { get; }
public string RelativePath { get; }
public FileHolder? ResizedFileHolder { get; }
public string SourceDirectoryFile { get; }
public FileHolder SourceDirectoryFileHolder { get; }
public bool ValidImageFormatExtension { get; }
}

View File

@ -3,6 +3,7 @@ namespace View_by_Distance.Shared.Models.Properties;
public interface IMappingFromItem
{
public DateTime[] ContainerDateTimes { init; get; }
public int Id { init; get; }
public FileHolder ImageFileHolder { init; get; }
public bool? IsWrongYear { init; get; }
@ -18,7 +19,7 @@ public interface IMappingFromLocation
public int AreaPermille { init; get; }
public int ConfidencePercent { init; get; }
public string DeterministicHashCodeKey { init; get; }
public int NormalizedPixelPercentage { init; get; }
public int NormalizedRectangle { init; get; }
}
@ -36,6 +37,7 @@ public interface IMapping
{
public int? By { get; }
public string? SegmentC { get; }
public MappingFromItem MappingFromItem { init; get; }
public MappingFromLocation MappingFromLocation { init; get; }
public MappingFromPerson? MappingFromPerson { get; }

View File

@ -12,7 +12,6 @@ public interface IProperty
public DateTime? GPSDateStamp { get; }
public int? Height { get; }
public int? Id { get; }
public int[] Indices { get; }
public DateTime LastWriteTime { get; }
public string Make { get; }
public string Model { get; }

View File

@ -4,16 +4,17 @@ public interface IPropertyConfiguration
{
public string DateGroup { init; get; }
public string? ModelName { get; }
public int? NumberOfJitters { get; }
public int? NumberOfTimesToUpsample { get; }
public string? PredictorModelName { get; }
public string[] IgnoreExtensions { init; get; }
public string[] PropertyContentCollectionFiles { init; get; }
public string ResultAllInOne { init; get; }
public string ResultCollection { init; get; }
public string ResultContent { init; get; }
public string ResultSingleton { init; get; }
public string RootDirectory { get; }
public string[] VerifyToSeason { init; get; }
public string? ModelName { get; }
public int? NumberOfJitters { get; }
public int? NumberOfTimesToUpsample { get; }
public string? PredictorModelName { get; }
public string RootDirectory { get; }
}

View File

@ -0,0 +1,12 @@
namespace View_by_Distance.Shared.Models.Properties;
public interface IRelativeLocation
{
public double Confidence { init; get; }
public string Height { init; get; }
public string Left { init; get; }
public string Top { init; get; }
public string Width { init; get; }
}

View File

@ -6,7 +6,7 @@ public interface ISorting
public int DaysDelta { init; get; }
public int DistancePermyriad { init; get; }
public int Id { init; get; }
public int NormalizedPixelPercentage { init; get; }
public int NormalizedRectangle { init; get; }
public int WithinRange { init; get; }
}

Some files were not shown because too many files have changed in this diff Show More