13 Commits

Author SHA1 Message Date
f914fd3577 Tif support 2024-08-31 07:32:45 -07:00
9ebfdc8af2 Reuse count over t
FilePath over String
Support first run better
Bump
2024-07-20 10:48:26 -07:00
5b9e748ba4 FileAttributes.Hidden
Nuget Bump
2024-07-13 10:05:31 -07:00
9c253786a9 Prep for item.FilePath.HasIgnoreKeyword, item.FilePath.HasDateTimeOriginal 2024-06-17 21:41:15 -07:00
86b13dc00f Fix the errors 2024-05-27 10:05:37 -07:00
665fb8ec06 GetOneOnly 2024-05-27 09:14:59 -07:00
365df1158a Format 2024-05-27 00:04:14 -07:00
dca487deb3 MapFaceFileLogic
Author:
2024-05-26 23:37:26 -07:00
7f8b09e66c ReSaveFace
Removed GetLocationContainers
Split SetCreationTime and MoveToDecade
GetFilteredDistinctFileNameFirstSegments instead of GetFilteredDistinctIds for some
void Tick();
FaceFile
2024-05-25 23:05:37 -07:00
9a772f8dcc Opposite logic 2024-05-18 22:56:13 -07:00
99e3f29720 IsOffsetDeterministicHashCode 2024-05-13 16:59:22 -07:00
bf2d6849b3 c9dbce3b
.editorconfig
JSON002
Private
IDE0230
Use Immich assets for random
2024-05-12 14:57:03 -07:00
c9dbce3b57 IEnumerable
Filtered => ValidImage
GetMappings =>
if (face.FaceEncoding is null || face.Location is null || face.OutputResolution is null)
PreFilter skip done
Removed sort
Better names
break out
RootAmazon
FilteredOriginalImage
DeleteContinueFiles
AppSetting PreVerify
Settings
Tasks
2024-04-28 17:30:55 -07:00
130 changed files with 1126 additions and 1673 deletions

80
.vscode/launch.json vendored
View File

@ -10,8 +10,8 @@
"name": "Compare", "name": "Compare",
"type": "coreclr", "type": "coreclr",
"request": "launch", "request": "launch",
"preLaunchTask": "buildSolution", "preLaunchTask": "build",
"program": "${workspaceFolder}/Compare/bin/Debug/net9.0/win-x64/Compare.dll", "program": "${workspaceFolder}/Compare/bin/Debug/net8.0/win-x64/Compare.dll",
"args": [ "args": [
"s" "s"
], ],
@ -27,8 +27,8 @@
"name": "Copy-Distinct", "name": "Copy-Distinct",
"type": "coreclr", "type": "coreclr",
"request": "launch", "request": "launch",
"preLaunchTask": "buildSolution", "preLaunchTask": "build",
"program": "${workspaceFolder}/Copy-Distinct/bin/Debug/net9.0/win-x64/Copy-Distinct.dll", "program": "${workspaceFolder}/Copy-Distinct/bin/Debug/net8.0/win-x64/Copy-Distinct.dll",
"args": [], "args": [],
"env": { "env": {
"ASPNETCORE_ENVIRONMENT": "Development" "ASPNETCORE_ENVIRONMENT": "Development"
@ -42,8 +42,8 @@
"name": "Duplicate-Search", "name": "Duplicate-Search",
"type": "coreclr", "type": "coreclr",
"request": "launch", "request": "launch",
"preLaunchTask": "buildSolution", "preLaunchTask": "build",
"program": "${workspaceFolder}/Duplicate-Search/bin/Debug/net9.0/win-x64/Duplicate-Search.dll", "program": "${workspaceFolder}/Duplicate-Search/bin/Debug/net8.0/win-x64/Duplicate-Search.dll",
"args": [ "args": [
"s" "s"
], ],
@ -59,8 +59,8 @@
"name": "Date-Group", "name": "Date-Group",
"type": "coreclr", "type": "coreclr",
"request": "launch", "request": "launch",
"preLaunchTask": "buildSolution", "preLaunchTask": "build",
"program": "${workspaceFolder}/Date-Group/bin/Debug/net9.0/win-x64/Date-Group.dll", "program": "${workspaceFolder}/Date-Group/bin/Debug/net8.0/win-x64/Date-Group.dll",
"args": [ "args": [
"s" "s"
], ],
@ -76,8 +76,8 @@
"name": "Delete-By-Distinct", "name": "Delete-By-Distinct",
"type": "coreclr", "type": "coreclr",
"request": "launch", "request": "launch",
"preLaunchTask": "buildSolution", "preLaunchTask": "build",
"program": "${workspaceFolder}/Delete-By-Distinct/bin/Debug/net9.0/win-x64/Delete-By-Distinct.dll", "program": "${workspaceFolder}/Delete-By-Distinct/bin/Debug/net8.0/win-x64/Delete-By-Distinct.dll",
"args": [ "args": [
"s" "s"
], ],
@ -93,8 +93,8 @@
"name": "Delete-By-Relative", "name": "Delete-By-Relative",
"type": "coreclr", "type": "coreclr",
"request": "launch", "request": "launch",
"preLaunchTask": "buildSolution", "preLaunchTask": "build",
"program": "${workspaceFolder}/Delete-By-Relative/bin/Debug/net9.0/win-x64/Delete-By-Relative.dll", "program": "${workspaceFolder}/Delete-By-Relative/bin/Debug/net8.0/win-x64/Delete-By-Relative.dll",
"args": [ "args": [
"s" "s"
], ],
@ -110,8 +110,8 @@
"name": "Drag-Drop", "name": "Drag-Drop",
"type": "coreclr", "type": "coreclr",
"request": "launch", "request": "launch",
"preLaunchTask": "buildSolution", "preLaunchTask": "build",
"program": "${workspaceFolder}/Drag-Drop/bin/Debug/net9.0-windows/win-x64/Drag-Drop.dll", "program": "${workspaceFolder}/Drag-Drop/bin/Debug/net8.0-windows/win-x64/Drag-Drop.dll",
"args": [ "args": [
"s" "s"
], ],
@ -127,8 +127,8 @@
"name": "Drag-Drop-Explorer", "name": "Drag-Drop-Explorer",
"type": "coreclr", "type": "coreclr",
"request": "launch", "request": "launch",
"preLaunchTask": "buildSolution", "preLaunchTask": "build",
"program": "${workspaceFolder}/Drag-Drop-Explorer/bin/Debug/net9.0-windows/win-x64/Drag-Drop-Explorer.dll", "program": "${workspaceFolder}/Drag-Drop-Explorer/bin/Debug/net8.0-windows/win-x64/Drag-Drop-Explorer.dll",
"args": [ "args": [
"s" "s"
], ],
@ -144,8 +144,8 @@
"name": "Drag-Drop-Move", "name": "Drag-Drop-Move",
"type": "coreclr", "type": "coreclr",
"request": "launch", "request": "launch",
"preLaunchTask": "buildSolution", "preLaunchTask": "build",
"program": "${workspaceFolder}/Drag-Drop-Move/bin/Debug/net9.0-windows/win-x64/Drag-Drop-Move.dll", "program": "${workspaceFolder}/Drag-Drop-Move/bin/Debug/net8.0-windows/win-x64/Drag-Drop-Move.dll",
"args": [ "args": [
"s" "s"
], ],
@ -161,8 +161,8 @@
"name": "Drag-Drop-Set-Property-Item", "name": "Drag-Drop-Set-Property-Item",
"type": "coreclr", "type": "coreclr",
"request": "launch", "request": "launch",
"preLaunchTask": "buildSolution", "preLaunchTask": "build",
"program": "${workspaceFolder}/Drag-Drop-Set-Property-Item/bin/Debug/net9.0-windows/win-x64/Drag-Drop-Set-Property-Item.dll", "program": "${workspaceFolder}/Drag-Drop-Set-Property-Item/bin/Debug/net8.0-windows/win-x64/Drag-Drop-Set-Property-Item.dll",
"args": [ "args": [
"s" "s"
], ],
@ -178,8 +178,8 @@
"name": "Instance", "name": "Instance",
"type": "coreclr", "type": "coreclr",
"request": "launch", "request": "launch",
"preLaunchTask": "buildInstance", "preLaunchTask": "build",
"program": "${workspaceFolder}/Instance/bin/Debug/net9.0/win-x64/Instance.dll", "program": "${workspaceFolder}/Instance/bin/Debug/net8.0/win-x64/Instance.dll",
"args": [ "args": [
"s" "s"
], ],
@ -195,8 +195,8 @@
"name": "Mirror-Length", "name": "Mirror-Length",
"type": "coreclr", "type": "coreclr",
"request": "launch", "request": "launch",
"preLaunchTask": "buildSolution", "preLaunchTask": "build",
"program": "${workspaceFolder}/Mirror-Length/bin/Debug/net9.0/win-x64/Mirror-Length.dll", "program": "${workspaceFolder}/Mirror-Length/bin/Debug/net8.0/win-x64/Mirror-Length.dll",
"args": [], "args": [],
"env": { "env": {
"ASPNETCORE_ENVIRONMENT": "Development" "ASPNETCORE_ENVIRONMENT": "Development"
@ -210,8 +210,8 @@
"name": "Metadata-Query", "name": "Metadata-Query",
"type": "coreclr", "type": "coreclr",
"request": "launch", "request": "launch",
"preLaunchTask": "buildSolution", "preLaunchTask": "build",
"program": "${workspaceFolder}/Metadata-Query/bin/Debug/net9.0/win-x64/Metadata-Query.dll", "program": "${workspaceFolder}/Metadata-Query/bin/Debug/net8.0/win-x64/Metadata-Query.dll",
"args": [ "args": [
"s" "s"
], ],
@ -227,8 +227,8 @@
"name": "Move-By-Id", "name": "Move-By-Id",
"type": "coreclr", "type": "coreclr",
"request": "launch", "request": "launch",
"preLaunchTask": "buildSolution", "preLaunchTask": "build",
"program": "${workspaceFolder}/Move-By-Id/bin/Debug/net9.0/win-x64/Move-By-Id.dll", "program": "${workspaceFolder}/Move-By-Id/bin/Debug/net8.0/win-x64/Move-By-Id.dll",
"args": [ "args": [
"s" "s"
], ],
@ -244,8 +244,8 @@
"name": "Not-Copy-Copy", "name": "Not-Copy-Copy",
"type": "coreclr", "type": "coreclr",
"request": "launch", "request": "launch",
"preLaunchTask": "buildSolution", "preLaunchTask": "build",
"program": "${workspaceFolder}/Not-Copy-Copy/bin/Debug/net9.0/win-x64/Not-Copy-Copy.dll", "program": "${workspaceFolder}/Not-Copy-Copy/bin/Debug/net8.0/win-x64/Not-Copy-Copy.dll",
"args": [ "args": [
"s" "s"
], ],
@ -261,8 +261,8 @@
"name": "Offset-Date-Time-Original", "name": "Offset-Date-Time-Original",
"type": "coreclr", "type": "coreclr",
"request": "launch", "request": "launch",
"preLaunchTask": "buildSolution", "preLaunchTask": "build",
"program": "${workspaceFolder}/Offset-Date-Time-Original/bin/Debug/net9.0/win-x64/Offset-Date-Time-Original.dll", "program": "${workspaceFolder}/Offset-Date-Time-Original/bin/Debug/net8.0/win-x64/Offset-Date-Time-Original.dll",
"args": [ "args": [
"s" "s"
], ],
@ -278,8 +278,8 @@
"name": "PrepareForOld", "name": "PrepareForOld",
"type": "coreclr", "type": "coreclr",
"request": "launch", "request": "launch",
"preLaunchTask": "buildSolution", "preLaunchTask": "build",
"program": "${workspaceFolder}/PrepareForOld/bin/Debug/net9.0/win-x64/PrepareForOld.dll", "program": "${workspaceFolder}/PrepareForOld/bin/Debug/net8.0/win-x64/PrepareForOld.dll",
"args": [ "args": [
"s" "s"
], ],
@ -295,8 +295,8 @@
"name": "Person", "name": "Person",
"type": "coreclr", "type": "coreclr",
"request": "launch", "request": "launch",
"preLaunchTask": "buildSolution", "preLaunchTask": "build",
"program": "${workspaceFolder}/Person/bin/Debug/net9.0/Person.dll", "program": "${workspaceFolder}/Person/bin/Debug/net8.0/Person.dll",
"args": [ "args": [
"s" "s"
], ],
@ -312,8 +312,8 @@
"name": "Rename", "name": "Rename",
"type": "coreclr", "type": "coreclr",
"request": "launch", "request": "launch",
"preLaunchTask": "buildSolution", "preLaunchTask": "build",
"program": "${workspaceFolder}/Rename/bin/Debug/net9.0/win-x64/Rename.dll", "program": "${workspaceFolder}/Rename/bin/Debug/net8.0/win-x64/Rename.dll",
"args": [ "args": [
"s" "s"
], ],
@ -329,8 +329,8 @@
"name": "Set-Created-Date", "name": "Set-Created-Date",
"type": "coreclr", "type": "coreclr",
"request": "launch", "request": "launch",
"preLaunchTask": "buildSolution", "preLaunchTask": "build",
"program": "${workspaceFolder}/Set-Created-Date/bin/Debug/net9.0/win-x64/Set-Created-Date.dll", "program": "${workspaceFolder}/Set-Created-Date/bin/Debug/net8.0/win-x64/Set-Created-Date.dll",
"args": [ "args": [
"s" "s"
], ],

5
.vscode/mklink.md vendored
View File

@ -13,8 +13,3 @@ mklink /J "D:\1-Images-A\Images-4083e56a-Results\A2)People\4083e56a\{}\!" "D:\1-
```bash ```bash
mklink /J "L:\Git\View-by-Distance-MKLink-Console\.Immich" "D:\1-Images-A\Images-c9dbce3b-Results\F)Immich\c9dbce3b\{}" mklink /J "L:\Git\View-by-Distance-MKLink-Console\.Immich" "D:\1-Images-A\Images-c9dbce3b-Results\F)Immich\c9dbce3b\{}"
``` ```
```bash 1740946894364 = 638765436943640000 = 2025-0.Winter = Sun Mar 02 2025 13:21:33 GMT-0700 (Mountain Standard Time)
mklink /J "V:\Tmp\Phares\Pictures-Results" "V:\6-Other-Large-Z\Current-Results-Test"
mklink /J "V:\1-Images-A\Images-0b793904-Results" "V:\6-Other-Large-Z\Current-Results"
```

View File

@ -23,9 +23,6 @@
"Immich", "Immich",
"jfif", "jfif",
"JOSN", "JOSN",
"makernote",
"Makernote",
"Makernotes",
"mmod", "mmod",
"Nicéphore", "Nicéphore",
"Niépce", "Niépce",
@ -35,8 +32,6 @@
"permyriad", "permyriad",
"Phares", "Phares",
"Phgtv", "Phgtv",
"photoshop",
"Photoshop",
"RDHC", "RDHC",
"Rects", "Rects",
"resnet", "resnet",

38
.vscode/tasks.json vendored
View File

@ -53,7 +53,7 @@
"problemMatcher": "$msCompile" "problemMatcher": "$msCompile"
}, },
{ {
"label": "buildSolution", "label": "build",
"command": "dotnet", "command": "dotnet",
"type": "process", "type": "process",
"args": [ "args": [
@ -63,42 +63,6 @@
"/consoleloggerparameters:NoSummary" "/consoleloggerparameters:NoSummary"
], ],
"problemMatcher": "$msCompile" "problemMatcher": "$msCompile"
},
{
"label": "buildInstance",
"command": "dotnet",
"type": "process",
"args": [
"build",
"${workspaceFolder}/Instance/Instance.csproj",
"/property:GenerateFullPaths=true",
"/consoleloggerparameters:NoSummary"
],
"problemMatcher": "$msCompile"
},
{
"label": "buildShared",
"command": "dotnet",
"type": "process",
"args": [
"build",
"${workspaceFolder}/Shared/View-by-Distance.Shared.csproj",
"/property:GenerateFullPaths=true",
"/consoleloggerparameters:NoSummary"
],
"problemMatcher": "$msCompile"
},
{
"label": "buildMetadata",
"command": "dotnet",
"type": "process",
"args": [
"build",
"${workspaceFolder}/Metadata/Metadata.csproj",
"/property:GenerateFullPaths=true",
"/consoleloggerparameters:NoSummary"
],
"problemMatcher": "$msCompile"
} }
] ]
} }

View File

@ -4,7 +4,7 @@
<Nullable>enable</Nullable> <Nullable>enable</Nullable>
<OutputType>library</OutputType> <OutputType>library</OutputType>
<RuntimeIdentifier>win-x64</RuntimeIdentifier> <RuntimeIdentifier>win-x64</RuntimeIdentifier>
<TargetFramework>net9.0</TargetFramework> <TargetFramework>net8.0</TargetFramework>
</PropertyGroup> </PropertyGroup>
<PropertyGroup> <PropertyGroup>
<PackageId>BlurHash.Core</PackageId> <PackageId>BlurHash.Core</PackageId>
@ -18,6 +18,6 @@
<PackageLicenseExpression>MIT</PackageLicenseExpression> <PackageLicenseExpression>MIT</PackageLicenseExpression>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="System.Memory" Version="4.6.0" /> <PackageReference Include="System.Memory" Version="4.5.5" />
</ItemGroup> </ItemGroup>
</Project> </Project>

View File

@ -4,7 +4,7 @@
<Nullable>enable</Nullable> <Nullable>enable</Nullable>
<OutputType>library</OutputType> <OutputType>library</OutputType>
<RuntimeIdentifier>win-x64</RuntimeIdentifier> <RuntimeIdentifier>win-x64</RuntimeIdentifier>
<TargetFramework>net9.0</TargetFramework> <TargetFramework>net8.0</TargetFramework>
</PropertyGroup> </PropertyGroup>
<PropertyGroup> <PropertyGroup>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks> <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
@ -24,6 +24,6 @@
<ProjectReference Include="..\BlurHash.Core\BlurHash.Core.csproj" /> <ProjectReference Include="..\BlurHash.Core\BlurHash.Core.csproj" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="System.Drawing.Common" Version="8.0.10" /> <PackageReference Include="System.Drawing.Common" Version="8.0.7" />
</ItemGroup> </ItemGroup>
</Project> </Project>

View File

@ -4,12 +4,12 @@
<Nullable>enable</Nullable> <Nullable>enable</Nullable>
<OutputType>library</OutputType> <OutputType>library</OutputType>
<RuntimeIdentifier>win-x64</RuntimeIdentifier> <RuntimeIdentifier>win-x64</RuntimeIdentifier>
<TargetFramework>net9.0</TargetFramework> <TargetFramework>net8.0</TargetFramework>
</PropertyGroup> </PropertyGroup>
<PropertyGroup> <PropertyGroup>
<PackageId>Phares.View.by.Distance.BlurHash</PackageId> <PackageId>Phares.View.by.Distance.BlurHash</PackageId>
<GeneratePackageOnBuild>false</GeneratePackageOnBuild> <GeneratePackageOnBuild>false</GeneratePackageOnBuild>
<Version>9.0.100.1</Version> <Version>8.0.101.1</Version>
<Authors>Mike Phares</Authors> <Authors>Mike Phares</Authors>
<Company>Phares</Company> <Company>Phares</Company>
<IncludeSymbols>true</IncludeSymbols> <IncludeSymbols>true</IncludeSymbols>
@ -33,8 +33,8 @@
<SupportedPlatform Include="browser" /> <SupportedPlatform Include="browser" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="System.Drawing.Common" Version="8.0.10" /> <PackageReference Include="System.Drawing.Common" Version="8.0.7" />
<PackageReference Include="System.Text.Json" Version="9.0.2" /> <PackageReference Include="System.Text.Json" Version="8.0.4" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\Shared\View-by-Distance.Shared.csproj" /> <ProjectReference Include="..\Shared\View-by-Distance.Shared.csproj" />

View File

@ -10,29 +10,21 @@ namespace View_by_Distance.BlurHash.Models;
public class C2_BlurHasher : IBlurHasher public class C2_BlurHasher : IBlurHasher
{ {
private readonly Dictionary<string, string[]> _FileGroups;
private readonly IPropertyConfiguration _PropertyConfiguration; private readonly IPropertyConfiguration _PropertyConfiguration;
private readonly ReadOnlyDictionary<byte, ReadOnlyCollection<string>>[] _ResultContentFileGroups;
private readonly ReadOnlyDictionary<byte, ReadOnlyCollection<string>>[] _ResultSingletonFileGroups;
public C2_BlurHasher(IPropertyConfiguration propertyConfiguration) public C2_BlurHasher(IPropertyConfiguration propertyConfiguration)
{ {
_FileGroups = [];
_PropertyConfiguration = propertyConfiguration; _PropertyConfiguration = propertyConfiguration;
_ResultContentFileGroups = [new(new Dictionary<byte, ReadOnlyCollection<string>>())];
_ResultSingletonFileGroups = [new(new Dictionary<byte, ReadOnlyCollection<string>>())];
} }
public void Update(string resultsFullGroupDirectory) public void Update(string resultsFullGroupDirectory)
{ {
ReadOnlyDictionary<string, ReadOnlyDictionary<byte, ReadOnlyCollection<string>>> keyValuePairs = Shared.Models.Stateless.Methods.IPath.GetKeyValuePairs(_PropertyConfiguration, resultsFullGroupDirectory, [_PropertyConfiguration.ResultContent, _PropertyConfiguration.ResultSingleton]); _FileGroups.Clear();
foreach (KeyValuePair<string, ReadOnlyDictionary<byte, ReadOnlyCollection<string>>> keyValuePair in keyValuePairs) ReadOnlyDictionary<string, string[]> keyValuePairs = Shared.Models.Stateless.Methods.IPath.GetKeyValuePairs(_PropertyConfiguration, resultsFullGroupDirectory, [_PropertyConfiguration.ResultContent, _PropertyConfiguration.ResultSingleton]);
{ foreach (KeyValuePair<string, string[]> keyValuePair in keyValuePairs)
if (keyValuePair.Key == _PropertyConfiguration.ResultContent) _FileGroups.Add(keyValuePair.Key, keyValuePair.Value);
_ResultContentFileGroups[0] = keyValuePair.Value;
else if (keyValuePair.Key == _PropertyConfiguration.ResultSingleton)
_ResultSingletonFileGroups[0] = keyValuePair.Value;
else
throw new Exception();
}
} }
string IBlurHasher.Encode(FileHolder fileHolder) string IBlurHasher.Encode(FileHolder fileHolder)
@ -48,39 +40,20 @@ public class C2_BlurHasher : IBlurHasher
return result; return result;
} }
private static void MoveIf(string fileName, CombinedEnumAndIndex cei, string directory, string fullFileName)
{
string[] segments = directory.Split(cei.Combined);
string? checkDirectory = segments.Length == 1 ?
Path.Combine(segments[0], $"{cei.Combined[2..]}") :
segments.Length == 2 ?
$"{segments[0]}{cei.Combined[2..]}{segments[1]}" :
null;
if (checkDirectory is not null && Directory.Exists(checkDirectory))
{
string checkFile = Path.Combine(checkDirectory, fileName);
if (File.Exists(checkFile))
File.Move(checkFile, fullFileName);
}
}
string IBlurHasher.GetFile(FilePath filePath) string IBlurHasher.GetFile(FilePath filePath)
{ {
string result; string result;
if (_ResultSingletonFileGroups[0].Count == 0) if (_FileGroups.Count == 0)
throw new Exception("Call Update first!"); throw new Exception("Call Update first!");
string fileName = $"{filePath.Name}.csv"; (_, int directoryIndex) = Shared.Models.Stateless.Methods.IPath.GetDirectoryNameAndIndex(_PropertyConfiguration, filePath);
CombinedEnumAndIndex cei = Shared.Models.Stateless.Methods.IPath.GetCombinedEnumAndIndex(_PropertyConfiguration, filePath); result = Path.Combine(_FileGroups[_PropertyConfiguration.ResultSingleton][directoryIndex], $"{filePath.Name}.csv");
string directory = _ResultSingletonFileGroups[0][cei.Enum][cei.Index];
result = Path.Combine(directory, fileName);
MoveIf(fileName, cei, directory, result);
return result; return result;
} }
string IBlurHasher.EncodeAndSave(FilePath filePath, FileHolder fileHolder) string IBlurHasher.EncodeAndSave(FilePath filePath, FileHolder fileHolder)
{ {
string result; string result;
if (_ResultSingletonFileGroups[0].Count == 0) if (_FileGroups.Count == 0)
throw new Exception("Call Update first!"); throw new Exception("Call Update first!");
int actualByte; int actualByte;
string extension = ".png"; string extension = ".png";
@ -97,18 +70,15 @@ public class C2_BlurHasher : IBlurHasher
byte[] blurHashBytes = Encoding.UTF8.GetBytes(result); byte[] blurHashBytes = Encoding.UTF8.GetBytes(result);
string joined = string.Join(string.Empty, blurHashBytes.Select(l => l.ToString("000"))); string joined = string.Join(string.Empty, blurHashBytes.Select(l => l.ToString("000")));
string fileNameWithoutExtension = $"{componentsX}x{componentsY}-{outputWidth}x{outputHeight}-{joined}"; string fileNameWithoutExtension = $"{componentsX}x{componentsY}-{outputWidth}x{outputHeight}-{joined}";
string fileName = $"{fileNameWithoutExtension}{extension}";
string contents = string.Concat(result, Environment.NewLine, fileNameWithoutExtension, Environment.NewLine, extension); string contents = string.Concat(result, Environment.NewLine, fileNameWithoutExtension, Environment.NewLine, extension);
_ = Shared.Models.Stateless.Methods.IPath.WriteAllText(file, contents, updateDateWhenMatches: false, compareBeforeWrite: true, updateToWhenMatches: null); _ = Shared.Models.Stateless.Methods.IPath.WriteAllText(file, contents, updateDateWhenMatches: false, compareBeforeWrite: true, updateToWhenMatches: null);
CombinedEnumAndIndex cei = Shared.Models.Stateless.Methods.IPath.GetCombinedEnumAndIndex(_PropertyConfiguration, filePath); (_, int directoryIndex) = Shared.Models.Stateless.Methods.IPath.GetDirectoryNameAndIndex(_PropertyConfiguration, filePath);
string directory = _ResultContentFileGroups[0][cei.Enum][cei.Index]; file = Path.Combine(_FileGroups[_PropertyConfiguration.ResultContent][directoryIndex], $"{fileNameWithoutExtension}{extension}");
string fullFileName = Path.Combine(directory, fileName); if (!File.Exists(file))
MoveIf(fileName, cei, directory, fullFileName);
if (!File.Exists(fullFileName))
{ {
try try
{ {
using FileStream fileStream = new(fullFileName, FileMode.CreateNew); using FileStream fileStream = new(file, FileMode.CreateNew);
actualImage.Save(fileStream, System.Drawing.Imaging.ImageFormat.Png); actualImage.Save(fileStream, System.Drawing.Imaging.ImageFormat.Png);
_ = fileStream.Seek(0, SeekOrigin.Begin); _ = fileStream.Seek(0, SeekOrigin.Begin);
actualByte = fileStream.ReadByte(); actualByte = fileStream.ReadByte();

View File

@ -211,7 +211,7 @@ public class Compare
} }
_Logger?.LogInformation(". . ."); _Logger?.LogInformation(". . .");
} }
string aPropertyContentCollectionDirectory = Property.Models.Stateless.IResult.GetResultsDateGroupDirectory(propertyConfiguration, nameof(A_Property), propertyConfiguration.ResultContentCollection); string aPropertyContentCollectionDirectory = Property.Models.Stateless.IResult.GetResultsDateGroupDirectory(propertyConfiguration, nameof(A_Property), "[()]");
ThirdPassToMove(propertyConfiguration, mapLogic, propertyLogic, containers, aPropertyContentCollectionDirectory); ThirdPassToMove(propertyConfiguration, mapLogic, propertyLogic, containers, aPropertyContentCollectionDirectory);
if (!isSilent) if (!isSilent)
{ {

View File

@ -4,12 +4,12 @@
<Nullable>enable</Nullable> <Nullable>enable</Nullable>
<OutputType>Exe</OutputType> <OutputType>Exe</OutputType>
<RuntimeIdentifier>win-x64</RuntimeIdentifier> <RuntimeIdentifier>win-x64</RuntimeIdentifier>
<TargetFramework>net9.0</TargetFramework> <TargetFramework>net8.0</TargetFramework>
</PropertyGroup> </PropertyGroup>
<PropertyGroup> <PropertyGroup>
<PackageId>Phares.View.by.Distance.Compare</PackageId> <PackageId>Phares.View.by.Distance.Compare</PackageId>
<GeneratePackageOnBuild>false</GeneratePackageOnBuild> <GeneratePackageOnBuild>false</GeneratePackageOnBuild>
<Version>9.0.100.1</Version> <Version>8.0.101.1</Version>
<Authors>Mike Phares</Authors> <Authors>Mike Phares</Authors>
<Company>Phares</Company> <Company>Phares</Company>
<IncludeSymbols>true</IncludeSymbols> <IncludeSymbols>true</IncludeSymbols>
@ -33,14 +33,14 @@
<SupportedPlatform Include="browser" /> <SupportedPlatform Include="browser" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Microsoft.Extensions.Hosting" Version="9.0.2" /> <PackageReference Include="Microsoft.Extensions.Hosting" Version="8.0.0" />
<PackageReference Include="Microsoft.AspNetCore.Cryptography.KeyDerivation" Version="9.0.2" /> <PackageReference Include="Microsoft.AspNetCore.Cryptography.KeyDerivation" Version="8.0.7" />
<PackageReference Include="Microsoft.Extensions.Identity.Core" Version="9.0.2" /> <PackageReference Include="Microsoft.Extensions.Identity.Core" Version="8.0.7" />
<PackageReference Include="Microsoft.Extensions.Options" Version="9.0.2" /> <PackageReference Include="Microsoft.Extensions.Options" Version="8.0.2" />
<PackageReference Include="ShellProgressBar" Version="5.2.0" /> <PackageReference Include="ShellProgressBar" Version="5.2.0" />
<PackageReference Include="WindowsShortcutFactory" Version="1.2.0" /> <PackageReference Include="WindowsShortcutFactory" Version="1.2.0" />
<PackageReference Include="System.Drawing.Common" Version="8.0.10" /> <PackageReference Include="System.Drawing.Common" Version="8.0.7" />
<PackageReference Include="System.Text.Json" Version="9.0.2" /> <PackageReference Include="System.Text.Json" Version="8.0.4" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\Map\Map.csproj" /> <ProjectReference Include="..\Map\Map.csproj" />

View File

@ -4,13 +4,13 @@
<Nullable>enable</Nullable> <Nullable>enable</Nullable>
<OutputType>Exe</OutputType> <OutputType>Exe</OutputType>
<RuntimeIdentifier>win-x64</RuntimeIdentifier> <RuntimeIdentifier>win-x64</RuntimeIdentifier>
<TargetFramework>net9.0</TargetFramework> <TargetFramework>net8.0</TargetFramework>
<UserSecretsId>d862524f-2b48-4f47-b4c3-5a8615814ec2</UserSecretsId> <UserSecretsId>d862524f-2b48-4f47-b4c3-5a8615814ec2</UserSecretsId>
</PropertyGroup> </PropertyGroup>
<PropertyGroup> <PropertyGroup>
<PackageId>Phares.View.by.Distance.Copy.Distinct</PackageId> <PackageId>Phares.View.by.Distance.Copy.Distinct</PackageId>
<GeneratePackageOnBuild>false</GeneratePackageOnBuild> <GeneratePackageOnBuild>false</GeneratePackageOnBuild>
<Version>9.0.100.1</Version> <Version>8.0.101.1</Version>
<Authors>Mike Phares</Authors> <Authors>Mike Phares</Authors>
<Company>Phares</Company> <Company>Phares</Company>
<IncludeSymbols>true</IncludeSymbols> <IncludeSymbols>true</IncludeSymbols>
@ -35,9 +35,9 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Humanizer.Core" Version="2.14.1" /> <PackageReference Include="Humanizer.Core" Version="2.14.1" />
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="9.0.2" /> <PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.UserSecrets" Version="9.0.2" /> <PackageReference Include="Microsoft.Extensions.Configuration.UserSecrets" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.Hosting" Version="9.0.2" /> <PackageReference Include="Microsoft.Extensions.Hosting" Version="8.0.0" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\Property\Property.csproj" /> <ProjectReference Include="..\Property\Property.csproj" />

View File

@ -18,8 +18,8 @@ public class CopyDistinct
private readonly Configuration _Configuration; private readonly Configuration _Configuration;
private readonly IsEnvironment _IsEnvironment; private readonly IsEnvironment _IsEnvironment;
private readonly IConfigurationRoot _ConfigurationRoot; private readonly IConfigurationRoot _ConfigurationRoot;
private readonly ReadOnlyDictionary<string, string[]> _FileGroups;
private readonly Property.Models.Configuration _PropertyConfiguration; private readonly Property.Models.Configuration _PropertyConfiguration;
private readonly ReadOnlyDictionary<string, ReadOnlyDictionary<byte, ReadOnlyCollection<string>>> _FileGroups;
public CopyDistinct(List<string> args, ILogger<Program> logger, IsEnvironment isEnvironment, IConfigurationRoot configurationRoot, AppSettings appSettings, string workingDirectory, bool isSilent, IConsole console) public CopyDistinct(List<string> args, ILogger<Program> logger, IsEnvironment isEnvironment, IConfigurationRoot configurationRoot, AppSettings appSettings, string workingDirectory, bool isSilent, IConsole console)
{ {
@ -179,10 +179,9 @@ public class CopyDistinct
{ {
progressBar = new(count, message, options); progressBar = new(count, message, options);
string key = string.IsNullOrEmpty(_AppSettings.ResultDirectoryKey) ? _PropertyConfiguration.ResultAllInOne : _AppSettings.ResultDirectoryKey; string key = string.IsNullOrEmpty(_AppSettings.ResultDirectoryKey) ? _PropertyConfiguration.ResultAllInOne : _AppSettings.ResultDirectoryKey;
if (key != _PropertyConfiguration.ResultContent) string[] directories = _FileGroups[key];
throw new NotImplementedException("Changed but didn't update!");
ReadOnlyCollection<ReadOnlyCollection<FilePath>> filePathsCollection = IDirectory.GetFilePathCollections(_Configuration.PropertyConfiguration, filesCollection); ReadOnlyCollection<ReadOnlyCollection<FilePath>> filePathsCollection = IDirectory.GetFilePathCollections(_Configuration.PropertyConfiguration, filesCollection);
(distinctDirectories, toDoCollection) = IDirectory.GetToDoCollection(_PropertyConfiguration, _AppSettings.CopyDuplicates, _AppSettings.IfCanUseId, filePathsCollection, _FileGroups, () => progressBar.Tick()); (distinctDirectories, toDoCollection) = IDirectory.GetToDoCollection(_PropertyConfiguration, _AppSettings.CopyDuplicates, _AppSettings.IfCanUseId, filePathsCollection, directories, () => progressBar.Tick());
progressBar.Dispose(); progressBar.Dispose();
} }
foreach (string distinctDirectory in distinctDirectories) foreach (string distinctDirectory in distinctDirectories)

View File

@ -34,15 +34,17 @@ public class Configuration
} }
} }
private static Models.Configuration Get(Configuration? configuration, Property.Models.Configuration propertyConfiguration) private static Models.Configuration Get(Configuration? configuration)
{ {
Models.Configuration result; Models.Configuration result;
if (configuration is null) throw new NullReferenceException(nameof(configuration)); if (configuration is null) throw new NullReferenceException(nameof(configuration));
if (configuration.IgnoreExtensions is null) throw new NullReferenceException(nameof(configuration.IgnoreExtensions)); if (configuration.IgnoreExtensions is null) throw new NullReferenceException(nameof(configuration.IgnoreExtensions));
if (configuration.PersonBirthdayFormat is null) throw new NullReferenceException(nameof(configuration.PersonBirthdayFormat)); if (configuration.PersonBirthdayFormat is null) throw new NullReferenceException(nameof(configuration.PersonBirthdayFormat));
result = new(propertyConfiguration, if (configuration.PropertyConfiguration is null) throw new NullReferenceException(nameof(configuration.PropertyConfiguration));
configuration.IgnoreExtensions, result = new(
configuration.PersonBirthdayFormat); configuration.IgnoreExtensions,
configuration.PersonBirthdayFormat,
configuration.PropertyConfiguration);
return result; return result;
} }
@ -64,7 +66,7 @@ public class Configuration
#pragma warning restore IL3050, IL2026 #pragma warning restore IL3050, IL2026
} }
PreVerify(configurationRoot, configuration); PreVerify(configurationRoot, configuration);
result = Get(configuration, propertyConfiguration); result = Get(configuration);
return result; return result;
} }

View File

@ -13,9 +13,10 @@ public class Configuration
public Property.Models.Configuration PropertyConfiguration => _PropertyConfiguration; public Property.Models.Configuration PropertyConfiguration => _PropertyConfiguration;
[JsonConstructor] [JsonConstructor]
public Configuration(Property.Models.Configuration propertyConfiguration, public Configuration(
string[] ignoreExtensions, string[] ignoreExtensions,
string personBirthdayFormat) string personBirthdayFormat,
Property.Models.Configuration propertyConfiguration)
{ {
IgnoreExtensions = ignoreExtensions; IgnoreExtensions = ignoreExtensions;
PersonBirthdayFormat = personBirthdayFormat; PersonBirthdayFormat = personBirthdayFormat;

View File

@ -4,13 +4,13 @@
<Nullable>enable</Nullable> <Nullable>enable</Nullable>
<OutputType>Exe</OutputType> <OutputType>Exe</OutputType>
<RuntimeIdentifier>win-x64</RuntimeIdentifier> <RuntimeIdentifier>win-x64</RuntimeIdentifier>
<TargetFramework>net9.0</TargetFramework> <TargetFramework>net8.0</TargetFramework>
<UserSecretsId>8004d966-1a9e-4545-a220-83f32b6a13e9</UserSecretsId> <UserSecretsId>8004d966-1a9e-4545-a220-83f32b6a13e9</UserSecretsId>
</PropertyGroup> </PropertyGroup>
<PropertyGroup> <PropertyGroup>
<PackageId>Phares.View.by.Distance.Date.Group</PackageId> <PackageId>Phares.View.by.Distance.Date.Group</PackageId>
<GeneratePackageOnBuild>false</GeneratePackageOnBuild> <GeneratePackageOnBuild>false</GeneratePackageOnBuild>
<Version>9.0.100.1</Version> <Version>8.0.101.1</Version>
<Authors>Mike Phares</Authors> <Authors>Mike Phares</Authors>
<Company>Phares</Company> <Company>Phares</Company>
<IncludeSymbols>true</IncludeSymbols> <IncludeSymbols>true</IncludeSymbols>
@ -34,15 +34,15 @@
<SupportedPlatform Include="browser" /> <SupportedPlatform Include="browser" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Cryptography.KeyDerivation" Version="9.0.2" /> <PackageReference Include="Microsoft.AspNetCore.Cryptography.KeyDerivation" Version="8.0.7" />
<PackageReference Include="Microsoft.Extensions.Hosting" Version="9.0.2" /> <PackageReference Include="Microsoft.Extensions.Hosting" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.Identity.Core" Version="9.0.2" /> <PackageReference Include="Microsoft.Extensions.Identity.Core" Version="8.0.7" />
<PackageReference Include="Microsoft.Extensions.Options" Version="9.0.2" /> <PackageReference Include="Microsoft.Extensions.Options" Version="8.0.2" />
<PackageReference Include="MetadataExtractor" Version="2.8.1" /> <PackageReference Include="MetadataExtractor" Version="2.8.1" />
<PackageReference Include="ShellProgressBar" Version="5.2.0" /> <PackageReference Include="ShellProgressBar" Version="5.2.0" />
<PackageReference Include="WindowsShortcutFactory" Version="1.2.0" /> <PackageReference Include="WindowsShortcutFactory" Version="1.2.0" />
<PackageReference Include="System.Drawing.Common" Version="8.0.10" /> <PackageReference Include="System.Drawing.Common" Version="8.0.7" />
<PackageReference Include="System.Text.Json" Version="9.0.2" /> <PackageReference Include="System.Text.Json" Version="8.0.4" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\Shared\View-by-Distance.Shared.csproj" /> <ProjectReference Include="..\Shared\View-by-Distance.Shared.csproj" />

View File

@ -251,11 +251,11 @@ public class DateGroup
if (topDirectoryName.Length > 1) if (topDirectoryName.Length > 1)
_ = destinationDirectoryName.Append(topDirectoryName); _ = destinationDirectoryName.Append(topDirectoryName);
if (_Configuration.BySeason) if (_Configuration.BySeason)
directoryNames.AddRange([$"{destinationDirectoryName} {year} {seasonName}"]); directoryNames.AddRange(new string[] { $"{destinationDirectoryName} {year} {seasonName}" });
else if (_Configuration.ByDay) else if (_Configuration.ByDay)
directoryNames.AddRange([$"{destinationDirectoryName} {year}", $"{weekOfYear}) {year}-{day}"]); directoryNames.AddRange(new string[] { $"{destinationDirectoryName} {year}", $"{weekOfYear}) {year}-{day}" });
else if (_Configuration.ByWeek) else if (_Configuration.ByWeek)
directoryNames.AddRange([$"{destinationDirectoryName} {year}", $"{weekOfYear}) {year} {month}"]); directoryNames.AddRange(new string[] { $"{destinationDirectoryName} {year}", $"{weekOfYear}) {year} {month}" });
else else
throw new Exception(); throw new Exception();
} }
@ -422,7 +422,7 @@ public class DateGroup
{ {
try try
{ {
windowsShortcut = new() { Path = item.FilePath.DirectoryFullPath, Description = item.FilePath.Name }; windowsShortcut = new() { Path = item.FilePath.DirectoryName, Description = item.FilePath.Name };
windowsShortcut.Save(string.Concat(fullFileName, ".lnk")); windowsShortcut.Save(string.Concat(fullFileName, ".lnk"));
windowsShortcut.Dispose(); windowsShortcut.Dispose();
} }

View File

@ -4,13 +4,13 @@
<Nullable>enable</Nullable> <Nullable>enable</Nullable>
<OutputType>Exe</OutputType> <OutputType>Exe</OutputType>
<RuntimeIdentifier>win-x64</RuntimeIdentifier> <RuntimeIdentifier>win-x64</RuntimeIdentifier>
<TargetFramework>net9.0</TargetFramework> <TargetFramework>net8.0</TargetFramework>
<UserSecretsId>0589ecff-b296-48be-a3f7-7bf27f453975</UserSecretsId> <UserSecretsId>0589ecff-b296-48be-a3f7-7bf27f453975</UserSecretsId>
</PropertyGroup> </PropertyGroup>
<PropertyGroup> <PropertyGroup>
<PackageId>Phares.View.by.Distance.Delete.By.Distinct</PackageId> <PackageId>Phares.View.by.Distance.Delete.By.Distinct</PackageId>
<GeneratePackageOnBuild>false</GeneratePackageOnBuild> <GeneratePackageOnBuild>false</GeneratePackageOnBuild>
<Version>9.0.100.1</Version> <Version>8.0.101.1</Version>
<Authors>Mike Phares</Authors> <Authors>Mike Phares</Authors>
<Company>Phares</Company> <Company>Phares</Company>
<IncludeSymbols>true</IncludeSymbols> <IncludeSymbols>true</IncludeSymbols>
@ -34,14 +34,14 @@
<SupportedPlatform Include="browser" /> <SupportedPlatform Include="browser" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Microsoft.Extensions.Hosting" Version="9.0.2" /> <PackageReference Include="Microsoft.Extensions.Hosting" Version="8.0.0" />
<PackageReference Include="Microsoft.AspNetCore.Cryptography.KeyDerivation" Version="9.0.2" /> <PackageReference Include="Microsoft.AspNetCore.Cryptography.KeyDerivation" Version="8.0.7" />
<PackageReference Include="Microsoft.Extensions.Identity.Core" Version="9.0.2" /> <PackageReference Include="Microsoft.Extensions.Identity.Core" Version="8.0.7" />
<PackageReference Include="Microsoft.Extensions.Options" Version="9.0.2" /> <PackageReference Include="Microsoft.Extensions.Options" Version="8.0.2" />
<PackageReference Include="ShellProgressBar" Version="5.2.0" /> <PackageReference Include="ShellProgressBar" Version="5.2.0" />
<PackageReference Include="WindowsShortcutFactory" Version="1.2.0" /> <PackageReference Include="WindowsShortcutFactory" Version="1.2.0" />
<PackageReference Include="System.Drawing.Common" Version="8.0.10" /> <PackageReference Include="System.Drawing.Common" Version="8.0.7" />
<PackageReference Include="System.Text.Json" Version="9.0.2" /> <PackageReference Include="System.Text.Json" Version="8.0.4" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\Property\Property.csproj" /> <ProjectReference Include="..\Property\Property.csproj" />

View File

@ -4,13 +4,13 @@
<Nullable>enable</Nullable> <Nullable>enable</Nullable>
<OutputType>Exe</OutputType> <OutputType>Exe</OutputType>
<RuntimeIdentifier>win-x64</RuntimeIdentifier> <RuntimeIdentifier>win-x64</RuntimeIdentifier>
<TargetFramework>net9.0</TargetFramework> <TargetFramework>net8.0</TargetFramework>
<UserSecretsId>ead2e5ee-5f40-4151-bdb6-31d630d94f28</UserSecretsId> <UserSecretsId>ead2e5ee-5f40-4151-bdb6-31d630d94f28</UserSecretsId>
</PropertyGroup> </PropertyGroup>
<PropertyGroup> <PropertyGroup>
<PackageId>Phares.View.by.Distance.Delete.By.Relative</PackageId> <PackageId>Phares.View.by.Distance.Delete.By.Relative</PackageId>
<GeneratePackageOnBuild>false</GeneratePackageOnBuild> <GeneratePackageOnBuild>false</GeneratePackageOnBuild>
<Version>9.0.100.1</Version> <Version>8.0.101.1</Version>
<Authors>Mike Phares</Authors> <Authors>Mike Phares</Authors>
<Company>Phares</Company> <Company>Phares</Company>
<IncludeSymbols>true</IncludeSymbols> <IncludeSymbols>true</IncludeSymbols>
@ -34,14 +34,14 @@
<SupportedPlatform Include="browser" /> <SupportedPlatform Include="browser" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Microsoft.Extensions.Hosting" Version="9.0.2" /> <PackageReference Include="Microsoft.Extensions.Hosting" Version="8.0.0" />
<PackageReference Include="Microsoft.AspNetCore.Cryptography.KeyDerivation" Version="9.0.2" /> <PackageReference Include="Microsoft.AspNetCore.Cryptography.KeyDerivation" Version="8.0.7" />
<PackageReference Include="Microsoft.Extensions.Identity.Core" Version="9.0.2" /> <PackageReference Include="Microsoft.Extensions.Identity.Core" Version="8.0.7" />
<PackageReference Include="Microsoft.Extensions.Options" Version="9.0.2" /> <PackageReference Include="Microsoft.Extensions.Options" Version="8.0.2" />
<PackageReference Include="ShellProgressBar" Version="5.2.0" /> <PackageReference Include="ShellProgressBar" Version="5.2.0" />
<PackageReference Include="WindowsShortcutFactory" Version="1.2.0" /> <PackageReference Include="WindowsShortcutFactory" Version="1.2.0" />
<PackageReference Include="System.Drawing.Common" Version="8.0.10" /> <PackageReference Include="System.Drawing.Common" Version="8.0.7" />
<PackageReference Include="System.Text.Json" Version="9.0.2" /> <PackageReference Include="System.Text.Json" Version="8.0.4" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\Property\Property.csproj" /> <ProjectReference Include="..\Property\Property.csproj" />

View File

@ -4,12 +4,12 @@
<Nullable>enable</Nullable> <Nullable>enable</Nullable>
<OutputType>library</OutputType> <OutputType>library</OutputType>
<RuntimeIdentifier>win-x64</RuntimeIdentifier> <RuntimeIdentifier>win-x64</RuntimeIdentifier>
<TargetFramework>net9.0</TargetFramework> <TargetFramework>net8.0</TargetFramework>
</PropertyGroup> </PropertyGroup>
<PropertyGroup> <PropertyGroup>
<PackageId>Phares.View.by.Distance.Distance</PackageId> <PackageId>Phares.View.by.Distance.Distance</PackageId>
<GeneratePackageOnBuild>false</GeneratePackageOnBuild> <GeneratePackageOnBuild>false</GeneratePackageOnBuild>
<Version>9.0.100.1</Version> <Version>8.0.101.1</Version>
<Authors>Mike Phares</Authors> <Authors>Mike Phares</Authors>
<Company>Phares</Company> <Company>Phares</Company>
<IncludeSymbols>true</IncludeSymbols> <IncludeSymbols>true</IncludeSymbols>
@ -36,7 +36,7 @@
<PackageReference Include="Humanizer.Core" Version="2.14.1" /> <PackageReference Include="Humanizer.Core" Version="2.14.1" />
<PackageReference Include="MetadataExtractor" Version="2.8.1" /> <PackageReference Include="MetadataExtractor" Version="2.8.1" />
<PackageReference Include="ShellProgressBar" Version="5.2.0" /> <PackageReference Include="ShellProgressBar" Version="5.2.0" />
<PackageReference Include="System.Text.Json" Version="9.0.2" /> <PackageReference Include="System.Text.Json" Version="8.0.4" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\FaceRecognitionDotNet\FaceRecognitionDotNet.csproj" /> <ProjectReference Include="..\FaceRecognitionDotNet\FaceRecognitionDotNet.csproj" />

View File

@ -21,7 +21,7 @@ public class DistanceLimits : IDistanceLimits
int faceDistancePermyriad, int faceDistancePermyriad,
int[] rangeDaysDeltaTolerance, int[] rangeDaysDeltaTolerance,
float[] rangeDistanceTolerance, float[] rangeDistanceTolerance,
float[] rangeFaceAreaTolerance, float[] rangeFaceAreaPermyriadTolerance,
float[] rangeFaceConfidence, float[] rangeFaceConfidence,
int sortingMaximumPerFaceShouldBeHigh, int sortingMaximumPerFaceShouldBeHigh,
int? useFiltersCounter = null) int? useFiltersCounter = null)
@ -33,7 +33,7 @@ public class DistanceLimits : IDistanceLimits
{ {
RangeDaysDeltaTolerance = rangeDaysDeltaTolerance[1]; RangeDaysDeltaTolerance = rangeDaysDeltaTolerance[1];
FaceConfidencePercent = faceConfidencePercent * rangeFaceConfidence[1]; FaceConfidencePercent = faceConfidencePercent * rangeFaceConfidence[1];
FaceAreaPermyriad = faceAreaPermyriad * rangeFaceAreaTolerance[1]; FaceAreaPermyriad = faceAreaPermyriad * rangeFaceAreaPermyriadTolerance[1];
FaceDistancePermyriad = faceDistancePermyriad * rangeDistanceTolerance[1]; FaceDistancePermyriad = faceDistancePermyriad * rangeDistanceTolerance[1];
} }
else else
@ -41,7 +41,7 @@ public class DistanceLimits : IDistanceLimits
RangeDaysDeltaTolerance = ((rangeDaysDeltaTolerance[2] - rangeDaysDeltaTolerance[0]) * 0.01 * useFiltersCounter.Value) + rangeDaysDeltaTolerance[1]; RangeDaysDeltaTolerance = ((rangeDaysDeltaTolerance[2] - rangeDaysDeltaTolerance[0]) * 0.01 * useFiltersCounter.Value) + rangeDaysDeltaTolerance[1];
FaceConfidencePercent = faceConfidencePercent * ((rangeFaceConfidence[2] - rangeFaceConfidence[0]) * 0.01 * useFiltersCounter.Value) + rangeFaceConfidence[1]; FaceConfidencePercent = faceConfidencePercent * ((rangeFaceConfidence[2] - rangeFaceConfidence[0]) * 0.01 * useFiltersCounter.Value) + rangeFaceConfidence[1];
FaceDistancePermyriad = faceDistancePermyriad * ((rangeDistanceTolerance[2] - rangeDistanceTolerance[0]) * 0.01 * useFiltersCounter.Value) + rangeDistanceTolerance[1]; FaceDistancePermyriad = faceDistancePermyriad * ((rangeDistanceTolerance[2] - rangeDistanceTolerance[0]) * 0.01 * useFiltersCounter.Value) + rangeDistanceTolerance[1];
FaceAreaPermyriad = faceAreaPermyriad * ((rangeFaceAreaTolerance[2] - rangeFaceAreaTolerance[0]) * 0.01 * useFiltersCounter.Value) + rangeFaceAreaTolerance[1]; FaceAreaPermyriad = faceAreaPermyriad * ((rangeFaceAreaPermyriadTolerance[2] - rangeFaceAreaPermyriadTolerance[0]) * 0.01 * useFiltersCounter.Value) + rangeFaceAreaPermyriadTolerance[1];
} }
} }

View File

@ -358,7 +358,7 @@ public partial class E_Distance : IDistance
} }
results.Add(keyValuePair.Key, new(keyValuePairs)); results.Add(keyValuePair.Key, new(keyValuePairs));
} }
return results.AsReadOnly(); return new(results);
} }
public static List<LocationContainer> GetPreFilterLocationContainer(int maxDegreeOfParallelism, Configuration configuration, string focusDirectory, string focusModel, int? skipPersonWithMoreThen, long ticks, MapLogic mapLogic, long[] jLinkResolvedPersonKeys, ReadOnlyDictionary<int, ReadOnlyDictionary<int, LocationContainer>> mapped, List<LocationContainer> available) public static List<LocationContainer> GetPreFilterLocationContainer(int maxDegreeOfParallelism, Configuration configuration, string focusDirectory, string focusModel, int? skipPersonWithMoreThen, long ticks, MapLogic mapLogic, long[] jLinkResolvedPersonKeys, ReadOnlyDictionary<int, ReadOnlyDictionary<int, LocationContainer>> mapped, List<LocationContainer> available)
@ -400,7 +400,7 @@ public partial class E_Distance : IDistance
} }
if (!string.IsNullOrEmpty(focusDirectory)) if (!string.IsNullOrEmpty(focusDirectory))
{ {
if (!locationContainer.FilePath.DirectoryFullPath.Contains(focusDirectory)) if (!locationContainer.FilePath.DirectoryName.Contains(focusDirectory))
continue; continue;
} }
json = Metadata.Models.Stateless.Methods.IMetadata.GetFaceEncoding(locationContainer.ExifDirectory); json = Metadata.Models.Stateless.Methods.IMetadata.GetFaceEncoding(locationContainer.ExifDirectory);
@ -426,10 +426,11 @@ public partial class E_Distance : IDistance
continue; continue;
if (face.Mapping.MappingFromFilterPre.IsFocusRelativePath is not null && !face.Mapping.MappingFromFilterPre.IsFocusRelativePath.Value) if (face.Mapping.MappingFromFilterPre.IsFocusRelativePath is not null && !face.Mapping.MappingFromFilterPre.IsFocusRelativePath.Value)
continue; continue;
// if (!configuration.ReMap && face.Mapping.MappingFromPerson is not null) if (!configuration.ReMap && face.Mapping.MappingFromPerson is not null)
// continue; continue;
if (!configuration.ReMap && face.FaceEncoding is not null && face.FaceDistance?.Encoding is not null && face.FaceDistance.Encoding is FaceRecognitionDotNet.FaceEncoding) if (!configuration.ReMap && face.FaceEncoding is not null && face.FaceDistance?.Encoding is not null && face.FaceDistance.Encoding is FaceRecognitionDotNet.FaceEncoding)
throw new NotSupportedException($"{face.FaceEncoding} should not be null!"); // throw new NotSupportedException($"{face.FaceEncoding} should not be null!");
continue;
faces.Add(face); faces.Add(face);
} }
int totalSeconds = (int)Math.Floor(new TimeSpan(DateTime.Now.Ticks - ticks).TotalSeconds); int totalSeconds = (int)Math.Floor(new TimeSpan(DateTime.Now.Ticks - ticks).TotalSeconds);
@ -509,7 +510,7 @@ public partial class E_Distance : IDistance
faceDistanceContainer = new(face, faceDistance); faceDistanceContainer = new(face, faceDistance);
collection.Add(faceDistanceContainer); collection.Add(faceDistanceContainer);
} }
results = collection.AsReadOnly(); results = new(collection.ToArray());
return results; return results;
} }
@ -568,7 +569,7 @@ public partial class E_Distance : IDistance
foreach (KeyValuePair<int, LocationContainer> keyValue in keyValuePair.Value) foreach (KeyValuePair<int, LocationContainer> keyValue in keyValuePair.Value)
results.Add(keyValue.Value); results.Add(keyValue.Value);
} }
return results.AsReadOnly(); return new(results);
} }
public static ReadOnlyCollection<LocationContainer> GetMatrixLocationContainers(IDlibDotNet dlibDotNet, Configuration mapConfiguration, long ticks, MapLogic mapLogic, ReadOnlyDictionary<int, ReadOnlyDictionary<int, LocationContainer>> mappedWithEncoding, List<LocationContainer> preFiltered, DistanceLimits distanceLimits, List<LocationContainer> postFiltered) public static ReadOnlyCollection<LocationContainer> GetMatrixLocationContainers(IDlibDotNet dlibDotNet, Configuration mapConfiguration, long ticks, MapLogic mapLogic, ReadOnlyDictionary<int, ReadOnlyDictionary<int, LocationContainer>> mappedWithEncoding, List<LocationContainer> preFiltered, DistanceLimits distanceLimits, List<LocationContainer> postFiltered)
@ -624,7 +625,7 @@ public partial class E_Distance : IDistance
results = ISortingContainer.Sort(results); results = ISortingContainer.Sort(results);
else else
results = ISortingContainer.SortUsingDaysDelta(results); results = ISortingContainer.SortUsingDaysDelta(results);
return results.AsReadOnly(); return new(results);
} }
private static ReadOnlyCollection<RelationContainer> GetRelationCollections(IDistanceLimits distanceLimits, int faceDistancePermyriad, int locationContainerDistanceTake, float distanceTolerance, List<Record> records) private static ReadOnlyCollection<RelationContainer> GetRelationCollections(IDistanceLimits distanceLimits, int faceDistancePermyriad, int locationContainerDistanceTake, float distanceTolerance, List<Record> records)
@ -672,7 +673,7 @@ public partial class E_Distance : IDistance
mappedRelations = (from l in mappedRelations orderby l.DistancePermyriad select l).Take(locationContainerDistanceTake).ToList(); mappedRelations = (from l in mappedRelations orderby l.DistancePermyriad select l).Take(locationContainerDistanceTake).ToList();
results.Add(new(fileHolder, new(mappedRelations))); results.Add(new(fileHolder, new(mappedRelations)));
} }
return results.AsReadOnly(); return new(results);
} }
ReadOnlyCollection<RelationContainer> IDistance.GetRelationContainers(IDistanceLimits distanceLimits, int faceDistancePermyriad, int locationContainerDistanceTake, float locationContainerDistanceTolerance, ReadOnlyCollection<LocationContainer> locationContainers) ReadOnlyCollection<RelationContainer> IDistance.GetRelationContainers(IDistanceLimits distanceLimits, int faceDistancePermyriad, int locationContainerDistanceTake, float locationContainerDistanceTolerance, ReadOnlyCollection<LocationContainer> locationContainers)

View File

@ -4,7 +4,7 @@
<Nullable>enable</Nullable> <Nullable>enable</Nullable>
<OutputType>WinExe</OutputType> <OutputType>WinExe</OutputType>
<RuntimeIdentifier>win-x64</RuntimeIdentifier> <RuntimeIdentifier>win-x64</RuntimeIdentifier>
<TargetFramework>net9.0-windows</TargetFramework> <TargetFramework>net8.0-windows</TargetFramework>
<UseWindowsForms>true</UseWindowsForms> <UseWindowsForms>true</UseWindowsForms>
</PropertyGroup> </PropertyGroup>
<PropertyGroup> <PropertyGroup>
@ -26,9 +26,9 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Humanizer.Core" Version="2.14.1" /> <PackageReference Include="Humanizer.Core" Version="2.14.1" />
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="9.0.2" /> <PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.UserSecrets" Version="9.0.2" /> <PackageReference Include="Microsoft.Extensions.Configuration.UserSecrets" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.Hosting" Version="9.0.2" /> <PackageReference Include="Microsoft.Extensions.Hosting" Version="8.0.0" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\Shared\View-by-Distance.Shared.csproj" /> <ProjectReference Include="..\Shared\View-by-Distance.Shared.csproj" />

View File

@ -6,8 +6,10 @@ public class Program
/// The main entry point for the application. /// The main entry point for the application.
/// </summary> /// </summary>
[STAThread] [STAThread]
private static void Main() => private static void Main()
// ApplicationConfiguration.Initialize(); {
ApplicationConfiguration.Initialize();
Application.Run(new DragDropExplorer()); Application.Run(new DragDropExplorer());
}
} }

View File

@ -4,7 +4,7 @@
<Nullable>enable</Nullable> <Nullable>enable</Nullable>
<OutputType>WinExe</OutputType> <OutputType>WinExe</OutputType>
<RuntimeIdentifier>win-x64</RuntimeIdentifier> <RuntimeIdentifier>win-x64</RuntimeIdentifier>
<TargetFramework>net9.0-windows</TargetFramework> <TargetFramework>net8.0-windows</TargetFramework>
<UseWindowsForms>true</UseWindowsForms> <UseWindowsForms>true</UseWindowsForms>
</PropertyGroup> </PropertyGroup>
<PropertyGroup> <PropertyGroup>
@ -26,9 +26,9 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Humanizer.Core" Version="2.14.1" /> <PackageReference Include="Humanizer.Core" Version="2.14.1" />
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="9.0.2" /> <PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.UserSecrets" Version="9.0.2" /> <PackageReference Include="Microsoft.Extensions.Configuration.UserSecrets" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.Hosting" Version="9.0.2" /> <PackageReference Include="Microsoft.Extensions.Hosting" Version="8.0.0" />
<PackageReference Include="WindowsShortcutFactory" Version="1.2.0" /> <PackageReference Include="WindowsShortcutFactory" Version="1.2.0" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>

View File

@ -6,8 +6,10 @@ public class Program
/// The main entry point for the application. /// The main entry point for the application.
/// </summary> /// </summary>
[STAThread] [STAThread]
private static void Main() => private static void Main()
// ApplicationConfiguration.Initialize(); {
ApplicationConfiguration.Initialize();
Application.Run(new DragDropMove()); Application.Run(new DragDropMove());
}
} }

View File

@ -4,7 +4,7 @@
<Nullable>enable</Nullable> <Nullable>enable</Nullable>
<OutputType>WinExe</OutputType> <OutputType>WinExe</OutputType>
<RuntimeIdentifier>win-x64</RuntimeIdentifier> <RuntimeIdentifier>win-x64</RuntimeIdentifier>
<TargetFramework>net9.0-windows</TargetFramework> <TargetFramework>net8.0-windows</TargetFramework>
<UseWindowsForms>true</UseWindowsForms> <UseWindowsForms>true</UseWindowsForms>
<UserSecretsId>7b153e3d-672b-4f7a-888a-cb31645a2439</UserSecretsId> <UserSecretsId>7b153e3d-672b-4f7a-888a-cb31645a2439</UserSecretsId>
</PropertyGroup> </PropertyGroup>
@ -27,9 +27,9 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Humanizer.Core" Version="2.14.1" /> <PackageReference Include="Humanizer.Core" Version="2.14.1" />
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="9.0.2" /> <PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.UserSecrets" Version="9.0.2" /> <PackageReference Include="Microsoft.Extensions.Configuration.UserSecrets" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.Hosting" Version="9.0.2" /> <PackageReference Include="Microsoft.Extensions.Hosting" Version="8.0.0" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\FaceRecognitionDotNet\FaceRecognitionDotNet.csproj" /> <ProjectReference Include="..\FaceRecognitionDotNet\FaceRecognitionDotNet.csproj" />

View File

@ -162,8 +162,8 @@ public partial class DragDropSearch : Form
{ {
Text = item.FilePath.Name; Text = item.FilePath.Name;
_TextBox.Text = item.FilePath.FullName; _TextBox.Text = item.FilePath.FullName;
if (!string.IsNullOrEmpty(item.FilePath.DirectoryFullPath)) if (!string.IsNullOrEmpty(item.FilePath.DirectoryName))
_ = Process.Start("explorer.exe", string.Concat("\"", item.FilePath.DirectoryFullPath, "\"")); _ = Process.Start("explorer.exe", string.Concat("\"", item.FilePath.DirectoryName, "\""));
} }
} }
} }

View File

@ -8,9 +8,11 @@ public class Program
/// The main entry point for the application. /// The main entry point for the application.
/// </summary> /// </summary>
[STAThread] [STAThread]
private static void Main() => private static void Main()
// ApplicationConfiguration.Initialize(); {
ApplicationConfiguration.Initialize();
Application.Run(new DragDropSearch()); Application.Run(new DragDropSearch());
}
private static Item[] GetFilterItems(Models.Configuration configuration, Container container) private static Item[] GetFilterItems(Models.Configuration configuration, Container container)
{ {

View File

@ -4,7 +4,7 @@
<Nullable>enable</Nullable> <Nullable>enable</Nullable>
<OutputType>WinExe</OutputType> <OutputType>WinExe</OutputType>
<RuntimeIdentifier>win-x64</RuntimeIdentifier> <RuntimeIdentifier>win-x64</RuntimeIdentifier>
<TargetFramework>net9.0-windows</TargetFramework> <TargetFramework>net8.0-windows</TargetFramework>
<UseWindowsForms>true</UseWindowsForms> <UseWindowsForms>true</UseWindowsForms>
<UserSecretsId>c64a15ed-0ba3-4378-8f80-0c19d0531747</UserSecretsId> <UserSecretsId>c64a15ed-0ba3-4378-8f80-0c19d0531747</UserSecretsId>
</PropertyGroup> </PropertyGroup>
@ -27,9 +27,9 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Humanizer.Core" Version="2.14.1" /> <PackageReference Include="Humanizer.Core" Version="2.14.1" />
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="9.0.2" /> <PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.UserSecrets" Version="9.0.2" /> <PackageReference Include="Microsoft.Extensions.Configuration.UserSecrets" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.Hosting" Version="9.0.2" /> <PackageReference Include="Microsoft.Extensions.Hosting" Version="8.0.0" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\Metadata\Metadata.csproj" /> <ProjectReference Include="..\Metadata\Metadata.csproj" />

View File

@ -6,8 +6,10 @@ public class Program
/// The main entry point for the application. /// The main entry point for the application.
/// </summary> /// </summary>
[STAThread] [STAThread]
private static void Main() => private static void Main()
// ApplicationConfiguration.Initialize(); {
ApplicationConfiguration.Initialize();
Application.Run(new DragDropSetPropertyItem()); Application.Run(new DragDropSetPropertyItem());
}
} }

View File

@ -4,12 +4,12 @@
<Nullable>enable</Nullable> <Nullable>enable</Nullable>
<OutputType>Exe</OutputType> <OutputType>Exe</OutputType>
<RuntimeIdentifier>win-x64</RuntimeIdentifier> <RuntimeIdentifier>win-x64</RuntimeIdentifier>
<TargetFramework>net9.0</TargetFramework> <TargetFramework>net8.0</TargetFramework>
</PropertyGroup> </PropertyGroup>
<PropertyGroup> <PropertyGroup>
<PackageId>Phares.View.by.Distance.Duplicate-Search</PackageId> <PackageId>Phares.View.by.Distance.Duplicate-Search</PackageId>
<GeneratePackageOnBuild>false</GeneratePackageOnBuild> <GeneratePackageOnBuild>false</GeneratePackageOnBuild>
<Version>9.0.100.1</Version> <Version>8.0.101.1</Version>
<Authors>Mike Phares</Authors> <Authors>Mike Phares</Authors>
<Company>Phares</Company> <Company>Phares</Company>
<IncludeSymbols>true</IncludeSymbols> <IncludeSymbols>true</IncludeSymbols>
@ -33,14 +33,14 @@
<SupportedPlatform Include="browser" /> <SupportedPlatform Include="browser" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Microsoft.Extensions.Hosting" Version="9.0.2" /> <PackageReference Include="Microsoft.Extensions.Hosting" Version="8.0.0" />
<PackageReference Include="Microsoft.AspNetCore.Cryptography.KeyDerivation" Version="9.0.2" /> <PackageReference Include="Microsoft.AspNetCore.Cryptography.KeyDerivation" Version="8.0.7" />
<PackageReference Include="Microsoft.Extensions.Identity.Core" Version="9.0.2" /> <PackageReference Include="Microsoft.Extensions.Identity.Core" Version="8.0.7" />
<PackageReference Include="Microsoft.Extensions.Options" Version="9.0.2" /> <PackageReference Include="Microsoft.Extensions.Options" Version="8.0.2" />
<PackageReference Include="ShellProgressBar" Version="5.2.0" /> <PackageReference Include="ShellProgressBar" Version="5.2.0" />
<PackageReference Include="WindowsShortcutFactory" Version="1.2.0" /> <PackageReference Include="WindowsShortcutFactory" Version="1.2.0" />
<PackageReference Include="System.Drawing.Common" Version="8.0.10" /> <PackageReference Include="System.Drawing.Common" Version="8.0.7" />
<PackageReference Include="System.Text.Json" Version="9.0.2" /> <PackageReference Include="System.Text.Json" Version="8.0.4" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\Property\Property.csproj" /> <ProjectReference Include="..\Property\Property.csproj" />

View File

@ -189,7 +189,7 @@ public class DuplicateSearch
if (mappingFromItem is not null) if (mappingFromItem is not null)
{ {
resizedFileHolder = Shared.Models.Stateless.Methods.IFileHolder.Get(mappingFromItem.ResizedFileHolder.FullName.Replace($"0{duplicates}", $"1{duplicates}")); resizedFileHolder = Shared.Models.Stateless.Methods.IFileHolder.Get(mappingFromItem.ResizedFileHolder.FullName.Replace($"0{duplicates}", $"1{duplicates}"));
collection[0] = new(mappingFromItem.ContainerDateTimes, item.Property.DateTimeDigitized, item.Property.DateTimeOriginal, mappingFromItem.Id, mappingFromItem.IsArchive, mappingFromItem.FilePath, mappingFromItem.IsWrongYear, item.Property.Keywords ?? [], mappingFromItem.MinimumDateTime, item.Property.Model, mappingFromItem.RelativePath, resizedFileHolder); collection[0] = new(mappingFromItem.ContainerDateTimes, item.Property.DateTimeDigitized, item.Property.DateTimeOriginal, mappingFromItem.Id, mappingFromItem.FilePath, mappingFromItem.IsWrongYear, item.Property.Keywords ?? [], mappingFromItem.MinimumDateTime, item.Property.Model, mappingFromItem.RelativePath, resizedFileHolder);
} }
} }
resizedFileHolder = Shared.Models.Stateless.Methods.IFileHolder.Get(string.Concat(Path.Combine(destinationRoot, directory), item.RelativePath)); resizedFileHolder = Shared.Models.Stateless.Methods.IFileHolder.Get(string.Concat(Path.Combine(destinationRoot, directory), item.RelativePath));
@ -208,11 +208,11 @@ public class DuplicateSearch
{ {
foreach (MappingFromItem? mappingFromItem in keyValuePair.Value) foreach (MappingFromItem? mappingFromItem in keyValuePair.Value)
{ {
if (mappingFromItem?.ResizedFileHolder.DirectoryFullPath is null) if (mappingFromItem?.ResizedFileHolder.DirectoryName is null)
continue; continue;
if (mappingFromItem.ResizedFileHolder.Exists) if (mappingFromItem.ResizedFileHolder.Exists)
continue; continue;
collection.Add(mappingFromItem.ResizedFileHolder.DirectoryFullPath); collection.Add(mappingFromItem.ResizedFileHolder.DirectoryName);
results.Add(new(mappingFromItem.FilePath, mappingFromItem.ResizedFileHolder.FullName)); results.Add(new(mappingFromItem.FilePath, mappingFromItem.ResizedFileHolder.FullName));
} }
} }

View File

@ -4,12 +4,12 @@
<Nullable>enable</Nullable> <Nullable>enable</Nullable>
<OutputType>library</OutputType> <OutputType>library</OutputType>
<RuntimeIdentifier>win-x64</RuntimeIdentifier> <RuntimeIdentifier>win-x64</RuntimeIdentifier>
<TargetFramework>net9.0</TargetFramework> <TargetFramework>net8.0</TargetFramework>
</PropertyGroup> </PropertyGroup>
<PropertyGroup> <PropertyGroup>
<PackageId>Phares.View.by.Distance.Face</PackageId> <PackageId>Phares.View.by.Distance.Face</PackageId>
<GeneratePackageOnBuild>false</GeneratePackageOnBuild> <GeneratePackageOnBuild>false</GeneratePackageOnBuild>
<Version>9.0.100.1</Version> <Version>8.0.101.1</Version>
<Authors>Mike Phares</Authors> <Authors>Mike Phares</Authors>
<Company>Phares</Company> <Company>Phares</Company>
<IncludeSymbols>true</IncludeSymbols> <IncludeSymbols>true</IncludeSymbols>
@ -33,7 +33,7 @@
<SupportedPlatform Include="browser" /> <SupportedPlatform Include="browser" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="System.Text.Json" Version="9.0.2" /> <PackageReference Include="System.Text.Json" Version="8.0.4" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\FaceRecognitionDotNet\FaceRecognitionDotNet.csproj" /> <ProjectReference Include="..\FaceRecognitionDotNet\FaceRecognitionDotNet.csproj" />

View File

@ -42,12 +42,11 @@ public class D_Face : IFaceD
private readonly int _FaceDistanceHiddenImageFactor; private readonly int _FaceDistanceHiddenImageFactor;
private readonly EncoderParameters _EncoderParameters; private readonly EncoderParameters _EncoderParameters;
private readonly ImageCodecInfo _HiddenImageCodecInfo; private readonly ImageCodecInfo _HiddenImageCodecInfo;
private readonly Dictionary<string, string[]> _FileGroups;
private readonly bool _ForceFaceLastWriteTimeToCreationTime; private readonly bool _ForceFaceLastWriteTimeToCreationTime;
private readonly EncoderParameters _HiddenEncoderParameters; private readonly EncoderParameters _HiddenEncoderParameters;
private readonly IPropertyConfiguration _PropertyConfiguration; private readonly IPropertyConfiguration _PropertyConfiguration;
private readonly JsonSerializerOptions _WriteIndentedAndWhenWritingNull; private readonly JsonSerializerOptions _WriteIndentedAndWhenWritingNull;
private readonly ReadOnlyDictionary<byte, ReadOnlyCollection<string>>[] _ResultContentFileGroups;
private readonly ReadOnlyDictionary<byte, ReadOnlyCollection<string>>[] _ResultCollectionFileGroups;
public D_Face( public D_Face(
string argZero, string argZero,
@ -70,6 +69,7 @@ public class D_Face : IFaceD
float[] rectangleIntersectMinimums) float[] rectangleIntersectMinimums)
{ {
_ArgZero = argZero; _ArgZero = argZero;
_FileGroups = [];
_ImageCodecInfo = imageCodecInfo; _ImageCodecInfo = imageCodecInfo;
_EncoderParameters = encoderParameters; _EncoderParameters = encoderParameters;
_FileNameExtension = filenameExtension; _FileNameExtension = filenameExtension;
@ -84,8 +84,6 @@ public class D_Face : IFaceD
_RectangleIntersectMinimum = rectangleIntersectMinimums.Min(); _RectangleIntersectMinimum = rectangleIntersectMinimums.Min();
_FaceDistanceHiddenImageFactor = faceDistanceHiddenImageFactor; _FaceDistanceHiddenImageFactor = faceDistanceHiddenImageFactor;
_ForceFaceLastWriteTimeToCreationTime = forceFaceLastWriteTimeToCreationTime; _ForceFaceLastWriteTimeToCreationTime = forceFaceLastWriteTimeToCreationTime;
_ResultContentFileGroups = [new(new Dictionary<byte, ReadOnlyCollection<string>>())];
_ResultCollectionFileGroups = [new(new Dictionary<byte, ReadOnlyCollection<string>>())];
(Model model, PredictorModel predictorModel, ModelParameter modelParameter) = GetModel(modelDirectory, modelName, predictorModelName); (Model model, PredictorModel predictorModel, ModelParameter modelParameter) = GetModel(modelDirectory, modelName, predictorModelName);
_Model = model; _Model = model;
_PredictorModel = predictorModel; _PredictorModel = predictorModel;
@ -103,16 +101,10 @@ public class D_Face : IFaceD
public void Update(string dResultsFullGroupDirectory) public void Update(string dResultsFullGroupDirectory)
{ {
ReadOnlyDictionary<string, ReadOnlyDictionary<byte, ReadOnlyCollection<string>>> keyValuePairs = Shared.Models.Stateless.Methods.IPath.GetKeyValuePairs(_PropertyConfiguration, dResultsFullGroupDirectory, [_PropertyConfiguration.ResultCollection, _PropertyConfiguration.ResultContent]); _FileGroups.Clear();
foreach (KeyValuePair<string, ReadOnlyDictionary<byte, ReadOnlyCollection<string>>> keyValuePair in keyValuePairs) ReadOnlyDictionary<string, string[]> keyValuePairs = Shared.Models.Stateless.Methods.IPath.GetKeyValuePairs(_PropertyConfiguration, dResultsFullGroupDirectory, [_PropertyConfiguration.ResultCollection, _PropertyConfiguration.ResultContent]);
{ foreach (KeyValuePair<string, string[]> keyValuePair in keyValuePairs)
if (keyValuePair.Key == _PropertyConfiguration.ResultContent) _FileGroups.Add(keyValuePair.Key, keyValuePair.Value);
_ResultContentFileGroups[0] = keyValuePair.Value;
else if (keyValuePair.Key == _PropertyConfiguration.ResultCollection)
_ResultCollectionFileGroups[0] = keyValuePair.Value;
else
throw new Exception();
}
} }
private static (Model model, PredictorModel predictorModel, ModelParameter modelParameter) GetModel(string modelDirectory, string modelName, string predictorModelName) private static (Model model, PredictorModel predictorModel, ModelParameter modelParameter) GetModel(string modelDirectory, string modelName, string predictorModelName)
@ -120,8 +112,8 @@ public class D_Face : IFaceD
(Model, PredictorModel, ModelParameter) result; (Model, PredictorModel, ModelParameter) result;
Array array; Array array;
Model? model = null; Model? model = null;
array = Enum.GetValues<Model>();
PredictorModel? predictorModel = null; PredictorModel? predictorModel = null;
array = Enum.GetValues(typeof(Model));
foreach (Model check in array) foreach (Model check in array)
{ {
if (modelName.Contains(check.ToString())) if (modelName.Contains(check.ToString()))
@ -133,7 +125,7 @@ public class D_Face : IFaceD
if (model is null) if (model is null)
throw new Exception("Destination directory must have Model name!"); throw new Exception("Destination directory must have Model name!");
model = model.Value; model = model.Value;
array = Enum.GetValues<PredictorModel>(); array = Enum.GetValues(typeof(PredictorModel));
foreach (PredictorModel check in array) foreach (PredictorModel check in array)
{ {
if (predictorModelName.Contains(check.ToString())) if (predictorModelName.Contains(check.ToString()))
@ -201,13 +193,11 @@ public class D_Face : IFaceD
rectangle = new Rectangle(location.Left, location.Top, width, height); rectangle = new Rectangle(location.Left, location.Top, width, height);
faceFile = new(face.Mapping?.MappingFromLocation?.AreaPermyriad, faceFile = new(face.Mapping?.MappingFromLocation?.AreaPermyriad,
face.Mapping?.MappingFromLocation?.ConfidencePercent, face.Mapping?.MappingFromLocation?.ConfidencePercent,
geoLocation?.ToDmsString(),
face.DateTime, face.DateTime,
null, geoLocation?.ToDmsString(),
face.FaceParts, face.FaceParts,
face.Location, face.Location,
maker, maker,
null,
model, model,
face.OutputResolution); face.OutputResolution);
faceFileJson = JsonSerializer.Serialize(faceFile, FaceFileGenerationContext.Default.FaceFile); faceFileJson = JsonSerializer.Serialize(faceFile, FaceFileGenerationContext.Default.FaceFile);
@ -303,37 +293,17 @@ public class D_Face : IFaceD
#pragma warning restore CA1416 #pragma warning restore CA1416
private static void MoveIf(string fileName, CombinedEnumAndIndex cei, string directory, FileInfo fileInfo) public List<Shared.Models.Face> GetFaces(string outputResolution, string cResultsFullGroupDirectory, string dResultsFullGroupDirectory, FilePath filePath, List<Tuple<string, DateTime>> subFileTuples, List<string> parseExceptions, Shared.Models.Property property, MappingFromItem mappingFromItem, Dictionary<string, int[]> outputResolutionToResize, List<MappingFromPhotoPrism>? mappingFromPhotoPrismCollection)
{
string[] segments = directory.Split(cei.Combined);
string? checkDirectory = segments.Length == 1 ?
Path.Combine(segments[0], $"{cei.Combined[2..]}") :
segments.Length == 2 ?
$"{segments[0]}{cei.Combined[2..]}{segments[1]}" :
null;
if (checkDirectory is not null && Directory.Exists(checkDirectory))
{
string checkFile = Path.Combine(checkDirectory, fileName);
if (File.Exists(checkFile))
{
File.Move(checkFile, fileInfo.FullName);
fileInfo.Refresh();
}
}
}
public List<Shared.Models.Face> GetFaces(string outputResolution, string cResultsFullGroupDirectory, FilePath filePath, List<Tuple<string, DateTime>> subFileTuples, List<string> parseExceptions, Shared.Models.Property property, MappingFromItem mappingFromItem, Dictionary<string, int[]> outputResolutionToResize, List<MappingFromPhotoPrism>? mappingFromPhotoPrismCollection)
{ {
List<Shared.Models.Face>? results; List<Shared.Models.Face>? results;
if (string.IsNullOrEmpty(dResultsFullGroupDirectory))
throw new NullReferenceException(nameof(dResultsFullGroupDirectory));
string? json; string? json;
List<Location> locations; List<Location> locations;
string[] changesFrom = [nameof(A_Property), nameof(B_Metadata), nameof(C_Resize)]; string[] changesFrom = [nameof(A_Property), nameof(B_Metadata), nameof(C_Resize)];
List<DateTime> dateTimes = (from l in subFileTuples where changesFrom.Contains(l.Item1) select l.Item2).ToList(); List<DateTime> dateTimes = (from l in subFileTuples where changesFrom.Contains(l.Item1) select l.Item2).ToList();
string fileName = $"{mappingFromItem.FilePath.NameWithoutExtension}{mappingFromItem.FilePath.ExtensionLowered}.json"; (_, int directoryIndex) = Shared.Models.Stateless.Methods.IPath.GetDirectoryNameAndIndex(_PropertyConfiguration, filePath);
CombinedEnumAndIndex cei = Shared.Models.Stateless.Methods.IPath.GetCombinedEnumAndIndex(_PropertyConfiguration, filePath); FileInfo fileInfo = new(Path.Combine(_FileGroups[_PropertyConfiguration.ResultCollection][directoryIndex], $"{mappingFromItem.FilePath.NameWithoutExtension}{mappingFromItem.FilePath.ExtensionLowered}.json"));
string directory = _ResultCollectionFileGroups[0][cei.Enum][cei.Index];
FileInfo fileInfo = new(Path.Combine(directory, fileName));
MoveIf(fileName, cei, directory, fileInfo);
if (_ForceFaceLastWriteTimeToCreationTime && !fileInfo.Exists && File.Exists(Path.ChangeExtension(fileInfo.FullName, ".delete"))) if (_ForceFaceLastWriteTimeToCreationTime && !fileInfo.Exists && File.Exists(Path.ChangeExtension(fileInfo.FullName, ".delete")))
{ {
File.Move(Path.ChangeExtension(fileInfo.FullName, ".delete"), fileInfo.FullName); File.Move(Path.ChangeExtension(fileInfo.FullName, ".delete"), fileInfo.FullName);
@ -396,39 +366,18 @@ public class D_Face : IFaceD
return results; return results;
} }
private static void MoveIf(string fileName, CombinedEnumAndIndex cei, string directory, DirectoryInfo directoryInfo) public List<(Shared.Models.Face, FileHolder?, string, bool)> SaveFaces(string f, string dResultsFullGroupDirectory, FilePath filePath, List<Tuple<string, DateTime>> subFileTuples, List<string> parseExceptions, MappingFromItem mappingFromItem, ExifDirectory exifDirectory, List<Shared.Models.Face> faces)
{
string[] segments = directory.Split(cei.Combined);
string? checkDirectory = segments.Length == 1 ?
Path.Combine(segments[0], $"{cei.Combined[2..]}") :
segments.Length == 2 ?
$"{segments[0]}{cei.Combined[2..]}{segments[1]}" :
null;
if (checkDirectory is not null && Directory.Exists(checkDirectory))
{
string checkFile = Path.Combine(checkDirectory, fileName);
if (Directory.Exists(checkFile))
{
Directory.Move(checkFile, directoryInfo.FullName);
directoryInfo.Refresh();
}
}
}
public List<(Shared.Models.Face, FileHolder?, string, bool)> SaveFaces(FilePath filePath, List<Tuple<string, DateTime>> subFileTuples, List<string> parseExceptions, MappingFromItem mappingFromItem, ExifDirectory exifDirectory, List<Shared.Models.Face> faces)
{ {
List<(Shared.Models.Face, FileHolder?, string, bool Save)> results = []; List<(Shared.Models.Face, FileHolder?, string, bool Save)> results = [];
bool save; bool save;
FileInfo fileInfo; FileInfo fileInfo;
FileHolder fileHolder; FileHolder fileHolder;
string deterministicHashCodeKey; string deterministicHashCodeKey;
string fileName = mappingFromItem.FilePath.NameWithoutExtension;
string[] changesFrom = [nameof(A_Property), nameof(B_Metadata), nameof(C_Resize)]; string[] changesFrom = [nameof(A_Property), nameof(B_Metadata), nameof(C_Resize)];
List<DateTime> dateTimes = (from l in subFileTuples where changesFrom.Contains(l.Item1) select l.Item2).ToList(); List<DateTime> dateTimes = (from l in subFileTuples where changesFrom.Contains(l.Item1) select l.Item2).ToList();
CombinedEnumAndIndex cei = Shared.Models.Stateless.Methods.IPath.GetCombinedEnumAndIndex(_PropertyConfiguration, filePath); (_, int directoryIndex) = Shared.Models.Stateless.Methods.IPath.GetDirectoryNameAndIndex(_PropertyConfiguration, filePath);
string directory = _ResultContentFileGroups[0][cei.Enum][cei.Index]; string directory = Path.Combine(_FileGroups[_PropertyConfiguration.ResultContent][directoryIndex], mappingFromItem.FilePath.NameWithoutExtension);
DirectoryInfo directoryInfo = new(Path.Combine(directory, fileName)); bool directoryExists = Directory.Exists(directory);
MoveIf(fileName, cei, directory, directoryInfo);
foreach (Shared.Models.Face face in faces) foreach (Shared.Models.Face face in faces)
{ {
save = false; save = false;
@ -438,9 +387,9 @@ public class D_Face : IFaceD
continue; continue;
} }
deterministicHashCodeKey = Shared.Models.Stateless.Methods.IMapping.GetDeterministicHashCodeKey(filePath, face.Location, Shared.Models.Stateless.ILocation.Digits, face.OutputResolution); deterministicHashCodeKey = Shared.Models.Stateless.Methods.IMapping.GetDeterministicHashCodeKey(filePath, face.Location, Shared.Models.Stateless.ILocation.Digits, face.OutputResolution);
fileInfo = new FileInfo(Path.Combine(directoryInfo.FullName, $"{deterministicHashCodeKey}{mappingFromItem.FilePath.ExtensionLowered}{_FileNameExtension}")); fileInfo = new FileInfo(Path.Combine(directory, $"{deterministicHashCodeKey}{mappingFromItem.FilePath.ExtensionLowered}{_FileNameExtension}"));
fileHolder = FileHolder.Get(fileInfo); fileHolder = FileHolder.Get(fileInfo);
if (!directoryInfo.Exists) if (!directoryExists)
save = true; save = true;
else if (_OverrideForFaceImages) else if (_OverrideForFaceImages)
save = true; save = true;
@ -448,12 +397,12 @@ public class D_Face : IFaceD
save = true; save = true;
else if (_CheckDFaceAndUpWriteDates && dateTimes.Count > 0 && dateTimes.Max() > fileInfo.LastWriteTime) else if (_CheckDFaceAndUpWriteDates && dateTimes.Count > 0 && dateTimes.Max() > fileInfo.LastWriteTime)
save = true; save = true;
results.Add(new(face, fileHolder, Path.Combine(directoryInfo.FullName, $"{deterministicHashCodeKey}{mappingFromItem.FilePath.ExtensionLowered}{_HiddenFileNameExtension}"), save)); results.Add(new(face, fileHolder, Path.Combine(directory, $"{deterministicHashCodeKey}{mappingFromItem.FilePath.ExtensionLowered}{_HiddenFileNameExtension}"), save));
} }
if (results.Any(l => l.Save)) if (results.Any(l => l.Save))
{ {
if (!directoryInfo.Exists) if (!directoryExists)
_ = Directory.CreateDirectory(directoryInfo.FullName); _ = Directory.CreateDirectory(directory);
SaveFaces(mappingFromItem.ResizedFileHolder, exifDirectory, results); SaveFaces(mappingFromItem.ResizedFileHolder, exifDirectory, results);
} }
return results; return results;
@ -504,13 +453,11 @@ public class D_Face : IFaceD
MetadataExtractor.GeoLocation? geoLocation = IMetadata.GeoLocation(exifDirectory); MetadataExtractor.GeoLocation? geoLocation = IMetadata.GeoLocation(exifDirectory);
FaceFile faceFile = new(face.Mapping?.MappingFromLocation?.AreaPermyriad, FaceFile faceFile = new(face.Mapping?.MappingFromLocation?.AreaPermyriad,
face.Mapping?.MappingFromLocation?.ConfidencePercent, face.Mapping?.MappingFromLocation?.ConfidencePercent,
geoLocation?.ToDmsString(),
face.DateTime, face.DateTime,
null, geoLocation?.ToDmsString(),
face.FaceParts, face.FaceParts,
face.Location, face.Location,
maker, maker,
null,
model, model,
face.OutputResolution); face.OutputResolution);
string faceFileJson = JsonSerializer.Serialize(faceFile, FaceFileGenerationContext.Default.FaceFile); string faceFileJson = JsonSerializer.Serialize(faceFile, FaceFileGenerationContext.Default.FaceFile);

View File

@ -4,12 +4,12 @@
<Nullable>enable</Nullable> <Nullable>enable</Nullable>
<OutputType>library</OutputType> <OutputType>library</OutputType>
<RuntimeIdentifier>win-x64</RuntimeIdentifier> <RuntimeIdentifier>win-x64</RuntimeIdentifier>
<TargetFramework>net9.0</TargetFramework> <TargetFramework>net8.0</TargetFramework>
</PropertyGroup> </PropertyGroup>
<PropertyGroup> <PropertyGroup>
<PackageId>Phares.View.by.Distance.FaceParts</PackageId> <PackageId>Phares.View.by.Distance.FaceParts</PackageId>
<GeneratePackageOnBuild>false</GeneratePackageOnBuild> <GeneratePackageOnBuild>false</GeneratePackageOnBuild>
<Version>9.0.100.1</Version> <Version>8.0.101.1</Version>
<Authors>Mike Phares</Authors> <Authors>Mike Phares</Authors>
<Company>Phares</Company> <Company>Phares</Company>
<IncludeSymbols>true</IncludeSymbols> <IncludeSymbols>true</IncludeSymbols>
@ -33,7 +33,7 @@
<SupportedPlatform Include="browser" /> <SupportedPlatform Include="browser" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="System.Text.Json" Version="9.0.2" /> <PackageReference Include="System.Text.Json" Version="8.0.4" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\FaceRecognitionDotNet\FaceRecognitionDotNet.csproj" /> <ProjectReference Include="..\FaceRecognitionDotNet\FaceRecognitionDotNet.csproj" />

View File

@ -2,12 +2,9 @@ using System.Collections.ObjectModel;
using System.Drawing; using System.Drawing;
using System.Drawing.Drawing2D; using System.Drawing.Drawing2D;
using System.Drawing.Imaging; using System.Drawing.Imaging;
using System.Reflection;
using System.Text;
using System.Text.Json; using System.Text.Json;
using View_by_Distance.Face.Models; using View_by_Distance.Face.Models;
using View_by_Distance.Metadata.Models; using View_by_Distance.Metadata.Models;
using View_by_Distance.Metadata.Models.Stateless.Methods;
using View_by_Distance.Property.Models; using View_by_Distance.Property.Models;
using View_by_Distance.Property.Models.Stateless; using View_by_Distance.Property.Models.Stateless;
using View_by_Distance.Resize.Models; using View_by_Distance.Resize.Models;
@ -28,23 +25,22 @@ public class D2_FaceParts
private readonly ImageCodecInfo _ImageCodecInfo; private readonly ImageCodecInfo _ImageCodecInfo;
private readonly bool _CheckDFaceAndUpWriteDates; private readonly bool _CheckDFaceAndUpWriteDates;
private readonly ConstructorInfo _ConstructorInfo;
private readonly bool _OverrideForFaceLandmarkImages; private readonly bool _OverrideForFaceLandmarkImages;
private readonly EncoderParameters _EncoderParameters; private readonly EncoderParameters _EncoderParameters;
private readonly List<string> _AngleBracketCollection;
private readonly Dictionary<string, string[]> _FileGroups;
private readonly IPropertyConfiguration _PropertyConfiguration; private readonly IPropertyConfiguration _PropertyConfiguration;
private readonly ReadOnlyDictionary<byte, ReadOnlyCollection<string>>[] _ResultContentFileGroups;
public D2_FaceParts(IPropertyConfiguration propertyConfiguration, ImageCodecInfo imageCodecInfo, EncoderParameters encoderParameters, string filenameExtension, bool checkDFaceAndUpWriteDates, bool overrideForFaceLandmarkImages) public D2_FaceParts(IPropertyConfiguration propertyConfiguration, ImageCodecInfo imageCodecInfo, EncoderParameters encoderParameters, string filenameExtension, bool checkDFaceAndUpWriteDates, bool overrideForFaceLandmarkImages)
{ {
_FileGroups = [];
_ImageCodecInfo = imageCodecInfo; _ImageCodecInfo = imageCodecInfo;
_EncoderParameters = encoderParameters; _EncoderParameters = encoderParameters;
_FileNameExtension = filenameExtension; _FileNameExtension = filenameExtension;
_AngleBracketCollection = [];
_PropertyConfiguration = propertyConfiguration; _PropertyConfiguration = propertyConfiguration;
_CheckDFaceAndUpWriteDates = checkDFaceAndUpWriteDates; _CheckDFaceAndUpWriteDates = checkDFaceAndUpWriteDates;
_OverrideForFaceLandmarkImages = overrideForFaceLandmarkImages; _OverrideForFaceLandmarkImages = overrideForFaceLandmarkImages;
_ResultContentFileGroups = [new(new Dictionary<byte, ReadOnlyCollection<string>>())];
ConstructorInfo? constructorInfo = typeof(PropertyItem).GetConstructor(BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Public, null, [], null) ?? throw new Exception();
_ConstructorInfo = constructorInfo;
} }
public override string ToString() public override string ToString()
@ -55,14 +51,45 @@ public class D2_FaceParts
public void Update(string dResultsFullGroupDirectory) public void Update(string dResultsFullGroupDirectory)
{ {
ReadOnlyDictionary<string, ReadOnlyDictionary<byte, ReadOnlyCollection<string>>> keyValuePairs = Shared.Models.Stateless.Methods.IPath.GetKeyValuePairs(_PropertyConfiguration, dResultsFullGroupDirectory, [_PropertyConfiguration.ResultContent]); _FileGroups.Clear();
foreach (KeyValuePair<string, ReadOnlyDictionary<byte, ReadOnlyCollection<string>>> keyValuePair in keyValuePairs) ReadOnlyDictionary<string, string[]> keyValuePairs = Shared.Models.Stateless.Methods.IPath.GetKeyValuePairs(_PropertyConfiguration, dResultsFullGroupDirectory, [_PropertyConfiguration.ResultContent]);
foreach (KeyValuePair<string, string[]> keyValuePair in keyValuePairs)
_FileGroups.Add(keyValuePair.Key, keyValuePair.Value);
}
public void SetAngleBracketCollection(IPropertyConfiguration propertyConfiguration, string d2ResultsFullGroupDirectory, string sourceDirectory)
{
_AngleBracketCollection.Clear();
_AngleBracketCollection.AddRange(IResult.GetDirectoryInfoCollection(propertyConfiguration,
sourceDirectory,
d2ResultsFullGroupDirectory,
contentDescription: "n gif file(s) for each face found",
singletonDescription: string.Empty,
collectionDescription: string.Empty,
converted: true));
}
public string GetFacePartsDirectory(IPropertyConfiguration propertyConfiguration, string dResultsFullGroupDirectory, Item item, bool includeNameWithoutExtension)
{
string result;
bool angleBracketCollectionAny = _AngleBracketCollection.Count != 0;
if (!angleBracketCollectionAny)
{ {
if (keyValuePair.Key == _PropertyConfiguration.ResultContent) if (item.FilePath.DirectoryName is null)
_ResultContentFileGroups[0] = keyValuePair.Value; throw new NullReferenceException(nameof(item.FilePath.DirectoryName));
else SetAngleBracketCollection(propertyConfiguration, dResultsFullGroupDirectory, item.FilePath.DirectoryName);
throw new Exception();
} }
if (includeNameWithoutExtension)
result = Path.Combine(_AngleBracketCollection[0].Replace("<>", _PropertyConfiguration.ResultContent), item.FilePath.NameWithoutExtension);
else
{
result = _AngleBracketCollection[0].Replace("<>", $"[{_PropertyConfiguration.ResultContent}]");
if (!Directory.Exists(result))
_ = Directory.CreateDirectory(result);
}
if (!angleBracketCollectionAny)
_AngleBracketCollection.Clear();
return result;
} }
private static void GetPointBounds(PointF[] points, out float xMinimum, out float xMaximum, out float yMinimum, out float yMaximum) private static void GetPointBounds(PointF[] points, out float xMinimum, out float xMaximum, out float yMinimum, out float yMaximum)
@ -156,270 +183,84 @@ public class D2_FaceParts
return result; return result;
} }
private void SaveRotated(MappingFromItem mappingFromItem, List<(Shared.Models.Face, string, string)> collection) private void SaveFaceParts(int pointSize, FileHolder resizedFileHolder, bool saveRotated, List<(Shared.Models.Face, string, string)> collection)
{ {
int x;
int y;
double? α; double? α;
int width;
int height;
Bitmap rotated; Bitmap rotated;
foreach ((Shared.Models.Face face, string _, string rotatedFileName) in collection) foreach ((Shared.Models.Face face, string fileName, string rotatedFileName) in collection)
{ {
if (face.FaceParts is null) if (face.FaceEncoding is null)
continue; continue;
(_, α) = Shared.Models.Stateless.Methods.IFace.GetEyeα(face.FaceParts);
if (α is null)
continue;
using Image image = Image.FromFile(mappingFromItem.ResizedFileHolder.FullName);
rotated = RotateBitmap(image, (float)α.Value);
if (rotated is not null)
{
rotated.Save(rotatedFileName, _ImageCodecInfo, _EncoderParameters);
rotated.Dispose();
}
}
}
private string GetSeasonDirectory(string d2ResultsFullGroupDirectory, MappingFromItem mappingFromItem, bool any)
{
string result;
string minimumDateYear = mappingFromItem.MinimumDateTime.ToString("yyyy");
DateTime dateTime = mappingFromItem.DateTimeOriginal is null ? mappingFromItem.MinimumDateTime : mappingFromItem.DateTimeOriginal.Value;
(int season, string seasonName) = Shared.Models.Stateless.Methods.IProperty.GetSeason(dateTime.DayOfYear);
string year = mappingFromItem.DateTimeOriginal is null ? $"{minimumDateYear[1..]}{minimumDateYear[0]}" : mappingFromItem.DateTimeOriginal.Value.ToString("yyyy");
string directory = Path.Combine(d2ResultsFullGroupDirectory, $"[{_PropertyConfiguration.ResultContent}]", $"{year}.{season} {seasonName}");
result = any ? Path.Combine(directory, "---") : Path.Combine(directory, "Complete");
if (!Directory.Exists(result))
_ = Directory.CreateDirectory(result);
return result;
}
private void SaveImage(MappingFromItem mappingFromItem, string directory, Image image, List<FaceFile> faceFiles)
{
short type = 2;
string faceFileJson;
PropertyItem? propertyItem;
const int artist = MetadataExtractor.Formats.Exif.ExifDirectoryBase.TagArtist; // 315
string fileName = Path.Combine(directory, $"{mappingFromItem.FilePath.Name}{_FileNameExtension}");
try
{
foreach (int propertyId in image.PropertyIdList)
{
if (propertyId == MetadataExtractor.Formats.Exif.ExifDirectoryBase.TagOrientation)
continue;
image.RemovePropertyItem(propertyId);
}
faceFileJson = JsonSerializer.Serialize(faceFiles.ToArray(), FaceFileCollectionGenerationContext.Default.FaceFileArray);
propertyItem = IProperty.GetPropertyItem(_ConstructorInfo, artist, type, faceFileJson);
image.SetPropertyItem(propertyItem);
image.Save(fileName, _ImageCodecInfo, _EncoderParameters);
}
catch (Exception ex)
{
if (ex is not null && !string.IsNullOrEmpty(fileName) && File.Exists(fileName))
File.Delete(fileName);
faceFileJson = JsonSerializer.Serialize(faceFiles.ToArray(), FaceFileCollectionGenerationContext.Default.FaceFileArray);
if (!string.IsNullOrEmpty(faceFileJson))
File.WriteAllText($"{fileName}.json", faceFileJson);
}
}
private void SaveAllFaceParts(string d2ResultsFullGroupDirectory, MappingFromItem mappingFromItem, ExifDirectory exifDirectory, List<Shared.Models.Face> faces)
{
int x;
int y;
Brush brush;
int pointSize;
bool any = false;
FaceFile faceFile;
bool? isDefaultName;
List<long> personKeys = [];
List<FaceFile> faceFiles = [];
StringBuilder stringBuilder = new();
MappingFromPerson? mappingFromPerson;
string? maker = IMetadata.GetMaker(exifDirectory);
string? model = IMetadata.GetModel(exifDirectory);
MetadataExtractor.GeoLocation? geoLocation = IMetadata.GeoLocation(exifDirectory);
using Image image = Image.FromFile(mappingFromItem.ResizedFileHolder.FullName);
using Graphics graphics = Graphics.FromImage(image);
foreach (Shared.Models.Face face in faces)
{
if (face.Location is null || face.FaceEncoding is null || face.FaceParts is null || face.FaceParts.Count == 0)
continue;
if (!any && face.Mapping?.MappingFromPerson is null)
any = true;
mappingFromPerson = face.Mapping?.MappingFromPerson;
brush = mappingFromPerson is null ? Brushes.Red : Brushes.GreenYellow;
isDefaultName = mappingFromPerson is null ? null : Shared.Models.Stateless.Methods.IPerson.IsDefaultName(mappingFromPerson);
if (mappingFromPerson is not null && isDefaultName is not null && !isDefaultName.Value)
personKeys.Add(mappingFromPerson.PersonKey);
faceFile = new(face.Mapping?.MappingFromLocation?.AreaPermyriad,
face.Mapping?.MappingFromLocation?.ConfidencePercent,
geoLocation?.ToDmsString(),
face.DateTime,
face.FaceEncoding,
face.FaceParts,
face.Location,
maker,
mappingFromPerson,
model,
face.OutputResolution);
faceFiles.Add(faceFile);
pointSize = GetPointSize(face.FaceParts, defaultPointSize: 2);
foreach ((FacePart facePart, FacePoint[] facePoints) in face.FaceParts)
{
foreach (FacePoint facePoint in facePoints)
graphics.FillEllipse(brush, facePoint.X - pointSize, facePoint.Y - pointSize, pointSize * 2, pointSize * 2);
if (facePart == FacePart.Chin)
continue;
if (facePoints.Length < 3)
continue;
x = (int)(from l in facePoints select l.X).Average();
y = (int)(from l in facePoints select l.Y).Average();
graphics.FillEllipse(Brushes.Purple, x - pointSize, y - pointSize, pointSize * 2, pointSize * 2);
}
}
_ = graphics.Save();
string directory = GetSeasonDirectory(d2ResultsFullGroupDirectory, mappingFromItem, any);
SaveImage(mappingFromItem, directory, image, faceFiles);
}
private void SaveImage(string fileName, Image image, FaceFile faceFile)
{
short type = 2;
string faceFileJson;
PropertyItem? propertyItem;
const int artist = MetadataExtractor.Formats.Exif.ExifDirectoryBase.TagArtist; // 315
try
{
foreach (int propertyId in image.PropertyIdList)
{
if (propertyId == MetadataExtractor.Formats.Exif.ExifDirectoryBase.TagOrientation)
continue;
image.RemovePropertyItem(propertyId);
}
faceFileJson = JsonSerializer.Serialize(faceFile, FaceFileGenerationContext.Default.FaceFile);
propertyItem = IProperty.GetPropertyItem(_ConstructorInfo, artist, type, faceFileJson);
image.SetPropertyItem(propertyItem);
image.Save(fileName, _ImageCodecInfo, _EncoderParameters);
}
catch (Exception ex)
{
if (ex is not null && !string.IsNullOrEmpty(fileName) && File.Exists(fileName))
File.Delete(fileName);
faceFileJson = JsonSerializer.Serialize(faceFile, FaceFileGenerationContext.Default.FaceFile);
if (!string.IsNullOrEmpty(faceFileJson))
File.WriteAllText($"{fileName}.json", faceFileJson);
}
}
private void SaveFaceParts(MappingFromItem mappingFromItem, ExifDirectory exifDirectory, List<(Shared.Models.Face, string, string)> collection)
{
int x;
int y;
Brush brush;
int pointSize;
FaceFile faceFile;
MappingFromPerson? mappingFromPerson;
string? maker = IMetadata.GetMaker(exifDirectory);
string? model = IMetadata.GetModel(exifDirectory);
MetadataExtractor.GeoLocation? geoLocation = IMetadata.GeoLocation(exifDirectory);
foreach ((Shared.Models.Face face, string fileName, string _) in collection)
{
try try
{ {
if (face.Location is null || face.FaceEncoding is null || face.FaceParts is null || face.FaceParts.Count == 0) using (Image image = Image.FromFile(resizedFileHolder.FullName))
continue;
using Image image = Image.FromFile(mappingFromItem.ResizedFileHolder.FullName);
mappingFromPerson = face.Mapping?.MappingFromPerson;
brush = mappingFromPerson is null ? Brushes.Red : Brushes.GreenYellow;
faceFile = new(face.Mapping?.MappingFromLocation?.AreaPermyriad,
face.Mapping?.MappingFromLocation?.ConfidencePercent,
geoLocation?.ToDmsString(),
face.DateTime,
face.FaceEncoding,
face.FaceParts,
face.Location,
maker,
mappingFromPerson,
model,
face.OutputResolution);
using Graphics graphics = Graphics.FromImage(image);
pointSize = GetPointSize(face.FaceParts, defaultPointSize: 2);
foreach ((FacePart facePart, FacePoint[] facePoints) in face.FaceParts)
{ {
foreach (FacePoint facePoint in facePoints) using Graphics graphic = Graphics.FromImage(image);
graphics.FillEllipse(brush, facePoint.X - pointSize, facePoint.Y - pointSize, pointSize * 2, pointSize * 2); if (face.FaceParts is null || face.FaceParts.Count == 0)
if (facePart == FacePart.Chin) {
continue; if (face.Location is null)
if (facePoints.Length < 3) continue;
continue; width = face.Location.Right - face.Location.Left;
x = (int)(from l in facePoints select l.X).Average(); height = face.Location.Bottom - face.Location.Top;
y = (int)(from l in facePoints select l.Y).Average(); graphic.DrawEllipse(Pens.Red, face.Location.Left, face.Location.Top, width, height);
graphics.FillEllipse(Brushes.Purple, x - pointSize, y - pointSize, pointSize * 2, pointSize * 2); }
else
{
foreach ((FacePart facePart, FacePoint[] facePoints) in face.FaceParts)
{
foreach (FacePoint facePoint in facePoints)
graphic.DrawEllipse(Pens.GreenYellow, facePoint.X - pointSize, facePoint.Y - pointSize, pointSize * 2, pointSize * 2);
if (facePart == FacePart.Chin)
continue;
if (facePoints.Length < 3)
continue;
x = (int)(from l in facePoints select l.X).Average();
y = (int)(from l in facePoints select l.Y).Average();
graphic.DrawEllipse(Pens.Purple, x - pointSize, y - pointSize, pointSize * 2, pointSize * 2);
}
}
image.Save(fileName, _ImageCodecInfo, _EncoderParameters);
}
if (saveRotated && face.FaceParts is not null)
{
(_, α) = Shared.Models.Stateless.Methods.IFace.GetEyeα(face.FaceParts);
if (α is null)
continue;
using Image image = Image.FromFile(resizedFileHolder.FullName);
rotated = RotateBitmap(image, (float)α.Value);
if (rotated is not null)
{
rotated.Save(rotatedFileName, _ImageCodecInfo, _EncoderParameters);
rotated.Dispose();
}
} }
_ = graphics.Save();
SaveImage(fileName, image, faceFile);
}
catch (Exception)
{
if (File.Exists(fileName))
File.Delete(fileName);
} }
catch (Exception) { }
} }
} }
private int GetPointSize(Dictionary<FacePart, FacePoint[]> faceParts, int defaultPointSize)
{
int result;
FacePoint[]? facePoints;
if (faceParts.TryGetValue(FacePart.LeftEye, out facePoints))
result = (int)Math.Ceiling((facePoints.Max(l => l.X) - facePoints.Min(l => l.X)) * .05);
else
{
if (faceParts.TryGetValue(FacePart.RightEye, out facePoints))
result = (int)Math.Ceiling((facePoints.Max(l => l.X) - facePoints.Min(l => l.X)) * .05);
else
result = defaultPointSize;
}
return result;
}
#pragma warning restore CA1416 #pragma warning restore CA1416
private static void MoveIf(string fileName, CombinedEnumAndIndex cei, string directory, DirectoryInfo directoryInfo) public void SaveFaceLandmarkImages(Configuration configuration, FilePath filePath, List<Tuple<string, DateTime>> subFileTuples, List<string> parseExceptions, MappingFromItem mappingFromItem, List<Shared.Models.Face> faces, bool saveRotated)
{
string[] segments = directory.Split(cei.Combined);
string? checkDirectory = segments.Length == 1 ?
Path.Combine(segments[0], $"{cei.Combined[2..]}") :
segments.Length == 2 ?
$"{segments[0]}{cei.Combined[2..]}{segments[1]}" :
null;
if (checkDirectory is not null && Directory.Exists(checkDirectory))
{
string checkFile = Path.Combine(checkDirectory, fileName);
if (Directory.Exists(checkFile))
{
Directory.Move(checkFile, directoryInfo.FullName);
directoryInfo.Refresh();
}
}
}
public void SaveFaceLandmarkImages(Configuration configuration, string d2ResultsFullGroupDirectory, FilePath filePath, List<Tuple<string, DateTime>> subFileTuples, List<string> parseExceptions, MappingFromItem mappingFromItem, ExifDirectory exifDirectory, List<Shared.Models.Face> faces, bool saveRotated)
{ {
FileInfo fileInfo; FileInfo fileInfo;
bool check = false; bool check = false;
const int pointSize = 2;
FileInfo rotatedFileInfo; FileInfo rotatedFileInfo;
DateTime? dateTime = null; DateTime? dateTime = null;
long ticks = DateTime.Now.Ticks; long ticks = DateTime.Now.Ticks;
string deterministicHashCodeKey; string deterministicHashCodeKey;
bool updateDateWhenMatches = false; bool updateDateWhenMatches = false;
List<(Shared.Models.Face, string, string)> collection = []; List<(Shared.Models.Face, string, string)> collection = [];
string fileName = mappingFromItem.FilePath.NameWithoutExtension;
string[] changesFrom = [nameof(A_Property), nameof(B_Metadata), nameof(C_Resize), nameof(D_Face)]; string[] changesFrom = [nameof(A_Property), nameof(B_Metadata), nameof(C_Resize), nameof(D_Face)];
List<DateTime> dateTimes = (from l in subFileTuples where changesFrom.Contains(l.Item1) select l.Item2).ToList(); List<DateTime> dateTimes = (from l in subFileTuples where changesFrom.Contains(l.Item1) select l.Item2).ToList();
CombinedEnumAndIndex cei = Shared.Models.Stateless.Methods.IPath.GetCombinedEnumAndIndex(_PropertyConfiguration, filePath); (_, int directoryIndex) = Shared.Models.Stateless.Methods.IPath.GetDirectoryNameAndIndex(_PropertyConfiguration, filePath);
string directory = _ResultContentFileGroups[0][cei.Enum][cei.Index]; string directory = Path.Combine(_FileGroups[_PropertyConfiguration.ResultContent][directoryIndex], mappingFromItem.FilePath.NameWithoutExtension);
DirectoryInfo directoryInfo = new(Path.Combine(directory, mappingFromItem.FilePath.NameWithoutExtension)); bool directoryExists = Directory.Exists(directory);
MoveIf(fileName, cei, directory, directoryInfo);
foreach (Shared.Models.Face face in faces) foreach (Shared.Models.Face face in faces)
{ {
if (face.FaceEncoding is null || face.Location is null || face.OutputResolution is null) if (face.FaceEncoding is null || face.Location is null || face.OutputResolution is null)
@ -428,14 +269,14 @@ public class D2_FaceParts
continue; continue;
} }
deterministicHashCodeKey = Shared.Models.Stateless.Methods.IMapping.GetDeterministicHashCodeKey(filePath, face.Location, Shared.Models.Stateless.ILocation.Digits, face.OutputResolution); deterministicHashCodeKey = Shared.Models.Stateless.Methods.IMapping.GetDeterministicHashCodeKey(filePath, face.Location, Shared.Models.Stateless.ILocation.Digits, face.OutputResolution);
fileInfo = new FileInfo(Path.Combine(directoryInfo.FullName, $"{deterministicHashCodeKey}{mappingFromItem.FilePath.ExtensionLowered}{_FileNameExtension}")); fileInfo = new FileInfo(Path.Combine(directory, $"{deterministicHashCodeKey}{mappingFromItem.FilePath.ExtensionLowered}{_FileNameExtension}"));
if (string.IsNullOrEmpty(fileInfo.DirectoryName)) if (string.IsNullOrEmpty(fileInfo.DirectoryName))
continue; continue;
rotatedFileInfo = new FileInfo(Path.Combine(fileInfo.DirectoryName, $"{deterministicHashCodeKey} - R{mappingFromItem.FilePath.ExtensionLowered}{_FileNameExtension}")); rotatedFileInfo = new FileInfo(Path.Combine(fileInfo.DirectoryName, $"{deterministicHashCodeKey} - R{mappingFromItem.FilePath.ExtensionLowered}{_FileNameExtension}"));
collection.Add(new(face, fileInfo.FullName, rotatedFileInfo.FullName)); collection.Add(new(face, fileInfo.FullName, rotatedFileInfo.FullName));
if (check) if (check)
continue; continue;
else if (!directoryInfo.Exists) else if (!directoryExists)
check = true; check = true;
else if (_OverrideForFaceLandmarkImages) else if (_OverrideForFaceLandmarkImages)
check = true; check = true;
@ -453,14 +294,39 @@ public class D2_FaceParts
} }
if (check) if (check)
{ {
if (!directoryInfo.Exists) if (!directoryExists)
_ = Directory.CreateDirectory(directoryInfo.FullName); _ = Directory.CreateDirectory(directory);
SaveFaceParts(mappingFromItem, exifDirectory, collection); SaveFaceParts(pointSize, mappingFromItem.ResizedFileHolder, saveRotated, collection);
if (saveRotated)
SaveRotated(mappingFromItem, collection);
} }
} }
#pragma warning disable CA1416
private void SaveFaceLandmarkImage(MappingFromItem mappingFromItem, List<(Shared.Models.Face, FileHolder?, string, bool)> faceCollection, string fileName)
{
Pen pen;
using Image image = Image.FromFile(mappingFromItem.ResizedFileHolder.FullName);
using Graphics graphic = Graphics.FromImage(image);
foreach ((Shared.Models.Face face, FileHolder? _, string _, bool _) in faceCollection)
{
if (face.FaceEncoding is null || face.Location is null || face.OutputResolution is null || face.FaceParts is null || face.FaceParts.Count == 0)
continue;
pen = face.Mapping?.MappingFromPerson is null ? Pens.Red : Pens.GreenYellow;
try
{
foreach ((FacePart facePart, FacePoint[] facePoints) in face.FaceParts)
{
for (int i = 0; i < facePoints.Length - 1; i++)
graphic.DrawLine(pen, new Point(facePoints[i].X, facePoints[i].Y), new Point(facePoints[i + 1].X, facePoints[i + 1].Y));
}
}
catch (Exception) { }
}
image.Save(fileName, _ImageCodecInfo, _EncoderParameters);
}
#pragma warning restore CA1416
private static bool GetNotMapped(string facePartsCollectionDirectory, List<(Shared.Models.Face Face, FileHolder?, string, bool)> faceCollection) private static bool GetNotMapped(string facePartsCollectionDirectory, List<(Shared.Models.Face Face, FileHolder?, string, bool)> faceCollection)
{ {
bool results = false; bool results = false;
@ -494,18 +360,19 @@ public class D2_FaceParts
return results; return results;
} }
public void SaveFaceLandmarkImages(string d2ResultsFullGroupDirectory, MappingFromItem mappingFromItem, ExifDirectory exifDirectory, List<Shared.Models.Face> faces) public void CopyFacesAndSaveFaceLandmarkImage(string facePartsCollectionDirectory, MappingFromItem mappingFromItem, List<(Shared.Models.Face Face, FileHolder?, string, bool)> faceCollection)
{ {
bool any = false; bool hasNotMapped = GetNotMapped(facePartsCollectionDirectory, faceCollection);
foreach (Shared.Models.Face face in faces) string fileName = Path.Combine(facePartsCollectionDirectory, $"{mappingFromItem.FilePath.Name}{_FileNameExtension}");
bool save = faceCollection.Any(l => l.Face.FaceEncoding is not null && l.Face.Location is not null && l.Face.OutputResolution is not null && l.Face.FaceParts is not null && l.Face.FaceParts.Count != 0);
FileInfo fileInfo = new(fileName);
if (save && (!fileInfo.Exists || new TimeSpan(DateTime.Now.Ticks - fileInfo.LastWriteTime.Ticks).TotalDays > 10))
{ {
if (face.Location is null || face.FaceEncoding is null || face.FaceParts is null || face.FaceParts.Count == 0) SaveFaceLandmarkImage(mappingFromItem, faceCollection, fileName);
continue; fileInfo.Refresh();
if (!any)
any = true;
} }
if (any) if (!hasNotMapped && !fileInfo.Attributes.HasFlag(FileAttributes.Hidden) && (fileInfo.Exists || save))
SaveAllFaceParts(d2ResultsFullGroupDirectory, mappingFromItem, exifDirectory, faces); File.SetAttributes(fileName, FileAttributes.Hidden);
} }
} }

View File

@ -4,12 +4,12 @@
<Nullable>enable</Nullable> <Nullable>enable</Nullable>
<OutputType>library</OutputType> <OutputType>library</OutputType>
<RuntimeIdentifier>win-x64</RuntimeIdentifier> <RuntimeIdentifier>win-x64</RuntimeIdentifier>
<TargetFramework>net9.0</TargetFramework> <TargetFramework>net8.0</TargetFramework>
</PropertyGroup> </PropertyGroup>
<PropertyGroup> <PropertyGroup>
<PackageId>Phares.View.by.Distance.FaceRecognitionDotNet</PackageId> <PackageId>Phares.View.by.Distance.FaceRecognitionDotNet</PackageId>
<GeneratePackageOnBuild>false</GeneratePackageOnBuild> <GeneratePackageOnBuild>false</GeneratePackageOnBuild>
<Version>9.0.100.1</Version> <Version>8.0.101.1</Version>
<Authors>Mike Phares</Authors> <Authors>Mike Phares</Authors>
<Company>Phares</Company> <Company>Phares</Company>
<IncludeSymbols>true</IncludeSymbols> <IncludeSymbols>true</IncludeSymbols>

View File

@ -88,7 +88,7 @@ public partial class DlibDotNet : IDlibDotNet, IDisposable
_Logger?.LogInformation(configuration.ModelDirectory); _Logger?.LogInformation(configuration.ModelDirectory);
{ {
(ImageCodecInfo imageCodecInfo, EncoderParameters encoderParameters, string filenameExtension) = C_Resize.GetPngLowQuality(); (ImageCodecInfo imageCodecInfo, EncoderParameters encoderParameters, string filenameExtension) = C_Resize.GetPngLowQuality();
(ImageCodecInfo hiddenImageCodecInfo, EncoderParameters hiddenEncoderParameters, string hiddenFileNameExtension) = C_Resize.GetJpegLowQuality(); (ImageCodecInfo hiddenImageCodecInfo, EncoderParameters hiddenEncoderParameters, string hiddenFileNameExtension) = C_Resize.GetGifLowQuality();
_Faces = new D_Face( _Faces = new D_Face(
argZero, argZero,
configuration.PropertyConfiguration, configuration.PropertyConfiguration,
@ -110,14 +110,14 @@ public partial class DlibDotNet : IDlibDotNet, IDisposable
configuration.RectangleIntersectMinimums); configuration.RectangleIntersectMinimums);
} }
{ {
(ImageCodecInfo imageCodecInfo, EncoderParameters encoderParameters, string filenameExtension) = C_Resize.GetJpegLowQuality(); (ImageCodecInfo imageCodecInfo, EncoderParameters encoderParameters, string filenameExtension) = C_Resize.GetGifLowQuality();
_FaceParts = new D2_FaceParts(_Configuration.PropertyConfiguration, imageCodecInfo, encoderParameters, filenameExtension, configuration.CheckDFaceAndUpWriteDates, configuration.OverrideForFaceLandmarkImages); _FaceParts = new D2_FaceParts(_Configuration.PropertyConfiguration, imageCodecInfo, encoderParameters, filenameExtension, configuration.CheckDFaceAndUpWriteDates, configuration.OverrideForFaceLandmarkImages);
} }
_DistanceLimits = new(_Configuration.FaceAreaPermyriad, _Configuration.FaceConfidencePercent, _Configuration.FaceDistancePermyriad, _Configuration.RangeDaysDeltaTolerance, _Configuration.RangeDistanceTolerance, _Configuration.RangeFaceAreaTolerance, _Configuration.RangeFaceConfidence, _Configuration.SortingMaximumPerFaceShouldBeHigh); _DistanceLimits = new(_Configuration.FaceAreaPermyriad, _Configuration.FaceConfidencePercent, _Configuration.FaceDistancePermyriad, _Configuration.RangeDaysDeltaTolerance, _Configuration.RangeDistanceTolerance, _Configuration.RangeFaceAreaPermyriadTolerance, _Configuration.RangeFaceConfidence, _Configuration.SortingMaximumPerFaceShouldBeHigh);
_MapConfiguration = Get(configuration, _DistanceLimits, _Faces.FileNameExtension, _Faces.HiddenFileNameExtension, _FaceParts.FileNameExtension); _MapConfiguration = Get(configuration, _DistanceLimits, _Faces.FileNameExtension, _Faces.HiddenFileNameExtension, _FaceParts.FileNameExtension);
_Distance = new(configuration.DistanceMoveUnableToMatch, configuration.DistanceRenameToMatch, configuration.FaceConfidencePercent, configuration.RangeDistanceTolerance, configuration.RectangleIntersectMinimums); _Distance = new(configuration.DistanceMoveUnableToMatch, configuration.DistanceRenameToMatch, configuration.FaceConfidencePercent, configuration.RangeDistanceTolerance, configuration.RectangleIntersectMinimums);
if (_PropertyRootExistedBefore || !_ArgZeroIsConfigurationRootDirectory) if (_PropertyRootExistedBefore || !_ArgZeroIsConfigurationRootDirectory)
personContainers = new([]); personContainers = new(new List<PersonContainer>());
else else
{ {
int totalSeconds = (int)Math.Floor(new TimeSpan(DateTime.Now.Ticks - ticks).TotalSeconds); int totalSeconds = (int)Math.Floor(new TimeSpan(DateTime.Now.Ticks - ticks).TotalSeconds);
@ -183,8 +183,8 @@ public partial class DlibDotNet : IDlibDotNet, IDisposable
throw new NullReferenceException(nameof(configuration.RangeDaysDeltaTolerance)); throw new NullReferenceException(nameof(configuration.RangeDaysDeltaTolerance));
if (configuration.RangeDistanceTolerance.Length != 3) if (configuration.RangeDistanceTolerance.Length != 3)
throw new NullReferenceException(nameof(configuration.RangeDistanceTolerance)); throw new NullReferenceException(nameof(configuration.RangeDistanceTolerance));
if (configuration.RangeFaceAreaTolerance.Length != 3) if (configuration.RangeFaceAreaPermyriadTolerance.Length != 3)
throw new NullReferenceException(nameof(configuration.RangeFaceAreaTolerance)); throw new NullReferenceException(nameof(configuration.RangeFaceAreaPermyriadTolerance));
if (configuration.RangeFaceConfidence.Length != 3) if (configuration.RangeFaceConfidence.Length != 3)
throw new NullReferenceException(nameof(configuration.RangeFaceConfidence)); throw new NullReferenceException(nameof(configuration.RangeFaceConfidence));
if (configuration.LocationContainerDistanceTolerance is null && !string.IsNullOrEmpty(configuration.LocationContainerDebugDirectory)) if (configuration.LocationContainerDistanceTolerance is null && !string.IsNullOrEmpty(configuration.LocationContainerDebugDirectory))
@ -204,8 +204,6 @@ public partial class DlibDotNet : IDlibDotNet, IDisposable
throw new Exception($"One or more {nameof(configuration.SaveShortcutsForOutputResolutions)} are not in the ValidResolutions list!"); throw new Exception($"One or more {nameof(configuration.SaveShortcutsForOutputResolutions)} are not in the ValidResolutions list!");
if ((from l in configuration.SaveFaceLandmarkForOutputResolutions where !configuration.ValidResolutions.Contains(l) select false).Any()) if ((from l in configuration.SaveFaceLandmarkForOutputResolutions where !configuration.ValidResolutions.Contains(l) select false).Any())
throw new Exception($"One or more {nameof(configuration.SaveFaceLandmarkForOutputResolutions)} are not in the ValidResolutions list!"); throw new Exception($"One or more {nameof(configuration.SaveFaceLandmarkForOutputResolutions)} are not in the ValidResolutions list!");
if ((from l in configuration.SaveFaceLandmarkForOutputResolutionsV2 where !configuration.ValidResolutions.Contains(l) select false).Any())
throw new Exception($"One or more {nameof(configuration.SaveFaceLandmarkForOutputResolutionsV2)} are not in the ValidResolutions list!");
if (string.IsNullOrEmpty(configuration.ModelName)) if (string.IsNullOrEmpty(configuration.ModelName))
throw new NullReferenceException(nameof(configuration.ModelName)); throw new NullReferenceException(nameof(configuration.ModelName));
if (string.IsNullOrEmpty(configuration.OutputExtension)) if (string.IsNullOrEmpty(configuration.OutputExtension))
@ -254,6 +252,31 @@ public partial class DlibDotNet : IDlibDotNet, IDisposable
throw new Exception("Configuration has SaveSortingWithoutPerson and FocusDirectory!"); throw new Exception("Configuration has SaveSortingWithoutPerson and FocusDirectory!");
} }
private ReadOnlyCollection<int> GetNotNineCollection(ReadOnlyCollection<ReadOnlyCollection<FilePath>> filePathsCollection)
{
List<int> results = [];
FileInfo fileInfo;
FileHolder fileHolder;
FilePath checkFilePath;
foreach (ReadOnlyCollection<FilePath> filePaths in filePathsCollection)
{
foreach (FilePath filePath in filePaths)
{
if (!filePath.FullName.Contains(" !9"))
continue;
fileInfo = new(filePath.FullName);
fileHolder = Shared.Models.Stateless.Methods.IFileHolder.Get(fileInfo);
if (!fileInfo.Attributes.HasFlag(FileAttributes.Hidden))
File.SetAttributes(fileHolder.FullName, FileAttributes.Hidden);
checkFilePath = FilePath.Get(_Configuration.PropertyConfiguration, fileHolder, index: null);
if (checkFilePath.Id is null)
continue;
results.Add(checkFilePath.Id.Value);
}
}
return new(results);
}
private static void DeleteContinueFiles(ReadOnlyCollection<PersonContainer> personContainers) private static void DeleteContinueFiles(ReadOnlyCollection<PersonContainer> personContainers)
{ {
foreach (PersonContainer personContainer in personContainers) foreach (PersonContainer personContainer in personContainers)
@ -312,8 +335,9 @@ public partial class DlibDotNet : IDlibDotNet, IDisposable
const string directorySearchFilter = "*"; const string directorySearchFilter = "*";
string? filesCollectionRootDirectory = null; string? filesCollectionRootDirectory = null;
bool configurationOutputResolutionsHas = false; bool configurationOutputResolutionsHas = false;
ReadOnlyCollection<Container> readOnlyContainers;
ReadOnlyCollection<int>? notNineCollection = null;
ReadOnlyDictionary<long, List<int>> personKeyToIds; ReadOnlyDictionary<long, List<int>> personKeyToIds;
ReadOnlyDictionary<int, Identifier>? splatNineIdentifiers = null;
ReadOnlyCollection<ReadOnlyCollection<FilePath>>? filePathsCollection = null; ReadOnlyCollection<ReadOnlyCollection<FilePath>>? filePathsCollection = null;
bool runToDoCollectionFirst = GetRunToDoCollectionFirst(_Configuration, ticks); bool runToDoCollectionFirst = GetRunToDoCollectionFirst(_Configuration, ticks);
(aResultsFullGroupDirectory, bResultsFullGroupDirectory) = GetResultsFullGroupDirectories(); (aResultsFullGroupDirectory, bResultsFullGroupDirectory) = GetResultsFullGroupDirectories();
@ -335,7 +359,7 @@ public partial class DlibDotNet : IDlibDotNet, IDisposable
if (!runToDoCollectionFirst) if (!runToDoCollectionFirst)
break; break;
(filesCollectionRootDirectory, filePathsCollection, filesCollectionCountIsOne) = GetFilesCollectionThenCopyOrMove(ticks, fileSearchFilter, directorySearchFilter, options, outputResolution); (filesCollectionRootDirectory, filePathsCollection, filesCollectionCountIsOne) = GetFilesCollectionThenCopyOrMove(ticks, fileSearchFilter, directorySearchFilter, options, outputResolution);
splatNineIdentifiers = GetSplatNineIdentifiersAndHideSplatNine(_Configuration.PropertyConfiguration, bResultsFullGroupDirectory, filePathsCollection); notNineCollection = GetNotNineCollection(filePathsCollection);
break; break;
} }
fPhotoPrismContentDirectory = Property.Models.Stateless.IResult.GetResultsDateGroupDirectory(_Configuration.PropertyConfiguration, nameof(F_PhotoPrism), _Configuration.PropertyConfiguration.ResultContent); fPhotoPrismContentDirectory = Property.Models.Stateless.IResult.GetResultsDateGroupDirectory(_Configuration.PropertyConfiguration, nameof(F_PhotoPrism), _Configuration.PropertyConfiguration.ResultContent);
@ -369,7 +393,7 @@ public partial class DlibDotNet : IDlibDotNet, IDisposable
continue; continue;
(cResultsFullGroupDirectory, _, _, _) = GetResultsFullGroupDirectories(outputResolution); (cResultsFullGroupDirectory, _, _, _) = GetResultsFullGroupDirectories(outputResolution);
filesCollectionRootDirectory = Path.Combine(cResultsFullGroupDirectory, _Configuration.PropertyConfiguration.ResultContent); filesCollectionRootDirectory = Path.Combine(cResultsFullGroupDirectory, _Configuration.PropertyConfiguration.ResultContent);
filePathsCollection = IDirectory.GetFilePathCollections(_Configuration.PropertyConfiguration, directorySearchFilter, fileSearchFilter, filesCollectionRootDirectory, useCeilingAverage: true); filePathsCollection = IDirectory.GetFilePathCollections(_Configuration.PropertyConfiguration, filesCollectionRootDirectory, directorySearchFilter, fileSearchFilter, useCeilingAverage: true);
break; break;
} }
} }
@ -379,9 +403,10 @@ public partial class DlibDotNet : IDlibDotNet, IDisposable
if (!Directory.Exists(aPropertySingletonDirectory)) if (!Directory.Exists(aPropertySingletonDirectory))
_ = Directory.CreateDirectory(aPropertySingletonDirectory); _ = Directory.CreateDirectory(aPropertySingletonDirectory);
int count = filePathsCollection.Select(l => l.Count).Sum(); int count = filePathsCollection.Select(l => l.Count).Sum();
SaveDistinctIds(_Configuration.PropertyConfiguration, bResultsFullGroupDirectory, filePathsCollection);
message = $") Building Container(s) - {(int)Math.Floor(new TimeSpan(DateTime.Now.Ticks - ticks).TotalSeconds)} total second(s)"; message = $") Building Container(s) - {(int)Math.Floor(new TimeSpan(DateTime.Now.Ticks - ticks).TotalSeconds)} total second(s)";
_ProgressBar = new(count, message, options); _ProgressBar = new(count, message, options);
ReadOnlyCollection<Container> readOnlyContainers = Shared.Models.Stateless.Methods.IContainer.GetContainers(this, _Configuration.PropertyConfiguration, aPropertySingletonDirectory, filesCollectionRootDirectory, splatNineIdentifiers, filePathsCollection); readOnlyContainers = Shared.Models.Stateless.Methods.IContainer.GetContainers(this, _Configuration.PropertyConfiguration, aPropertySingletonDirectory, filesCollectionRootDirectory, filePathsCollection);
_ProgressBar.Dispose(); _ProgressBar.Dispose();
mapLogic ??= new(_AppSettings.MaxDegreeOfParallelism, _Configuration.PropertyConfiguration, _MapConfiguration, _Distance, personContainers, ticks, a2PeopleContentDirectory, a2PeopleSingletonDirectory, eDistanceContentDirectory); mapLogic ??= new(_AppSettings.MaxDegreeOfParallelism, _Configuration.PropertyConfiguration, _MapConfiguration, _Distance, personContainers, ticks, a2PeopleContentDirectory, a2PeopleSingletonDirectory, eDistanceContentDirectory);
DeleteContinueFiles(personContainers); DeleteContinueFiles(personContainers);
@ -428,8 +453,8 @@ public partial class DlibDotNet : IDlibDotNet, IDisposable
&& _Configuration.LoadOrCreateThenSaveDistanceResultsForOutputResolutions.Contains(outputResolution) && _Configuration.LoadOrCreateThenSaveDistanceResultsForOutputResolutions.Contains(outputResolution)
&& _Exceptions.Count == 0) && _Exceptions.Count == 0)
MapLogic(ticks, readOnlyContainers, fPhotoPrismContentDirectory, mapLogic, outputResolution, new(personKeyToIds), distinctValidImageFaces, distinctValidImageMappingCollection); MapLogic(ticks, readOnlyContainers, fPhotoPrismContentDirectory, mapLogic, outputResolution, new(personKeyToIds), distinctValidImageFaces, distinctValidImageMappingCollection);
if (runToDoCollectionFirst && _Configuration.SaveRandomForOutputResolutions.Contains(outputResolution) && personKeyToIds.Count > 0 && splatNineIdentifiers is not null && distinctValidImageMappingCollection.Count > 0) if (runToDoCollectionFirst && _Configuration.SaveRandomForOutputResolutions.Contains(outputResolution) && personKeyToIds.Count > 0 && distinctValidImageMappingCollection.Count > 0)
_Random.Random(_Configuration.PropertyConfiguration, _Configuration.ImmichAssetsFile, _Configuration.ImmichOwnerId, _Configuration.ImmichRoot, _Configuration.RadomUseBirthdayMinimum, _Configuration.ValidKeyWordsToIgnoreInRandom, personKeyToIds, splatNineIdentifiers, distinctValidImageMappingCollection); _Random.Random(_Configuration.PropertyConfiguration, _Configuration.ImmichAssetsFile, _Configuration.RadomUseBirthdayMinimum, _Configuration.ValidKeyWordsToIgnoreInRandom, personKeyToIds, notNineCollection, distinctValidImageMappingCollection);
if (_IsEnvironment.Development) if (_IsEnvironment.Development)
continue; continue;
if (!_IsEnvironment.Development) if (!_IsEnvironment.Development)
@ -471,7 +496,8 @@ public partial class DlibDotNet : IDlibDotNet, IDisposable
[ [
Path.Combine(rootDirectory, "Ancestry"), Path.Combine(rootDirectory, "Ancestry"),
Path.Combine(rootDirectory, "Facebook"), Path.Combine(rootDirectory, "Facebook"),
Path.Combine(rootDirectory, "LinkedIn") Path.Combine(rootDirectory, "LinkedIn"),
rootDirectory,
]; ];
foreach (string checkDirectory in checkDirectories) foreach (string checkDirectory in checkDirectories)
{ {
@ -508,7 +534,7 @@ public partial class DlibDotNet : IDlibDotNet, IDisposable
string result; string result;
if (filePaths.Count == 0) if (filePaths.Count == 0)
throw new NotSupportedException(); throw new NotSupportedException();
string? sourceDirectory = filePaths[0].DirectoryFullPath; string? sourceDirectory = filePaths[0].DirectoryName;
if (string.IsNullOrEmpty(sourceDirectory)) if (string.IsNullOrEmpty(sourceDirectory))
throw new NotSupportedException(); throw new NotSupportedException();
Uri uri; Uri uri;
@ -542,7 +568,7 @@ public partial class DlibDotNet : IDlibDotNet, IDisposable
isValidImageFormatExtension = _Configuration.PropertyConfiguration.ValidImageFormatExtensions.Contains(extensionLowered); isValidImageFormatExtension = _Configuration.PropertyConfiguration.ValidImageFormatExtensions.Contains(extensionLowered);
fileHolder = Shared.Models.Stateless.Methods.IFileHolder.Get(sourceDirectoryFile); fileHolder = Shared.Models.Stateless.Methods.IFileHolder.Get(sourceDirectoryFile);
filePath = FilePath.Get(_Configuration.PropertyConfiguration, fileHolder, index: null); filePath = FilePath.Get(_Configuration.PropertyConfiguration, fileHolder, index: null);
_ = Item.Get(filePath, fileHolder, relativePath, isValidImageFormatExtension); _ = new Item(filePath, fileHolder, relativePath, isValidImageFormatExtension);
// container.Items.Add(item); // container.Items.Add(item);
} }
_Logger?.LogInformation(". . ."); _Logger?.LogInformation(". . .");
@ -604,6 +630,7 @@ public partial class DlibDotNet : IDlibDotNet, IDisposable
outputResolution, outputResolution,
outputResolutionHasNumber, outputResolutionHasNumber,
cResultsFullGroupDirectory, cResultsFullGroupDirectory,
dResultsFullGroupDirectory,
d2ResultsFullGroupDirectory, d2ResultsFullGroupDirectory,
sourceDirectoryChanges, sourceDirectoryChanges,
fileNameToCollection, fileNameToCollection,
@ -636,55 +663,31 @@ public partial class DlibDotNet : IDlibDotNet, IDisposable
} }
} }
private static ReadOnlyDictionary<int, Identifier> GetSplatNineIdentifiersAndHideSplatNine(Property.Models.Configuration propertyConfiguration, string bResultsFullGroupDirectory, ReadOnlyCollection<ReadOnlyCollection<FilePath>> filePathsCollection) private static void SaveDistinctIds(Property.Models.Configuration propertyConfiguration, string bResultsFullGroupDirectory, ReadOnlyCollection<ReadOnlyCollection<FilePath>> filePathsCollection)
{ {
Dictionary<int, Identifier> results = []; string paddedId;
ReadOnlyDictionary<int, ReadOnlyCollection<FilePath>> keyValuePairs = FilePath.GetKeyValuePairs(filePathsCollection); List<int> distinct = [];
if (keyValuePairs.Count > 0) List<Identifier> identifiers = [];
string bMetadataCollectionDirectory = Path.Combine(bResultsFullGroupDirectory, propertyConfiguration.ResultCollection);
if (!Directory.Exists(bMetadataCollectionDirectory))
_ = Directory.CreateDirectory(bMetadataCollectionDirectory);
foreach (ReadOnlyCollection<FilePath> filePaths in filePathsCollection)
{ {
string json; if (filePaths.Count == 0)
string paddedId; continue;
FileInfo fileInfo; foreach (FilePath filePath in filePaths)
FilePath filePath;
FileHolder fileHolder;
Identifier identifier;
string[] directoryNames;
List<int> distinct = [];
List<Identifier> identifiers = [];
string rootDirectory = propertyConfiguration.RootDirectory.Replace('\\', '/');
string bMetadataCollectionDirectory = Path.Combine(bResultsFullGroupDirectory, propertyConfiguration.ResultCollection);
if (!Directory.Exists(bMetadataCollectionDirectory))
_ = Directory.CreateDirectory(bMetadataCollectionDirectory);
foreach (KeyValuePair<int, ReadOnlyCollection<FilePath>> keyValuePair in keyValuePairs)
{ {
for (int i = 0; i < keyValuePair.Value.Count; i++) if (filePath.Id is null)
{ continue;
filePath = keyValuePair.Value[0]; if (distinct.Contains(filePath.Id.Value))
if (filePath.Id is null) continue;
continue; distinct.Add(filePath.Id.Value);
directoryNames = keyValuePair.Value.Select(l => l.DirectoryFullPath.Replace('\\', '/')).ToArray(); paddedId = IId.GetPaddedId(propertyConfiguration, filePath.Id.Value, filePath.HasIgnoreKeyword, filePath.HasDateTimeOriginal, index: null);
paddedId = IId.GetPaddedId(propertyConfiguration, filePath.Id.Value, filePath.HasIgnoreKeyword, filePath.HasDateTimeOriginal, index: null); identifiers.Add(new(filePath.Id.Value, paddedId));
identifier = new(directoryNames, filePath.ExtensionLowered, filePath.HasDateTimeOriginal, filePath.Id.Value, filePath.Length, paddedId, filePath.LastWriteTicks);
if (i == 0)
identifiers.Add(identifier);
if (!filePath.FullName.Contains(" !9"))
continue;
fileInfo = new(filePath.FullName);
fileHolder = Shared.Models.Stateless.Methods.IFileHolder.Get(fileInfo);
if (!fileInfo.Attributes.HasFlag(FileAttributes.Hidden))
File.SetAttributes(fileHolder.FullName, FileAttributes.Hidden);
if (distinct.Contains(keyValuePair.Key))
continue;
distinct.Add(keyValuePair.Key);
results.Add(keyValuePair.Key, identifier);
}
} }
json = JsonSerializer.Serialize(results.Values.ToArray(), IdentifierCollectionSourceGenerationContext.Default.IdentifierArray);
_ = Shared.Models.Stateless.Methods.IPath.WriteAllText(Path.Combine(bMetadataCollectionDirectory, "!9.json"), json, updateDateWhenMatches: false, compareBeforeWrite: true, updateToWhenMatches: null);
json = JsonSerializer.Serialize((from l in identifiers orderby l.DirectoryNames.Length descending, l.Id select l).ToArray(), IdentifierCollectionSourceGenerationContext.Default.IdentifierArray);
_ = Shared.Models.Stateless.Methods.IPath.WriteAllText(Path.Combine(bMetadataCollectionDirectory, ".json"), json.Replace(rootDirectory, string.Empty), updateDateWhenMatches: false, compareBeforeWrite: true, updateToWhenMatches: null);
} }
return results.AsReadOnly(); string json = JsonSerializer.Serialize(identifiers.OrderBy(l => l.PaddedId).ToArray(), IdentifierCollectionSourceGenerationContext.Default.IdentifierArray);
_ = Shared.Models.Stateless.Methods.IPath.WriteAllText(Path.Combine(bMetadataCollectionDirectory, ".json"), json, updateDateWhenMatches: false, compareBeforeWrite: true, updateToWhenMatches: null);
} }
private ReadOnlyCollection<Mapping> GetMappings(Property.Models.Configuration propertyConfiguration, string eDistanceContentDirectory, ReadOnlyCollection<Container> readOnlyContainers, MapLogic mapLogic, bool distinctItems) private ReadOnlyCollection<Mapping> GetMappings(Property.Models.Configuration propertyConfiguration, string eDistanceContentDirectory, ReadOnlyCollection<Container> readOnlyContainers, MapLogic mapLogic, bool distinctItems)
@ -741,7 +744,7 @@ public partial class DlibDotNet : IDlibDotNet, IDisposable
} }
if (_Configuration.MoveToDecade && _Configuration.LocationContainerDistanceTolerance is null) if (_Configuration.MoveToDecade && _Configuration.LocationContainerDistanceTolerance is null)
_ = Shared.Models.Stateless.Methods.IPath.DeleteEmptyDirectories(eDistanceContentDirectory); _ = Shared.Models.Stateless.Methods.IPath.DeleteEmptyDirectories(eDistanceContentDirectory);
return results.AsReadOnly(); return new(results);
} }
private static void SavePropertyShortcutsForOutputResolutions(string eDistanceContentDirectory, ReadOnlyCollection<Item> distinctValidImageItems) private static void SavePropertyShortcutsForOutputResolutions(string eDistanceContentDirectory, ReadOnlyCollection<Item> distinctValidImageItems)
@ -850,7 +853,7 @@ public partial class DlibDotNet : IDlibDotNet, IDisposable
continue; continue;
results.Add(filePath); results.Add(filePath);
} }
return results.AsReadOnly(); return new(results);
} }
public ReadOnlyDictionary<string, LocationContainer> GetOnlyOne(IDistanceLimits distanceLimits, ReadOnlyCollection<LocationContainer> matrix) public ReadOnlyDictionary<string, LocationContainer> GetOnlyOne(IDistanceLimits distanceLimits, ReadOnlyCollection<LocationContainer> matrix)
@ -878,7 +881,7 @@ public partial class DlibDotNet : IDlibDotNet, IDisposable
added.Add(locationContainer.LengthSource.Name); added.Add(locationContainer.LengthSource.Name);
results.Add(locationContainer.LengthSource.Name, locationContainer); results.Add(locationContainer.LengthSource.Name, locationContainer);
} }
return results.AsReadOnly(); return new(results);
} }
private List<SaveContainer> GetSaveContainers(long ticks, ReadOnlyCollection<PersonContainer> personContainers, string a2PeopleSingletonDirectory, string eDistanceContentDirectory, ProgressBarOptions options, MapLogic mapLogic, string outputResolution) private List<SaveContainer> GetSaveContainers(long ticks, ReadOnlyCollection<PersonContainer> personContainers, string a2PeopleSingletonDirectory, string eDistanceContentDirectory, ProgressBarOptions options, MapLogic mapLogic, string outputResolution)
@ -902,7 +905,7 @@ public partial class DlibDotNet : IDlibDotNet, IDisposable
results = []; results = [];
else else
{ {
DistanceLimits distanceLimits = new(_Configuration.FaceAreaPermyriad, _Configuration.FaceConfidencePercent, _Configuration.FaceDistancePermyriad, _Configuration.RangeDaysDeltaTolerance, _Configuration.RangeDistanceTolerance, _Configuration.RangeFaceAreaTolerance, _Configuration.RangeFaceConfidence, _Configuration.SortingMaximumPerFaceShouldBeHigh); DistanceLimits distanceLimits = new(_Configuration.FaceAreaPermyriad, _Configuration.FaceConfidencePercent, _Configuration.FaceDistancePermyriad, _Configuration.RangeDaysDeltaTolerance, _Configuration.RangeDistanceTolerance, _Configuration.RangeFaceAreaPermyriadTolerance, _Configuration.RangeFaceConfidence, _Configuration.SortingMaximumPerFaceShouldBeHigh);
List<LocationContainer> postFiltered = E_Distance.GetPostFilterLocationContainer(mapLogic, preFiltered, distanceLimits); List<LocationContainer> postFiltered = E_Distance.GetPostFilterLocationContainer(mapLogic, preFiltered, distanceLimits);
if (postFiltered.Count == 0) if (postFiltered.Count == 0)
results = []; results = [];
@ -917,7 +920,7 @@ public partial class DlibDotNet : IDlibDotNet, IDisposable
results = []; results = [];
else else
{ {
ReadOnlyDictionary<long, PersonContainer> personKeyToPersonContainer = PersonContainer.Extract(personContainers); ReadOnlyDictionary<long, PersonContainer> personKeyToPersonContainer = mapLogic.GetPersonKeyToPersonContainer();
results = mapLogic.GetSaveContainers(cResultsFullGroupDirectory, dResultsFullGroupDirectory, d2ResultsFullGroupDirectory, distanceLimits, onlyOne, personKeyToPersonContainer); results = mapLogic.GetSaveContainers(cResultsFullGroupDirectory, dResultsFullGroupDirectory, d2ResultsFullGroupDirectory, distanceLimits, onlyOne, personKeyToPersonContainer);
} }
} }
@ -930,7 +933,7 @@ public partial class DlibDotNet : IDlibDotNet, IDisposable
(_, _, string dResultsFullGroupDirectory, string d2ResultsFullGroupDirectory) = GetResultsFullGroupDirectories(outputResolution); (_, _, string dResultsFullGroupDirectory, string d2ResultsFullGroupDirectory) = GetResultsFullGroupDirectories(outputResolution);
string dFacesContentDirectory = Path.Combine(dResultsFullGroupDirectory, _Configuration.PropertyConfiguration.ResultContent); string dFacesContentDirectory = Path.Combine(dResultsFullGroupDirectory, _Configuration.PropertyConfiguration.ResultContent);
string d2FacePartsContentDirectory = Path.Combine(d2ResultsFullGroupDirectory, _Configuration.PropertyConfiguration.ResultContent); string d2FacePartsContentDirectory = Path.Combine(d2ResultsFullGroupDirectory, _Configuration.PropertyConfiguration.ResultContent);
string d2FacePartsContentCollectionDirectory = Path.Combine(d2ResultsFullGroupDirectory, _Configuration.PropertyConfiguration.ResultContentCollection); string d2FacePartsContentCollectionDirectory = Path.Combine(d2ResultsFullGroupDirectory, "[()]");
if (distinctValidImageMappingCollection.Count > 0) if (distinctValidImageMappingCollection.Count > 0)
{ {
Shared.Models.Stateless.Methods.IPath.ChangeDateForEmptyDirectories(d2FacePartsContentDirectory, ticks); Shared.Models.Stateless.Methods.IPath.ChangeDateForEmptyDirectories(d2FacePartsContentDirectory, ticks);
@ -991,10 +994,11 @@ public partial class DlibDotNet : IDlibDotNet, IDisposable
MappingFromFilterPre mappingFromFilterPre; MappingFromFilterPre mappingFromFilterPre;
MappingFromFilterPost mappingFromFilterPost; MappingFromFilterPost mappingFromFilterPost;
bool? isFocusModel = GetIsFocusModel(item.Property); bool? isFocusModel = GetIsFocusModel(item.Property);
ReadOnlyDictionary<int, ReadOnlyCollection<PersonContainer>>? wholePercentagesToPersonContainers = mapLogic.GetWholePercentagesToPersonContainers(item.Property?.Id);
long[] jLinkResolvedPersonKeys = _JLinkResolvedDirectories.Select(l => l.PersonKey).ToArray(); long[] jLinkResolvedPersonKeys = _JLinkResolvedDirectories.Select(l => l.PersonKey).ToArray();
ReadOnlyDictionary<int, ReadOnlyCollection<PersonContainer>>? wholePercentagesToPersonContainers;
foreach (Shared.Models.Face face in faces) foreach (Shared.Models.Face face in faces)
{ {
wholePercentagesToPersonContainers = mapLogic.GetWholePercentagesToPersonContainers(item.Property?.Id);
if (item.Property?.Id is null || face.FaceEncoding is null || face.Location is null || face.OutputResolution is null) if (item.Property?.Id is null || face.FaceEncoding is null || face.Location is null || face.OutputResolution is null)
{ {
canReMap = null; canReMap = null;
@ -1024,7 +1028,7 @@ public partial class DlibDotNet : IDlibDotNet, IDisposable
isFocusPerson = mapLogic.IsFocusPerson(_Configuration.SkipPersonWithMoreThen, jLinkResolvedPersonKeys, wholePercentagesToPersonContainers, mappingFromLocation); isFocusPerson = mapLogic.IsFocusPerson(_Configuration.SkipPersonWithMoreThen, jLinkResolvedPersonKeys, wholePercentagesToPersonContainers, mappingFromLocation);
mappingFromFilterPost = new(canReMap, inSkipCollection, isFocusPerson); mappingFromFilterPost = new(canReMap, inSkipCollection, isFocusPerson);
} }
mapping = Mapping.Get(item.FilePath, mappingFromFilterPost, mappingFromFilterPre, mappingFromItem, mappingFromLocation, mappingFromPhotoPrismCollection); mapping = new(item.FilePath, mappingFromFilterPost, mappingFromFilterPre, mappingFromItem, mappingFromLocation, mappingFromPhotoPrismCollection);
notMapped += mapLogic.UpdateMappingFromPerson(wholePercentagesToPersonContainers, mapping); notMapped += mapLogic.UpdateMappingFromPerson(wholePercentagesToPersonContainers, mapping);
face.SetMapping(mapping); face.SetMapping(mapping);
} }
@ -1075,16 +1079,16 @@ public partial class DlibDotNet : IDlibDotNet, IDisposable
int faceAreaPermyriad = 0; int faceAreaPermyriad = 0;
bool? isFocusModel = GetIsFocusModel(item.Property); bool? isFocusModel = GetIsFocusModel(item.Property);
long[] jLinkResolvedPersonKeys = _JLinkResolvedDirectories.Select(l => l.PersonKey).ToArray(); long[] jLinkResolvedPersonKeys = _JLinkResolvedDirectories.Select(l => l.PersonKey).ToArray();
ReadOnlyDictionary<int, ReadOnlyCollection<PersonContainer>>? wholePercentagesToPersonContainers = mapLogic.GetWholePercentagesToPersonContainers(mappingFromItem.Id);
int wholePercentRectangle = Shared.Models.Stateless.Methods.ILocation.GetWholePercentages(Shared.Models.Stateless.ILocation.Digits); int wholePercentRectangle = Shared.Models.Stateless.Methods.ILocation.GetWholePercentages(Shared.Models.Stateless.ILocation.Digits);
string deterministicHashCodeKey = IMapping.GetDeterministicHashCodeKey(item.FilePath, Shared.Models.Stateless.ILocation.Digits); string deterministicHashCodeKey = IMapping.GetDeterministicHashCodeKey(item.FilePath, Shared.Models.Stateless.ILocation.Digits);
MappingFromLocation? mappingFromLocation = new(faceAreaPermyriad, confidencePercent, deterministicHashCodeKey, eyeα, eyeReview, wholePercentRectangle); MappingFromLocation? mappingFromLocation = new(faceAreaPermyriad, confidencePercent, deterministicHashCodeKey, eyeα, eyeReview, wholePercentRectangle);
bool? inSkipCollection = mapLogic.InSkipCollection(mappingFromItem.Id, mappingFromLocation); bool? inSkipCollection = mapLogic.InSkipCollection(mappingFromItem.Id, mappingFromLocation);
MappingFromFilterPre mappingFromFilterPre = new(inSkipCollection, isFocusModel, isFocusRelativePath); MappingFromFilterPre mappingFromFilterPre = new(inSkipCollection, isFocusModel, isFocusRelativePath);
ReadOnlyDictionary<int, ReadOnlyCollection<PersonContainer>>? wholePercentagesToPersonContainers = mapLogic.GetWholePercentagesToPersonContainers(mappingFromItem.Id);
bool? canReMap = Map.Models.Stateless.Methods.IMapLogic.CanReMap(jLinkResolvedPersonKeys, wholePercentagesToPersonContainers, mappingFromLocation); bool? canReMap = Map.Models.Stateless.Methods.IMapLogic.CanReMap(jLinkResolvedPersonKeys, wholePercentagesToPersonContainers, mappingFromLocation);
bool? isFocusPerson = mapLogic.IsFocusPerson(_Configuration.SkipPersonWithMoreThen, jLinkResolvedPersonKeys, wholePercentagesToPersonContainers, mappingFromLocation); bool? isFocusPerson = mapLogic.IsFocusPerson(_Configuration.SkipPersonWithMoreThen, jLinkResolvedPersonKeys, wholePercentagesToPersonContainers, mappingFromLocation);
MappingFromFilterPost mappingFromFilterPost = new(canReMap, inSkipCollection, isFocusPerson); MappingFromFilterPost mappingFromFilterPost = new(canReMap, inSkipCollection, isFocusPerson);
result = Mapping.Get(item.FilePath, mappingFromFilterPost, mappingFromFilterPre, mappingFromItem, mappingFromLocation, mappingFromPhotoPrismCollection: null); result = new(item.FilePath, mappingFromFilterPost, mappingFromFilterPre, mappingFromItem, mappingFromLocation, mappingFromPhotoPrismCollection: null);
int notMapped = mapLogic.UpdateMappingFromPerson(wholePercentagesToPersonContainers, result); int notMapped = mapLogic.UpdateMappingFromPerson(wholePercentagesToPersonContainers, result);
return (result, notMapped); return (result, notMapped);
} }
@ -1095,13 +1099,16 @@ public partial class DlibDotNet : IDlibDotNet, IDisposable
string outputResolution, string outputResolution,
bool outputResolutionHasNumber, bool outputResolutionHasNumber,
string cResultsFullGroupDirectory, string cResultsFullGroupDirectory,
string dResultsFullGroupDirectory,
string d2ResultsFullGroupDirectory, string d2ResultsFullGroupDirectory,
List<Tuple<string, DateTime>> sourceDirectoryChanges, List<Tuple<string, DateTime>> sourceDirectoryChanges,
Dictionary<int, List<MappingFromPhotoPrism>> fileNameToCollection, Dictionary<int, List<MappingFromPhotoPrism>> fileNameToCollection,
Container container, Container container,
int index,
Item item, Item item,
DateTime[] containerDateTimes, DateTime[] containerDateTimes,
bool? isFocusRelativePath) bool? isFocusRelativePath,
string facePartsCollectionDirectory)
{ {
int result = 0; int result = 0;
List<Shared.Models.Face> faces; List<Shared.Models.Face> faces;
@ -1159,7 +1166,7 @@ public partial class DlibDotNet : IDlibDotNet, IDisposable
} }
if (resizedFileHolder.Exists && item.FilePath.HasIgnoreKeyword is not null && item.FilePath.HasIgnoreKeyword.Value != shouldIgnore.Value) if (resizedFileHolder.Exists && item.FilePath.HasIgnoreKeyword is not null && item.FilePath.HasIgnoreKeyword.Value != shouldIgnore.Value)
{ {
if (!item.FilePath.DirectoryFullPath.Contains("Results") || !item.FilePath.DirectoryFullPath.Contains("Resize")) if (!item.FilePath.DirectoryName.Contains("Results") || !item.FilePath.DirectoryName.Contains("Resize"))
throw new NotSupportedException($"Rename File! <{item.FilePath.FileNameFirstSegment}>"); throw new NotSupportedException($"Rename File! <{item.FilePath.FileNameFirstSegment}>");
else else
{ {
@ -1212,9 +1219,11 @@ public partial class DlibDotNet : IDlibDotNet, IDisposable
if (!fileNameToCollection.TryGetValue(mappingFromItem.Id, out mappingFromPhotoPrismCollection)) if (!fileNameToCollection.TryGetValue(mappingFromItem.Id, out mappingFromPhotoPrismCollection))
mappingFromPhotoPrismCollection = null; mappingFromPhotoPrismCollection = null;
bool move = _Configuration.DistanceMoveUnableToMatch || _Configuration.DistanceRenameToMatch && _Configuration.LoadOrCreateThenSaveDistanceResultsForOutputResolutions.Contains(outputResolution); bool move = _Configuration.DistanceMoveUnableToMatch || _Configuration.DistanceRenameToMatch && _Configuration.LoadOrCreateThenSaveDistanceResultsForOutputResolutions.Contains(outputResolution);
faces = _Faces.GetFaces(outputResolution, cResultsFullGroupDirectory, item.FilePath, subFileTuples, parseExceptions, property, mappingFromItem, outputResolutionToResize, mappingFromPhotoPrismCollection); faces = _Faces.GetFaces(outputResolution, cResultsFullGroupDirectory, dResultsFullGroupDirectory, item.FilePath, subFileTuples, parseExceptions, property, mappingFromItem, outputResolutionToResize, mappingFromPhotoPrismCollection);
result = GetNotMappedCountAndUpdateMappingFromPersonThenSetMapping(mapLogic, item, isFocusRelativePath, mappingFromItem, mappingFromPhotoPrismCollection, faces); result = GetNotMappedCountAndUpdateMappingFromPersonThenSetMapping(mapLogic, item, isFocusRelativePath, mappingFromItem, mappingFromPhotoPrismCollection, faces);
List<(Shared.Models.Face, FileHolder?, string, bool Saved)> faceCollection = _Faces.SaveFaces(item.FilePath, subFileTuples, parseExceptions, mappingFromItem, exifDirectory, faces); List<(Shared.Models.Face, FileHolder?, string, bool Saved)> faceCollection = _Faces.SaveFaces(_FaceParts.FileNameExtension, dResultsFullGroupDirectory, item.FilePath, subFileTuples, parseExceptions, mappingFromItem, exifDirectory, faces);
if (_Configuration.CopyFacesAndSaveFaceLandmarkForOutputResolutions.Contains(outputResolution))
_FaceParts.CopyFacesAndSaveFaceLandmarkImage(facePartsCollectionDirectory, mappingFromItem, faceCollection);
if (move && faceCollection.All(l => !l.Saved)) if (move && faceCollection.All(l => !l.Saved))
{ {
ReadOnlyCollection<LocationContainer> locationContainers = mapLogic.GetLocationContainers(item); ReadOnlyCollection<LocationContainer> locationContainers = mapLogic.GetLocationContainers(item);
@ -1231,10 +1240,8 @@ public partial class DlibDotNet : IDlibDotNet, IDisposable
{ {
bool saveRotated = false; bool saveRotated = false;
string sourceDirectorySegment = Property.Models.Stateless.IResult.GetRelativePath(_Configuration.PropertyConfiguration, container.SourceDirectory); string sourceDirectorySegment = Property.Models.Stateless.IResult.GetRelativePath(_Configuration.PropertyConfiguration, container.SourceDirectory);
_FaceParts.SaveFaceLandmarkImages(_Configuration.PropertyConfiguration, d2ResultsFullGroupDirectory, item.FilePath, subFileTuples, parseExceptions, mappingFromItem, exifDirectory, faces, saveRotated); _FaceParts.SaveFaceLandmarkImages(_Configuration.PropertyConfiguration, item.FilePath, subFileTuples, parseExceptions, mappingFromItem, faces, saveRotated);
} }
if (_Configuration.SaveFaceLandmarkForOutputResolutionsV2.Contains(outputResolution))
_FaceParts.SaveFaceLandmarkImages(d2ResultsFullGroupDirectory, mappingFromItem, exifDirectory, faces);
} }
lock (sourceDirectoryChanges) lock (sourceDirectoryChanges)
{ {
@ -1251,6 +1258,7 @@ public partial class DlibDotNet : IDlibDotNet, IDisposable
string outputResolution, string outputResolution,
bool outputResolutionHasNumber, bool outputResolutionHasNumber,
string cResultsFullGroupDirectory, string cResultsFullGroupDirectory,
string dResultsFullGroupDirectory,
string d2ResultsFullGroupDirectory, string d2ResultsFullGroupDirectory,
List<Tuple<string, DateTime>> sourceDirectoryChanges, List<Tuple<string, DateTime>> sourceDirectoryChanges,
Dictionary<int, List<MappingFromPhotoPrism>> fileNameToCollection, Dictionary<int, List<MappingFromPhotoPrism>> fileNameToCollection,
@ -1265,6 +1273,7 @@ public partial class DlibDotNet : IDlibDotNet, IDisposable
ProgressBarOptions options = new() { ProgressCharacter = '─', ProgressBarOnBottom = true, DisableBottomPercentage = true }; ProgressBarOptions options = new() { ProgressCharacter = '─', ProgressBarOnBottom = true, DisableBottomPercentage = true };
string focusRelativePath = Path.GetFullPath(string.Concat(_Configuration.PropertyConfiguration.RootDirectory, _Configuration.FocusDirectory)); string focusRelativePath = Path.GetFullPath(string.Concat(_Configuration.PropertyConfiguration.RootDirectory, _Configuration.FocusDirectory));
bool? isFocusRelativePath = string.IsNullOrEmpty(_Configuration.FocusDirectory) ? null : container.SourceDirectory.StartsWith(focusRelativePath); bool? isFocusRelativePath = string.IsNullOrEmpty(_Configuration.FocusDirectory) ? null : container.SourceDirectory.StartsWith(focusRelativePath);
string facePartsCollectionDirectory = _Configuration.CopyFacesAndSaveFaceLandmarkForOutputResolutions.Contains(outputResolution) ? _FaceParts.GetFacePartsDirectory(_Configuration.PropertyConfiguration, d2ResultsFullGroupDirectory, item: filteredItems.First(), includeNameWithoutExtension: false) : string.Empty;
bool anyPropertiesChangedForX = _Configuration.PropertyConfiguration.PropertiesChangedForProperty || _Configuration.PropertiesChangedForDistance || _Configuration.PropertiesChangedForFaces || _Configuration.PropertiesChangedForIndex || _Configuration.PropertiesChangedForMetadata || _Configuration.PropertiesChangedForResize; bool anyPropertiesChangedForX = _Configuration.PropertyConfiguration.PropertiesChangedForProperty || _Configuration.PropertiesChangedForDistance || _Configuration.PropertiesChangedForFaces || _Configuration.PropertiesChangedForIndex || _Configuration.PropertiesChangedForMetadata || _Configuration.PropertiesChangedForResize;
using ProgressBar progressBar = new(filteredItems.Count, message, options); using ProgressBar progressBar = new(filteredItems.Count, message, options);
_ = Parallel.For(0, filteredItems.Count, parallelOptions, (i, state) => _ = Parallel.For(0, filteredItems.Count, parallelOptions, (i, state) =>
@ -1277,13 +1286,16 @@ public partial class DlibDotNet : IDlibDotNet, IDisposable
outputResolution, outputResolution,
outputResolutionHasNumber, outputResolutionHasNumber,
cResultsFullGroupDirectory, cResultsFullGroupDirectory,
dResultsFullGroupDirectory,
d2ResultsFullGroupDirectory, d2ResultsFullGroupDirectory,
sourceDirectoryChanges, sourceDirectoryChanges,
fileNameToCollection, fileNameToCollection,
container, container,
index: i,
filteredItems[i], filteredItems[i],
containerDateTimes, containerDateTimes,
isFocusRelativePath); isFocusRelativePath,
facePartsCollectionDirectory);
if (!anyPropertiesChangedForX && (i == 0 || sourceDirectoryChanges.Count > 0)) if (!anyPropertiesChangedForX && (i == 0 || sourceDirectoryChanges.Count > 0))
progressBar.Tick(); progressBar.Tick();
} }
@ -1356,7 +1368,7 @@ public partial class DlibDotNet : IDlibDotNet, IDisposable
ReadOnlyCollection<SortingContainer> sortingContainers; ReadOnlyCollection<SortingContainer> sortingContainers;
FaceDistanceContainer[] filteredFaceDistanceContainers; FaceDistanceContainer[] filteredFaceDistanceContainers;
long? skipOlderThan = _Configuration.SkipOlderThanDays is null ? null : new DateTime(ticks).AddDays(-_Configuration.SkipOlderThanDays.Value).Ticks; long? skipOlderThan = _Configuration.SkipOlderThanDays is null ? null : new DateTime(ticks).AddDays(-_Configuration.SkipOlderThanDays.Value).Ticks;
distanceLimits = new(_Configuration.FaceAreaPermyriad, _Configuration.FaceConfidencePercent, _Configuration.FaceDistancePermyriad, _Configuration.RangeDaysDeltaTolerance, _Configuration.RangeDistanceTolerance, _Configuration.RangeFaceAreaTolerance, _Configuration.RangeFaceConfidence, _Configuration.SortingMaximumPerFaceShouldBeHigh); distanceLimits = new(_Configuration.FaceAreaPermyriad, _Configuration.FaceConfidencePercent, _Configuration.FaceDistancePermyriad, _Configuration.RangeDaysDeltaTolerance, _Configuration.RangeDistanceTolerance, _Configuration.RangeFaceAreaPermyriadTolerance, _Configuration.RangeFaceConfidence, _Configuration.SortingMaximumPerFaceShouldBeHigh);
filteredFaceDistanceContainers = E_Distance.FilteredPostLoadFaceDistanceContainers(mapLogic, faceDistanceContainers, skipOlderThan, distanceLimits); filteredFaceDistanceContainers = E_Distance.FilteredPostLoadFaceDistanceContainers(mapLogic, faceDistanceContainers, skipOlderThan, distanceLimits);
if (filteredFaceDistanceContainers.Length == 0) if (filteredFaceDistanceContainers.Length == 0)
_Logger?.LogInformation("All images have been filtered!"); _Logger?.LogInformation("All images have been filtered!");
@ -1367,7 +1379,7 @@ public partial class DlibDotNet : IDlibDotNet, IDisposable
{ {
for (useFiltersCounter = 1; useFiltersCounter < _Configuration.UseFilterTries; useFiltersCounter++) for (useFiltersCounter = 1; useFiltersCounter < _Configuration.UseFilterTries; useFiltersCounter++)
{ {
distanceLimits = new(_Configuration.FaceAreaPermyriad, _Configuration.FaceConfidencePercent, _Configuration.FaceDistancePermyriad, _Configuration.RangeDaysDeltaTolerance, _Configuration.RangeDistanceTolerance, _Configuration.RangeFaceAreaTolerance, _Configuration.RangeFaceConfidence, _Configuration.SortingMaximumPerFaceShouldBeHigh, useFiltersCounter); distanceLimits = new(_Configuration.FaceAreaPermyriad, _Configuration.FaceConfidencePercent, _Configuration.FaceDistancePermyriad, _Configuration.RangeDaysDeltaTolerance, _Configuration.RangeDistanceTolerance, _Configuration.RangeFaceAreaPermyriadTolerance, _Configuration.RangeFaceConfidence, _Configuration.SortingMaximumPerFaceShouldBeHigh, useFiltersCounter);
filteredFaceDistanceContainers = E_Distance.FilteredPostLoadFaceDistanceContainers(mapLogic, faceDistanceContainers, skipOlderThan, distanceLimits); filteredFaceDistanceContainers = E_Distance.FilteredPostLoadFaceDistanceContainers(mapLogic, faceDistanceContainers, skipOlderThan, distanceLimits);
if (filteredFaceDistanceContainers.Length == 0) if (filteredFaceDistanceContainers.Length == 0)
_Logger?.LogInformation("All images have been filtered!"); _Logger?.LogInformation("All images have been filtered!");
@ -1462,13 +1474,13 @@ public partial class DlibDotNet : IDlibDotNet, IDisposable
ProgressBar progressBar; ProgressBar progressBar;
string filesCollectionRootDirectory = _Configuration.PropertyConfiguration.RootDirectory; string filesCollectionRootDirectory = _Configuration.PropertyConfiguration.RootDirectory;
(string cResultsFullGroupDirectory, _, _, _) = GetResultsFullGroupDirectories(outputResolution); (string cResultsFullGroupDirectory, _, _, _) = GetResultsFullGroupDirectories(outputResolution);
IReadOnlyDictionary<string, ReadOnlyDictionary<byte, ReadOnlyCollection<string>>> fileGroups = Shared.Models.Stateless.Methods.IPath.GetKeyValuePairs(_Configuration.PropertyConfiguration, cResultsFullGroupDirectory, [_Configuration.PropertyConfiguration.ResultContent, _Configuration.PropertyConfiguration.ResultContentCollection]); IReadOnlyDictionary<string, string[]> fileGroups = Shared.Models.Stateless.Methods.IPath.GetKeyValuePairs(_Configuration.PropertyConfiguration, cResultsFullGroupDirectory, [_Configuration.PropertyConfiguration.ResultContent]);
ReadOnlyCollection<ReadOnlyCollection<FilePath>> filePathsCollection = IDirectory.GetFilePathCollections(_Configuration.PropertyConfiguration, directorySearchFilter, fileSearchFilter, filesCollectionRootDirectory, useCeilingAverage: false); ReadOnlyCollection<ReadOnlyCollection<FilePath>> filePathsCollection = IDirectory.GetFilePathCollections(_Configuration.PropertyConfiguration, filesCollectionRootDirectory, directorySearchFilter, fileSearchFilter, useCeilingAverage: false);
int count = filePathsCollection.Select(l => l.Count).Sum(); int count = filePathsCollection.Select(l => l.Count).Sum();
bool filesCollectionCountIsOne = IsFilesCollectionCountIsOne(filePathsCollection); bool filesCollectionCountIsOne = IsFilesCollectionCountIsOne(filePathsCollection);
string message = $") Selecting for ## pattern directory - {(int)Math.Floor(new TimeSpan(DateTime.Now.Ticks - ticks).TotalSeconds)} total second(s)"; string message = $") Selecting for ## pattern directory - {(int)Math.Floor(new TimeSpan(DateTime.Now.Ticks - ticks).TotalSeconds)} total second(s)";
progressBar = new(count, message, options); progressBar = new(count, message, options);
(string[] distinctDirectories, List<(FilePath, string)> toDoCollection) = IDirectory.GetToDoCollection(_Configuration.PropertyConfiguration, filePathsCollection, fileGroups, () => progressBar.Tick()); (string[] distinctDirectories, List<(FilePath, string)> toDoCollection) = IDirectory.GetToDoCollection(_Configuration.PropertyConfiguration, filePathsCollection, fileGroups[_Configuration.PropertyConfiguration.ResultContent], () => progressBar.Tick());
progressBar.Dispose(); progressBar.Dispose();
foreach (string distinctDirectory in distinctDirectories) foreach (string distinctDirectory in distinctDirectories)
{ {

View File

@ -4,13 +4,13 @@
<Nullable>enable</Nullable> <Nullable>enable</Nullable>
<OutputType>Exe</OutputType> <OutputType>Exe</OutputType>
<RuntimeIdentifier>win-x64</RuntimeIdentifier> <RuntimeIdentifier>win-x64</RuntimeIdentifier>
<TargetFramework>net9.0</TargetFramework> <TargetFramework>net8.0</TargetFramework>
<UserSecretsId>2999dda1-5329-4d9f-9d68-cccfabe0e47f</UserSecretsId> <UserSecretsId>2999dda1-5329-4d9f-9d68-cccfabe0e47f</UserSecretsId>
</PropertyGroup> </PropertyGroup>
<PropertyGroup> <PropertyGroup>
<PackageId>Phares.View.by.Distance.Instance</PackageId> <PackageId>Phares.View.by.Distance.Instance</PackageId>
<GeneratePackageOnBuild>false</GeneratePackageOnBuild> <GeneratePackageOnBuild>false</GeneratePackageOnBuild>
<Version>9.0.100.1</Version> <Version>8.0.101.1</Version>
<Authors>Mike Phares</Authors> <Authors>Mike Phares</Authors>
<Company>Phares</Company> <Company>Phares</Company>
<IncludeSymbols>true</IncludeSymbols> <IncludeSymbols>true</IncludeSymbols>
@ -34,12 +34,12 @@
<SupportedPlatform Include="browser" /> <SupportedPlatform Include="browser" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Cryptography.KeyDerivation" Version="9.0.2" /> <PackageReference Include="Microsoft.AspNetCore.Cryptography.KeyDerivation" Version="8.0.7" />
<PackageReference Include="Microsoft.Extensions.Hosting" Version="9.0.2" /> <PackageReference Include="Microsoft.Extensions.Hosting" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.Identity.Core" Version="9.0.2" /> <PackageReference Include="Microsoft.Extensions.Identity.Core" Version="8.0.7" />
<PackageReference Include="Microsoft.Extensions.Options" Version="9.0.2" /> <PackageReference Include="Microsoft.Extensions.Options" Version="8.0.2" />
<PackageReference Include="System.Drawing.Common" Version="8.0.10" /> <PackageReference Include="System.Drawing.Common" Version="8.0.7" />
<PackageReference Include="System.Text.Json" Version="9.0.2" /> <PackageReference Include="System.Text.Json" Version="8.0.4" />
<PackageReference Include="MetadataExtractor" Version="2.8.1" /> <PackageReference Include="MetadataExtractor" Version="2.8.1" />
<PackageReference Include="ShellProgressBar" Version="5.2.0" /> <PackageReference Include="ShellProgressBar" Version="5.2.0" />
<PackageReference Include="WindowsShortcutFactory" Version="1.2.0" /> <PackageReference Include="WindowsShortcutFactory" Version="1.2.0" />

View File

@ -9,6 +9,7 @@ public class Configuration
public bool? CheckDFaceAndUpWriteDates { get; set; } public bool? CheckDFaceAndUpWriteDates { get; set; }
public bool? CheckJsonForDistanceResults { get; set; } public bool? CheckJsonForDistanceResults { get; set; }
public string[]? CopyFacesAndSaveFaceLandmarkForOutputResolutions { get; set; }
public int? CrossDirectoryMaxItemsInDistanceCollection { get; set; } public int? CrossDirectoryMaxItemsInDistanceCollection { get; set; }
public bool? DeletePossibleDuplicates { get; set; } public bool? DeletePossibleDuplicates { get; set; }
public int? DistanceFactor { get; set; } public int? DistanceFactor { get; set; }
@ -27,8 +28,6 @@ public class Configuration
public bool? ForceResizeLastWriteTimeToCreationTime { get; set; } public bool? ForceResizeLastWriteTimeToCreationTime { get; set; }
public string? GenealogicalDataCommunicationFile { get; set; } public string? GenealogicalDataCommunicationFile { get; set; }
public string? ImmichAssetsFile { get; set; } public string? ImmichAssetsFile { get; set; }
public string? ImmichOwnerId { get; set; }
public string? ImmichRoot { get; set; }
public string[]? IgnoreExtensions { get; set; } public string[]? IgnoreExtensions { get; set; }
public string[]? JLinks { get; set; } public string[]? JLinks { get; set; }
public string? LinkedAlpha { get; set; } public string? LinkedAlpha { get; set; }
@ -78,7 +77,6 @@ public class Configuration
public string[]? SaveBlurHashForOutputResolutions { get; set; } public string[]? SaveBlurHashForOutputResolutions { get; set; }
public string[]? SaveFaceDistancesForOutputResolutions { get; set; } public string[]? SaveFaceDistancesForOutputResolutions { get; set; }
public string[]? SaveFaceLandmarkForOutputResolutions { get; set; } public string[]? SaveFaceLandmarkForOutputResolutions { get; set; }
public string[]? SaveFaceLandmarkForOutputResolutionsV2 { get; set; }
public string[]? SaveFilteredOriginalImagesFromJLinksForOutputResolutions { get; set; } public string[]? SaveFilteredOriginalImagesFromJLinksForOutputResolutions { get; set; }
public bool? SaveFullYearOfRandomFiles { get; set; } public bool? SaveFullYearOfRandomFiles { get; set; }
public bool? SaveIndividually { get; set; } public bool? SaveIndividually { get; set; }
@ -131,6 +129,7 @@ public class Configuration
if (configuration.CheckDFaceAndUpWriteDates is null) throw new NullReferenceException(nameof(configuration.CheckDFaceAndUpWriteDates)); if (configuration.CheckDFaceAndUpWriteDates is null) throw new NullReferenceException(nameof(configuration.CheckDFaceAndUpWriteDates));
if (configuration?.CheckDFaceAndUpWriteDates is null) throw new NullReferenceException(nameof(configuration.CheckDFaceAndUpWriteDates)); if (configuration?.CheckDFaceAndUpWriteDates is null) throw new NullReferenceException(nameof(configuration.CheckDFaceAndUpWriteDates));
if (configuration?.CheckJsonForDistanceResults is null) throw new NullReferenceException(nameof(configuration.CheckJsonForDistanceResults)); if (configuration?.CheckJsonForDistanceResults is null) throw new NullReferenceException(nameof(configuration.CheckJsonForDistanceResults));
// if (configuration?.CopyFacesAndSaveFaceLandmarkForOutputResolutions is null) throw new NullReferenceException(nameof(configuration.CopyFacesAndSaveFaceLandmarkForOutputResolutions));
if (configuration?.CrossDirectoryMaxItemsInDistanceCollection is null) throw new NullReferenceException(nameof(configuration.CrossDirectoryMaxItemsInDistanceCollection)); if (configuration?.CrossDirectoryMaxItemsInDistanceCollection is null) throw new NullReferenceException(nameof(configuration.CrossDirectoryMaxItemsInDistanceCollection));
if (configuration?.DeletePossibleDuplicates is null) throw new NullReferenceException(nameof(configuration.DeletePossibleDuplicates)); if (configuration?.DeletePossibleDuplicates is null) throw new NullReferenceException(nameof(configuration.DeletePossibleDuplicates));
if (configuration?.DistanceFactor is null) throw new NullReferenceException(nameof(configuration.DistanceFactor)); if (configuration?.DistanceFactor is null) throw new NullReferenceException(nameof(configuration.DistanceFactor));
@ -149,8 +148,6 @@ public class Configuration
if (configuration?.ForceResizeLastWriteTimeToCreationTime is null) throw new NullReferenceException(nameof(configuration.ForceResizeLastWriteTimeToCreationTime)); if (configuration?.ForceResizeLastWriteTimeToCreationTime is null) throw new NullReferenceException(nameof(configuration.ForceResizeLastWriteTimeToCreationTime));
if (configuration?.GenealogicalDataCommunicationFile is null) throw new NullReferenceException(nameof(configuration.GenealogicalDataCommunicationFile)); if (configuration?.GenealogicalDataCommunicationFile is null) throw new NullReferenceException(nameof(configuration.GenealogicalDataCommunicationFile));
if (configuration?.ImmichAssetsFile is null) throw new NullReferenceException(nameof(configuration.ImmichAssetsFile)); if (configuration?.ImmichAssetsFile is null) throw new NullReferenceException(nameof(configuration.ImmichAssetsFile));
if (configuration?.ImmichOwnerId is null) throw new NullReferenceException(nameof(configuration.ImmichOwnerId));
if (configuration?.ImmichRoot is null) throw new NullReferenceException(nameof(configuration.ImmichRoot));
// if (configuration?.IgnoreExtensions is null) throw new NullReferenceException(nameof(configuration.IgnoreExtensions)); // if (configuration?.IgnoreExtensions is null) throw new NullReferenceException(nameof(configuration.IgnoreExtensions));
// if (configuration?.JLinks is null) throw new NullReferenceException(nameof(configuration.JLinks)); // if (configuration?.JLinks is null) throw new NullReferenceException(nameof(configuration.JLinks));
// if (configuration?.LinkedAlpha is null) throw new NullReferenceException(nameof(configuration.LinkedAlpha)); // if (configuration?.LinkedAlpha is null) throw new NullReferenceException(nameof(configuration.LinkedAlpha));
@ -200,7 +197,6 @@ public class Configuration
// if (configuration?.SaveBlurHashForOutputResolutions is null) throw new NullReferenceException(nameof(configuration.SaveBlurHashForOutputResolutions)); // if (configuration?.SaveBlurHashForOutputResolutions is null) throw new NullReferenceException(nameof(configuration.SaveBlurHashForOutputResolutions));
// if (configuration?.SaveFaceDistancesForOutputResolutions is null) throw new NullReferenceException(nameof(configuration.SaveFaceDistancesForOutputResolutions)); // if (configuration?.SaveFaceDistancesForOutputResolutions is null) throw new NullReferenceException(nameof(configuration.SaveFaceDistancesForOutputResolutions));
// if (configuration?.SaveFaceLandmarkForOutputResolutions is null) throw new NullReferenceException(nameof(configuration.SaveFaceLandmarkForOutputResolutions)); // if (configuration?.SaveFaceLandmarkForOutputResolutions is null) throw new NullReferenceException(nameof(configuration.SaveFaceLandmarkForOutputResolutions));
// if (configuration?.SaveFaceLandmarkForOutputResolutionsV2 is null) throw new NullReferenceException(nameof(configuration.SaveFaceLandmarkForOutputResolutionsV2));
// if (configuration?.SaveFilteredOriginalImagesFromJLinksForOutputResolutions is null) throw new NullReferenceException(nameof(configuration.SaveFilteredOriginalImagesFromJLinksForOutputResolutions)); // if (configuration?.SaveFilteredOriginalImagesFromJLinksForOutputResolutions is null) throw new NullReferenceException(nameof(configuration.SaveFilteredOriginalImagesFromJLinksForOutputResolutions));
if (configuration?.SaveFullYearOfRandomFiles is null) throw new NullReferenceException(nameof(configuration.SaveFullYearOfRandomFiles)); if (configuration?.SaveFullYearOfRandomFiles is null) throw new NullReferenceException(nameof(configuration.SaveFullYearOfRandomFiles));
if (configuration?.SaveIndividually is null) throw new NullReferenceException(nameof(configuration.SaveIndividually)); if (configuration?.SaveIndividually is null) throw new NullReferenceException(nameof(configuration.SaveIndividually));
@ -225,6 +221,7 @@ public class Configuration
result = new(propertyConfiguration, result = new(propertyConfiguration,
configuration.CheckDFaceAndUpWriteDates.Value, configuration.CheckDFaceAndUpWriteDates.Value,
configuration.CheckJsonForDistanceResults.Value, configuration.CheckJsonForDistanceResults.Value,
configuration.CopyFacesAndSaveFaceLandmarkForOutputResolutions ?? [],
configuration.CrossDirectoryMaxItemsInDistanceCollection.Value, configuration.CrossDirectoryMaxItemsInDistanceCollection.Value,
configuration.DeletePossibleDuplicates.Value, configuration.DeletePossibleDuplicates.Value,
configuration.DistanceFactor.Value, configuration.DistanceFactor.Value,
@ -243,8 +240,6 @@ public class Configuration
configuration.ForceResizeLastWriteTimeToCreationTime.Value, configuration.ForceResizeLastWriteTimeToCreationTime.Value,
configuration.GenealogicalDataCommunicationFile, configuration.GenealogicalDataCommunicationFile,
configuration.ImmichAssetsFile, configuration.ImmichAssetsFile,
configuration.ImmichOwnerId,
configuration.ImmichRoot,
configuration.IgnoreExtensions ?? [], configuration.IgnoreExtensions ?? [],
configuration.JLinks ?? [], configuration.JLinks ?? [],
configuration.LinkedAlpha, configuration.LinkedAlpha,
@ -294,7 +289,6 @@ public class Configuration
configuration.SaveBlurHashForOutputResolutions ?? [], configuration.SaveBlurHashForOutputResolutions ?? [],
configuration.SaveFaceDistancesForOutputResolutions ?? [], configuration.SaveFaceDistancesForOutputResolutions ?? [],
configuration.SaveFaceLandmarkForOutputResolutions ?? [], configuration.SaveFaceLandmarkForOutputResolutions ?? [],
configuration.SaveFaceLandmarkForOutputResolutionsV2 ?? [],
configuration.SaveFilteredOriginalImagesFromJLinksForOutputResolutions ?? [], configuration.SaveFilteredOriginalImagesFromJLinksForOutputResolutions ?? [],
configuration.SaveFullYearOfRandomFiles.Value, configuration.SaveFullYearOfRandomFiles.Value,
configuration.SaveIndividually.Value, configuration.SaveIndividually.Value,

View File

@ -54,7 +54,7 @@ public class Place
results.Add(Get(place)); results.Add(Get(place));
} }
} }
return results.AsReadOnly(); return new(results);
} }
} }

View File

@ -3,6 +3,7 @@ namespace View_by_Distance.Instance.Models;
public record Configuration(Property.Models.Configuration PropertyConfiguration, public record Configuration(Property.Models.Configuration PropertyConfiguration,
bool CheckDFaceAndUpWriteDates, bool CheckDFaceAndUpWriteDates,
bool CheckJsonForDistanceResults, bool CheckJsonForDistanceResults,
string[] CopyFacesAndSaveFaceLandmarkForOutputResolutions,
int CrossDirectoryMaxItemsInDistanceCollection, int CrossDirectoryMaxItemsInDistanceCollection,
bool DeletePossibleDuplicates, bool DeletePossibleDuplicates,
int DistanceFactor, int DistanceFactor,
@ -21,8 +22,6 @@ public record Configuration(Property.Models.Configuration PropertyConfiguration,
bool ForceResizeLastWriteTimeToCreationTime, bool ForceResizeLastWriteTimeToCreationTime,
string GenealogicalDataCommunicationFile, string GenealogicalDataCommunicationFile,
string ImmichAssetsFile, string ImmichAssetsFile,
string ImmichOwnerId,
string ImmichRoot,
string[] IgnoreExtensions, string[] IgnoreExtensions,
string[] JLinks, string[] JLinks,
string? LinkedAlpha, string? LinkedAlpha,
@ -64,7 +63,7 @@ public record Configuration(Property.Models.Configuration PropertyConfiguration,
int RadomUseBirthdayMinimum, int RadomUseBirthdayMinimum,
int[] RangeDaysDeltaTolerance, int[] RangeDaysDeltaTolerance,
float[] RangeDistanceTolerance, float[] RangeDistanceTolerance,
float[] RangeFaceAreaTolerance, float[] RangeFaceAreaPermyriadTolerance,
float[] RangeFaceConfidence, float[] RangeFaceConfidence,
float[] RectangleIntersectMinimums, float[] RectangleIntersectMinimums,
bool ReMap, bool ReMap,
@ -72,7 +71,6 @@ public record Configuration(Property.Models.Configuration PropertyConfiguration,
string[] SaveBlurHashForOutputResolutions, string[] SaveBlurHashForOutputResolutions,
string[] SaveFaceDistancesForOutputResolutions, string[] SaveFaceDistancesForOutputResolutions,
string[] SaveFaceLandmarkForOutputResolutions, string[] SaveFaceLandmarkForOutputResolutions,
string[] SaveFaceLandmarkForOutputResolutionsV2,
string[] SaveFilteredOriginalImagesFromJLinksForOutputResolutions, string[] SaveFilteredOriginalImagesFromJLinksForOutputResolutions,
bool SaveFullYearOfRandomFiles, bool SaveFullYearOfRandomFiles,
bool SaveIndividually, bool SaveIndividually,

View File

@ -0,0 +1,27 @@
using System.Text.Json;
using System.Text.Json.Serialization;
namespace View_by_Distance.Instance.Models;
internal record Identifier(int Id, string PaddedId)
{
public override string ToString()
{
string result = JsonSerializer.Serialize(this, IdentifierSourceGenerationContext.Default.Identifier);
return result;
}
}
[JsonSourceGenerationOptions(WriteIndented = true)]
[JsonSerializable(typeof(Identifier))]
internal partial class IdentifierSourceGenerationContext : JsonSerializerContext
{
}
[JsonSourceGenerationOptions(WriteIndented = true)]
[JsonSerializable(typeof(Identifier[]))]
internal partial class IdentifierCollectionSourceGenerationContext : JsonSerializerContext
{
}

View File

@ -25,7 +25,7 @@ internal class F_Random
return result; return result;
} }
private static ReadOnlyDictionary<string, List<string>> GetDayToRelativePaths(ReadOnlyCollection<Mapping> distinctValidImageMappingCollection, string dateFormat, string immichOwnerId, string immichRoot, Dictionary<string, ImmichAsset> immichAssets, ReadOnlyDictionary<int, List<long>> idToPersonKeys) private static ReadOnlyDictionary<string, List<string>> GetDayToRelativePaths(ReadOnlyCollection<Mapping> distinctValidImageMappingCollection, string dateFormat, Dictionary<string, ImmichAsset> immichAssets, ReadOnlyDictionary<int, List<long>> idToPersonKeys)
{ {
Dictionary<string, List<string>> results = []; Dictionary<string, List<string>> results = [];
string key; string key;
@ -36,7 +36,7 @@ internal class F_Random
bool immichAssetsCountIsZero = immichAssets.Count == 0; bool immichAssetsCountIsZero = immichAssets.Count == 0;
foreach (Mapping mapping in distinctValidImageMappingCollection) foreach (Mapping mapping in distinctValidImageMappingCollection)
{ {
if (mapping.MappingFromItem.FilePath.DirectoryFullPath is null || mapping.MappingFromPerson is null) if (mapping.MappingFromItem.FilePath.DirectoryName is null || mapping.MappingFromPerson is null)
continue; continue;
if (!idToPersonKeys.TryGetValue(mapping.MappingFromItem.Id, out personKeys)) if (!idToPersonKeys.TryGetValue(mapping.MappingFromItem.Id, out personKeys))
continue; continue;
@ -56,14 +56,12 @@ internal class F_Random
relativePaths.Add(mapping.MappingFromItem.RelativePath); relativePaths.Add(mapping.MappingFromItem.RelativePath);
else else
{ {
if (!immichAssets.TryGetValue($"{immichRoot}{mapping.MappingFromItem.RelativePath}", out immichAsset)) if (!immichAssets.TryGetValue(mapping.MappingFromItem.RelativePath, out immichAsset))
continue; continue;
if (!immichAsset.Path.Contains(immichOwnerId)) relativePaths.Add(immichAsset.PreviewPath);
continue;
relativePaths.Add(immichAsset.Path.Split(immichOwnerId)[1]);
} }
} }
return results.AsReadOnly(); return new(results);
} }
private static Dictionary<string, ImmichAsset> GetImmichAssets(string immichAssetsFile) private static Dictionary<string, ImmichAsset> GetImmichAssets(string immichAssetsFile)
@ -82,7 +80,7 @@ internal class F_Random
return results; return results;
} }
internal void Random(Property.Models.Configuration configuration, string immichAssetsFile, string immichOwnerId, string immichRoot, int radomUseBirthdayMinimum, string[] validKeyWordsToIgnoreInRandom, ReadOnlyDictionary<long, List<int>> personKeyToIds, ReadOnlyDictionary<int, Identifier> splatNineIdentifiers, ReadOnlyCollection<Mapping> distinctValidImageMappingCollection) internal void Random(Property.Models.Configuration configuration, string immichAssetsFile, int radomUseBirthdayMinimum, string[] validKeyWordsToIgnoreInRandom, ReadOnlyDictionary<long, List<int>> personKeyToIds, ReadOnlyCollection<int>? notNineCollection, ReadOnlyCollection<Mapping> distinctValidImageMappingCollection)
{ {
string key; string key;
string json; string json;
@ -95,9 +93,8 @@ internal class F_Random
List<int> distinctCollection = []; List<int> distinctCollection = [];
DateTime dateTime = new(2024, 1, 1); //Leap year DateTime dateTime = new(2024, 1, 1); //Leap year
Dictionary<string, ImmichAsset> immichAssets = GetImmichAssets(immichAssetsFile); Dictionary<string, ImmichAsset> immichAssets = GetImmichAssets(immichAssetsFile);
int[] splatNineIdentifiersKeys = splatNineIdentifiers.Select(l => l.Key).ToArray();
ReadOnlyDictionary<int, List<long>> idToPersonKeys = Map.Models.Stateless.Methods.IMapLogic.GetIdToPersonKeys(personKeyToIds); ReadOnlyDictionary<int, List<long>> idToPersonKeys = Map.Models.Stateless.Methods.IMapLogic.GetIdToPersonKeys(personKeyToIds);
ReadOnlyDictionary<string, List<string>> dayToRelativePaths = GetDayToRelativePaths(distinctValidImageMappingCollection, dateFormat, immichOwnerId, immichRoot, immichAssets, idToPersonKeys); ReadOnlyDictionary<string, List<string>> dayToRelativePaths = GetDayToRelativePaths(distinctValidImageMappingCollection, dateFormat, immichAssets, idToPersonKeys);
string fRandomCollectionDirectory = Property.Models.Stateless.IResult.GetResultsDateGroupDirectory(configuration, nameof(F_Random), "[]"); string fRandomCollectionDirectory = Property.Models.Stateless.IResult.GetResultsDateGroupDirectory(configuration, nameof(F_Random), "[]");
string[] files = Directory.GetFiles(fRandomCollectionDirectory, "*", SearchOption.TopDirectoryOnly); string[] files = Directory.GetFiles(fRandomCollectionDirectory, "*", SearchOption.TopDirectoryOnly);
foreach (string file in files) foreach (string file in files)
@ -105,13 +102,11 @@ internal class F_Random
bool immichAssetsCountIsZero = immichAssets.Count == 0; bool immichAssetsCountIsZero = immichAssets.Count == 0;
foreach (Mapping mapping in distinctValidImageMappingCollection) foreach (Mapping mapping in distinctValidImageMappingCollection)
{ {
if (mapping.MappingFromItem.IsArchive is not null && mapping.MappingFromItem.IsArchive.Value)
continue;
if (distinctCollection.Contains(mapping.MappingFromItem.Id)) if (distinctCollection.Contains(mapping.MappingFromItem.Id))
continue; continue;
if (mapping.MappingFromItem.FilePath.DirectoryFullPath is null) if (mapping.MappingFromItem.FilePath.DirectoryName is null)
continue; continue;
if (!splatNineIdentifiersKeys.Contains(mapping.MappingFromItem.Id)) if (notNineCollection is not null && notNineCollection.Contains(mapping.MappingFromItem.Id))
continue; continue;
if (mapping.MappingFromItem.Keywords is not null && mapping.MappingFromItem.Keywords.Any(l => validKeyWordsToIgnoreInRandom.Contains(l))) if (mapping.MappingFromItem.Keywords is not null && mapping.MappingFromItem.Keywords.Any(l => validKeyWordsToIgnoreInRandom.Contains(l)))
continue; continue;
@ -119,11 +114,9 @@ internal class F_Random
relativePaths.Add(mapping.MappingFromItem.RelativePath); relativePaths.Add(mapping.MappingFromItem.RelativePath);
else else
{ {
if (!immichAssets.TryGetValue($"{immichRoot}{mapping.MappingFromItem.RelativePath}", out immichAsset)) if (!immichAssets.TryGetValue(mapping.MappingFromItem.RelativePath, out immichAsset))
continue; continue;
if (!immichAsset.Path.Contains(immichOwnerId)) relativePaths.Add(immichAsset.PreviewPath);
continue;
relativePaths.Add(immichAsset.Path.Split(immichOwnerId)[1]);
} }
distinctCollection.Add(mapping.MappingFromItem.Id); distinctCollection.Add(mapping.MappingFromItem.Id);
} }

View File

@ -4,12 +4,12 @@
<Nullable>enable</Nullable> <Nullable>enable</Nullable>
<OutputType>library</OutputType> <OutputType>library</OutputType>
<RuntimeIdentifier>win-x64</RuntimeIdentifier> <RuntimeIdentifier>win-x64</RuntimeIdentifier>
<TargetFramework>net9.0</TargetFramework> <TargetFramework>net8.0</TargetFramework>
</PropertyGroup> </PropertyGroup>
<PropertyGroup> <PropertyGroup>
<PackageId>Phares.View.by.Distance.Map</PackageId> <PackageId>Phares.View.by.Distance.Map</PackageId>
<GeneratePackageOnBuild>false</GeneratePackageOnBuild> <GeneratePackageOnBuild>false</GeneratePackageOnBuild>
<Version>9.0.100.1</Version> <Version>8.0.101.1</Version>
<Authors>Mike Phares</Authors> <Authors>Mike Phares</Authors>
<Company>Phares</Company> <Company>Phares</Company>
<IncludeSymbols>true</IncludeSymbols> <IncludeSymbols>true</IncludeSymbols>
@ -37,7 +37,7 @@
<PackageReference Include="MetadataExtractor" Version="2.8.1" /> <PackageReference Include="MetadataExtractor" Version="2.8.1" />
<PackageReference Include="ShellProgressBar" Version="5.2.0" /> <PackageReference Include="ShellProgressBar" Version="5.2.0" />
<PackageReference Include="WindowsShortcutFactory" Version="1.2.0" /> <PackageReference Include="WindowsShortcutFactory" Version="1.2.0" />
<PackageReference Include="System.Text.Json" Version="9.0.2" /> <PackageReference Include="System.Text.Json" Version="8.0.4" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\Shared\View-by-Distance.Shared.csproj" /> <ProjectReference Include="..\Shared\View-by-Distance.Shared.csproj" />

View File

@ -170,9 +170,9 @@ public partial class MapLogic : Shared.Models.Methods.IMapLogic
directory = Path.Combine($"{eDistanceContentDirectory}---", "Date Shortcuts", $"{dateTime.Year}.{season}-MM{dateTime.Month:00}-WW{weekOfYear}"); directory = Path.Combine($"{eDistanceContentDirectory}---", "Date Shortcuts", $"{dateTime.Year}.{season}-MM{dateTime.Month:00}-WW{weekOfYear}");
fileName = Path.Combine(directory, $"{mapping.MappingFromItem.FilePath.Name}.lnk"); fileName = Path.Combine(directory, $"{mapping.MappingFromItem.FilePath.Name}.lnk");
results.Add(new(mapping.MappingFromItem.FilePath.FullName, directory, dateTime, fileName, description, MakeAllHidden: false)); results.Add(new(mapping.MappingFromItem.FilePath.FullName, directory, dateTime, fileName, description, MakeAllHidden: false));
if (mapping.MappingFromItem.FilePath.DirectoryFullPath is null) if (mapping.MappingFromItem.FilePath.DirectoryName is null)
continue; continue;
directoryName = Path.GetFileName(mapping.MappingFromItem.FilePath.DirectoryFullPath); directoryName = Path.GetFileName(mapping.MappingFromItem.FilePath.DirectoryName);
if (!string.IsNullOrEmpty(mapping.MappingFromItem.Model) && !string.IsNullOrEmpty(mapping.MappingFromItem.Model.Trim())) if (!string.IsNullOrEmpty(mapping.MappingFromItem.Model) && !string.IsNullOrEmpty(mapping.MappingFromItem.Model.Trim()))
{ {
// Remove-Item -LiteralPath "\\?\D:\Tmp\a\EX-Z70 " // Remove-Item -LiteralPath "\\?\D:\Tmp\a\EX-Z70 "
@ -264,7 +264,7 @@ public partial class MapLogic : Shared.Models.Methods.IMapLogic
{ {
List<string> personKeyFormattedCollection = []; List<string> personKeyFormattedCollection = [];
Dictionary<string, string> personKeyFormattedToNewestPersonKeyFormatted = []; Dictionary<string, string> personKeyFormattedToNewestPersonKeyFormatted = [];
Stateless.MapLogic.SetPersonCollectionsAfterSetSkipCollections(configuration, personContainers, personKeyFormattedToNewestPersonKeyFormatted, personKeyFormattedCollection); Stateless.MapLogic.SetPersonCollections(configuration, personContainers, personKeyFormattedToNewestPersonKeyFormatted, personKeyFormattedCollection);
readOnlyPersonKeyFormattedCollection = new(personKeyFormattedCollection); readOnlyPersonKeyFormattedCollection = new(personKeyFormattedCollection);
readOnlyPersonKeyFormattedToNewestPersonKeyFormatted = new(personKeyFormattedToNewestPersonKeyFormatted); readOnlyPersonKeyFormattedToNewestPersonKeyFormatted = new(personKeyFormattedToNewestPersonKeyFormatted);
} }
@ -356,7 +356,13 @@ public partial class MapLogic : Shared.Models.Methods.IMapLogic
else else
results = []; results = [];
} }
return results.AsReadOnly(); return new(results);
}
public ReadOnlyDictionary<long, PersonContainer> GetPersonKeyToPersonContainer()
{
Dictionary<long, PersonContainer> results = [];
return new(results);
} }
public ReadOnlyDictionary<long, List<int>> GetPersonKeyToIds() public ReadOnlyDictionary<long, List<int>> GetPersonKeyToIds()
@ -393,7 +399,7 @@ public partial class MapLogic : Shared.Models.Methods.IMapLogic
} }
if (shouldMove.Count > 0) if (shouldMove.Count > 0)
throw new Exception(string.Join(Environment.NewLine, shouldMove)); throw new Exception(string.Join(Environment.NewLine, shouldMove));
return results.AsReadOnly(); return new(results);
} }
(bool, ReadOnlyDictionary<int, ReadOnlyCollection<PersonContainer>>?) Shared.Models.Methods.IMapLogic.GetWholePercentagesToPersonContainers(int id) (bool, ReadOnlyDictionary<int, ReadOnlyCollection<PersonContainer>>?) Shared.Models.Methods.IMapLogic.GetWholePercentagesToPersonContainers(int id)
@ -894,7 +900,7 @@ public partial class MapLogic : Shared.Models.Methods.IMapLogic
continue; continue;
} }
results.Add(new(record.PersonDirectory)); results.Add(new(record.PersonDirectory));
facesDirectory = locationContainer.LengthSource.DirectoryFullPath; facesDirectory = locationContainer.LengthSource.DirectoryName;
faceFileHolder = IFileHolder.Get(locationContainer.LengthSource.FullName); faceFileHolder = IFileHolder.Get(locationContainer.LengthSource.FullName);
checkFile = Path.Combine(directory, $"{locationContainer.LengthSource.Name}"); checkFile = Path.Combine(directory, $"{locationContainer.LengthSource.Name}");
shortcutFile = Path.Combine(record.PersonDirectory, $"{locationContainer.LengthSource.Name}.lnk"); shortcutFile = Path.Combine(record.PersonDirectory, $"{locationContainer.LengthSource.Name}.lnk");
@ -1089,7 +1095,7 @@ public partial class MapLogic : Shared.Models.Methods.IMapLogic
results.Add(new(keyMapping, sortingContainer.Sorting, sortingContainer.Source)); results.Add(new(keyMapping, sortingContainer.Sorting, sortingContainer.Source));
} }
} }
return results.AsReadOnly(); return new(results);
} }
private (string, PersonBirthday?) GetPersonBirthday(string[] directoryNames) private (string, PersonBirthday?) GetPersonBirthday(string[] directoryNames)
@ -1259,7 +1265,6 @@ public partial class MapLogic : Shared.Models.Methods.IMapLogic
{ {
if (_Configuration is null) if (_Configuration is null)
throw new NullReferenceException(nameof(_Configuration)); throw new NullReferenceException(nameof(_Configuration));
int? updated = null;
FileHolder fileHolder; FileHolder fileHolder;
SaveContainer? saveContainer; SaveContainer? saveContainer;
List<SaveContainer> saveContainers = []; List<SaveContainer> saveContainers = [];
@ -1272,7 +1277,7 @@ public partial class MapLogic : Shared.Models.Methods.IMapLogic
saveContainer = new(fileHolder, filteredOriginalImage.CheckFile, filteredOriginalImage.Directory); saveContainer = new(fileHolder, filteredOriginalImage.CheckFile, filteredOriginalImage.Directory);
saveContainers.Add(saveContainer); saveContainers.Add(saveContainer);
} }
SaveContainers(updated, saveContainers); SaveContainers(null, saveContainers);
} }
public void SaveShortcutsForOutputResolutionsPreMapLogic(string eDistanceContentDirectory, ReadOnlyDictionary<long, List<int>> personKeyToIds, ReadOnlyCollection<Mapping> distinctValidImageMappingCollection) public void SaveShortcutsForOutputResolutionsPreMapLogic(string eDistanceContentDirectory, ReadOnlyDictionary<long, List<int>> personKeyToIds, ReadOnlyCollection<Mapping> distinctValidImageMappingCollection)
@ -1343,16 +1348,16 @@ public partial class MapLogic : Shared.Models.Methods.IMapLogic
directoryName = Path.GetDirectoryName(face.Mapping.MappingFromItem.RelativePath); directoryName = Path.GetDirectoryName(face.Mapping.MappingFromItem.RelativePath);
if (directoryName is null) if (directoryName is null)
throw new NotSupportedException(); throw new NotSupportedException();
if (item.ResizedFileHolder?.DirectoryFullPath is null || !item.ResizedFileHolder.Exists) if (item.ResizedFileHolder?.DirectoryName is null || !item.ResizedFileHolder.Exists)
continue; continue;
directory = Path.Combine(item.ResizedFileHolder.DirectoryFullPath, $"{_PropertyConfiguration.ResultAllInOne}Shortcuts", _PropertyConfiguration.ResultAllInOne); directory = Path.Combine(item.ResizedFileHolder.DirectoryName, $"{_PropertyConfiguration.ResultAllInOne}Shortcuts", _PropertyConfiguration.ResultAllInOne);
personDirectory = Path.Combine(directory, "No Faces"); personDirectory = Path.Combine(directory, "No Faces");
fileName = Path.Combine(personDirectory, $"{item.ResizedFileHolder.Name}.lnk"); fileName = Path.Combine(personDirectory, $"{item.ResizedFileHolder.Name}.lnk");
collection.Add(new(item.ResizedFileHolder.FullName, personDirectory, new(item.FilePath.LastWriteTicks), fileName, face.Mapping.MappingFromItem.Id.ToString(), MakeAllHidden: false)); collection.Add(new(item.ResizedFileHolder.FullName, personDirectory, new(item.FilePath.LastWriteTicks), fileName, face.Mapping.MappingFromItem.Id.ToString(), MakeAllHidden: false));
if (face.Mapping.MappingFromItem.ContainerDateTimes.Length > 0 && !distinct.Contains(item.ResizedFileHolder.DirectoryFullPath)) if (face.Mapping.MappingFromItem.ContainerDateTimes.Length > 0 && !distinct.Contains(item.ResizedFileHolder.DirectoryName))
{ {
distinct.Add(item.ResizedFileHolder.DirectoryFullPath); distinct.Add(item.ResizedFileHolder.DirectoryName);
directoriesAndDateTimes.Add(new(item.ResizedFileHolder.DirectoryFullPath, face.Mapping.MappingFromItem.ContainerDateTimes)); directoriesAndDateTimes.Add(new(item.ResizedFileHolder.DirectoryName, face.Mapping.MappingFromItem.ContainerDateTimes));
} }
} }
} }
@ -1361,17 +1366,17 @@ public partial class MapLogic : Shared.Models.Methods.IMapLogic
directoryName = Path.GetDirectoryName(mapping.MappingFromItem.RelativePath); directoryName = Path.GetDirectoryName(mapping.MappingFromItem.RelativePath);
if (directoryName is null) if (directoryName is null)
throw new NotSupportedException(); throw new NotSupportedException();
if (mapping.MappingFromItem.ResizedFileHolder.DirectoryFullPath is null || !mapping.MappingFromItem.ResizedFileHolder.Exists) if (mapping.MappingFromItem.ResizedFileHolder.DirectoryName is null || !mapping.MappingFromItem.ResizedFileHolder.Exists)
continue; continue;
dateTime = mapping.MappingFromItem.GetDateTimeOriginalThenMinimumDateTime(); dateTime = mapping.MappingFromItem.GetDateTimeOriginalThenMinimumDateTime();
if (mapping.By is null or Shared.Models.Stateless.IMapLogic.Sorting || mapping.MappingFromPerson?.ApproximateYears is null) if (mapping.By is null or Shared.Models.Stateless.IMapLogic.Sorting || mapping.MappingFromPerson?.ApproximateYears is null)
{ {
if (mapping.MappingFromItem.ContainerDateTimes.Length > 0 && !distinct.Contains(mapping.MappingFromItem.ResizedFileHolder.DirectoryFullPath)) if (mapping.MappingFromItem.ContainerDateTimes.Length > 0 && !distinct.Contains(mapping.MappingFromItem.ResizedFileHolder.DirectoryName))
{ {
distinct.Add(mapping.MappingFromItem.ResizedFileHolder.DirectoryFullPath); distinct.Add(mapping.MappingFromItem.ResizedFileHolder.DirectoryName);
directoriesAndDateTimes.Add(new(mapping.MappingFromItem.ResizedFileHolder.DirectoryFullPath, mapping.MappingFromItem.ContainerDateTimes)); directoriesAndDateTimes.Add(new(mapping.MappingFromItem.ResizedFileHolder.DirectoryName, mapping.MappingFromItem.ContainerDateTimes));
} }
directory = Path.Combine(mapping.MappingFromItem.ResizedFileHolder.DirectoryFullPath, $"{_PropertyConfiguration.ResultAllInOne}Shortcuts", _PropertyConfiguration.ResultAllInOne); directory = Path.Combine(mapping.MappingFromItem.ResizedFileHolder.DirectoryName, $"{_PropertyConfiguration.ResultAllInOne}Shortcuts", _PropertyConfiguration.ResultAllInOne);
personDirectory = Path.Combine(directory, "Unknown"); personDirectory = Path.Combine(directory, "Unknown");
fileName = Path.Combine(personDirectory, $"{mapping.MappingFromItem.ResizedFileHolder.Name}.lnk"); fileName = Path.Combine(personDirectory, $"{mapping.MappingFromItem.ResizedFileHolder.Name}.lnk");
collection.Add(new(mapping.MappingFromItem.ResizedFileHolder.FullName, personDirectory, dateTime, fileName, mapping.MappingFromLocation?.DeterministicHashCodeKey, MakeAllHidden: false)); collection.Add(new(mapping.MappingFromItem.ResizedFileHolder.FullName, personDirectory, dateTime, fileName, mapping.MappingFromLocation?.DeterministicHashCodeKey, MakeAllHidden: false));
@ -1389,12 +1394,12 @@ public partial class MapLogic : Shared.Models.Methods.IMapLogic
if (string.IsNullOrEmpty(mapping.MappingFromPerson.DisplayDirectoryName)) if (string.IsNullOrEmpty(mapping.MappingFromPerson.DisplayDirectoryName))
throw new NotSupportedException(); throw new NotSupportedException();
personKeyFormatted = IPersonBirthday.GetFormatted(_Configuration.PersonBirthdayFormat, mapping.MappingFromPerson.PersonKey); personKeyFormatted = IPersonBirthday.GetFormatted(_Configuration.PersonBirthdayFormat, mapping.MappingFromPerson.PersonKey);
if (mapping.MappingFromItem.ContainerDateTimes.Length > 0 && !distinct.Contains(mapping.MappingFromItem.ResizedFileHolder.DirectoryFullPath)) if (mapping.MappingFromItem.ContainerDateTimes.Length > 0 && !distinct.Contains(mapping.MappingFromItem.ResizedFileHolder.DirectoryName))
{ {
distinct.Add(mapping.MappingFromItem.ResizedFileHolder.DirectoryFullPath); distinct.Add(mapping.MappingFromItem.ResizedFileHolder.DirectoryName);
directoriesAndDateTimes.Add(new(mapping.MappingFromItem.ResizedFileHolder.DirectoryFullPath, mapping.MappingFromItem.ContainerDateTimes)); directoriesAndDateTimes.Add(new(mapping.MappingFromItem.ResizedFileHolder.DirectoryName, mapping.MappingFromItem.ContainerDateTimes));
} }
directory = Path.Combine(mapping.MappingFromItem.ResizedFileHolder.DirectoryFullPath, $"{_PropertyConfiguration.ResultAllInOne}Shortcuts", personKeyFormatted); directory = Path.Combine(mapping.MappingFromItem.ResizedFileHolder.DirectoryName, $"{_PropertyConfiguration.ResultAllInOne}Shortcuts", personKeyFormatted);
if (!personKeyToIds.TryGetValue(mapping.MappingFromPerson.PersonKey, out ids)) if (!personKeyToIds.TryGetValue(mapping.MappingFromPerson.PersonKey, out ids))
personDirectory = Path.Combine(directory, mapping.MappingFromPerson.DisplayDirectoryName); personDirectory = Path.Combine(directory, mapping.MappingFromPerson.DisplayDirectoryName);
else else

View File

@ -58,10 +58,10 @@ internal abstract class DecadeLogic
string? personKeyFormattedDirectoryName; string? personKeyFormattedDirectoryName;
foreach (LocationContainer locationContainer in locationContainers) foreach (LocationContainer locationContainer in locationContainers)
{ {
if (string.IsNullOrEmpty(locationContainer.FilePath.DirectoryFullPath)) if (string.IsNullOrEmpty(locationContainer.FilePath.DirectoryName))
continue; continue;
personNameDirectoryName = Path.GetFileName(locationContainer.FilePath.DirectoryFullPath); personNameDirectoryName = Path.GetFileName(locationContainer.FilePath.DirectoryName);
yearDirectory = Path.GetDirectoryName(locationContainer.FilePath.DirectoryFullPath); yearDirectory = Path.GetDirectoryName(locationContainer.FilePath.DirectoryName);
if (string.IsNullOrEmpty(yearDirectory)) if (string.IsNullOrEmpty(yearDirectory))
continue; continue;
yearDirectoryName = Path.GetFileName(yearDirectory); yearDirectoryName = Path.GetFileName(yearDirectory);

View File

@ -64,22 +64,21 @@ internal abstract class FaceFileLogic
exifDirectory = Metadata.Models.Stateless.Methods.IMetadata.GetExifDirectory(mappedFile.FilePath); exifDirectory = Metadata.Models.Stateless.Methods.IMetadata.GetExifDirectory(mappedFile.FilePath);
RectangleF? rectangle = ILocation.GetPercentagesRectangle(configuration.LocationDigits, wholePercentages.Value); RectangleF? rectangle = ILocation.GetPercentagesRectangle(configuration.LocationDigits, wholePercentages.Value);
personDisplayDirectoryName = mappedFile.PersonDisplayDirectoryName is null ? configuration.MappingDefaultName : mappedFile.PersonDisplayDirectoryName; personDisplayDirectoryName = mappedFile.PersonDisplayDirectoryName is null ? configuration.MappingDefaultName : mappedFile.PersonDisplayDirectoryName;
LocationContainer locationContainer = new(dateOnly,
exifDirectory,
mappedFile.DirectoryNumber,
personDisplayDirectoryName,
null,
null,
mappedFile.FilePath,
fromDistanceContent,
id.Value,
null,
null,
mappedFile.PersonKey,
rectangle,
wholePercentages.Value);
lock (locationContainers) lock (locationContainers)
locationContainers.Add(locationContainer); locationContainers.Add(new(dateOnly,
exifDirectory,
mappedFile.DirectoryNumber,
personDisplayDirectoryName,
null,
null,
mappedFile.FilePath,
fromDistanceContent,
id.Value,
null,
null,
mappedFile.PersonKey,
rectangle,
wholePercentages.Value));
} }
private static ReadOnlyDictionary<int, ReadOnlyDictionary<int, LocationContainer>> GetReadOnly(Dictionary<int, Dictionary<int, LocationContainer>> keyValuePairs) private static ReadOnlyDictionary<int, ReadOnlyDictionary<int, LocationContainer>> GetReadOnly(Dictionary<int, Dictionary<int, LocationContainer>> keyValuePairs)
@ -87,33 +86,40 @@ internal abstract class FaceFileLogic
Dictionary<int, ReadOnlyDictionary<int, LocationContainer>> results = []; Dictionary<int, ReadOnlyDictionary<int, LocationContainer>> results = [];
foreach (KeyValuePair<int, Dictionary<int, LocationContainer>> keyValuePair in keyValuePairs) foreach (KeyValuePair<int, Dictionary<int, LocationContainer>> keyValuePair in keyValuePairs)
results.Add(keyValuePair.Key, new(keyValuePair.Value)); results.Add(keyValuePair.Key, new(keyValuePair.Value));
return results.AsReadOnly(); return new(results);
} }
internal static ReadOnlyDictionary<int, ReadOnlyDictionary<int, LocationContainer>> GetMapped(int maxDegreeOfParallelism, Property.Models.Configuration propertyConfiguration, Configuration configuration, long ticks, ReadOnlyCollection<PersonContainer> personContainers, string a2PeopleSingletonDirectory, string eDistanceContentDirectory) internal static ReadOnlyDictionary<int, ReadOnlyDictionary<int, LocationContainer>> GetMapped(int maxDegreeOfParallelism, Property.Models.Configuration propertyConfiguration, Configuration configuration, long ticks, ReadOnlyCollection<PersonContainer> personContainers, string a2PeopleSingletonDirectory, string eDistanceContentDirectory)
{ {
Dictionary<int, Dictionary<int, LocationContainer>> results = []; Dictionary<int, Dictionary<int, LocationContainer>> results = [];
List<LocationContainer> locationContainers = []; List<LocationContainer> locationContainers = [];
List<string> personKeyFormattedCollection = [];
Dictionary<int, LocationContainer>? keyValuePairs; Dictionary<int, LocationContainer>? keyValuePairs;
Dictionary<int, List<(string, int)>> skipCollection = []; Dictionary<int, List<(string, int)>> skipCollection = [];
Dictionary<int, List<(string, int)>> skipNotSkipCollection = []; Dictionary<int, List<(string, int)>> skipNotSkipCollection = [];
Dictionary<string, string> personKeyFormattedToNewestPersonKeyFormatted = []; ReadOnlyCollection<string> readOnlyPersonKeyFormattedCollection;
ReadOnlyDictionary<string, string> readOnlyPersonKeyFormattedToNewestPersonKeyFormatted;
SetSkipCollections(configuration, personContainers, a2PeopleSingletonDirectory, skipCollection, skipNotSkipCollection); SetSkipCollections(configuration, personContainers, a2PeopleSingletonDirectory, skipCollection, skipNotSkipCollection);
SetPersonCollectionsAfterSetSkipCollections(configuration, personContainers, personKeyFormattedToNewestPersonKeyFormatted, personKeyFormattedCollection); {
List<Record> records = DistanceLogic.DeleteEmptyDirectoriesAndGetCollection(propertyConfiguration, configuration, ticks, eDistanceContentDirectory, personKeyFormattedToNewestPersonKeyFormatted.AsReadOnly(), personKeyFormattedCollection.AsReadOnly()); List<string> personKeyFormattedCollection = [];
Dictionary<string, string> personKeyFormattedToNewestPersonKeyFormatted = [];
SetPersonCollections(configuration, personContainers, personKeyFormattedToNewestPersonKeyFormatted, personKeyFormattedCollection);
readOnlyPersonKeyFormattedCollection = new(personKeyFormattedCollection);
readOnlyPersonKeyFormattedToNewestPersonKeyFormatted = new(personKeyFormattedToNewestPersonKeyFormatted);
}
List<Record> records = DistanceLogic.DeleteEmptyDirectoriesAndGetCollection(propertyConfiguration, configuration, ticks, eDistanceContentDirectory, readOnlyPersonKeyFormattedToNewestPersonKeyFormatted, readOnlyPersonKeyFormattedCollection);
List<MappedFile> mappedFiles = GetMappedFiles(propertyConfiguration, configuration, personContainers, records); List<MappedFile> mappedFiles = GetMappedFiles(propertyConfiguration, configuration, personContainers, records);
if (mappedFiles.Count > 0) if (mappedFiles.Count > 0)
{ {
int totalSeconds = (int)Math.Floor(new TimeSpan(DateTime.Now.Ticks - ticks).TotalSeconds); int totalSeconds = (int)Math.Floor(new TimeSpan(DateTime.Now.Ticks - ticks).TotalSeconds);
string message = $") Building Mapped Face Files Collection - {totalSeconds} total second(s)"; string message = $") Building Mapped Face Files Collection - {totalSeconds} total second(s)";
ParallelOptions parallelOptions = new() { MaxDegreeOfParallelism = maxDegreeOfParallelism }; ParallelOptions parallelOptions = new() { MaxDegreeOfParallelism = maxDegreeOfParallelism };
ReadOnlyDictionary<int, List<(string, int)>> readOnlySkipNotSkipCollection = new(skipCollection);
ProgressBarOptions options = new() { ProgressCharacter = '─', ProgressBarOnBottom = true, DisableBottomPercentage = true }; ProgressBarOptions options = new() { ProgressCharacter = '─', ProgressBarOnBottom = true, DisableBottomPercentage = true };
using ProgressBar progressBar = new(mappedFiles.Count, message, options); using ProgressBar progressBar = new(mappedFiles.Count, message, options);
_ = Parallel.For(0, mappedFiles.Count, parallelOptions, (i, state) => _ = Parallel.For(0, mappedFiles.Count, parallelOptions, (i, state) =>
{ {
progressBar.Tick(); progressBar.Tick();
MappedParallelFor(propertyConfiguration, configuration, skipCollection.AsReadOnly(), locationContainers, mappedFiles[i]); MappedParallelFor(propertyConfiguration, configuration, readOnlySkipNotSkipCollection, locationContainers, mappedFiles[i]);
}); });
} }
foreach (LocationContainer locationContainer in locationContainers) foreach (LocationContainer locationContainer in locationContainers)
@ -170,22 +176,21 @@ internal abstract class FaceFileLogic
RectangleF? rectangle = ILocation.GetPercentagesRectangle(configuration.LocationDigits, wholePercentages.Value); RectangleF? rectangle = ILocation.GetPercentagesRectangle(configuration.LocationDigits, wholePercentages.Value);
if (rectangle is null) if (rectangle is null)
return; return;
LocationContainer locationContainer = new(dateOnly,
exifDirectory,
null,
null,
null,
faceFile,
filePath,
fromDistanceContent,
filePath.Id.Value,
null,
null,
null,
rectangle,
wholePercentages.Value);
lock (locationContainers) lock (locationContainers)
locationContainers.Add(locationContainer); locationContainers.Add(new(dateOnly,
exifDirectory,
null,
null,
null,
faceFile,
filePath,
fromDistanceContent,
filePath.Id.Value,
null,
null,
null,
rectangle,
wholePercentages.Value));
} }
internal static List<LocationContainer> GetAvailable(int maxDegreeOfParallelism, Configuration configuration, IFaceD dFace, long ticks, ReadOnlyCollection<FilePath> filePaths) internal static List<LocationContainer> GetAvailable(int maxDegreeOfParallelism, Configuration configuration, IFaceD dFace, long ticks, ReadOnlyCollection<FilePath> filePaths)

View File

@ -83,7 +83,7 @@ internal abstract class MapLogic
} }
} }
internal static void SetPersonCollectionsAfterSetSkipCollections(Configuration configuration, ReadOnlyCollection<PersonContainer> personContainers, Dictionary<string, string> personKeyFormattedToNewestPersonKeyFormatted, List<string> personKeyFormattedCollection) internal static void SetPersonCollections(Configuration configuration, ReadOnlyCollection<PersonContainer> personContainers, Dictionary<string, string> personKeyFormattedToNewestPersonKeyFormatted, List<string> personKeyFormattedCollection)
{ {
string personKeyFormatted; string personKeyFormatted;
string newestPersonKeyFormatted; string newestPersonKeyFormatted;
@ -174,7 +174,7 @@ internal abstract class MapLogic
results.Add(face); results.Add(face);
} }
} }
return results.AsReadOnly(); return new(results);
} }
internal static string GetMappingSegmentB(long ticks, PersonBirthday personBirthday, int? approximateYears, MappingFromItem mappingFromItem) internal static string GetMappingSegmentB(long ticks, PersonBirthday personBirthday, int? approximateYears, MappingFromItem mappingFromItem)
@ -215,47 +215,30 @@ internal abstract class MapLogic
{ {
if (duplicate.Percent is null) if (duplicate.Percent is null)
continue; continue;
_ = Process.Start("explorer.exe", string.Concat("\"", duplicate.FilePath.DirectoryFullPath, "\"")); _ = Process.Start("explorer.exe", string.Concat("\"", duplicate.FilePath.DirectoryName, "\""));
personKeyFormatted = IPersonBirthday.GetFormatted(configuration.PersonBirthdayFormat, duplicate.PersonKey); personKeyFormatted = IPersonBirthday.GetFormatted(configuration.PersonBirthdayFormat, duplicate.PersonKey);
} }
foreach ((long personKey, int id, FilePath filePath, float? percent) in duplicates) foreach ((long personKey, int id, FilePath filePath, float? percent) in duplicates)
{ {
if (percent is not null && percent.Value == 0) if (percent is not null && percent.Value == 0)
continue; continue;
_ = Process.Start("explorer.exe", string.Concat("\"", filePath.DirectoryFullPath, "\"")); _ = Process.Start("explorer.exe", string.Concat("\"", filePath.DirectoryName, "\""));
personKeyFormatted = IPersonBirthday.GetFormatted(configuration.PersonBirthdayFormat, personKey); personKeyFormatted = IPersonBirthday.GetFormatted(configuration.PersonBirthdayFormat, personKey);
} }
foreach ((long personKey, int id, FilePath filePath, float? percent) in duplicates) foreach ((long personKey, int id, FilePath filePath, float? percent) in duplicates)
{ {
if (percent is not null && percent.Value > 0) if (percent is not null && percent.Value > 0)
continue; continue;
_ = Process.Start("explorer.exe", string.Concat("\"", filePath.DirectoryFullPath, "\"")); _ = Process.Start("explorer.exe", string.Concat("\"", filePath.DirectoryName, "\""));
personKeyFormatted = IPersonBirthday.GetFormatted(configuration.PersonBirthdayFormat, personKey); personKeyFormatted = IPersonBirthday.GetFormatted(configuration.PersonBirthdayFormat, personKey);
} }
} }
private static void MoveIf(string fileName, CombinedEnumAndIndex cei, string directory, string fullFileName)
{
string[] segments = directory.Split(cei.Combined);
string? checkDirectory = segments.Length == 1 ?
Path.Combine(segments[0], $"{cei.Combined[2..]}") :
segments.Length == 2 ?
$"{segments[0]}{cei.Combined[2..]}{segments[1]}" :
null;
if (checkDirectory is not null && Directory.Exists(checkDirectory))
{
string checkFile = Path.Combine(checkDirectory, fileName);
if (File.Exists(checkFile))
File.Move(checkFile, fullFileName);
}
}
internal static string GetFacesDirectory(Shared.Models.Properties.IPropertyConfiguration propertyConfiguration, string dFacesContentDirectory, FilePath filePath, MappingFromItem mappingFromItem) internal static string GetFacesDirectory(Shared.Models.Properties.IPropertyConfiguration propertyConfiguration, string dFacesContentDirectory, FilePath filePath, MappingFromItem mappingFromItem)
{ {
string result; string result;
CombinedEnumAndIndex cei = IPath.GetCombinedEnumAndIndex(propertyConfiguration, filePath); (string directoryName, _) = IPath.GetDirectoryNameAndIndex(propertyConfiguration, filePath);
result = Path.Combine(dFacesContentDirectory, cei.Combined, mappingFromItem.FilePath.NameWithoutExtension); result = Path.Combine(dFacesContentDirectory, directoryName, mappingFromItem.FilePath.NameWithoutExtension);
MoveIf(mappingFromItem.FilePath.NameWithoutExtension, cei, dFacesContentDirectory, result);
return result; return result;
} }
@ -386,7 +369,7 @@ internal abstract class MapLogic
} }
results.Add(idTo.Key, new(keyValuePairs)); results.Add(idTo.Key, new(keyValuePairs));
} }
return results.AsReadOnly(); return new(results);
} }
private static ReadOnlyDictionary<int, ReadOnlyDictionary<int, Mapping>> GetReadOnly(Dictionary<int, Dictionary<int, Mapping>> keyValuePairs) private static ReadOnlyDictionary<int, ReadOnlyDictionary<int, Mapping>> GetReadOnly(Dictionary<int, Dictionary<int, Mapping>> keyValuePairs)
@ -394,7 +377,7 @@ internal abstract class MapLogic
Dictionary<int, ReadOnlyDictionary<int, Mapping>> results = []; Dictionary<int, ReadOnlyDictionary<int, Mapping>> results = [];
foreach (KeyValuePair<int, Dictionary<int, Mapping>> keyValuePair in keyValuePairs) foreach (KeyValuePair<int, Dictionary<int, Mapping>> keyValuePair in keyValuePairs)
results.Add(keyValuePair.Key, new(keyValuePair.Value)); results.Add(keyValuePair.Key, new(keyValuePair.Value));
return results.AsReadOnly(); return new(results);
} }
private static List<PersonContainer> GetNonSpecificPeopleCollection(Configuration configuration, long ticks, List<long> personKeys, ReadOnlyDictionary<long, int> personKeyToCount) private static List<PersonContainer> GetNonSpecificPeopleCollection(Configuration configuration, long ticks, List<long> personKeys, ReadOnlyDictionary<long, int> personKeyToCount)
@ -435,7 +418,7 @@ internal abstract class MapLogic
if (check) if (check)
continue; continue;
personBirthday = IPersonBirthday.GetPersonBirthday(personKey + (oneHour * 2)); personBirthday = IPersonBirthday.GetPersonBirthday(personKey + (oneHour * 2));
personContainer = PersonContainer.Get(approximateYears, [personBirthday], new(personDisplayDirectoryAllFilePaths), configuration.MappingDefaultName, personKey); personContainer = new(approximateYears, [personBirthday], new(personDisplayDirectoryAllFilePaths), configuration.MappingDefaultName, personKey);
results.Add(personContainer); results.Add(personContainer);
if (results.Count > 99) if (results.Count > 99)
break; break;
@ -464,9 +447,6 @@ internal abstract class MapLogic
FileHolder fileHolder; FileHolder fileHolder;
List<string> distinct = []; List<string> distinct = [];
PersonBirthday? personBirthday; PersonBirthday? personBirthday;
PersonContainer? personContainer;
string? personDisplayDirectoryName;
ReadOnlyDictionary<long, PersonContainer> keyValuePairs = PersonContainer.Extract(personContainers);
results.AddRange(GetDisplayDirectoryAllFiles(configuration.FacesFileNameExtension, configuration.PersonBirthdayFormat, personContainers)); results.AddRange(GetDisplayDirectoryAllFiles(configuration.FacesFileNameExtension, configuration.PersonBirthdayFormat, personContainers));
foreach (Record record in records) foreach (Record record in records)
{ {
@ -475,13 +455,9 @@ internal abstract class MapLogic
continue; continue;
if (distinct.Contains(record.MappedFaceFilePath.Name)) if (distinct.Contains(record.MappedFaceFilePath.Name))
continue; continue;
personKey = personBirthday.Value.Ticks;
distinct.Add(record.MappedFaceFilePath.Name); distinct.Add(record.MappedFaceFilePath.Name);
if (!keyValuePairs.TryGetValue(personKey, out personContainer)) personKey = personBirthday.Value.Ticks;
personDisplayDirectoryName = record.PersonDisplayDirectoryName; results.Add(new(personKey, record.PersonKeyFormatted, record.PersonDisplayDirectoryName, record.DirectoryNumber, record.MappedFaceFilePath));
else
personDisplayDirectoryName = personContainer.DisplayDirectoryName;
results.Add(new(personKey, record.PersonKeyFormatted, personDisplayDirectoryName, record.DirectoryNumber, record.MappedFaceFilePath));
} }
for (int i = results.Count - 1; i > -1; i--) for (int i = results.Count - 1; i > -1; i--)
{ {
@ -559,22 +535,21 @@ internal abstract class MapLogic
exifDirectory = Metadata.Models.Stateless.Methods.IMetadata.GetExifDirectory(mappedFile.FilePath); exifDirectory = Metadata.Models.Stateless.Methods.IMetadata.GetExifDirectory(mappedFile.FilePath);
RectangleF? rectangle = ILocation.GetPercentagesRectangle(configuration.LocationDigits, wholePercentages.Value); RectangleF? rectangle = ILocation.GetPercentagesRectangle(configuration.LocationDigits, wholePercentages.Value);
personDisplayDirectoryName = mappedFile.PersonDisplayDirectoryName is null ? configuration.MappingDefaultName : mappedFile.PersonDisplayDirectoryName; personDisplayDirectoryName = mappedFile.PersonDisplayDirectoryName is null ? configuration.MappingDefaultName : mappedFile.PersonDisplayDirectoryName;
LocationContainer locationContainer = new(dateOnly,
exifDirectory,
mappedFile.DirectoryNumber,
personDisplayDirectoryName,
null,
null,
mappedFile.FilePath,
fromDistanceContent,
id.Value,
null,
null,
mappedFile.PersonKey,
rectangle,
wholePercentages.Value);
lock (locationContainers) lock (locationContainers)
locationContainers.Add(locationContainer); locationContainers.Add(new(dateOnly,
exifDirectory,
mappedFile.DirectoryNumber,
personDisplayDirectoryName,
null,
null,
mappedFile.FilePath,
fromDistanceContent,
id.Value,
null,
null,
mappedFile.PersonKey,
rectangle,
wholePercentages.Value));
} }
private static void LookForPossibleDuplicates(Configuration configuration, ReadOnlyCollection<LocationContainer> locationContainers) private static void LookForPossibleDuplicates(Configuration configuration, ReadOnlyCollection<LocationContainer> locationContainers)
@ -764,7 +739,7 @@ internal abstract class MapLogic
group = IPerson.GetHourGroup(personKeyFormattedIdThenWholePercentages.PersonDisplayDirectoryName, personBirthday.Value.Hour); group = IPerson.GetHourGroup(personKeyFormattedIdThenWholePercentages.PersonDisplayDirectoryName, personBirthday.Value.Hour);
(status, sex, first) = IPerson.GetPersonHour(personKeyFormattedIdThenWholePercentages.PersonDisplayDirectoryName, personBirthday.Value.Hour); (status, sex, first) = IPerson.GetPersonHour(personKeyFormattedIdThenWholePercentages.PersonDisplayDirectoryName, personBirthday.Value.Hour);
personDirectory = new(matches.First(), group, status, sex, first); personDirectory = new(matches.First(), group, status, sex, first);
personContainer = PersonContainer.Get(configuration.PersonCharacters.ToArray(), personBirthday, personDisplayDirectoryName, personDirectory); personContainer = new(configuration.PersonCharacters.ToArray(), personBirthday, personDisplayDirectoryName, personDirectory);
personKeyFormattedToPersonContainer.Add(personKeyFormattedIdThenWholePercentages.PersonKeyFormatted, personContainer); personKeyFormattedToPersonContainer.Add(personKeyFormattedIdThenWholePercentages.PersonKeyFormatted, personContainer);
} }
if (personContainer.Key is null) if (personContainer.Key is null)
@ -810,7 +785,7 @@ internal abstract class MapLogic
idToWholePercentagesCollection[record.MappedFaceFilePath.Id.Value].Add(wholePercentages.Value); idToWholePercentagesCollection[record.MappedFaceFilePath.Id.Value].Add(wholePercentages.Value);
results.Add(new(record.PersonKeyFormatted, record.PersonDisplayDirectoryName, record.IsDefault, record.LinksCount, record.MappedFaceFilePath, record.MappedFaceFilePath.Id.Value, wholePercentages.Value)); results.Add(new(record.PersonKeyFormatted, record.PersonDisplayDirectoryName, record.IsDefault, record.LinksCount, record.MappedFaceFilePath, record.MappedFaceFilePath.Id.Value, wholePercentages.Value));
} }
return results.AsReadOnly(); return new(results);
} }
internal static List<PersonContainer> GetNotMappedPersonContainers(Configuration configuration, long ticks, ReadOnlyCollection<PersonContainer> personContainers, ReadOnlyDictionary<long, int> personKeyToCount) internal static List<PersonContainer> GetNotMappedPersonContainers(Configuration configuration, long ticks, ReadOnlyCollection<PersonContainer> personContainers, ReadOnlyDictionary<long, int> personKeyToCount)
@ -864,9 +839,9 @@ internal abstract class MapLogic
continue; continue;
personBirthday = IPersonBirthday.GetPersonBirthday(keyValuePair.Key); personBirthday = IPersonBirthday.GetPersonBirthday(keyValuePair.Key);
if (!personKeyToPersonContainerCollection.TryGetValue(keyValuePair.Key, out collection)) if (!personKeyToPersonContainerCollection.TryGetValue(keyValuePair.Key, out collection))
personContainer = PersonContainer.Get(approximateYears, personBirthday, displayDirectoryName, keyValuePair.Key); personContainer = new(approximateYears, personBirthday, displayDirectoryName, keyValuePair.Key);
else else
personContainer = PersonContainer.Get(approximateYears, personBirthday, collection[zero].PersonDirectory, displayDirectoryName, keyValuePair.Key); personContainer = new(approximateYears, personBirthday, collection[zero].PersonDirectory, displayDirectoryName, keyValuePair.Key);
personKeyToPersonContainer.Add(keyValuePair.Key, personContainer); personKeyToPersonContainer.Add(keyValuePair.Key, personContainer);
} }
} }
@ -980,7 +955,7 @@ internal abstract class MapLogic
if (distinct.Contains(personContainer.DisplayDirectoryAllFilePaths[i].Name)) if (distinct.Contains(personContainer.DisplayDirectoryAllFilePaths[i].Name))
continue; continue;
distinct.Add(personContainer.DisplayDirectoryAllFilePaths[i].Name); distinct.Add(personContainer.DisplayDirectoryAllFilePaths[i].Name);
directoryName = Path.GetFileName(personContainer.DisplayDirectoryAllFilePaths[i].DirectoryFullPath); directoryName = Path.GetFileName(personContainer.DisplayDirectoryAllFilePaths[i].DirectoryName);
if (directoryName != personContainer.DisplayDirectoryName) if (directoryName != personContainer.DisplayDirectoryName)
continue; continue;
personBirthday = IPersonBirthday.GetPersonBirthday(personContainer.Key.Value); personBirthday = IPersonBirthday.GetPersonBirthday(personContainer.Key.Value);
@ -1015,26 +990,24 @@ internal abstract class MapLogic
internal static string GetFacePartsDirectory(Shared.Models.Properties.IPropertyConfiguration propertyConfiguration, string d2FacePartsContentDirectory, FilePath filePath, MappingFromItem mappingFromItem) internal static string GetFacePartsDirectory(Shared.Models.Properties.IPropertyConfiguration propertyConfiguration, string d2FacePartsContentDirectory, FilePath filePath, MappingFromItem mappingFromItem)
{ {
string result; string result;
CombinedEnumAndIndex cei = IPath.GetCombinedEnumAndIndex(propertyConfiguration, filePath); (string directoryName, _) = IPath.GetDirectoryNameAndIndex(propertyConfiguration, filePath);
result = Path.Combine(d2FacePartsContentDirectory, cei.Combined, mappingFromItem.FilePath.NameWithoutExtension); result = Path.Combine(d2FacePartsContentDirectory, directoryName, mappingFromItem.FilePath.NameWithoutExtension);
MoveIf(mappingFromItem.FilePath.NameWithoutExtension, cei, d2FacePartsContentDirectory, result);
return result; return result;
} }
internal static string GetFacePartsDirectoryX(Shared.Models.Properties.IPropertyConfiguration propertyConfiguration, string d2FacePartsContentDirectory, FilePath filePath) internal static string GetFacePartsDirectoryX(Shared.Models.Properties.IPropertyConfiguration propertyConfiguration, string d2FacePartsContentDirectory, FilePath filePath)
{ {
string result; string result;
CombinedEnumAndIndex cei = IPath.GetCombinedEnumAndIndex(propertyConfiguration, filePath); (string directoryName, _) = IPath.GetDirectoryNameAndIndex(propertyConfiguration, filePath);
result = Path.Combine(d2FacePartsContentDirectory, cei.Combined, filePath.NameWithoutExtension); result = Path.Combine(d2FacePartsContentDirectory, directoryName, filePath.NameWithoutExtension);
MoveIf(filePath.NameWithoutExtension, cei, d2FacePartsContentDirectory, result);
return result; return result;
} }
internal static string GetResizeContentDirectory(Shared.Models.Properties.IPropertyConfiguration propertyConfiguration, string cContentDirectory, FilePath filePath) internal static string GetResizeContentDirectory(Shared.Models.Properties.IPropertyConfiguration propertyConfiguration, string cContentDirectory, FilePath filePath)
{ {
string result; string result;
CombinedEnumAndIndex cei = IPath.GetCombinedEnumAndIndex(propertyConfiguration, filePath); (string directoryName, _) = IPath.GetDirectoryNameAndIndex(propertyConfiguration, filePath);
result = Path.Combine(cContentDirectory, cei.Combined); result = Path.Combine(cContentDirectory, directoryName);
return result; return result;
} }
@ -1143,7 +1116,7 @@ internal abstract class MapLogic
collection.Add(keyValuePair.Key); collection.Add(keyValuePair.Key);
} }
} }
return results.AsReadOnly(); return new(results);
} }
internal static ReadOnlyDictionary<int, ReadOnlyDictionary<int, Mapping>> GetIdToWholePercentagesToFace(ReadOnlyCollection<Mapping> distinctValidImageMappingCollection) internal static ReadOnlyDictionary<int, ReadOnlyDictionary<int, Mapping>> GetIdToWholePercentagesToFace(ReadOnlyCollection<Mapping> distinctValidImageMappingCollection)
@ -1293,7 +1266,7 @@ internal abstract class MapLogic
foreach ((string _, int wholePercentage) in keyValuePair.Value) foreach ((string _, int wholePercentage) in keyValuePair.Value)
wholePercentagesCollection.Add(wholePercentage); wholePercentagesCollection.Add(wholePercentage);
} }
return results.AsReadOnly(); return new(results);
} }
internal static ReadOnlyDictionary<int, List<int>> ConvertSkipNotSkip(Dictionary<int, List<(string, int)>> skipNotSkipCollection) internal static ReadOnlyDictionary<int, List<int>> ConvertSkipNotSkip(Dictionary<int, List<(string, int)>> skipNotSkipCollection)
@ -1311,7 +1284,7 @@ internal abstract class MapLogic
foreach ((string _, int wholePercentage) in keyValuePair.Value) foreach ((string _, int wholePercentage) in keyValuePair.Value)
wholePercentagesCollection.Add(wholePercentage); wholePercentagesCollection.Add(wholePercentage);
} }
return results.AsReadOnly(); return new(results);
} }
internal static ReadOnlyDictionary<int, List<LocationContainer>> ConvertLocationContainers(List<LocationContainer> locationContainers) internal static ReadOnlyDictionary<int, List<LocationContainer>> ConvertLocationContainers(List<LocationContainer> locationContainers)
@ -1323,7 +1296,7 @@ internal abstract class MapLogic
results.Add(locationContainer.Id, []); results.Add(locationContainer.Id, []);
results[locationContainer.Id].Add(locationContainer); results[locationContainer.Id].Add(locationContainer);
} }
return results.AsReadOnly(); return new(results);
} }
internal static bool? CanReMap(long[] jLinkResolvedPersonKeys, ReadOnlyDictionary<int, ReadOnlyCollection<PersonContainer>>? wholePercentagesToPersonContainers, int wholePercentages) internal static bool? CanReMap(long[] jLinkResolvedPersonKeys, ReadOnlyDictionary<int, ReadOnlyCollection<PersonContainer>>? wholePercentagesToPersonContainers, int wholePercentages)

View File

@ -82,12 +82,12 @@ internal abstract class RelationLogic
locationContainer = collection[0]; locationContainer = collection[0];
if (locationContainer.PersonKey is null) if (locationContainer.PersonKey is null)
continue; continue;
results.Add(new(key, locationContainer.PersonKey.Value, collection.AsReadOnly())); results.Add(new(key, locationContainer.PersonKey.Value, new(collection)));
collection = []; collection = [];
years.Clear(); years.Clear();
} }
} }
return results.AsReadOnly(); return new(results);
} }
private static ReadOnlyDictionary<string, string> MoveFiles(Configuration configuration, string key, bool isCounterPersonYear, string? displayDirectoryName, ReadOnlyCollection<RelationContainer> relationContainers, List<List<string>> linked) private static ReadOnlyDictionary<string, string> MoveFiles(Configuration configuration, string key, bool isCounterPersonYear, string? displayDirectoryName, ReadOnlyCollection<RelationContainer> relationContainers, List<List<string>> linked)
@ -104,7 +104,7 @@ internal abstract class RelationLogic
string? personKeyFormattedDirectory; string? personKeyFormattedDirectory;
foreach ((FileHolder fileHolder, _) in relationContainers) foreach ((FileHolder fileHolder, _) in relationContainers)
{ {
personNameDirectory = fileHolder.DirectoryFullPath; personNameDirectory = fileHolder.DirectoryName;
yearDirectory = Path.GetDirectoryName(personNameDirectory); yearDirectory = Path.GetDirectoryName(personNameDirectory);
personNameDirectoryName = Path.GetFileName(personNameDirectory); personNameDirectoryName = Path.GetFileName(personNameDirectory);
personKeyFormattedDirectory = Path.GetDirectoryName(yearDirectory); personKeyFormattedDirectory = Path.GetDirectoryName(yearDirectory);
@ -202,7 +202,7 @@ internal abstract class RelationLogic
_ = Directory.CreateDirectory(checkDirectory); _ = Directory.CreateDirectory(checkDirectory);
} }
} }
return results.AsReadOnly(); return new(results);
} }
private static string? GetDisplayDirectoryName(ReadOnlyDictionary<long, List<PersonContainer>> readOnlyPersonKeyToPersonContainerCollection, ReadOnlyDictionary<string, PersonContainer> readOnlyPersonKeyFormattedToPersonContainer, long personKey, string personKeyFormatted) private static string? GetDisplayDirectoryName(ReadOnlyDictionary<long, List<PersonContainer>> readOnlyPersonKeyToPersonContainerCollection, ReadOnlyDictionary<string, PersonContainer> readOnlyPersonKeyFormattedToPersonContainer, long personKey, string personKeyFormatted)

View File

@ -4,13 +4,13 @@
<Nullable>enable</Nullable> <Nullable>enable</Nullable>
<OutputType>Exe</OutputType> <OutputType>Exe</OutputType>
<RuntimeIdentifier>win-x64</RuntimeIdentifier> <RuntimeIdentifier>win-x64</RuntimeIdentifier>
<TargetFramework>net9.0</TargetFramework> <TargetFramework>net8.0</TargetFramework>
<UserSecretsId>f89b7242-dbb0-4349-b950-657eb8cf87ef</UserSecretsId> <UserSecretsId>f89b7242-dbb0-4349-b950-657eb8cf87ef</UserSecretsId>
</PropertyGroup> </PropertyGroup>
<PropertyGroup> <PropertyGroup>
<PackageId>Phares.View.by.Distance.Metadata.Query</PackageId> <PackageId>Phares.View.by.Distance.Metadata.Query</PackageId>
<GeneratePackageOnBuild>false</GeneratePackageOnBuild> <GeneratePackageOnBuild>false</GeneratePackageOnBuild>
<Version>9.0.100.1</Version> <Version>8.0.101.1</Version>
<Authors>Mike Phares</Authors> <Authors>Mike Phares</Authors>
<Company>Phares</Company> <Company>Phares</Company>
<IncludeSymbols>true</IncludeSymbols> <IncludeSymbols>true</IncludeSymbols>
@ -35,10 +35,10 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Humanizer.Core" Version="2.14.1" /> <PackageReference Include="Humanizer.Core" Version="2.14.1" />
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="9.0.2" /> <PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.UserSecrets" Version="9.0.2" /> <PackageReference Include="Microsoft.Extensions.Configuration.UserSecrets" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.Hosting" Version="9.0.2" /> <PackageReference Include="Microsoft.Extensions.Hosting" Version="8.0.0" />
<PackageReference Include="System.Text.Json" Version="9.0.2" /> <PackageReference Include="System.Text.Json" Version="8.0.4" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\Property\Property.csproj" /> <ProjectReference Include="..\Property\Property.csproj" />

View File

@ -34,15 +34,17 @@ public class Configuration
} }
} }
private static Models.Configuration Get(Configuration? configuration, Property.Models.Configuration propertyConfiguration) private static Models.Configuration Get(Configuration? configuration)
{ {
Models.Configuration result; Models.Configuration result;
if (configuration is null) throw new NullReferenceException(nameof(configuration)); if (configuration is null) throw new NullReferenceException(nameof(configuration));
if (configuration.IgnoreExtensions is null) throw new NullReferenceException(nameof(configuration.IgnoreExtensions)); if (configuration.IgnoreExtensions is null) throw new NullReferenceException(nameof(configuration.IgnoreExtensions));
if (configuration.PersonBirthdayFormat is null) throw new NullReferenceException(nameof(configuration.PersonBirthdayFormat)); if (configuration.PersonBirthdayFormat is null) throw new NullReferenceException(nameof(configuration.PersonBirthdayFormat));
result = new(propertyConfiguration, if (configuration.PropertyConfiguration is null) throw new NullReferenceException(nameof(configuration.PropertyConfiguration));
configuration.IgnoreExtensions, result = new(
configuration.PersonBirthdayFormat); configuration.IgnoreExtensions,
configuration.PersonBirthdayFormat,
configuration.PropertyConfiguration);
return result; return result;
} }
@ -64,7 +66,7 @@ public class Configuration
#pragma warning restore IL3050, IL2026 #pragma warning restore IL3050, IL2026
} }
PreVerify(configurationRoot, configuration); PreVerify(configurationRoot, configuration);
result = Get(configuration, propertyConfiguration); result = Get(configuration);
return result; return result;
} }

View File

@ -13,9 +13,10 @@ public class Configuration
public Property.Models.Configuration PropertyConfiguration => _PropertyConfiguration; public Property.Models.Configuration PropertyConfiguration => _PropertyConfiguration;
[JsonConstructor] [JsonConstructor]
public Configuration(Property.Models.Configuration propertyConfiguration, public Configuration(
string[] ignoreExtensions, string[] ignoreExtensions,
string personBirthdayFormat) string personBirthdayFormat,
Property.Models.Configuration propertyConfiguration)
{ {
IgnoreExtensions = ignoreExtensions; IgnoreExtensions = ignoreExtensions;
PersonBirthdayFormat = personBirthdayFormat; PersonBirthdayFormat = personBirthdayFormat;

View File

@ -4,12 +4,12 @@
<Nullable>enable</Nullable> <Nullable>enable</Nullable>
<OutputType>library</OutputType> <OutputType>library</OutputType>
<RuntimeIdentifier>win-x64</RuntimeIdentifier> <RuntimeIdentifier>win-x64</RuntimeIdentifier>
<TargetFramework>net9.0</TargetFramework> <TargetFramework>net8.0</TargetFramework>
</PropertyGroup> </PropertyGroup>
<PropertyGroup> <PropertyGroup>
<PackageId>Phares.View.by.Distance.Metadata</PackageId> <PackageId>Phares.View.by.Distance.Metadata</PackageId>
<GeneratePackageOnBuild>false</GeneratePackageOnBuild> <GeneratePackageOnBuild>false</GeneratePackageOnBuild>
<Version>9.0.100.1</Version> <Version>8.0.101.1</Version>
<Authors>Mike Phares</Authors> <Authors>Mike Phares</Authors>
<Company>Phares</Company> <Company>Phares</Company>
<IncludeSymbols>true</IncludeSymbols> <IncludeSymbols>true</IncludeSymbols>
@ -34,7 +34,7 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="MetadataExtractor" Version="2.8.1" /> <PackageReference Include="MetadataExtractor" Version="2.8.1" />
<PackageReference Include="System.Text.Json" Version="9.0.2" /> <PackageReference Include="System.Text.Json" Version="8.0.4" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\Property\Property.csproj" /> <ProjectReference Include="..\Property\Property.csproj" />

View File

@ -16,24 +16,16 @@ public class B_Metadata : IMetadata<MetadataExtractor.Directory>
private readonly bool _PropertiesChangedForMetadata; private readonly bool _PropertiesChangedForMetadata;
private readonly IPropertyConfiguration _PropertyConfiguration; private readonly IPropertyConfiguration _PropertyConfiguration;
private readonly bool _ForceMetadataLastWriteTimeToCreationTime; private readonly bool _ForceMetadataLastWriteTimeToCreationTime;
private readonly ReadOnlyDictionary<string, string[]> _FileGroups;
private readonly JsonSerializerOptions _WriteIndentedJsonSerializerOptions; private readonly JsonSerializerOptions _WriteIndentedJsonSerializerOptions;
private readonly ReadOnlyDictionary<byte, ReadOnlyCollection<string>>[] _ResultSingletonFileGroups;
public B_Metadata(IPropertyConfiguration propertyConfiguration) public B_Metadata(IPropertyConfiguration propertyConfiguration)
{ {
_PropertiesChangedForMetadata = false; _PropertiesChangedForMetadata = false;
_PropertyConfiguration = propertyConfiguration; _PropertyConfiguration = propertyConfiguration;
_ForceMetadataLastWriteTimeToCreationTime = false; _ForceMetadataLastWriteTimeToCreationTime = false;
_ResultSingletonFileGroups = [new(new Dictionary<byte, ReadOnlyCollection<string>>())];
_WriteIndentedJsonSerializerOptions = new JsonSerializerOptions { WriteIndented = true }; _WriteIndentedJsonSerializerOptions = new JsonSerializerOptions { WriteIndented = true };
ReadOnlyDictionary<string, ReadOnlyDictionary<byte, ReadOnlyCollection<string>>> keyValuePairs = Shared.Models.Stateless.Methods.IPath.GetKeyValuePairs(propertyConfiguration, null, [propertyConfiguration.ResultSingleton]); _FileGroups = Shared.Models.Stateless.Methods.IPath.GetKeyValuePairs(propertyConfiguration, null, [propertyConfiguration.ResultSingleton]);
foreach (KeyValuePair<string, ReadOnlyDictionary<byte, ReadOnlyCollection<string>>> keyValuePair in keyValuePairs)
{
if (keyValuePair.Key == _PropertyConfiguration.ResultSingleton)
_ResultSingletonFileGroups[0] = keyValuePair.Value;
else
throw new Exception();
}
} }
public B_Metadata(IPropertyConfiguration propertyConfiguration, bool forceMetadataLastWriteTimeToCreationTime, bool propertiesChangedForMetadata, string bResultsFullGroupDirectory) public B_Metadata(IPropertyConfiguration propertyConfiguration, bool forceMetadataLastWriteTimeToCreationTime, bool propertiesChangedForMetadata, string bResultsFullGroupDirectory)
@ -41,16 +33,8 @@ public class B_Metadata : IMetadata<MetadataExtractor.Directory>
_PropertyConfiguration = propertyConfiguration; _PropertyConfiguration = propertyConfiguration;
_PropertiesChangedForMetadata = propertiesChangedForMetadata; _PropertiesChangedForMetadata = propertiesChangedForMetadata;
_ForceMetadataLastWriteTimeToCreationTime = forceMetadataLastWriteTimeToCreationTime; _ForceMetadataLastWriteTimeToCreationTime = forceMetadataLastWriteTimeToCreationTime;
_ResultSingletonFileGroups = [new(new Dictionary<byte, ReadOnlyCollection<string>>())];
_WriteIndentedJsonSerializerOptions = new JsonSerializerOptions { WriteIndented = true }; _WriteIndentedJsonSerializerOptions = new JsonSerializerOptions { WriteIndented = true };
ReadOnlyDictionary<string, ReadOnlyDictionary<byte, ReadOnlyCollection<string>>> keyValuePairs = Shared.Models.Stateless.Methods.IPath.GetKeyValuePairs(propertyConfiguration, bResultsFullGroupDirectory, [propertyConfiguration.ResultSingleton]); _FileGroups = Shared.Models.Stateless.Methods.IPath.GetKeyValuePairs(propertyConfiguration, bResultsFullGroupDirectory, [propertyConfiguration.ResultSingleton]);
foreach (KeyValuePair<string, ReadOnlyDictionary<byte, ReadOnlyCollection<string>>> keyValuePair in keyValuePairs)
{
if (keyValuePair.Key == _PropertyConfiguration.ResultSingleton)
_ResultSingletonFileGroups[0] = keyValuePair.Value;
else
throw new Exception();
}
} }
public override string ToString() public override string ToString()
@ -59,34 +43,12 @@ public class B_Metadata : IMetadata<MetadataExtractor.Directory>
return result; return result;
} }
private static void MoveIf(string fileName, CombinedEnumAndIndex cei, string directory, FileInfo fileInfo)
{
string[] segments = directory.Split(cei.Combined);
string? checkDirectory = segments.Length == 1 ?
Path.Combine(segments[0], $"{cei.Combined[2..]}") :
segments.Length == 2 ?
$"{segments[0]}{cei.Combined[2..]}{segments[1]}" :
null;
if (checkDirectory is not null && System.IO.Directory.Exists(checkDirectory))
{
string checkFile = Path.Combine(checkDirectory, fileName);
if (File.Exists(checkFile))
{
File.Move(checkFile, fileInfo.FullName);
fileInfo.Refresh();
}
}
}
public ExifDirectory GetMetadataCollection(FilePath filePath, List<Tuple<string, DateTime>> subFileTuples, List<string> parseExceptions, string[] changesFrom, MappingFromItem mappingFromItem) public ExifDirectory GetMetadataCollection(FilePath filePath, List<Tuple<string, DateTime>> subFileTuples, List<string> parseExceptions, string[] changesFrom, MappingFromItem mappingFromItem)
{ {
ExifDirectory? result = null; ExifDirectory? result = null;
List<DateTime> dateTimes = (from l in subFileTuples where changesFrom.Contains(l.Item1) select l.Item2).ToList(); List<DateTime> dateTimes = (from l in subFileTuples where changesFrom.Contains(l.Item1) select l.Item2).ToList();
CombinedEnumAndIndex cei = Shared.Models.Stateless.Methods.IPath.GetCombinedEnumAndIndex(_PropertyConfiguration, filePath); (_, int directoryIndex) = Shared.Models.Stateless.Methods.IPath.GetDirectoryNameAndIndex(_PropertyConfiguration, filePath);
string fileName = $"{mappingFromItem.FilePath.NameWithoutExtension}{mappingFromItem.FilePath.ExtensionLowered}.json"; FileInfo fileInfo = new(Path.Combine(_FileGroups[_PropertyConfiguration.ResultSingleton][directoryIndex], $"{mappingFromItem.FilePath.NameWithoutExtension}{mappingFromItem.FilePath.ExtensionLowered}.json"));
string directory = _ResultSingletonFileGroups[0][cei.Enum][cei.Index];
FileInfo fileInfo = new(Path.Combine(directory, fileName));
MoveIf(fileName, cei, directory, fileInfo);
if (_ForceMetadataLastWriteTimeToCreationTime && !fileInfo.Exists && File.Exists(Path.ChangeExtension(fileInfo.FullName, ".delete"))) if (_ForceMetadataLastWriteTimeToCreationTime && !fileInfo.Exists && File.Exists(Path.ChangeExtension(fileInfo.FullName, ".delete")))
{ {
File.Move(Path.ChangeExtension(fileInfo.FullName, ".delete"), fileInfo.FullName); File.Move(Path.ChangeExtension(fileInfo.FullName, ".delete"), fileInfo.FullName);

View File

@ -484,7 +484,7 @@ internal abstract class Exif
return results.ToArray(); return results.ToArray();
} }
private static Shared.Models.ExifDirectory Covert(Shared.Models.FilePath filePath, IReadOnlyList<MetadataExtractor.Directory> directories, System.Drawing.Size? size) private static Shared.Models.ExifDirectory Covert(Shared.Models.FilePath filePath, System.Drawing.Size? size, IReadOnlyList<MetadataExtractor.Directory> directories)
{ {
Shared.Models.ExifDirectory result; Shared.Models.ExifDirectory result;
Shared.Models.AviDirectory[] aviDirectories = GetAviDirectories(directories); Shared.Models.AviDirectory[] aviDirectories = GetAviDirectories(directories);
@ -502,12 +502,12 @@ internal abstract class Exif
result = new(aviDirectories, result = new(aviDirectories,
exifBaseDirectories, exifBaseDirectories,
fileMetadataDirectories, fileMetadataDirectories,
filePath,
gifHeaderDirectories, gifHeaderDirectories,
gpsDirectories, gpsDirectories,
size?.Height, size?.Height,
jpegDirectories, jpegDirectories,
makernoteDirectories, makernoteDirectories,
filePath.Name,
photoshopDirectories, photoshopDirectories,
pngDirectories, pngDirectories,
quickTimeMovieHeaderDirectories, quickTimeMovieHeaderDirectories,
@ -520,13 +520,13 @@ internal abstract class Exif
internal static Shared.Models.ExifDirectory GetExifDirectory(Shared.Models.FilePath filePath) internal static Shared.Models.ExifDirectory GetExifDirectory(Shared.Models.FilePath filePath)
{ {
Shared.Models.ExifDirectory result; Shared.Models.ExifDirectory result;
IReadOnlyList<MetadataExtractor.Directory> directories = ImageMetadataReader.ReadMetadata(filePath.FullName);
System.Drawing.Size? size; System.Drawing.Size? size;
try try
{ size = Dimensions.GetDimensions(filePath.FullName); } { size = Dimensions.GetDimensions(filePath.FullName); }
catch (Exception) catch (Exception)
{ size = null; } { size = null; }
result = Covert(filePath, directories, size); IReadOnlyList<MetadataExtractor.Directory> directories = ImageMetadataReader.ReadMetadata(filePath.FullName);
result = Covert(filePath, size, directories);
return result; return result;
} }

View File

@ -4,13 +4,13 @@
<Nullable>enable</Nullable> <Nullable>enable</Nullable>
<OutputType>Exe</OutputType> <OutputType>Exe</OutputType>
<RuntimeIdentifier>win-x64</RuntimeIdentifier> <RuntimeIdentifier>win-x64</RuntimeIdentifier>
<TargetFramework>net9.0</TargetFramework> <TargetFramework>net8.0</TargetFramework>
<UserSecretsId>fa06c6db-0226-42ca-8728-68b1e336184d</UserSecretsId> <UserSecretsId>fa06c6db-0226-42ca-8728-68b1e336184d</UserSecretsId>
</PropertyGroup> </PropertyGroup>
<PropertyGroup> <PropertyGroup>
<PackageId>Phares.View.by.Distance.Mirror.Length</PackageId> <PackageId>Phares.View.by.Distance.Mirror.Length</PackageId>
<GeneratePackageOnBuild>false</GeneratePackageOnBuild> <GeneratePackageOnBuild>false</GeneratePackageOnBuild>
<Version>9.0.100.1</Version> <Version>8.0.101.1</Version>
<Authors>Mike Phares</Authors> <Authors>Mike Phares</Authors>
<Company>Phares</Company> <Company>Phares</Company>
<IncludeSymbols>true</IncludeSymbols> <IncludeSymbols>true</IncludeSymbols>
@ -35,10 +35,10 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Humanizer.Core" Version="2.14.1" /> <PackageReference Include="Humanizer.Core" Version="2.14.1" />
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="9.0.2" /> <PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.UserSecrets" Version="9.0.2" /> <PackageReference Include="Microsoft.Extensions.Configuration.UserSecrets" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.Hosting" Version="9.0.2" /> <PackageReference Include="Microsoft.Extensions.Hosting" Version="8.0.0" />
<PackageReference Include="System.Text.Json" Version="9.0.2" /> <PackageReference Include="System.Text.Json" Version="8.0.4" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\Property\Property.csproj" /> <ProjectReference Include="..\Property\Property.csproj" />

View File

@ -193,7 +193,6 @@ public class MirrorLength
{ {
string message = nameof(MirrorLength); string message = nameof(MirrorLength);
List<(string, string, int)> collectionForMarkDown; List<(string, string, int)> collectionForMarkDown;
logger?.LogDebug("{method}", nameof(MirrorLengthFilesInDirectories));
bool inPlaceSave = _PropertyConfiguration.RootDirectory.First() == _AppSettings.Destination; bool inPlaceSave = _PropertyConfiguration.RootDirectory.First() == _AppSettings.Destination;
if (!inPlaceSave) if (!inPlaceSave)
collectionForMarkDown = []; collectionForMarkDown = [];

View File

@ -34,15 +34,17 @@ public class Configuration
} }
} }
private static Models.Configuration Get(Configuration? configuration, Property.Models.Configuration propertyConfiguration) private static Models.Configuration Get(Configuration? configuration)
{ {
Models.Configuration result; Models.Configuration result;
if (configuration is null) throw new NullReferenceException(nameof(configuration)); if (configuration is null) throw new NullReferenceException(nameof(configuration));
if (configuration.IgnoreExtensions is null) throw new NullReferenceException(nameof(configuration.IgnoreExtensions)); if (configuration.IgnoreExtensions is null) throw new NullReferenceException(nameof(configuration.IgnoreExtensions));
if (configuration.PersonBirthdayFormat is null) throw new NullReferenceException(nameof(configuration.PersonBirthdayFormat)); if (configuration.PersonBirthdayFormat is null) throw new NullReferenceException(nameof(configuration.PersonBirthdayFormat));
result = new(propertyConfiguration, if (configuration.PropertyConfiguration is null) throw new NullReferenceException(nameof(configuration.PropertyConfiguration));
configuration.IgnoreExtensions, result = new(
configuration.PersonBirthdayFormat); configuration.IgnoreExtensions,
configuration.PersonBirthdayFormat,
configuration.PropertyConfiguration);
return result; return result;
} }
@ -64,7 +66,7 @@ public class Configuration
#pragma warning restore IL3050, IL2026 #pragma warning restore IL3050, IL2026
} }
PreVerify(configurationRoot, configuration); PreVerify(configurationRoot, configuration);
result = Get(configuration, propertyConfiguration); result = Get(configuration);
return result; return result;
} }

View File

@ -13,9 +13,10 @@ public class Configuration
public Property.Models.Configuration PropertyConfiguration => _PropertyConfiguration; public Property.Models.Configuration PropertyConfiguration => _PropertyConfiguration;
[JsonConstructor] [JsonConstructor]
public Configuration(Property.Models.Configuration propertyConfiguration, public Configuration(
string[] ignoreExtensions, string[] ignoreExtensions,
string personBirthdayFormat) string personBirthdayFormat,
Property.Models.Configuration propertyConfiguration)
{ {
IgnoreExtensions = ignoreExtensions; IgnoreExtensions = ignoreExtensions;
PersonBirthdayFormat = personBirthdayFormat; PersonBirthdayFormat = personBirthdayFormat;

View File

@ -34,15 +34,17 @@ public class Configuration
} }
} }
private static Models.Configuration Get(Configuration? configuration, Property.Models.Configuration propertyConfiguration) private static Models.Configuration Get(Configuration? configuration)
{ {
Models.Configuration result; Models.Configuration result;
if (configuration is null) throw new NullReferenceException(nameof(configuration)); if (configuration is null) throw new NullReferenceException(nameof(configuration));
if (configuration.IgnoreExtensions is null) throw new NullReferenceException(nameof(configuration.IgnoreExtensions)); if (configuration.IgnoreExtensions is null) throw new NullReferenceException(nameof(configuration.IgnoreExtensions));
if (configuration.PersonBirthdayFormat is null) throw new NullReferenceException(nameof(configuration.PersonBirthdayFormat)); if (configuration.PersonBirthdayFormat is null) throw new NullReferenceException(nameof(configuration.PersonBirthdayFormat));
result = new(propertyConfiguration, if (configuration.PropertyConfiguration is null) throw new NullReferenceException(nameof(configuration.PropertyConfiguration));
configuration.IgnoreExtensions, result = new(
configuration.PersonBirthdayFormat); configuration.IgnoreExtensions,
configuration.PersonBirthdayFormat,
configuration.PropertyConfiguration);
return result; return result;
} }
@ -64,7 +66,7 @@ public class Configuration
#pragma warning restore IL3050, IL2026 #pragma warning restore IL3050, IL2026
} }
PreVerify(configurationRoot, configuration); PreVerify(configurationRoot, configuration);
result = Get(configuration, propertyConfiguration); result = Get(configuration);
return result; return result;
} }

View File

@ -13,9 +13,10 @@ public class Configuration
public Property.Models.Configuration PropertyConfiguration => _PropertyConfiguration; public Property.Models.Configuration PropertyConfiguration => _PropertyConfiguration;
[JsonConstructor] [JsonConstructor]
public Configuration(Property.Models.Configuration propertyConfiguration, public Configuration(
string[] ignoreExtensions, string[] ignoreExtensions,
string personBirthdayFormat) string personBirthdayFormat,
Property.Models.Configuration propertyConfiguration)
{ {
IgnoreExtensions = ignoreExtensions; IgnoreExtensions = ignoreExtensions;
PersonBirthdayFormat = personBirthdayFormat; PersonBirthdayFormat = personBirthdayFormat;

View File

@ -4,13 +4,13 @@
<Nullable>enable</Nullable> <Nullable>enable</Nullable>
<OutputType>Exe</OutputType> <OutputType>Exe</OutputType>
<RuntimeIdentifier>win-x64</RuntimeIdentifier> <RuntimeIdentifier>win-x64</RuntimeIdentifier>
<TargetFramework>net9.0</TargetFramework> <TargetFramework>net8.0</TargetFramework>
<UserSecretsId>ce31220e-ef92-4e68-89c5-91b027a94dca</UserSecretsId> <UserSecretsId>ce31220e-ef92-4e68-89c5-91b027a94dca</UserSecretsId>
</PropertyGroup> </PropertyGroup>
<PropertyGroup> <PropertyGroup>
<PackageId>Phares.View.by.Distance.Move.By.Id</PackageId> <PackageId>Phares.View.by.Distance.Move.By.Id</PackageId>
<GeneratePackageOnBuild>false</GeneratePackageOnBuild> <GeneratePackageOnBuild>false</GeneratePackageOnBuild>
<Version>9.0.100.1</Version> <Version>8.0.101.1</Version>
<Authors>Mike Phares</Authors> <Authors>Mike Phares</Authors>
<Company>Phares</Company> <Company>Phares</Company>
<IncludeSymbols>true</IncludeSymbols> <IncludeSymbols>true</IncludeSymbols>
@ -35,9 +35,9 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Humanizer.Core" Version="2.14.1" /> <PackageReference Include="Humanizer.Core" Version="2.14.1" />
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="9.0.2" /> <PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.UserSecrets" Version="9.0.2" /> <PackageReference Include="Microsoft.Extensions.Configuration.UserSecrets" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.Hosting" Version="9.0.2" /> <PackageReference Include="Microsoft.Extensions.Hosting" Version="8.0.0" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\Property\Property.csproj" /> <ProjectReference Include="..\Property\Property.csproj" />

View File

@ -115,7 +115,7 @@ public class MoveById
progressBar.Tick(); progressBar.Tick();
fileHolder = Shared.Models.Stateless.Methods.IFileHolder.Get(file); fileHolder = Shared.Models.Stateless.Methods.IFileHolder.Get(file);
filePath = FilePath.Get(_Configuration.PropertyConfiguration, fileHolder, index: null); filePath = FilePath.Get(_Configuration.PropertyConfiguration, fileHolder, index: null);
if (fileHolder.ExtensionLowered == ".id" || fileHolder.DirectoryFullPath is null) if (fileHolder.ExtensionLowered == ".id" || fileHolder.DirectoryName is null)
continue; continue;
if (allFiles.Contains($"{fileHolder.FullName}.id")) if (allFiles.Contains($"{fileHolder.FullName}.id"))
continue; continue;

View File

@ -34,15 +34,17 @@ public class Configuration
} }
} }
private static Models.Configuration Get(Configuration? configuration, Property.Models.Configuration propertyConfiguration) private static Models.Configuration Get(Configuration? configuration)
{ {
Models.Configuration result; Models.Configuration result;
if (configuration is null) throw new NullReferenceException(nameof(configuration)); if (configuration is null) throw new NullReferenceException(nameof(configuration));
if (configuration.IgnoreExtensions is null) throw new NullReferenceException(nameof(configuration.IgnoreExtensions)); if (configuration.IgnoreExtensions is null) throw new NullReferenceException(nameof(configuration.IgnoreExtensions));
if (configuration.PersonBirthdayFormat is null) throw new NullReferenceException(nameof(configuration.PersonBirthdayFormat)); if (configuration.PersonBirthdayFormat is null) throw new NullReferenceException(nameof(configuration.PersonBirthdayFormat));
result = new(propertyConfiguration, if (configuration.PropertyConfiguration is null) throw new NullReferenceException(nameof(configuration.PropertyConfiguration));
configuration.IgnoreExtensions, result = new(
configuration.PersonBirthdayFormat); configuration.IgnoreExtensions,
configuration.PersonBirthdayFormat,
configuration.PropertyConfiguration);
return result; return result;
} }
@ -64,7 +66,7 @@ public class Configuration
#pragma warning restore IL3050, IL2026 #pragma warning restore IL3050, IL2026
} }
PreVerify(configurationRoot, configuration); PreVerify(configurationRoot, configuration);
result = Get(configuration, propertyConfiguration); result = Get(configuration);
return result; return result;
} }

View File

@ -13,9 +13,10 @@ public class Configuration
public Property.Models.Configuration PropertyConfiguration => _PropertyConfiguration; public Property.Models.Configuration PropertyConfiguration => _PropertyConfiguration;
[JsonConstructor] [JsonConstructor]
public Configuration(Property.Models.Configuration propertyConfiguration, public Configuration(
string[] ignoreExtensions, string[] ignoreExtensions,
string personBirthdayFormat) string personBirthdayFormat,
Property.Models.Configuration propertyConfiguration)
{ {
IgnoreExtensions = ignoreExtensions; IgnoreExtensions = ignoreExtensions;
PersonBirthdayFormat = personBirthdayFormat; PersonBirthdayFormat = personBirthdayFormat;

View File

@ -4,13 +4,13 @@
<Nullable>enable</Nullable> <Nullable>enable</Nullable>
<OutputType>Exe</OutputType> <OutputType>Exe</OutputType>
<RuntimeIdentifier>win-x64</RuntimeIdentifier> <RuntimeIdentifier>win-x64</RuntimeIdentifier>
<TargetFramework>net9.0</TargetFramework> <TargetFramework>net8.0</TargetFramework>
<UserSecretsId>ae069946-d0c0-4e4f-94f6-9c526e4ae4e7</UserSecretsId> <UserSecretsId>ae069946-d0c0-4e4f-94f6-9c526e4ae4e7</UserSecretsId>
</PropertyGroup> </PropertyGroup>
<PropertyGroup> <PropertyGroup>
<PackageId>Phares.View.by.Distance.Offset.Date.Time.Original</PackageId> <PackageId>Phares.View.by.Distance.Offset.Date.Time.Original</PackageId>
<GeneratePackageOnBuild>false</GeneratePackageOnBuild> <GeneratePackageOnBuild>false</GeneratePackageOnBuild>
<Version>9.0.100.1</Version> <Version>8.0.101.1</Version>
<Authors>Mike Phares</Authors> <Authors>Mike Phares</Authors>
<Company>Phares</Company> <Company>Phares</Company>
<IncludeSymbols>true</IncludeSymbols> <IncludeSymbols>true</IncludeSymbols>
@ -35,10 +35,10 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Humanizer.Core" Version="2.14.1" /> <PackageReference Include="Humanizer.Core" Version="2.14.1" />
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="9.0.2" /> <PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.UserSecrets" Version="9.0.2" /> <PackageReference Include="Microsoft.Extensions.Configuration.UserSecrets" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.Hosting" Version="9.0.2" /> <PackageReference Include="Microsoft.Extensions.Hosting" Version="8.0.0" />
<PackageReference Include="System.Text.Json" Version="9.0.2" /> <PackageReference Include="System.Text.Json" Version="8.0.4" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\Property\Property.csproj" /> <ProjectReference Include="..\Property\Property.csproj" />

View File

@ -216,17 +216,6 @@ public class OffsetDateTimeOriginal
{ {
TimeSpan timeSpan = new(targetDateTimeOriginal.Value.Ticks - badDateTimeOriginal.Value.Ticks); TimeSpan timeSpan = new(targetDateTimeOriginal.Value.Ticks - badDateTimeOriginal.Value.Ticks);
DateFix(sourceDirectory, asciiEncoding, checkDirectory, minimumDateTime, maximumDateTime, timeSpan.Ticks); DateFix(sourceDirectory, asciiEncoding, checkDirectory, minimumDateTime, maximumDateTime, timeSpan.Ticks);
// DateTime a = new(2020, 01, 04, 02, 12, 51, 32);
// // DateTime a = new(2020, 01, 05, 18, 17, 15, 97);
// DateTime b = new(2020, 01, 05, 19, 52, 30, 17);
// DateTime c = new(2024, 12, 07, 11, 19, 06, 13);
// // DateTime d = new(2024, 12, 07, 12, 07, 30, 38);
// long e = new DateTime(c.Ticks - b.Ticks).AddMinutes(-5).Ticks;
// if (a != DateTime.MinValue)
// minimumDateTime = a.AddTicks(e).AddHours(-1);
// if (c != DateTime.MinValue)
// maximumDateTime = c;
// DateFix(sourceDirectory, asciiEncoding, checkDirectory, minimumDateTime, maximumDateTime, e);
} }
} }
} }

View File

@ -4,12 +4,12 @@
<Nullable>enable</Nullable> <Nullable>enable</Nullable>
<OutputType>library</OutputType> <OutputType>library</OutputType>
<RuntimeIdentifier>win-x64</RuntimeIdentifier> <RuntimeIdentifier>win-x64</RuntimeIdentifier>
<TargetFramework>net9.0</TargetFramework> <TargetFramework>net8.0</TargetFramework>
</PropertyGroup> </PropertyGroup>
<PropertyGroup> <PropertyGroup>
<PackageId>Phares.View.by.Distance.PhotoPrism</PackageId> <PackageId>Phares.View.by.Distance.PhotoPrism</PackageId>
<GeneratePackageOnBuild>false</GeneratePackageOnBuild> <GeneratePackageOnBuild>false</GeneratePackageOnBuild>
<Version>9.0.100.1</Version> <Version>8.0.101.1</Version>
<Authors>Mike Phares</Authors> <Authors>Mike Phares</Authors>
<Company>Phares</Company> <Company>Phares</Company>
<IncludeSymbols>true</IncludeSymbols> <IncludeSymbols>true</IncludeSymbols>
@ -37,7 +37,7 @@
<PackageReference Include="MetadataExtractor" Version="2.8.1" /> <PackageReference Include="MetadataExtractor" Version="2.8.1" />
<PackageReference Include="ShellProgressBar" Version="5.2.0" /> <PackageReference Include="ShellProgressBar" Version="5.2.0" />
<PackageReference Include="WindowsShortcutFactory" Version="1.2.0" /> <PackageReference Include="WindowsShortcutFactory" Version="1.2.0" />
<PackageReference Include="System.Text.Json" Version="9.0.2" /> <PackageReference Include="System.Text.Json" Version="8.0.4" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\Shared\View-by-Distance.Shared.csproj" /> <ProjectReference Include="..\Shared\View-by-Distance.Shared.csproj" />

View File

@ -4,12 +4,12 @@
<Nullable>enable</Nullable> <Nullable>enable</Nullable>
<OutputType>Exe</OutputType> <OutputType>Exe</OutputType>
<RuntimeIdentifier>win-x64</RuntimeIdentifier> <RuntimeIdentifier>win-x64</RuntimeIdentifier>
<TargetFramework>net9.0</TargetFramework> <TargetFramework>net8.0</TargetFramework>
</PropertyGroup> </PropertyGroup>
<PropertyGroup> <PropertyGroup>
<PackageId>Phares.View.by.Distance.PrepareForOld</PackageId> <PackageId>Phares.View.by.Distance.PrepareForOld</PackageId>
<GeneratePackageOnBuild>false</GeneratePackageOnBuild> <GeneratePackageOnBuild>false</GeneratePackageOnBuild>
<Version>9.0.100.1</Version> <Version>8.0.101.1</Version>
<Authors>Mike Phares</Authors> <Authors>Mike Phares</Authors>
<Company>Phares</Company> <Company>Phares</Company>
<IncludeSymbols>true</IncludeSymbols> <IncludeSymbols>true</IncludeSymbols>
@ -33,14 +33,14 @@
<SupportedPlatform Include="browser" /> <SupportedPlatform Include="browser" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Microsoft.Extensions.Hosting" Version="9.0.2" /> <PackageReference Include="Microsoft.Extensions.Hosting" Version="8.0.0" />
<PackageReference Include="ShellProgressBar" Version="5.2.0" /> <PackageReference Include="ShellProgressBar" Version="5.2.0" />
<PackageReference Include="System.Drawing.Common" Version="8.0.10" /> <PackageReference Include="System.Drawing.Common" Version="8.0.7" />
<PackageReference Include="System.Text.Json" Version="9.0.2" /> <PackageReference Include="System.Text.Json" Version="8.0.4" />
<PackageReference Include="MetadataExtractor" Version="2.8.1" /> <PackageReference Include="MetadataExtractor" Version="2.8.1" />
<PackageReference Include="Microsoft.AspNetCore.Cryptography.KeyDerivation" Version="9.0.2" /> <PackageReference Include="Microsoft.AspNetCore.Cryptography.KeyDerivation" Version="8.0.7" />
<PackageReference Include="Microsoft.Extensions.Identity.Core" Version="9.0.2" /> <PackageReference Include="Microsoft.Extensions.Identity.Core" Version="8.0.7" />
<PackageReference Include="Microsoft.Extensions.Options" Version="9.0.2" /> <PackageReference Include="Microsoft.Extensions.Options" Version="8.0.2" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\Shared\View-by-Distance.Shared.csproj" /> <ProjectReference Include="..\Shared\View-by-Distance.Shared.csproj" />

View File

@ -4,12 +4,12 @@
<Nullable>enable</Nullable> <Nullable>enable</Nullable>
<OutputType>library</OutputType> <OutputType>library</OutputType>
<RuntimeIdentifier>win-x64</RuntimeIdentifier> <RuntimeIdentifier>win-x64</RuntimeIdentifier>
<TargetFramework>net9.0</TargetFramework> <TargetFramework>net8.0</TargetFramework>
</PropertyGroup> </PropertyGroup>
<PropertyGroup> <PropertyGroup>
<PackageId>Phares.View.by.Distance.Property.Compare</PackageId> <PackageId>Phares.View.by.Distance.Property.Compare</PackageId>
<GeneratePackageOnBuild>false</GeneratePackageOnBuild> <GeneratePackageOnBuild>false</GeneratePackageOnBuild>
<Version>9.0.100.1</Version> <Version>8.0.101.1</Version>
<Authors>Mike Phares</Authors> <Authors>Mike Phares</Authors>
<Company>Phares</Company> <Company>Phares</Company>
<IncludeSymbols>true</IncludeSymbols> <IncludeSymbols>true</IncludeSymbols>
@ -34,8 +34,8 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="ShellProgressBar" Version="5.2.0" /> <PackageReference Include="ShellProgressBar" Version="5.2.0" />
<PackageReference Include="System.Drawing.Common" Version="8.0.10" /> <PackageReference Include="System.Drawing.Common" Version="8.0.7" />
<PackageReference Include="System.Text.Json" Version="9.0.2" /> <PackageReference Include="System.Text.Json" Version="8.0.4" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\Shared\View-by-Distance.Shared.csproj" /> <ProjectReference Include="..\Shared\View-by-Distance.Shared.csproj" />

View File

@ -22,27 +22,19 @@ public class A_Property
private readonly Configuration _Configuration; private readonly Configuration _Configuration;
private readonly List<string> _AngleBracketCollection; private readonly List<string> _AngleBracketCollection;
private readonly IPropertyConfiguration _PropertyConfiguration; private readonly IPropertyConfiguration _PropertyConfiguration;
private readonly ReadOnlyDictionary<byte, ReadOnlyCollection<string>>[] _ResultSingletonFileGroups; private readonly ReadOnlyDictionary<string, string[]> _FileGroups;
public A_Property(int maxDegreeOfParallelism, Configuration propertyConfiguration, string outputExtension, bool reverse, string aResultsFullGroupDirectory) public A_Property(int maxDegreeOfParallelism, Configuration propertyConfiguration, string outputExtension, bool reverse, string aResultsFullGroupDirectory)
{ {
Reverse = reverse; Reverse = reverse;
_ExceptionsDirectories = []; _ExceptionsDirectories = [];
_AngleBracketCollection = [];
_OutputExtension = outputExtension; _OutputExtension = outputExtension;
_ASCIIEncoding = new ASCIIEncoding(); _ASCIIEncoding = new ASCIIEncoding();
_Configuration = propertyConfiguration; _Configuration = propertyConfiguration;
_AngleBracketCollection = [];
_PropertyConfiguration = propertyConfiguration; _PropertyConfiguration = propertyConfiguration;
_MaxDegreeOfParallelism = maxDegreeOfParallelism; _MaxDegreeOfParallelism = maxDegreeOfParallelism;
_ResultSingletonFileGroups = [new(new Dictionary<byte, ReadOnlyCollection<string>>())]; _FileGroups = Shared.Models.Stateless.Methods.IPath.GetKeyValuePairs(propertyConfiguration, aResultsFullGroupDirectory, [propertyConfiguration.ResultSingleton]);
ReadOnlyDictionary<string, ReadOnlyDictionary<byte, ReadOnlyCollection<string>>> keyValuePairs = Shared.Models.Stateless.Methods.IPath.GetKeyValuePairs(propertyConfiguration, aResultsFullGroupDirectory, [propertyConfiguration.ResultSingleton]);
foreach (KeyValuePair<string, ReadOnlyDictionary<byte, ReadOnlyCollection<string>>> keyValuePair in keyValuePairs)
{
if (keyValuePair.Key == _PropertyConfiguration.ResultSingleton)
_ResultSingletonFileGroups[0] = keyValuePair.Value;
else
throw new Exception();
}
} }
public override string ToString() public override string ToString()
@ -51,25 +43,6 @@ public class A_Property
return result; return result;
} }
private static void MoveIf(string fileName, CombinedEnumAndIndex cei, string directory, FileInfo fileInfo)
{
string[] segments = directory.Split(cei.Combined);
string? checkDirectory = segments.Length == 1 ?
Path.Combine(segments[0], $"{cei.Combined[2..]}") :
segments.Length == 2 ?
$"{segments[0]}{cei.Combined[2..]}{segments[1]}" :
null;
if (checkDirectory is not null && Directory.Exists(checkDirectory))
{
string checkFile = Path.Combine(checkDirectory, fileName);
if (File.Exists(checkFile))
{
File.Move(checkFile, fileInfo.FullName);
fileInfo.Refresh();
}
}
}
private Shared.Models.Property GetImageProperty(Shared.Models.Methods.IMetadata<MetadataExtractor.Directory> metadata, Item item, List<Tuple<string, DateTime>> sourceDirectoryFileTuples, List<string> parseExceptions, bool isIgnoreExtension) private Shared.Models.Property GetImageProperty(Shared.Models.Methods.IMetadata<MetadataExtractor.Directory> metadata, Item item, List<Tuple<string, DateTime>> sourceDirectoryFileTuples, List<string> parseExceptions, bool isIgnoreExtension)
{ {
Shared.Models.Property? result; Shared.Models.Property? result;
@ -84,11 +57,8 @@ public class A_Property
fileInfo = new(Path.Combine(angleBracket.Replace("<>", _PropertyConfiguration.ResultSingleton), $"{item.FilePath.NameWithoutExtension}{item.FilePath.ExtensionLowered}.json")); fileInfo = new(Path.Combine(angleBracket.Replace("<>", _PropertyConfiguration.ResultSingleton), $"{item.FilePath.NameWithoutExtension}{item.FilePath.ExtensionLowered}.json"));
else else
{ {
string fileName = $"{item.FilePath.NameWithoutExtension}{item.FilePath.ExtensionLowered}.json"; (_, int directoryIndex) = Shared.Models.Stateless.Methods.IPath.GetDirectoryNameAndIndex(_PropertyConfiguration, item.FilePath);
CombinedEnumAndIndex cei = Shared.Models.Stateless.Methods.IPath.GetCombinedEnumAndIndex(_PropertyConfiguration, item.FilePath); fileInfo = new(Path.Combine(_FileGroups[_PropertyConfiguration.ResultSingleton][directoryIndex], $"{item.FilePath.NameWithoutExtension}{item.FilePath.ExtensionLowered}.json"));
string directory = _ResultSingletonFileGroups[0][cei.Enum][cei.Index];
fileInfo = new(Path.Combine(directory, fileName));
MoveIf(fileName, cei, directory, fileInfo);
} }
List<DateTime> dateTimes = (from l in sourceDirectoryFileTuples where l is not null && changesFrom.Contains(l.Item1) select l.Item2).ToList(); List<DateTime> dateTimes = (from l in sourceDirectoryFileTuples where l is not null && changesFrom.Contains(l.Item1) select l.Item2).ToList();
if (_Configuration.ForcePropertyLastWriteTimeToCreationTime && !fileInfo.Exists && File.Exists(Path.ChangeExtension(fileInfo.FullName, ".delete"))) if (_Configuration.ForcePropertyLastWriteTimeToCreationTime && !fileInfo.Exists && File.Exists(Path.ChangeExtension(fileInfo.FullName, ".delete")))
@ -198,7 +168,7 @@ public class A_Property
{ {
_AngleBracketCollection.Clear(); _AngleBracketCollection.Clear();
if (!anyNullOrNoIsUniqueFileName) if (!anyNullOrNoIsUniqueFileName)
_AngleBracketCollection.AddRange([Path.Combine(aResultsFullGroupDirectory, "<>")]); _AngleBracketCollection.AddRange(new[] { Path.Combine(aResultsFullGroupDirectory, "<>") });
else else
_AngleBracketCollection.AddRange(IResult.GetDirectoryInfoCollection(_PropertyConfiguration, _AngleBracketCollection.AddRange(IResult.GetDirectoryInfoCollection(_PropertyConfiguration,
sourceDirectory, sourceDirectory,
@ -307,9 +277,9 @@ public class A_Property
bool angleBracketCollectionAny = _AngleBracketCollection.Count != 0; bool angleBracketCollectionAny = _AngleBracketCollection.Count != 0;
if (!angleBracketCollectionAny) if (!angleBracketCollectionAny)
{ {
if (item.FilePath.DirectoryFullPath is null) if (item.FilePath.DirectoryName is null)
throw new NullReferenceException(nameof(item.FilePath.DirectoryFullPath)); throw new NullReferenceException(nameof(item.FilePath.DirectoryName));
SetAngleBracketCollection(item.FilePath.DirectoryFullPath, !item.IsUniqueFileName); SetAngleBracketCollection(item.FilePath.DirectoryName, !item.IsUniqueFileName);
} }
bool isIgnoreExtension = item.IsValidImageFormatExtension && _PropertyConfiguration.IgnoreExtensions.Contains(item.FilePath.ExtensionLowered); bool isIgnoreExtension = item.IsValidImageFormatExtension && _PropertyConfiguration.IgnoreExtensions.Contains(item.FilePath.ExtensionLowered);
result = GetImageProperty(metadata, item, sourceDirectoryFileTuples, parseExceptions, isIgnoreExtension); result = GetImageProperty(metadata, item, sourceDirectoryFileTuples, parseExceptions, isIgnoreExtension);

View File

@ -28,11 +28,9 @@ public class Configuration
public int? ResultAllInOneSubdirectoryLength { get; set; } public int? ResultAllInOneSubdirectoryLength { get; set; }
public string? ResultCollection { get; set; } public string? ResultCollection { get; set; }
public string? ResultContent { get; set; } public string? ResultContent { get; set; }
public string? ResultContentCollection { get; set; }
public string? ResultSingleton { get; set; } public string? ResultSingleton { get; set; }
public string? RootDirectory { get; set; } public string? RootDirectory { get; set; }
public string[]? ValidImageFormatExtensions { get; set; } public string[]? ValidImageFormatExtensions { get; set; }
public string[]? ValidVideoFormatExtensions { get; set; }
public string[]? VerifyToSeason { get; set; } public string[]? VerifyToSeason { get; set; }
public override string ToString() public override string ToString()
@ -83,11 +81,9 @@ public class Configuration
if (configuration.ResultAllInOneSubdirectoryLength is null) throw new NullReferenceException(nameof(configuration.ResultAllInOneSubdirectoryLength)); if (configuration.ResultAllInOneSubdirectoryLength is null) throw new NullReferenceException(nameof(configuration.ResultAllInOneSubdirectoryLength));
if (configuration.ResultCollection is null) throw new NullReferenceException(nameof(configuration.ResultCollection)); if (configuration.ResultCollection is null) throw new NullReferenceException(nameof(configuration.ResultCollection));
if (configuration.ResultContent is null) throw new NullReferenceException(nameof(configuration.ResultContent)); if (configuration.ResultContent is null) throw new NullReferenceException(nameof(configuration.ResultContent));
if (configuration.ResultContentCollection is null) throw new NullReferenceException(nameof(configuration.ResultContentCollection));
if (configuration.ResultSingleton is null) throw new NullReferenceException(nameof(configuration.ResultSingleton)); if (configuration.ResultSingleton is null) throw new NullReferenceException(nameof(configuration.ResultSingleton));
if (configuration.RootDirectory is null) throw new NullReferenceException(nameof(configuration.RootDirectory)); if (configuration.RootDirectory is null) throw new NullReferenceException(nameof(configuration.RootDirectory));
if (configuration.ValidImageFormatExtensions is null) throw new NullReferenceException(nameof(configuration.ValidImageFormatExtensions)); if (configuration.ValidImageFormatExtensions is null) throw new NullReferenceException(nameof(configuration.ValidImageFormatExtensions));
if (configuration.ValidVideoFormatExtensions is null) throw new NullReferenceException(nameof(configuration.ValidVideoFormatExtensions));
// if (configuration.VerifyToSeason is null) throw new NullReferenceException(nameof(configuration.VerifyToSeason)); // if (configuration.VerifyToSeason is null) throw new NullReferenceException(nameof(configuration.VerifyToSeason));
result = new(configuration.DateGroup, result = new(configuration.DateGroup,
configuration.FileNameDirectorySeparator, configuration.FileNameDirectorySeparator,
@ -110,11 +106,9 @@ public class Configuration
configuration.ResultAllInOneSubdirectoryLength.Value, configuration.ResultAllInOneSubdirectoryLength.Value,
configuration.ResultCollection, configuration.ResultCollection,
configuration.ResultContent, configuration.ResultContent,
configuration.ResultContentCollection,
configuration.ResultSingleton, configuration.ResultSingleton,
Path.GetFullPath(configuration.RootDirectory), Path.GetFullPath(configuration.RootDirectory),
configuration.ValidImageFormatExtensions, configuration.ValidImageFormatExtensions,
configuration.ValidVideoFormatExtensions,
configuration.VerifyToSeason ?? []); configuration.VerifyToSeason ?? []);
return result; return result;
} }

View File

@ -31,10 +31,8 @@ public class Configuration : Shared.Models.Properties.IPropertyConfiguration
public int ResultAllInOneSubdirectoryLength { init; get; } public int ResultAllInOneSubdirectoryLength { init; get; }
public string ResultCollection { init; get; } public string ResultCollection { init; get; }
public string ResultContent { init; get; } public string ResultContent { init; get; }
public string ResultContentCollection { init; get; }
public string ResultSingleton { init; get; } public string ResultSingleton { init; get; }
public string[] ValidImageFormatExtensions { init; get; } public string[] ValidImageFormatExtensions { init; get; }
public string[] ValidVideoFormatExtensions { init; get; }
[JsonConstructor] [JsonConstructor]
public Configuration(string dateGroup, public Configuration(string dateGroup,
@ -58,11 +56,9 @@ public class Configuration : Shared.Models.Properties.IPropertyConfiguration
int resultAllInOneSubdirectoryLength, int resultAllInOneSubdirectoryLength,
string resultCollection, string resultCollection,
string resultContent, string resultContent,
string resultContentCollection,
string resultSingleton, string resultSingleton,
string rootDirectory, string rootDirectory,
string[] validImageFormatExtensions, string[] validImageFormatExtensions,
string[] validVideoFormatExtensions,
string[] verifyToSeason) string[] verifyToSeason)
{ {
DateGroup = dateGroup; DateGroup = dateGroup;
@ -86,11 +82,9 @@ public class Configuration : Shared.Models.Properties.IPropertyConfiguration
ResultAllInOneSubdirectoryLength = resultAllInOneSubdirectoryLength; ResultAllInOneSubdirectoryLength = resultAllInOneSubdirectoryLength;
ResultCollection = resultCollection; ResultCollection = resultCollection;
ResultContent = resultContent; ResultContent = resultContent;
ResultContentCollection = resultContentCollection;
ResultSingleton = resultSingleton; ResultSingleton = resultSingleton;
_RootDirectory = rootDirectory; _RootDirectory = rootDirectory;
ValidImageFormatExtensions = validImageFormatExtensions; ValidImageFormatExtensions = validImageFormatExtensions;
ValidVideoFormatExtensions = validVideoFormatExtensions;
} }
public override string ToString() public override string ToString()

View File

@ -4,12 +4,12 @@
<Nullable>enable</Nullable> <Nullable>enable</Nullable>
<OutputType>library</OutputType> <OutputType>library</OutputType>
<RuntimeIdentifiers>win-x64;linux-x64</RuntimeIdentifiers> <RuntimeIdentifiers>win-x64;linux-x64</RuntimeIdentifiers>
<TargetFramework>net9.0</TargetFramework> <TargetFramework>net8.0</TargetFramework>
</PropertyGroup> </PropertyGroup>
<PropertyGroup> <PropertyGroup>
<PackageId>Phares.View.by.Distance.Property</PackageId> <PackageId>Phares.View.by.Distance.Property</PackageId>
<GeneratePackageOnBuild>false</GeneratePackageOnBuild> <GeneratePackageOnBuild>false</GeneratePackageOnBuild>
<Version>9.0.100.1</Version> <Version>8.0.101.1</Version>
<Authors>Mike Phares</Authors> <Authors>Mike Phares</Authors>
<Company>Phares</Company> <Company>Phares</Company>
<IncludeSymbols>true</IncludeSymbols> <IncludeSymbols>true</IncludeSymbols>
@ -40,10 +40,10 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="MetadataExtractor" Version="2.8.1" /> <PackageReference Include="MetadataExtractor" Version="2.8.1" />
<PackageReference Include="Microsoft.Extensions.Hosting" Version="9.0.2" /> <PackageReference Include="Microsoft.Extensions.Hosting" Version="8.0.0" />
<PackageReference Include="ShellProgressBar" Version="5.2.0" /> <PackageReference Include="ShellProgressBar" Version="5.2.0" />
<PackageReference Include="System.Drawing.Common" Version="8.0.10" /> <PackageReference Include="System.Drawing.Common" Version="8.0.7" />
<PackageReference Include="System.Text.Json" Version="9.0.2" /> <PackageReference Include="System.Text.Json" Version="8.0.4" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\Shared\View-by-Distance.Shared.csproj" /> <ProjectReference Include="..\Shared\View-by-Distance.Shared.csproj" />

View File

@ -20,7 +20,7 @@ public class Rename
bool IsIgnoreExtension, bool IsIgnoreExtension,
bool IsValidImageFormatExtension, bool IsValidImageFormatExtension,
List<FileHolder> FileHolders, List<FileHolder> FileHolders,
bool FastForwardMovingPictureExpertsGroupFilesPresent, bool FfmpegFilesPresent,
DateTime? DateTimeOriginal, DateTime? DateTimeOriginal,
DateTime[] DateTimes, DateTime[] DateTimes,
int? Id); int? Id);
@ -218,11 +218,11 @@ public class Rename
FilePath filePath; FilePath filePath;
DateTime[] dateTimes; DateTime[] dateTimes;
FileHolder fileHolder; FileHolder fileHolder;
string[]? ffmpegFiles;
bool isIgnoreExtension; bool isIgnoreExtension;
DateTime? dateTimeOriginal; DateTime? dateTimeOriginal;
bool isValidImageFormatExtension; bool isValidImageFormatExtension;
ASCIIEncoding asciiEncoding = new(); ASCIIEncoding asciiEncoding = new();
string[]? fastForwardMovingPictureExpertsGroupFiles;
IReadOnlyList<MetadataExtractor.Directory> directories; IReadOnlyList<MetadataExtractor.Directory> directories;
for (int i = 0; i < files.Length; i++) for (int i = 0; i < files.Length; i++)
{ {
@ -234,7 +234,7 @@ public class Rename
if (string.IsNullOrEmpty(directory)) if (string.IsNullOrEmpty(directory))
continue; continue;
filePath = FilePath.Get(_Configuration.PropertyConfiguration, fileHolder, index: i); filePath = FilePath.Get(_Configuration.PropertyConfiguration, fileHolder, index: i);
if (fileHolder.ExtensionLowered == ".paddedId" || fileHolder.ExtensionLowered == ".lsv" || fileHolder.DirectoryFullPath is null) if (fileHolder.ExtensionLowered == ".paddedId" || fileHolder.ExtensionLowered == ".lsv" || fileHolder.DirectoryName is null)
continue; continue;
if (files.Contains($"{fileHolder.FullName}.paddedId")) if (files.Contains($"{fileHolder.FullName}.paddedId"))
continue; continue;
@ -243,7 +243,7 @@ public class Rename
isValidImageFormatExtension = _PropertyConfiguration.ValidImageFormatExtensions.Contains(fileHolder.ExtensionLowered); isValidImageFormatExtension = _PropertyConfiguration.ValidImageFormatExtensions.Contains(fileHolder.ExtensionLowered);
isIgnoreExtension = isValidImageFormatExtension && _PropertyConfiguration.IgnoreExtensions.Contains(fileHolder.ExtensionLowered); isIgnoreExtension = isValidImageFormatExtension && _PropertyConfiguration.IgnoreExtensions.Contains(fileHolder.ExtensionLowered);
if (!isIgnoreExtension && isValidImageFormatExtension) if (!isIgnoreExtension && isValidImageFormatExtension)
fastForwardMovingPictureExpertsGroupFiles = null; ffmpegFiles = null;
else else
{ {
try try
@ -251,33 +251,33 @@ public class Rename
catch (Exception) { continue; } catch (Exception) { continue; }
CommandTask<CommandResult> result = Cli.Wrap("ffmpeg.exe") CommandTask<CommandResult> result = Cli.Wrap("ffmpeg.exe")
// .WithArguments(new[] { "-ss", "00:00:00", "-t", "00:00:00", "-i", files[i], "-qscale:v", "2", "-r", "0.01", $"{fileHolder.Name}-%4d.jpg" }) // .WithArguments(new[] { "-ss", "00:00:00", "-t", "00:00:00", "-i", files[i], "-qscale:v", "2", "-r", "0.01", $"{fileHolder.Name}-%4d.jpg" })
.WithArguments(["-i", files[i], "-vframes", "1", $"{fileHolder.Name}-%4d.jpg"]) .WithArguments(new[] { "-i", files[i], "-vframes", "1", $"{fileHolder.Name}-%4d.jpg" })
.WithWorkingDirectory(fileHolder.DirectoryFullPath) .WithWorkingDirectory(fileHolder.DirectoryName)
.ExecuteAsync(); .ExecuteAsync();
result.Task.Wait(); result.Task.Wait();
fastForwardMovingPictureExpertsGroupFiles = Directory.GetFiles(fileHolder.DirectoryFullPath, $"{fileHolder.Name}-*.jpg", SearchOption.TopDirectoryOnly); ffmpegFiles = Directory.GetFiles(fileHolder.DirectoryName, $"{fileHolder.Name}-*.jpg", SearchOption.TopDirectoryOnly);
if (fastForwardMovingPictureExpertsGroupFiles.Length == 0) if (ffmpegFiles.Length == 0)
continue; continue;
fileHolder = Shared.Models.Stateless.Methods.IFileHolder.Get(fastForwardMovingPictureExpertsGroupFiles.First()); fileHolder = Shared.Models.Stateless.Methods.IFileHolder.Get(ffmpegFiles.First());
if (!fileHolder.Name.EndsWith("-0001.jpg")) if (!fileHolder.Name.EndsWith("-0001.jpg"))
throw new Exception(); throw new Exception();
isValidImageFormatExtension = _PropertyConfiguration.ValidImageFormatExtensions.Contains(fileHolder.ExtensionLowered); isValidImageFormatExtension = _PropertyConfiguration.ValidImageFormatExtensions.Contains(fileHolder.ExtensionLowered);
isIgnoreExtension = isValidImageFormatExtension && _PropertyConfiguration.IgnoreExtensions.Contains(fileHolder.ExtensionLowered); isIgnoreExtension = isValidImageFormatExtension && _PropertyConfiguration.IgnoreExtensions.Contains(fileHolder.ExtensionLowered);
if (isIgnoreExtension || !isValidImageFormatExtension) if (isIgnoreExtension || !isValidImageFormatExtension)
continue; continue;
if (fileHolder.DirectoryFullPath is null) if (fileHolder.DirectoryName is null)
continue; continue;
} }
(dateTimeOriginal, dateTimes, id, message) = Property.Models.Stateless.IProperty.Get(_PropertyConfiguration, _PropertyConfiguration.PopulatePropertyId, metadata, fileHolder, isIgnoreExtension, isValidImageFormatExtension, asciiEncoding); (dateTimeOriginal, dateTimes, id, message) = Property.Models.Stateless.IProperty.Get(_PropertyConfiguration, _PropertyConfiguration.PopulatePropertyId, metadata, fileHolder, isIgnoreExtension, isValidImageFormatExtension, asciiEncoding);
if (fastForwardMovingPictureExpertsGroupFiles is not null) if (ffmpegFiles is not null)
{ {
fileHolder = Shared.Models.Stateless.Methods.IFileHolder.Get(files[i]); fileHolder = Shared.Models.Stateless.Methods.IFileHolder.Get(files[i]);
foreach (string fastForwardMovingPictureExpertsGroupFile in fastForwardMovingPictureExpertsGroupFiles) foreach (string ffmpegFile in ffmpegFiles)
File.Delete(fastForwardMovingPictureExpertsGroupFile); File.Delete(ffmpegFile);
} }
if (message is not null) if (message is not null)
throw new Exception(message); throw new Exception(message);
results.Add(new(i + offset, isIgnoreExtension, isValidImageFormatExtension, [fileHolder], fastForwardMovingPictureExpertsGroupFiles is null, dateTimeOriginal, dateTimes, id)); results.Add(new(i + offset, isIgnoreExtension, isValidImageFormatExtension, [fileHolder], ffmpegFiles is null, dateTimeOriginal, dateTimes, id));
} }
return results; return results;
} }
@ -311,7 +311,7 @@ public class Rename
fileHolder = record.FileHolders.First(); fileHolder = record.FileHolders.First();
if (!fileHolder.Exists) if (!fileHolder.Exists)
continue; continue;
if (string.IsNullOrEmpty(fileHolder.DirectoryFullPath)) if (string.IsNullOrEmpty(fileHolder.DirectoryName))
continue; continue;
dateTimeFromName = record.DateTimes.Length == 0 ? null : record.DateTimes.First(); dateTimeFromName = record.DateTimes.Length == 0 ? null : record.DateTimes.First();
if (fileHolder.ExtensionLowered == jpeg) if (fileHolder.ExtensionLowered == jpeg)
@ -320,30 +320,30 @@ public class Rename
{ {
if (File.Exists($"{fileHolder.FullName}.paddedId")) if (File.Exists($"{fileHolder.FullName}.paddedId"))
{ {
checkFile = Path.Combine(fileHolder.DirectoryFullPath, $"{fileHolder.NameWithoutExtension}{jpg}.paddedId"); checkFile = Path.Combine(fileHolder.DirectoryName, $"{fileHolder.NameWithoutExtension}{jpg}.paddedId");
if (File.Exists(checkFile)) if (File.Exists(checkFile))
continue; continue;
if (distinct.Contains(checkFile)) if (distinct.Contains(checkFile))
continue; continue;
distinct.Add(checkFile); distinct.Add(checkFile);
results.Add(new(Shared.Models.Stateless.Methods.IFileHolder.Get($"{fileHolder.FullName}.paddedId"), fileHolder.DirectoryFullPath, checkFile)); results.Add(new(Shared.Models.Stateless.Methods.IFileHolder.Get($"{fileHolder.FullName}.paddedId"), fileHolder.DirectoryName, checkFile));
} }
checkFile = Path.Combine(fileHolder.DirectoryFullPath, $"{fileHolder.NameWithoutExtension}{jpg}"); checkFile = Path.Combine(fileHolder.DirectoryName, $"{fileHolder.NameWithoutExtension}{jpg}");
if (File.Exists(checkFile)) if (File.Exists(checkFile))
continue; continue;
if (distinct.Contains(checkFile)) if (distinct.Contains(checkFile))
continue; continue;
distinct.Add(checkFile); distinct.Add(checkFile);
results.Add(new(fileHolder, fileHolder.DirectoryFullPath, checkFile)); results.Add(new(fileHolder, fileHolder.DirectoryName, checkFile));
if (nefPresent) if (nefPresent)
results.Add(new(Shared.Models.Stateless.Methods.IFileHolder.Get($"{fileHolder.FullName[..^4]}.tif"), fileHolder.DirectoryFullPath, $"{checkFile[..^4]}.tif")); results.Add(new(Shared.Models.Stateless.Methods.IFileHolder.Get($"{fileHolder.FullName[..^4]}.tif"), fileHolder.DirectoryName, $"{checkFile[..^4]}.tif"));
if (nefPresent) if (nefPresent)
results.Add(new(Shared.Models.Stateless.Methods.IFileHolder.Get($"{fileHolder.FullName[..^4]}.nef"), fileHolder.DirectoryFullPath, $"{checkFile[..^4]}.nef")); results.Add(new(Shared.Models.Stateless.Methods.IFileHolder.Get($"{fileHolder.FullName[..^4]}.nef"), fileHolder.DirectoryName, $"{checkFile[..^4]}.nef"));
if (File.Exists(checkFile)) if (File.Exists(checkFile))
continue; continue;
File.Move(fileHolder.FullName, checkFile); File.Move(fileHolder.FullName, checkFile);
fileHolder = Shared.Models.Stateless.Methods.IFileHolder.Get(checkFile); fileHolder = Shared.Models.Stateless.Methods.IFileHolder.Get(checkFile);
if (fileHolder.DirectoryFullPath is null) if (fileHolder.DirectoryName is null)
continue; continue;
} }
} }
@ -361,13 +361,13 @@ public class Rename
if (timeSpan is null || timeSpan.Value.TotalMinutes > _AppSettings.MaxMinutesDelta) if (timeSpan is null || timeSpan.Value.TotalMinutes > _AppSettings.MaxMinutesDelta)
{ {
if (string.IsNullOrEmpty(_AppSettings.DefaultUnknownDirectoryName)) if (string.IsNullOrEmpty(_AppSettings.DefaultUnknownDirectoryName))
(isWrongYear, seasonDirectory) = (null, !_AppSettings.ForceIdName ? null : fileHolder.DirectoryFullPath); (isWrongYear, seasonDirectory) = (null, !_AppSettings.ForceIdName ? null : fileHolder.DirectoryName);
else else
(isWrongYear, seasonDirectory) = (null, !_AppSettings.ForceIdName ? null : Path.Combine(fileHolder.DirectoryFullPath, _AppSettings.DefaultUnknownDirectoryName)); (isWrongYear, seasonDirectory) = (null, !_AppSettings.ForceIdName ? null : Path.Combine(fileHolder.DirectoryName, _AppSettings.DefaultUnknownDirectoryName));
} }
else else
{ {
directoryName = Path.GetFileName(fileHolder.DirectoryFullPath); directoryName = Path.GetFileName(fileHolder.DirectoryName);
directoryNameSegments = directoryName.Split(' '); directoryNameSegments = directoryName.Split(' ');
if (dateTimeFromName is null) if (dateTimeFromName is null)
isWrongYear = null; isWrongYear = null;
@ -375,7 +375,7 @@ public class Rename
(isWrongYear, _) = Shared.Models.Stateless.Methods.IProperty.IsWrongYear(directoryNameSegments, dateTimeFromName.Value.ToString("yyyy")); (isWrongYear, _) = Shared.Models.Stateless.Methods.IProperty.IsWrongYear(directoryNameSegments, dateTimeFromName.Value.ToString("yyyy"));
dateTime = minimumDateTime.Value.AddTicks(timeSpan.Value.Ticks); dateTime = minimumDateTime.Value.AddTicks(timeSpan.Value.Ticks);
(season, seasonName) = Shared.Models.Stateless.Methods.IProperty.GetSeason(dateTime.DayOfYear); (season, seasonName) = Shared.Models.Stateless.Methods.IProperty.GetSeason(dateTime.DayOfYear);
seasonDirectory = Path.Combine(fileHolder.DirectoryFullPath, $"{dateTime.Year}.{season} {seasonName}"); seasonDirectory = Path.Combine(fileHolder.DirectoryName, $"{dateTime.Year}.{season} {seasonName}");
} }
if (seasonDirectory is null || (isWrongYear is not null && isWrongYear.Value)) if (seasonDirectory is null || (isWrongYear is not null && isWrongYear.Value))
{ {
@ -386,17 +386,17 @@ public class Rename
if (minimumDateTime is null) if (minimumDateTime is null)
continue; continue;
checkFileExtension = fileHolder.ExtensionLowered == jpeg ? jpg : fileHolder.ExtensionLowered; checkFileExtension = fileHolder.ExtensionLowered == jpeg ? jpg : fileHolder.ExtensionLowered;
checkFile = Path.Combine(fileHolder.DirectoryFullPath, $"{minimumDateTime.Value:yyyy-MM-dd}.{minimumDateTime.Value.Ticks}.{fileHolder.Length}{checkFileExtension}"); checkFile = Path.Combine(fileHolder.DirectoryName, $"{minimumDateTime.Value:yyyy-MM-dd}.{minimumDateTime.Value.Ticks}.{fileHolder.Length}{checkFileExtension}");
if (checkFile == fileHolder.FullName) if (checkFile == fileHolder.FullName)
continue; continue;
if (distinct.Contains(checkFile)) if (distinct.Contains(checkFile))
continue; continue;
distinct.Add(checkFile); distinct.Add(checkFile);
results.Add(new(fileHolder, fileHolder.DirectoryFullPath, checkFile)); results.Add(new(fileHolder, fileHolder.DirectoryName, checkFile));
if (nefPresent) if (nefPresent)
results.Add(new(Shared.Models.Stateless.Methods.IFileHolder.Get($"{fileHolder.FullName[..^4]}.tif"), fileHolder.DirectoryFullPath, $"{checkFile[..^4]}.tif")); results.Add(new(Shared.Models.Stateless.Methods.IFileHolder.Get($"{fileHolder.FullName[..^4]}.tif"), fileHolder.DirectoryName, $"{checkFile[..^4]}.tif"));
if (nefPresent) if (nefPresent)
results.Add(new(Shared.Models.Stateless.Methods.IFileHolder.Get($"{fileHolder.FullName[..^4]}.nef"), fileHolder.DirectoryFullPath, $"{checkFile[..^4]}.nef")); results.Add(new(Shared.Models.Stateless.Methods.IFileHolder.Get($"{fileHolder.FullName[..^4]}.nef"), fileHolder.DirectoryName, $"{checkFile[..^4]}.nef"));
} }
else else
{ {

View File

@ -4,13 +4,13 @@
<Nullable>enable</Nullable> <Nullable>enable</Nullable>
<OutputType>Exe</OutputType> <OutputType>Exe</OutputType>
<RuntimeIdentifier>win-x64</RuntimeIdentifier> <RuntimeIdentifier>win-x64</RuntimeIdentifier>
<TargetFramework>net9.0</TargetFramework> <TargetFramework>net8.0</TargetFramework>
<UserSecretsId>6e026d2f-9edf-4c6c-a042-162758114e9a</UserSecretsId> <UserSecretsId>6e026d2f-9edf-4c6c-a042-162758114e9a</UserSecretsId>
</PropertyGroup> </PropertyGroup>
<PropertyGroup> <PropertyGroup>
<PackageId>Phares.View.by.Distance.Rename</PackageId> <PackageId>Phares.View.by.Distance.Rename</PackageId>
<GeneratePackageOnBuild>false</GeneratePackageOnBuild> <GeneratePackageOnBuild>false</GeneratePackageOnBuild>
<Version>9.0.100.1</Version> <Version>8.0.101.1</Version>
<Authors>Mike Phares</Authors> <Authors>Mike Phares</Authors>
<Company>Phares</Company> <Company>Phares</Company>
<IncludeSymbols>true</IncludeSymbols> <IncludeSymbols>true</IncludeSymbols>
@ -34,11 +34,11 @@
<SupportedPlatform Include="browser" /> <SupportedPlatform Include="browser" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="CliWrap" Version="3.8.1" /> <PackageReference Include="CliWrap" Version="3.6.6" />
<PackageReference Include="Humanizer.Core" Version="2.14.1" /> <PackageReference Include="Humanizer.Core" Version="2.14.1" />
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="9.0.2" /> <PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.UserSecrets" Version="9.0.2" /> <PackageReference Include="Microsoft.Extensions.Configuration.UserSecrets" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.Hosting" Version="9.0.2" /> <PackageReference Include="Microsoft.Extensions.Hosting" Version="8.0.0" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\Metadata\Metadata.csproj" /> <ProjectReference Include="..\Metadata\Metadata.csproj" />

View File

@ -37,13 +37,14 @@ public class C_Resize
private readonly int _OutputResolutionHeightIndex; private readonly int _OutputResolutionHeightIndex;
private readonly EncoderParameters _EncoderParameters; private readonly EncoderParameters _EncoderParameters;
private readonly int _OutputResolutionOrientationIndex; private readonly int _OutputResolutionOrientationIndex;
private readonly Dictionary<string, string[]> _FileGroups;
private readonly bool _ForceResizeLastWriteTimeToCreationTime; private readonly bool _ForceResizeLastWriteTimeToCreationTime;
private readonly IPropertyConfiguration _PropertyConfiguration; private readonly IPropertyConfiguration _PropertyConfiguration;
private readonly JsonSerializerOptions _WriteIndentedJsonSerializerOptions; private readonly JsonSerializerOptions _WriteIndentedJsonSerializerOptions;
private readonly ReadOnlyDictionary<byte, ReadOnlyCollection<string>>[] _ResultSingletonFileGroups;
public C_Resize(IPropertyConfiguration propertyConfiguration, bool forceResizeLastWriteTimeToCreationTime, bool overrideForResizeImages, bool propertiesChangedForResize, string[] validResolutions, ImageCodecInfo imageCodecInfo, EncoderParameters encoderParameters, string filenameExtension) public C_Resize(IPropertyConfiguration propertyConfiguration, bool forceResizeLastWriteTimeToCreationTime, bool overrideForResizeImages, bool propertiesChangedForResize, string[] validResolutions, ImageCodecInfo imageCodecInfo, EncoderParameters encoderParameters, string filenameExtension)
{ {
_FileGroups = [];
_Original = "Original"; _Original = "Original";
_TempResolutionWidth = 3; _TempResolutionWidth = 3;
_TempResolutionHeight = 4; _TempResolutionHeight = 4;
@ -60,7 +61,6 @@ public class C_Resize
_OverrideForResizeImages = overrideForResizeImages; _OverrideForResizeImages = overrideForResizeImages;
_PropertiesChangedForResize = propertiesChangedForResize; _PropertiesChangedForResize = propertiesChangedForResize;
_ForceResizeLastWriteTimeToCreationTime = forceResizeLastWriteTimeToCreationTime; _ForceResizeLastWriteTimeToCreationTime = forceResizeLastWriteTimeToCreationTime;
_ResultSingletonFileGroups = [new(new Dictionary<byte, ReadOnlyCollection<string>>())];
_WriteIndentedJsonSerializerOptions = new JsonSerializerOptions { WriteIndented = true }; _WriteIndentedJsonSerializerOptions = new JsonSerializerOptions { WriteIndented = true };
ConstructorInfo? constructorInfo = typeof(PropertyItem).GetConstructor(BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Public, null, [], null) ?? throw new Exception(); ConstructorInfo? constructorInfo = typeof(PropertyItem).GetConstructor(BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Public, null, [], null) ?? throw new Exception();
_ConstructorInfo = constructorInfo; _ConstructorInfo = constructorInfo;
@ -74,14 +74,10 @@ public class C_Resize
public void Update(string cResultsFullGroupDirectory) public void Update(string cResultsFullGroupDirectory)
{ {
ReadOnlyDictionary<string, ReadOnlyDictionary<byte, ReadOnlyCollection<string>>> keyValuePairs = Shared.Models.Stateless.Methods.IPath.GetKeyValuePairs(_PropertyConfiguration, cResultsFullGroupDirectory, [_PropertyConfiguration.ResultSingleton]); _FileGroups.Clear();
foreach (KeyValuePair<string, ReadOnlyDictionary<byte, ReadOnlyCollection<string>>> keyValuePair in keyValuePairs) ReadOnlyDictionary<string, string[]> keyValuePairs = Shared.Models.Stateless.Methods.IPath.GetKeyValuePairs(_PropertyConfiguration, cResultsFullGroupDirectory, [_PropertyConfiguration.ResultSingleton]);
{ foreach (KeyValuePair<string, string[]> keyValuePair in keyValuePairs)
if (keyValuePair.Key == _PropertyConfiguration.ResultSingleton) _FileGroups.Add(keyValuePair.Key, keyValuePair.Value);
_ResultSingletonFileGroups[0] = keyValuePair.Value;
else
throw new Exception();
}
} }
public void SetAngleBracketCollection(string cResultsFullGroupDirectory, string sourceDirectory) public void SetAngleBracketCollection(string cResultsFullGroupDirectory, string sourceDirectory)
@ -98,12 +94,11 @@ public class C_Resize
#pragma warning disable CA1416 #pragma warning disable CA1416
public static (ImageCodecInfo imageCodecInfo, EncoderParameters encoderParameters, string filenameExtension) GetJpegLowQuality() public static (ImageCodecInfo imageCodecInfo, EncoderParameters encoderParameters, string filenameExtension) GetGifLowQuality()
{ {
(ImageCodecInfo, EncoderParameters, string) result; (ImageCodecInfo, EncoderParameters, string) result;
ImageFormat imageFormat = ImageFormat.Jpeg; ImageFormat imageFormat = ImageFormat.Gif;
ImageCodecInfo[] imageCodecInfoCollection = ImageCodecInfo.GetImageEncoders(); ImageCodecInfo imageCodecInfo = (from l in ImageCodecInfo.GetImageEncoders() where l.FormatID == imageFormat.Guid select l).First();
ImageCodecInfo imageCodecInfo = (from l in imageCodecInfoCollection where l.FormatID == imageFormat.Guid select l).First();
EncoderParameters encoderParameters = new(1); EncoderParameters encoderParameters = new(1);
encoderParameters.Param[0] = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, 75L); encoderParameters.Param[0] = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, 75L);
if (string.IsNullOrEmpty(imageCodecInfo.FilenameExtension)) if (string.IsNullOrEmpty(imageCodecInfo.FilenameExtension))
@ -116,8 +111,7 @@ public class C_Resize
{ {
(ImageCodecInfo, EncoderParameters, string) result; (ImageCodecInfo, EncoderParameters, string) result;
ImageFormat imageFormat = ImageFormat.Png; ImageFormat imageFormat = ImageFormat.Png;
ImageCodecInfo[] imageCodecInfoCollection = ImageCodecInfo.GetImageEncoders(); ImageCodecInfo imageCodecInfo = (from l in ImageCodecInfo.GetImageEncoders() where l.FormatID == imageFormat.Guid select l).First();
ImageCodecInfo imageCodecInfo = (from l in imageCodecInfoCollection where l.FormatID == imageFormat.Guid select l).First();
EncoderParameters encoderParameters = new(1); EncoderParameters encoderParameters = new(1);
encoderParameters.Param[0] = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, 75L); encoderParameters.Param[0] = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, 75L);
if (string.IsNullOrEmpty(imageCodecInfo.FilenameExtension)) if (string.IsNullOrEmpty(imageCodecInfo.FilenameExtension))
@ -141,8 +135,7 @@ public class C_Resize
".tiff" => ImageFormat.Tiff, ".tiff" => ImageFormat.Tiff,
_ => throw new Exception(), _ => throw new Exception(),
}; };
ImageCodecInfo[] imageCodecInfoCollection = ImageCodecInfo.GetImageEncoders(); ImageCodecInfo imageCodecInfo = (from l in ImageCodecInfo.GetImageEncoders() where l.FormatID == imageFormat.Guid select l).First();
ImageCodecInfo imageCodecInfo = (from l in imageCodecInfoCollection where l.FormatID == imageFormat.Guid select l).First();
EncoderParameters encoderParameters = new(1); EncoderParameters encoderParameters = new(1);
// encoderParameters.Param[0] = New EncoderParameter(Encoder.Quality, CType(75L, Int32)) 'Default // encoderParameters.Param[0] = New EncoderParameter(Encoder.Quality, CType(75L, Int32)) 'Default
// encoderParameters.Param[0] = New EncoderParameter(Encoder.Quality, CType(95L, Int32)) 'Paint // encoderParameters.Param[0] = New EncoderParameter(Encoder.Quality, CType(95L, Int32)) 'Paint
@ -431,8 +424,8 @@ public class C_Resize
result = Shared.Models.Stateless.Methods.IFileHolder.Get(Path.Combine(AngleBracketCollection[0].Replace("<>", _PropertyConfiguration.ResultContent), fileName)); result = Shared.Models.Stateless.Methods.IFileHolder.Get(Path.Combine(AngleBracketCollection[0].Replace("<>", _PropertyConfiguration.ResultContent), fileName));
else else
{ {
CombinedEnumAndIndex cei = Shared.Models.Stateless.Methods.IPath.GetCombinedEnumAndIndex(_PropertyConfiguration, filePath); (string directoryName, _) = Shared.Models.Stateless.Methods.IPath.GetDirectoryNameAndIndex(_PropertyConfiguration, filePath);
result = Shared.Models.Stateless.Methods.IFileHolder.Get(Path.Combine(cResultsFullGroupDirectory, _PropertyConfiguration.ResultContent, cei.Combined, fileName)); result = Shared.Models.Stateless.Methods.IFileHolder.Get(Path.Combine(cResultsFullGroupDirectory, _PropertyConfiguration.ResultContent, directoryName, fileName));
} }
return result; return result;
} }
@ -443,36 +436,14 @@ public class C_Resize
public FileHolder GetResizedFileHolder(string cResultsFullGroupDirectory, Item item, bool outputResolutionHasNumber, int id) => public FileHolder GetResizedFileHolder(string cResultsFullGroupDirectory, Item item, bool outputResolutionHasNumber, int id) =>
GetResizedFileHolder(cResultsFullGroupDirectory, item.FilePath, outputResolutionHasNumber, $"{id}{item.FilePath.ExtensionLowered}"); GetResizedFileHolder(cResultsFullGroupDirectory, item.FilePath, outputResolutionHasNumber, $"{id}{item.FilePath.ExtensionLowered}");
private static void MoveIf(string fileName, CombinedEnumAndIndex cei, string directory, FileInfo fileInfo)
{
string[] segments = directory.Split(cei.Combined);
string? checkDirectory = segments.Length == 1 ?
Path.Combine(segments[0], $"{cei.Combined[2..]}") :
segments.Length == 2 ?
$"{segments[0]}{cei.Combined[2..]}{segments[1]}" :
null;
if (checkDirectory is not null && Directory.Exists(checkDirectory))
{
string checkFile = Path.Combine(checkDirectory, fileName);
if (File.Exists(checkFile))
{
File.Move(checkFile, fileInfo.FullName);
fileInfo.Refresh();
}
}
}
public Dictionary<string, int[]> GetResizeKeyValuePairs(Configuration configuration, string cResultsFullGroupDirectory, FilePath filePath, List<Tuple<string, DateTime>> subFileTuples, List<string> parseExceptions, Shared.Models.Property property, MappingFromItem mappingFromItem) public Dictionary<string, int[]> GetResizeKeyValuePairs(Configuration configuration, string cResultsFullGroupDirectory, FilePath filePath, List<Tuple<string, DateTime>> subFileTuples, List<string> parseExceptions, Shared.Models.Property property, MappingFromItem mappingFromItem)
{ {
Dictionary<string, int[]>? results; Dictionary<string, int[]>? results;
string json; string json;
string[] changesFrom = [nameof(A_Property), nameof(B_Metadata)]; string[] changesFrom = [nameof(A_Property), nameof(B_Metadata)];
List<DateTime> dateTimes = (from l in subFileTuples where changesFrom.Contains(l.Item1) select l.Item2).ToList(); List<DateTime> dateTimes = (from l in subFileTuples where changesFrom.Contains(l.Item1) select l.Item2).ToList();
CombinedEnumAndIndex cei = Shared.Models.Stateless.Methods.IPath.GetCombinedEnumAndIndex(_PropertyConfiguration, filePath); (_, int directoryIndex) = Shared.Models.Stateless.Methods.IPath.GetDirectoryNameAndIndex(_PropertyConfiguration, filePath);
string fileName = $"{mappingFromItem.FilePath.NameWithoutExtension}{mappingFromItem.FilePath.ExtensionLowered}.json"; FileInfo fileInfo = new(Path.Combine(_FileGroups[_PropertyConfiguration.ResultSingleton][directoryIndex], $"{mappingFromItem.FilePath.NameWithoutExtension}{mappingFromItem.FilePath.ExtensionLowered}.json"));
string directory = _ResultSingletonFileGroups[0][cei.Enum][cei.Index];
FileInfo fileInfo = new(Path.Combine(directory, fileName));
MoveIf(fileName, cei, directory, fileInfo);
if (_ForceResizeLastWriteTimeToCreationTime && !fileInfo.Exists && File.Exists(Path.ChangeExtension(fileInfo.FullName, ".delete"))) if (_ForceResizeLastWriteTimeToCreationTime && !fileInfo.Exists && File.Exists(Path.ChangeExtension(fileInfo.FullName, ".delete")))
{ {
File.Move(Path.ChangeExtension(fileInfo.FullName, ".delete"), fileInfo.FullName); File.Move(Path.ChangeExtension(fileInfo.FullName, ".delete"), fileInfo.FullName);

View File

@ -4,12 +4,12 @@
<Nullable>enable</Nullable> <Nullable>enable</Nullable>
<OutputType>library</OutputType> <OutputType>library</OutputType>
<RuntimeIdentifier>win-x64</RuntimeIdentifier> <RuntimeIdentifier>win-x64</RuntimeIdentifier>
<TargetFramework>net9.0</TargetFramework> <TargetFramework>net8.0</TargetFramework>
</PropertyGroup> </PropertyGroup>
<PropertyGroup> <PropertyGroup>
<PackageId>Phares.View.by.Distance.Resize</PackageId> <PackageId>Phares.View.by.Distance.Resize</PackageId>
<GeneratePackageOnBuild>false</GeneratePackageOnBuild> <GeneratePackageOnBuild>false</GeneratePackageOnBuild>
<Version>9.0.100.1</Version> <Version>8.0.101.1</Version>
<Authors>Mike Phares</Authors> <Authors>Mike Phares</Authors>
<Company>Phares</Company> <Company>Phares</Company>
<IncludeSymbols>true</IncludeSymbols> <IncludeSymbols>true</IncludeSymbols>
@ -34,8 +34,8 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="MetadataExtractor" Version="2.8.1" /> <PackageReference Include="MetadataExtractor" Version="2.8.1" />
<PackageReference Include="System.Drawing.Common" Version="8.0.10" /> <PackageReference Include="System.Drawing.Common" Version="8.0.7" />
<PackageReference Include="System.Text.Json" Version="9.0.2" /> <PackageReference Include="System.Text.Json" Version="8.0.4" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\Shared\View-by-Distance.Shared.csproj" /> <ProjectReference Include="..\Shared\View-by-Distance.Shared.csproj" />

View File

@ -34,15 +34,17 @@ public class Configuration
} }
} }
private static Models.Configuration Get(Configuration? configuration, Property.Models.Configuration propertyConfiguration) private static Models.Configuration Get(Configuration? configuration)
{ {
Models.Configuration result; Models.Configuration result;
if (configuration is null) throw new NullReferenceException(nameof(configuration)); if (configuration is null) throw new NullReferenceException(nameof(configuration));
if (configuration.IgnoreExtensions is null) throw new NullReferenceException(nameof(configuration.IgnoreExtensions)); if (configuration.IgnoreExtensions is null) throw new NullReferenceException(nameof(configuration.IgnoreExtensions));
if (configuration.PersonBirthdayFormat is null) throw new NullReferenceException(nameof(configuration.PersonBirthdayFormat)); if (configuration.PersonBirthdayFormat is null) throw new NullReferenceException(nameof(configuration.PersonBirthdayFormat));
result = new(propertyConfiguration, if (configuration.PropertyConfiguration is null) throw new NullReferenceException(nameof(configuration.PropertyConfiguration));
configuration.IgnoreExtensions, result = new(
configuration.PersonBirthdayFormat); configuration.IgnoreExtensions,
configuration.PersonBirthdayFormat,
configuration.PropertyConfiguration);
return result; return result;
} }
@ -64,7 +66,7 @@ public class Configuration
#pragma warning restore IL3050, IL2026 #pragma warning restore IL3050, IL2026
} }
PreVerify(configurationRoot, configuration); PreVerify(configurationRoot, configuration);
result = Get(configuration, propertyConfiguration); result = Get(configuration);
return result; return result;
} }

View File

@ -13,9 +13,10 @@ public class Configuration
public Property.Models.Configuration PropertyConfiguration => _PropertyConfiguration; public Property.Models.Configuration PropertyConfiguration => _PropertyConfiguration;
[JsonConstructor] [JsonConstructor]
public Configuration(Property.Models.Configuration propertyConfiguration, public Configuration(
string[] ignoreExtensions, string[] ignoreExtensions,
string personBirthdayFormat) string personBirthdayFormat,
Property.Models.Configuration propertyConfiguration)
{ {
IgnoreExtensions = ignoreExtensions; IgnoreExtensions = ignoreExtensions;
PersonBirthdayFormat = personBirthdayFormat; PersonBirthdayFormat = personBirthdayFormat;

View File

@ -4,13 +4,13 @@
<Nullable>enable</Nullable> <Nullable>enable</Nullable>
<OutputType>Exe</OutputType> <OutputType>Exe</OutputType>
<RuntimeIdentifier>win-x64</RuntimeIdentifier> <RuntimeIdentifier>win-x64</RuntimeIdentifier>
<TargetFramework>net9.0</TargetFramework> <TargetFramework>net8.0</TargetFramework>
<UserSecretsId>b3bbcc69-1439-4e86-9bbf-75c8e8839cc0</UserSecretsId> <UserSecretsId>b3bbcc69-1439-4e86-9bbf-75c8e8839cc0</UserSecretsId>
</PropertyGroup> </PropertyGroup>
<PropertyGroup> <PropertyGroup>
<PackageId>Phares.View.by.Distance.Set.Created.Date</PackageId> <PackageId>Phares.View.by.Distance.Set.Created.Date</PackageId>
<GeneratePackageOnBuild>false</GeneratePackageOnBuild> <GeneratePackageOnBuild>false</GeneratePackageOnBuild>
<Version>9.0.100.1</Version> <Version>8.0.101.1</Version>
<Authors>Mike Phares</Authors> <Authors>Mike Phares</Authors>
<Company>Phares</Company> <Company>Phares</Company>
<IncludeSymbols>true</IncludeSymbols> <IncludeSymbols>true</IncludeSymbols>
@ -35,9 +35,9 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Humanizer.Core" Version="2.14.1" /> <PackageReference Include="Humanizer.Core" Version="2.14.1" />
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="9.0.2" /> <PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.UserSecrets" Version="9.0.2" /> <PackageReference Include="Microsoft.Extensions.Configuration.UserSecrets" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.Hosting" Version="9.0.2" /> <PackageReference Include="Microsoft.Extensions.Hosting" Version="8.0.0" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\Metadata\Metadata.csproj" /> <ProjectReference Include="..\Metadata\Metadata.csproj" />

View File

@ -21,8 +21,8 @@ public class SetCreatedDate
private readonly Configuration _Configuration; private readonly Configuration _Configuration;
private readonly IsEnvironment _IsEnvironment; private readonly IsEnvironment _IsEnvironment;
private readonly IConfigurationRoot _ConfigurationRoot; private readonly IConfigurationRoot _ConfigurationRoot;
private readonly ReadOnlyDictionary<string, string[]> _FileGroups;
private readonly Property.Models.Configuration _PropertyConfiguration; private readonly Property.Models.Configuration _PropertyConfiguration;
private readonly ReadOnlyDictionary<string, ReadOnlyDictionary<byte, ReadOnlyCollection<string>>> _FileGroups;
public SetCreatedDate(List<string> args, ILogger<Program> logger, IsEnvironment isEnvironment, IConfigurationRoot configurationRoot, AppSettings appSettings, string workingDirectory, bool isSilent, IConsole console) public SetCreatedDate(List<string> args, ILogger<Program> logger, IsEnvironment isEnvironment, IConfigurationRoot configurationRoot, AppSettings appSettings, string workingDirectory, bool isSilent, IConsole console)
{ {
@ -78,7 +78,7 @@ public class SetCreatedDate
{ {
progressBar.Tick(); progressBar.Tick();
fileHolder = Shared.Models.Stateless.Methods.IFileHolder.Get(file); fileHolder = Shared.Models.Stateless.Methods.IFileHolder.Get(file);
if (fileHolder.ExtensionLowered == ".id" || fileHolder.ExtensionLowered == ".lsv" || fileHolder.DirectoryFullPath is null) if (fileHolder.ExtensionLowered == ".id" || fileHolder.ExtensionLowered == ".lsv" || fileHolder.DirectoryName is null)
continue; continue;
if (_PropertyConfiguration.IgnoreExtensions.Contains(fileHolder.ExtensionLowered)) if (_PropertyConfiguration.IgnoreExtensions.Contains(fileHolder.ExtensionLowered))
continue; continue;

View File

@ -1,23 +0,0 @@
using System.Text.Json;
using System.Text.Json.Serialization;
namespace View_by_Distance.Shared.Models;
public record CombinedEnumAndIndex(string Combined,
byte Enum,
int Index)
{
public override string ToString()
{
string result = JsonSerializer.Serialize(this, CombinedEnumAndIndexSourceGenerationContext.Default.CombinedEnumAndIndex);
return result;
}
}
[JsonSourceGenerationOptions(WriteIndented = true)]
[JsonSerializable(typeof(CombinedEnumAndIndex))]
internal partial class CombinedEnumAndIndexSourceGenerationContext : JsonSerializerContext
{
}

View File

@ -4,7 +4,7 @@ namespace View_by_Distance.Shared.Models;
public record Datum( public record Datum(
[property: JsonPropertyName("accessRuleIds")] IReadOnlyList<object> AccessRuleIds, [property: JsonPropertyName("accessRuleIds")] IReadOnlyList<object> AccessRuleIds,
[property: JsonPropertyName("childAssetTyceinfo")] IReadOnlyList<object> ChildAssetTyceinfo, [property: JsonPropertyName("childAssetTypeInfo")] IReadOnlyList<object> ChildAssetTypeInfo,
[property: JsonPropertyName("contentProperties")] ContentProperties ContentProperties, [property: JsonPropertyName("contentProperties")] ContentProperties ContentProperties,
[property: JsonPropertyName("createdBy")] string CreatedBy, [property: JsonPropertyName("createdBy")] string CreatedBy,
[property: JsonPropertyName("createdDate")] DateTime CreatedDate, [property: JsonPropertyName("createdDate")] DateTime CreatedDate,

View File

@ -6,12 +6,12 @@ namespace View_by_Distance.Shared.Models;
public record ExifDirectory(AviDirectory[] AviDirectories, public record ExifDirectory(AviDirectory[] AviDirectories,
ExifDirectoryBase[] ExifBaseDirectories, ExifDirectoryBase[] ExifBaseDirectories,
FileMetadataDirectory[] FileMetadataDirectories, FileMetadataDirectory[] FileMetadataDirectories,
FilePath FilePath,
GifHeaderDirectory[] GifHeaderDirectories, GifHeaderDirectory[] GifHeaderDirectories,
GpsDirectory[] GpsDirectories, GpsDirectory[] GpsDirectories,
int? Height, int? Height,
JpegDirectory[] JpegDirectories, JpegDirectory[] JpegDirectories,
MakernoteDirectory[] MakernoteDirectories, MakernoteDirectory[] MakernoteDirectories,
string OriginalFileName,
PhotoshopDirectory[] PhotoshopDirectories, PhotoshopDirectory[] PhotoshopDirectories,
PngDirectory[] PngDirectories, PngDirectory[] PngDirectories,
QuickTimeMovieHeaderDirectory[] QuickTimeMovieHeaderDirectories, QuickTimeMovieHeaderDirectory[] QuickTimeMovieHeaderDirectories,

View File

@ -40,14 +40,8 @@ public record class FaceDistance : Properties.IFaceDistance
public override string ToString() public override string ToString()
{ {
string result = JsonSerializer.Serialize(this, FaceDistanceSourceGenerationContext.Default.FaceDistance); string result = JsonSerializer.Serialize(this, new JsonSerializerOptions() { WriteIndented = true });
return result; return result;
} }
} }
[JsonSourceGenerationOptions(WriteIndented = true)]
[JsonSerializable(typeof(FaceDistance))]
internal partial class FaceDistanceSourceGenerationContext : JsonSerializerContext
{
}

View File

@ -1,11 +1,27 @@
using System.Text.Json;
using System.Text.Json.Serialization; using System.Text.Json.Serialization;
namespace View_by_Distance.Shared.Models; namespace View_by_Distance.Shared.Models;
public record FaceEncoding(double[] RawEncoding, int Size); public class FaceEncoding : Properties.IFaceEncoding
[JsonSourceGenerationOptions(WriteIndented = false)]
[JsonSerializable(typeof(FaceEncoding))]
public partial class FaceEncodingGenerationContext : JsonSerializerContext
{ {
protected double[] _RawEncoding;
protected int _Size;
public double[] RawEncoding => _RawEncoding;
public int Size => _Size;
[JsonConstructor]
public FaceEncoding(double[] rawEncoding, int size)
{
_RawEncoding = rawEncoding;
_Size = size;
}
public override string ToString()
{
string result = JsonSerializer.Serialize(this, new JsonSerializerOptions() { WriteIndented = true });
return result;
}
} }

View File

@ -4,13 +4,11 @@ namespace View_by_Distance.Shared.Models;
public record FaceFile(int? AreaPermyriad, public record FaceFile(int? AreaPermyriad,
int? ConfidencePercent, int? ConfidencePercent,
string? DMS,
DateTime DateTime, DateTime DateTime,
FaceEncoding? FaceEncoding, string? DMS,
Dictionary<Stateless.FacePart, FacePoint[]>? FaceParts, Dictionary<Stateless.FacePart, FacePoint[]>? FaceParts,
Location? Location, Location? Location,
string? Maker, string? Maker,
MappingFromPerson? MappingFromPerson,
string? Model, string? Model,
OutputResolution? OutputResolution); OutputResolution? OutputResolution);
@ -19,15 +17,3 @@ public record FaceFile(int? AreaPermyriad,
public partial class FaceFileGenerationContext : JsonSerializerContext public partial class FaceFileGenerationContext : JsonSerializerContext
{ {
} }
[JsonSourceGenerationOptions(WriteIndented = false, DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull)]
[JsonSerializable(typeof(FaceFile[]))]
public partial class FaceFileCollectionGenerationContext : JsonSerializerContext
{
}
[JsonSourceGenerationOptions(WriteIndented = true, DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull)]
[JsonSerializable(typeof(FaceFile[]))]
public partial class FaceFileCollectionWriteIndentedGenerationContext : JsonSerializerContext
{
}

View File

@ -1,35 +1,58 @@
using System.Drawing; using System.Drawing;
using System.Text.Json;
using System.Text.Json.Serialization; using System.Text.Json.Serialization;
namespace View_by_Distance.Shared.Models; namespace View_by_Distance.Shared.Models;
[method: JsonConstructor] public class FacePoint : Properties.IFacePoint
public class FacePoint(int index, int x, int y) : Properties.IFacePoint
{ {
public int Index { get; } = index;
public int X { get; } = x;
public int Y { get; } = y;
private readonly Point _Point = new(x, y); protected int _Index;
protected int _X;
protected int _Y;
public int Index => _Index;
public int X => _X;
public int Y => _Y;
private readonly Point _Point;
[JsonConstructor]
public FacePoint(int index, int x, int y)
{
_Index = index;
_X = x;
_Y = y;
_Point = new(x, y);
}
public FacePoint(Point point, int index) :
this(index, point.X, point.Y)
{ }
public override bool Equals(object? obj) => obj is FacePoint point && Equals(point); public override bool Equals(object? obj) => obj is FacePoint point && Equals(point);
public override string ToString()
{
string result = JsonSerializer.Serialize(this, new JsonSerializerOptions() { WriteIndented = true });
return result;
}
#pragma warning disable IDE0070 #pragma warning disable IDE0070
public override int GetHashCode() public override int GetHashCode()
#pragma warning restore IDE0070 #pragma warning restore IDE0070
{ {
int hashCode = 1861411795; int hashCode = 1861411795;
hashCode = (hashCode * -1521134295) + _Point.GetHashCode(); hashCode = hashCode * -1521134295 + _Point.GetHashCode();
hashCode = (hashCode * -1521134295) + Index.GetHashCode(); hashCode = hashCode * -1521134295 + _Index.GetHashCode();
return hashCode; return hashCode;
} }
public bool Equals(FacePoint? facePoint) public bool Equals(FacePoint? facePoint)
{ {
return facePoint is not null return facePoint is not null
&& X == facePoint.X && _X == facePoint.X
&& Y == facePoint.Y && _Y == facePoint.Y
&& Index == facePoint.Index; && _Index == facePoint.Index;
} }
public static bool operator ==(FacePoint point1, FacePoint point2) => point1.Equals(point2); public static bool operator ==(FacePoint point1, FacePoint point2) => point1.Equals(point2);

View File

@ -4,7 +4,7 @@ using System.Text.Json.Serialization;
namespace View_by_Distance.Shared.Models; namespace View_by_Distance.Shared.Models;
public record FileHolder(DateTime? CreationTime, public record FileHolder(DateTime? CreationTime,
string? DirectoryFullPath, string? DirectoryName,
bool Exists, bool Exists,
string ExtensionLowered, string ExtensionLowered,
string FullName, string FullName,
@ -49,7 +49,7 @@ public record FileHolder(DateTime? CreationTime,
{ {
FileHolder result; FileHolder result;
result = new(new(filePath.CreationTicks), result = new(new(filePath.CreationTicks),
filePath.DirectoryFullPath, filePath.DirectoryName,
true, true,
filePath.ExtensionLowered, filePath.ExtensionLowered,
filePath.FullName, filePath.FullName,

View File

@ -1,4 +1,3 @@
using System.Collections.ObjectModel;
using System.Text.Json; using System.Text.Json;
using System.Text.Json.Serialization; using System.Text.Json.Serialization;
using View_by_Distance.Shared.Models.Stateless.Methods; using View_by_Distance.Shared.Models.Stateless.Methods;
@ -6,7 +5,7 @@ using View_by_Distance.Shared.Models.Stateless.Methods;
namespace View_by_Distance.Shared.Models; namespace View_by_Distance.Shared.Models;
public record FilePath(long CreationTicks, public record FilePath(long CreationTicks,
string DirectoryFullPath, string DirectoryName,
string ExtensionLowered, string ExtensionLowered,
string FileNameFirstSegment, string FileNameFirstSegment,
string FullName, string FullName,
@ -40,7 +39,7 @@ public record FilePath(long CreationTicks,
int? sortOder; int? sortOder;
string fileNameFirstSegment = fileHolder.Name.Split('.')[0]; string fileNameFirstSegment = fileHolder.Name.Split('.')[0];
int sortOrderOnlyLengthIndex = propertyConfiguration.Offset.ToString().Length; int sortOrderOnlyLengthIndex = propertyConfiguration.Offset.ToString().Length;
string fileDirectoryName = fileHolder.DirectoryFullPath ?? throw new NullReferenceException(); string fileDirectoryName = fileHolder.DirectoryName ?? throw new NullReferenceException();
bool isIntelligentIdFormat = IId.NameWithoutExtensionIsIntelligentIdFormat(propertyConfiguration, fileNameFirstSegment); bool isIntelligentIdFormat = IId.NameWithoutExtensionIsIntelligentIdFormat(propertyConfiguration, fileNameFirstSegment);
bool isPaddedIntelligentIdFormat = IId.NameWithoutExtensionIsPaddedIntelligentIdFormat(propertyConfiguration, sortOrderOnlyLengthIndex, fileNameFirstSegment); bool isPaddedIntelligentIdFormat = IId.NameWithoutExtensionIsPaddedIntelligentIdFormat(propertyConfiguration, sortOrderOnlyLengthIndex, fileNameFirstSegment);
bool fileNameFirstSegmentIsIdFormat = !isPaddedIntelligentIdFormat && !isIntelligentIdFormat && IId.NameWithoutExtensionIsIdFormat(propertyConfiguration, fileHolder); bool fileNameFirstSegmentIsIdFormat = !isPaddedIntelligentIdFormat && !isIntelligentIdFormat && IId.NameWithoutExtensionIsIdFormat(propertyConfiguration, fileHolder);
@ -84,33 +83,6 @@ public record FilePath(long CreationTicks,
return result; return result;
} }
public static ReadOnlyDictionary<int, ReadOnlyCollection<FilePath>> GetKeyValuePairs(ReadOnlyCollection<ReadOnlyCollection<FilePath>> filePathsCollection)
{
Dictionary<int, ReadOnlyCollection<FilePath>> results = [];
List<FilePath>? collection;
Dictionary<int, List<FilePath>> keyValuePairs = [];
foreach (ReadOnlyCollection<FilePath> filePaths in filePathsCollection)
{
if (filePaths.Count == 0)
continue;
foreach (FilePath filePath in filePaths)
{
if (filePath.Id is null)
continue;
if (!keyValuePairs.TryGetValue(filePath.Id.Value, out collection))
{
keyValuePairs.Add(filePath.Id.Value, []);
if (!keyValuePairs.TryGetValue(filePath.Id.Value, out collection))
throw new Exception();
}
collection.Add(filePath);
}
}
foreach (KeyValuePair<int, List<FilePath>> keyValuePair in keyValuePairs)
results.Add(keyValuePair.Key, new(keyValuePair.Value));
return results.AsReadOnly();
}
} }
[JsonSourceGenerationOptions(WriteIndented = true)] [JsonSourceGenerationOptions(WriteIndented = true)]

View File

@ -1,33 +0,0 @@
using System.Text.Json;
using System.Text.Json.Serialization;
namespace View_by_Distance.Shared.Models;
public sealed record Identifier(string[] DirectoryNames,
string Extension,
bool? HasDateTimeOriginal,
int Id,
long Length,
string PaddedId,
long Ticks)
{
public override string ToString()
{
string result = JsonSerializer.Serialize(this, IdentifierSourceGenerationContext.Default.Identifier);
return result;
}
}
[JsonSourceGenerationOptions(WriteIndented = true)]
[JsonSerializable(typeof(Identifier))]
public partial class IdentifierSourceGenerationContext : JsonSerializerContext
{
}
[JsonSourceGenerationOptions(WriteIndented = true)]
[JsonSerializable(typeof(Identifier[]))]
public partial class IdentifierCollectionSourceGenerationContext : JsonSerializerContext
{
}

View File

@ -5,33 +5,11 @@ namespace View_by_Distance.Shared.Models;
public record ImmichAsset([property: JsonPropertyName("id")] string Id, public record ImmichAsset([property: JsonPropertyName("id")] string Id,
[property: JsonPropertyName("deviceAssetId")] string DeviceAssetId, [property: JsonPropertyName("deviceAssetId")] string DeviceAssetId,
// [property: JsonPropertyName("ownerId")] string OwnerId,
// [property: JsonPropertyName("deviceId")] string DeviceId,
// [property: JsonPropertyName("type")] string Type,
[property: JsonPropertyName("originalPath")] string OriginalPath, [property: JsonPropertyName("originalPath")] string OriginalPath,
// [property: JsonPropertyName("fileCreatedAt")] DateTime FileCreatedAt, [property: JsonPropertyName("previewPath")] string PreviewPath,
// [property: JsonPropertyName("fileModifiedAt")] DateTime FileModifiedAt, [property: JsonPropertyName("isFavorite")] bool IsFavorite,
// [property: JsonPropertyName("isFavorite")] bool IsFavorite, [property: JsonPropertyName("thumbnailPath")] string ThumbnailPath,
// [property: JsonPropertyName("duration")] string? Duration, [property: JsonPropertyName("thumbhash")] string Thumbhash)
// [property: JsonPropertyName("encodedVideoPath")] string EncodedVideoPath,
// [property: JsonPropertyName("checksum")] string Checksum,
// [property: JsonPropertyName("isVisible")] bool IsVisible,
// [property: JsonPropertyName("livePhotoVideoId")] object? LivePhotoVideoId,
// [property: JsonPropertyName("updatedAt")] DateTime UpdatedAt,
// [property: JsonPropertyName("createdAt")] DateTime CreatedAt,
// [property: JsonPropertyName("isArchived")] bool IsArchived,
[property: JsonPropertyName("originalFileName")] string OriginalFileName,
// [property: JsonPropertyName("sidecarPath")] object? SidecarPath,
// [property: JsonPropertyName("thumbhash")] string Thumbhash,
// [property: JsonPropertyName("isOffline")] bool IsOffline,
// [property: JsonPropertyName("libraryId")] string LibraryId,
// [property: JsonPropertyName("isExternal")] bool IsExternal,
// [property: JsonPropertyName("deletedAt")] object? DeletedAt,
// [property: JsonPropertyName("localDateTime")] DateTime LocalDateTime,
// [property: JsonPropertyName("stackId")]? object? StackId,
[property: JsonPropertyName("duplicateId")] string? DuplicateId,
// [property: JsonPropertyName("status")] string Status,
[property: JsonPropertyName("path")] string Path)
{ {
public override string ToString() public override string ToString()

View File

@ -9,7 +9,6 @@ public class Item : Properties.IItem
protected List<Face> _Faces; protected List<Face> _Faces;
protected readonly bool? _FileSizeChanged; protected readonly bool? _FileSizeChanged;
protected readonly FilePath _FilePath; protected readonly FilePath _FilePath;
protected bool? _IsArchive;
protected bool? _IsNotUniqueAndNeedsReview; protected bool? _IsNotUniqueAndNeedsReview;
protected bool _IsUniqueFileName; protected bool _IsUniqueFileName;
protected bool _IsValidImageFormatExtension; protected bool _IsValidImageFormatExtension;
@ -22,7 +21,6 @@ public class Item : Properties.IItem
public List<Face> Faces => _Faces; public List<Face> Faces => _Faces;
public bool? FileSizeChanged => _FileSizeChanged; public bool? FileSizeChanged => _FileSizeChanged;
public FilePath FilePath => _FilePath; public FilePath FilePath => _FilePath;
public bool? IsArchive => _IsArchive;
public bool? IsNotUniqueAndNeedsReview => _IsNotUniqueAndNeedsReview; public bool? IsNotUniqueAndNeedsReview => _IsNotUniqueAndNeedsReview;
public bool IsUniqueFileName => _IsUniqueFileName; public bool IsUniqueFileName => _IsUniqueFileName;
public bool IsValidImageFormatExtension => _IsValidImageFormatExtension; public bool IsValidImageFormatExtension => _IsValidImageFormatExtension;
@ -34,12 +32,11 @@ public class Item : Properties.IItem
public FileHolder SourceDirectoryFileHolder => _SourceDirectoryFileHolder; public FileHolder SourceDirectoryFileHolder => _SourceDirectoryFileHolder;
[JsonConstructor] [JsonConstructor]
public Item(List<Face> faces, FilePath filePath, bool? fileSizeChanged, bool? isArchive, bool? isNotUniqueAndNeedsReview, bool isUniqueFileName, bool isValidImageFormatExtension, bool? lastWriteTimeChanged, bool? moved, Property? property, string relativePath, FileHolder? resizedFileHolder, FileHolder sourceDirectoryFileHolder) public Item(List<Face> faces, FilePath filePath, bool? fileSizeChanged, bool? isNotUniqueAndNeedsReview, bool isUniqueFileName, bool isValidImageFormatExtension, bool? lastWriteTimeChanged, bool? moved, Property? property, string relativePath, FileHolder? resizedFileHolder, FileHolder sourceDirectoryFileHolder)
{ {
_Faces = faces; _Faces = faces;
_FilePath = filePath; _FilePath = filePath;
_FileSizeChanged = fileSizeChanged; _FileSizeChanged = fileSizeChanged;
_IsArchive = isArchive;
_IsNotUniqueAndNeedsReview = isNotUniqueAndNeedsReview; _IsNotUniqueAndNeedsReview = isNotUniqueAndNeedsReview;
_IsUniqueFileName = isUniqueFileName; _IsUniqueFileName = isUniqueFileName;
_IsValidImageFormatExtension = isValidImageFormatExtension; _IsValidImageFormatExtension = isValidImageFormatExtension;
@ -51,19 +48,18 @@ public class Item : Properties.IItem
_SourceDirectoryFileHolder = sourceDirectoryFileHolder; _SourceDirectoryFileHolder = sourceDirectoryFileHolder;
} }
public static Item Get(FilePath filePath, FileHolder sourceDirectoryFileHolder, string relativePath, bool? isArchive, bool? isNotUniqueAndNeedsReview, bool isUniqueFileName, bool isValidImageFormatExtension, Property? property, bool? abandoned, bool? fileSizeChanged, bool? lastWriteTimeChanged) public Item(FilePath filePath, FileHolder sourceDirectoryFileHolder, string relativePath, bool? isNotUniqueAndNeedsReview, bool isUniqueFileName, bool isValidImageFormatExtension, Property? property, bool? abandoned, bool? fileSizeChanged, bool? lastWriteTimeChanged) :
this([], filePath, fileSizeChanged, isNotUniqueAndNeedsReview, isUniqueFileName, isValidImageFormatExtension, lastWriteTimeChanged, null, property, relativePath, null, sourceDirectoryFileHolder)
{ {
Item result;
if (relativePath.EndsWith(".json")) if (relativePath.EndsWith(".json"))
throw new ArgumentException("Can not be a *.json file!"); throw new ArgumentException("Can not be a *.json file!");
if (filePath.ExtensionLowered is ".json") if (filePath is not null && filePath.ExtensionLowered is ".json")
throw new ArgumentException("Can not be a *.json file!"); throw new ArgumentException("Can not be a *.json file!");
result = new([], filePath, fileSizeChanged, isArchive, isNotUniqueAndNeedsReview, isUniqueFileName, isValidImageFormatExtension, lastWriteTimeChanged, null, property, relativePath, null, sourceDirectoryFileHolder);
return result;
} }
public static Item Get(FilePath filePath, FileHolder sourceDirectoryFileHolder, string relativePath, bool isValidImageFormatExtension) => public Item(FilePath filePath, FileHolder sourceDirectoryFileHolder, string relativePath, bool isValidImageFormatExtension) :
Get(filePath, sourceDirectoryFileHolder, relativePath, null, null, false, isValidImageFormatExtension, null, null, null, null); this(filePath, sourceDirectoryFileHolder, relativePath, null, false, isValidImageFormatExtension, null, null, null, null)
{ }
public override string ToString() public override string ToString()
{ {

View File

@ -79,10 +79,10 @@ public class Location : Properties.ILocation, IEquatable<Location>
#pragma warning restore IDE0070 #pragma warning restore IDE0070
{ {
int hashCode = -773114317; int hashCode = -773114317;
hashCode = (hashCode * -1521134295) + Bottom.GetHashCode(); hashCode = hashCode * -1521134295 + Bottom.GetHashCode();
hashCode = (hashCode * -1521134295) + Left.GetHashCode(); hashCode = hashCode * -1521134295 + Left.GetHashCode();
hashCode = (hashCode * -1521134295) + Right.GetHashCode(); hashCode = hashCode * -1521134295 + Right.GetHashCode();
hashCode = (hashCode * -1521134295) + Top.GetHashCode(); hashCode = hashCode * -1521134295 + Top.GetHashCode();
return hashCode; return hashCode;
} }

View File

@ -36,8 +36,9 @@ public class Mapping : Properties.IMapping
_SortingContainer = sortingContainer; _SortingContainer = sortingContainer;
} }
public static Mapping Get(FilePath filePath, MappingFromFilterPost mappingFromFilterPost, MappingFromFilterPre mappingFromFilterPre, MappingFromItem mappingFromItem, MappingFromLocation? mappingFromLocation, List<MappingFromPhotoPrism>? mappingFromPhotoPrismCollection) => public Mapping(FilePath filePath, MappingFromFilterPost mappingFromFilterPost, MappingFromFilterPre mappingFromFilterPre, MappingFromItem mappingFromItem, MappingFromLocation? mappingFromLocation, List<MappingFromPhotoPrism>? mappingFromPhotoPrismCollection) :
new(null, filePath, mappingFromFilterPost, mappingFromFilterPre, mappingFromItem, mappingFromLocation, null, mappingFromPhotoPrismCollection, null, null); this(null, filePath, mappingFromFilterPost, mappingFromFilterPre, mappingFromItem, mappingFromLocation, null, mappingFromPhotoPrismCollection, null, null)
{ }
public override string ToString() public override string ToString()
{ {

View File

@ -7,7 +7,6 @@ public record MappingFromItem(DateTime[] ContainerDateTimes,
DateTime? DateTimeDigitized, DateTime? DateTimeDigitized,
DateTime? DateTimeOriginal, DateTime? DateTimeOriginal,
int Id, int Id,
bool? IsArchive,
FilePath FilePath, FilePath FilePath,
bool? IsWrongYear, bool? IsWrongYear,
string[] Keywords, string[] Keywords,
@ -36,7 +35,7 @@ public record MappingFromItem(DateTime[] ContainerDateTimes,
List<DateTime> dateTimes = item.Property.GetDateTimes(); List<DateTime> dateTimes = item.Property.GetDateTimes();
DateTime minimumDateTime = Stateless.Methods.IProperty.GetMinimumDateTime(item.Property); DateTime minimumDateTime = Stateless.Methods.IProperty.GetMinimumDateTime(item.Property);
(bool? isWrongYear, _) = Stateless.Methods.IProperty.IsWrongYear(item.FilePath, item.Property.DateTimeOriginal, dateTimes); (bool? isWrongYear, _) = Stateless.Methods.IProperty.IsWrongYear(item.FilePath, item.Property.DateTimeOriginal, dateTimes);
result = new(containerDateTimes, item.Property.DateTimeDigitized, item.Property.DateTimeOriginal, item.Property.Id.Value, item.IsArchive, item.FilePath, isWrongYear, item.Property.Keywords ?? [], minimumDateTime, item.Property.Model, item.RelativePath, resizedFileHolder); result = new(containerDateTimes, item.Property.DateTimeDigitized, item.Property.DateTimeOriginal, item.Property.Id.Value, item.FilePath, isWrongYear, item.Property.Keywords ?? [], minimumDateTime, item.Property.Model, item.RelativePath, resizedFileHolder);
return result; return result;
} }

View File

@ -1,5 +1,30 @@
using System.Text.Json;
using System.Text.Json.Serialization;
namespace View_by_Distance.Shared.Models; namespace View_by_Distance.Shared.Models;
public record OutputResolution(int Height, public class OutputResolution : Properties.IOutputResolution
int Orientation, {
int Width);
protected int _Height;
protected int _Orientation;
protected int _Width;
public int Height => _Height;
public int Orientation => _Orientation;
public int Width => _Width;
[JsonConstructor]
public OutputResolution(int height, int orientation, int width)
{
_Height = height;
_Orientation = orientation;
_Width = width;
}
public override string ToString()
{
string result = JsonSerializer.Serialize(this, new JsonSerializerOptions() { WriteIndented = true });
return result;
}
}

View File

@ -3,19 +3,23 @@ using System.Text.Json.Serialization;
namespace View_by_Distance.Shared.Models; namespace View_by_Distance.Shared.Models;
public record PersonBirthday(DateTime Value) public class PersonBirthday : Properties.IPersonBirthday
{ {
protected readonly DateTime _Value; // {{1}}SingletonValue
public DateTime Value => _Value; // {{1}}SingletonValue
[JsonConstructor]
public PersonBirthday
(
DateTime value
) => _Value = value; // {{1}}SingletonValue
public override string ToString() public override string ToString()
{ {
string result = JsonSerializer.Serialize(this, PersonBirthdaySourceGenerationContext.Default.PersonBirthday); string result = JsonSerializer.Serialize(this, new JsonSerializerOptions() { WriteIndented = true });
return result; return result;
} } // ...
} }
[JsonSourceGenerationOptions(WriteIndented = true, DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull)]
[JsonSerializable(typeof(PersonBirthday))]
public partial class PersonBirthdaySourceGenerationContext : JsonSerializerContext
{
}

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