Compare commits

..

20 Commits

Author SHA1 Message Date
ee0219f321 Using PersonContainer for PersonDisplayDirectoryName 2024-12-29 11:51:08 -07:00
75cfb2a0d9 Alignment with AA 2024-12-28 19:36:44 -07:00
17be39bef9 Updated Offset date to update images from new camera 2024-12-08 19:05:54 -07:00
c085ac3f76 Random with Immich and IsArchive 2024-11-24 15:47:19 -07:00
a6b3318eec net9.0 2024-11-23 21:37:12 -07:00
49e9daea8f IgnoreExtensions 2024-11-09 09:38:28 -07:00
e2e6e15ea2 d8013da9 2024-11-09 09:38:20 -07:00
d8013da912 ResultContentCollection
ValidVideoFormatExtensions
2024-11-03 10:33:56 -07:00
4da353d150 Season breakout
DirectoryName to DirectoryFullPath
2024-11-02 14:24:28 -07:00
444e7ed71a Fast Forward Moving Picture Experts Group 2024-10-30 17:16:52 -07:00
99198cc378 Small changes 2024-10-20 20:12:05 -07:00
e532c3ef1e FaceFile for D2 2024-10-20 17:49:11 -07:00
c580c7eaa4 Identifier new properties 2024-10-14 08:59:26 -07:00
43b66f01b6 Bump 2024-10-14 08:59:18 -07:00
304b5e2a0e Patch but not understood 2024-08-31 09:31:03 -07:00
326e579d5c Runs but broken 2024-08-31 08:32:06 -07:00
f458af776a Body Changes Only 2024-08-31 08:17:11 -07:00
3b63279545 New Models Only 2024-08-31 08:09:06 -07:00
61d1ae71f6 PreVerify 2024-08-31 08:01:45 -07:00
368138bb78 Bump 2024-08-31 07:53:10 -07:00
123 changed files with 1180 additions and 965 deletions

80
.vscode/launch.json vendored
View File

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

View File

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

50
.vscode/tasks.json vendored
View File

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

View File

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

View File

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

View File

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

View File

@ -10,8 +10,8 @@ namespace View_by_Distance.BlurHash.Models;
public class C2_BlurHasher : IBlurHasher
{
private readonly Dictionary<string, string[]> _FileGroups;
private readonly IPropertyConfiguration _PropertyConfiguration;
private readonly Dictionary<string, ReadOnlyCollection<string>> _FileGroups;
public C2_BlurHasher(IPropertyConfiguration propertyConfiguration)
{
@ -22,8 +22,8 @@ public class C2_BlurHasher : IBlurHasher
public void Update(string resultsFullGroupDirectory)
{
_FileGroups.Clear();
ReadOnlyDictionary<string, string[]> keyValuePairs = Shared.Models.Stateless.Methods.IPath.GetKeyValuePairs(_PropertyConfiguration, resultsFullGroupDirectory, [_PropertyConfiguration.ResultContent, _PropertyConfiguration.ResultSingleton]);
foreach (KeyValuePair<string, string[]> keyValuePair in keyValuePairs)
ReadOnlyDictionary<string, ReadOnlyCollection<string>> keyValuePairs = Shared.Models.Stateless.Methods.IPath.GetKeyValuePairs(_PropertyConfiguration, resultsFullGroupDirectory, [_PropertyConfiguration.ResultContent, _PropertyConfiguration.ResultSingleton]);
foreach (KeyValuePair<string, ReadOnlyCollection<string>> keyValuePair in keyValuePairs)
_FileGroups.Add(keyValuePair.Key, keyValuePair.Value);
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -422,7 +422,7 @@ public class DateGroup
{
try
{
windowsShortcut = new() { Path = item.FilePath.DirectoryName, Description = item.FilePath.Name };
windowsShortcut = new() { Path = item.FilePath.DirectoryFullPath, Description = item.FilePath.Name };
windowsShortcut.Save(string.Concat(fullFileName, ".lnk"));
windowsShortcut.Dispose();
}

View File

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

View File

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

View File

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

View File

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

View File

@ -400,7 +400,7 @@ public partial class E_Distance : IDistance
}
if (!string.IsNullOrEmpty(focusDirectory))
{
if (!locationContainer.FilePath.DirectoryName.Contains(focusDirectory))
if (!locationContainer.FilePath.DirectoryFullPath.Contains(focusDirectory))
continue;
}
json = Metadata.Models.Stateless.Methods.IMetadata.GetFaceEncoding(locationContainer.ExifDirectory);
@ -426,11 +426,10 @@ public partial class E_Distance : IDistance
continue;
if (face.Mapping.MappingFromFilterPre.IsFocusRelativePath is not null && !face.Mapping.MappingFromFilterPre.IsFocusRelativePath.Value)
continue;
if (!configuration.ReMap && face.Mapping.MappingFromPerson is not null)
continue;
// if (!configuration.ReMap && face.Mapping.MappingFromPerson is not null)
// continue;
if (!configuration.ReMap && face.FaceEncoding is not null && face.FaceDistance?.Encoding is not null && face.FaceDistance.Encoding is FaceRecognitionDotNet.FaceEncoding)
// throw new NotSupportedException($"{face.FaceEncoding} should not be null!");
continue;
throw new NotSupportedException($"{face.FaceEncoding} should not be null!");
faces.Add(face);
}
int totalSeconds = (int)Math.Floor(new TimeSpan(DateTime.Now.Ticks - ticks).TotalSeconds);

View File

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

View File

@ -8,7 +8,7 @@ public class Program
[STAThread]
private static void Main()
{
ApplicationConfiguration.Initialize();
// ApplicationConfiguration.Initialize();
Application.Run(new DragDropExplorer());
}

View File

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

View File

@ -8,7 +8,7 @@ public class Program
[STAThread]
private static void Main()
{
ApplicationConfiguration.Initialize();
// ApplicationConfiguration.Initialize();
Application.Run(new DragDropMove());
}

View File

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

View File

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

View File

@ -10,7 +10,7 @@ public class Program
[STAThread]
private static void Main()
{
ApplicationConfiguration.Initialize();
// ApplicationConfiguration.Initialize();
Application.Run(new DragDropSearch());
}

View File

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

View File

@ -8,7 +8,7 @@ public class Program
[STAThread]
private static void Main()
{
ApplicationConfiguration.Initialize();
// ApplicationConfiguration.Initialize();
Application.Run(new DragDropSetPropertyItem());
}

View File

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

View File

@ -189,7 +189,7 @@ public class DuplicateSearch
if (mappingFromItem is not null)
{
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.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.IsArchive, 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));
@ -208,11 +208,11 @@ public class DuplicateSearch
{
foreach (MappingFromItem? mappingFromItem in keyValuePair.Value)
{
if (mappingFromItem?.ResizedFileHolder.DirectoryName is null)
if (mappingFromItem?.ResizedFileHolder.DirectoryFullPath is null)
continue;
if (mappingFromItem.ResizedFileHolder.Exists)
continue;
collection.Add(mappingFromItem.ResizedFileHolder.DirectoryName);
collection.Add(mappingFromItem.ResizedFileHolder.DirectoryFullPath);
results.Add(new(mappingFromItem.FilePath, mappingFromItem.ResizedFileHolder.FullName));
}
}

View File

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

View File

@ -42,11 +42,11 @@ public class D_Face : IFaceD
private readonly int _FaceDistanceHiddenImageFactor;
private readonly EncoderParameters _EncoderParameters;
private readonly ImageCodecInfo _HiddenImageCodecInfo;
private readonly Dictionary<string, string[]> _FileGroups;
private readonly bool _ForceFaceLastWriteTimeToCreationTime;
private readonly EncoderParameters _HiddenEncoderParameters;
private readonly IPropertyConfiguration _PropertyConfiguration;
private readonly JsonSerializerOptions _WriteIndentedAndWhenWritingNull;
private readonly Dictionary<string, ReadOnlyCollection<string>> _FileGroups;
public D_Face(
string argZero,
@ -102,8 +102,8 @@ public class D_Face : IFaceD
public void Update(string dResultsFullGroupDirectory)
{
_FileGroups.Clear();
ReadOnlyDictionary<string, string[]> keyValuePairs = Shared.Models.Stateless.Methods.IPath.GetKeyValuePairs(_PropertyConfiguration, dResultsFullGroupDirectory, [_PropertyConfiguration.ResultCollection, _PropertyConfiguration.ResultContent]);
foreach (KeyValuePair<string, string[]> keyValuePair in keyValuePairs)
ReadOnlyDictionary<string, ReadOnlyCollection<string>> keyValuePairs = Shared.Models.Stateless.Methods.IPath.GetKeyValuePairs(_PropertyConfiguration, dResultsFullGroupDirectory, [_PropertyConfiguration.ResultCollection, _PropertyConfiguration.ResultContent]);
foreach (KeyValuePair<string, ReadOnlyCollection<string>> keyValuePair in keyValuePairs)
_FileGroups.Add(keyValuePair.Key, keyValuePair.Value);
}
@ -112,8 +112,8 @@ public class D_Face : IFaceD
(Model, PredictorModel, ModelParameter) result;
Array array;
Model? model = null;
array = Enum.GetValues<Model>();
PredictorModel? predictorModel = null;
array = Enum.GetValues(typeof(Model));
foreach (Model check in array)
{
if (modelName.Contains(check.ToString()))
@ -125,7 +125,7 @@ public class D_Face : IFaceD
if (model is null)
throw new Exception("Destination directory must have Model name!");
model = model.Value;
array = Enum.GetValues(typeof(PredictorModel));
array = Enum.GetValues<PredictorModel>();
foreach (PredictorModel check in array)
{
if (predictorModelName.Contains(check.ToString()))
@ -193,11 +193,13 @@ public class D_Face : IFaceD
rectangle = new Rectangle(location.Left, location.Top, width, height);
faceFile = new(face.Mapping?.MappingFromLocation?.AreaPermyriad,
face.Mapping?.MappingFromLocation?.ConfidencePercent,
face.DateTime,
geoLocation?.ToDmsString(),
face.DateTime,
null,
face.FaceParts,
face.Location,
maker,
null,
model,
face.OutputResolution);
faceFileJson = JsonSerializer.Serialize(faceFile, FaceFileGenerationContext.Default.FaceFile);
@ -293,11 +295,9 @@ public class D_Face : IFaceD
#pragma warning restore CA1416
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)
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;
if (string.IsNullOrEmpty(dResultsFullGroupDirectory))
throw new NullReferenceException(nameof(dResultsFullGroupDirectory));
string? json;
List<Location> locations;
string[] changesFrom = [nameof(A_Property), nameof(B_Metadata), nameof(C_Resize)];
@ -366,7 +366,7 @@ public class D_Face : IFaceD
return results;
}
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)
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 = [];
bool save;
@ -453,11 +453,13 @@ public class D_Face : IFaceD
MetadataExtractor.GeoLocation? geoLocation = IMetadata.GeoLocation(exifDirectory);
FaceFile faceFile = new(face.Mapping?.MappingFromLocation?.AreaPermyriad,
face.Mapping?.MappingFromLocation?.ConfidencePercent,
face.DateTime,
geoLocation?.ToDmsString(),
face.DateTime,
null,
face.FaceParts,
face.Location,
maker,
null,
model,
face.OutputResolution);
string faceFileJson = JsonSerializer.Serialize(faceFile, FaceFileGenerationContext.Default.FaceFile);

View File

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

View File

@ -2,9 +2,12 @@ using System.Collections.ObjectModel;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.Reflection;
using System.Text;
using System.Text.Json;
using View_by_Distance.Face.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.Stateless;
using View_by_Distance.Resize.Models;
@ -25,11 +28,11 @@ public class D2_FaceParts
private readonly ImageCodecInfo _ImageCodecInfo;
private readonly bool _CheckDFaceAndUpWriteDates;
private readonly ConstructorInfo _ConstructorInfo;
private readonly bool _OverrideForFaceLandmarkImages;
private readonly EncoderParameters _EncoderParameters;
private readonly List<string> _AngleBracketCollection;
private readonly Dictionary<string, string[]> _FileGroups;
private readonly IPropertyConfiguration _PropertyConfiguration;
private readonly Dictionary<string, ReadOnlyCollection<string>> _FileGroups;
public D2_FaceParts(IPropertyConfiguration propertyConfiguration, ImageCodecInfo imageCodecInfo, EncoderParameters encoderParameters, string filenameExtension, bool checkDFaceAndUpWriteDates, bool overrideForFaceLandmarkImages)
{
@ -37,10 +40,11 @@ public class D2_FaceParts
_ImageCodecInfo = imageCodecInfo;
_EncoderParameters = encoderParameters;
_FileNameExtension = filenameExtension;
_AngleBracketCollection = [];
_PropertyConfiguration = propertyConfiguration;
_CheckDFaceAndUpWriteDates = checkDFaceAndUpWriteDates;
_OverrideForFaceLandmarkImages = overrideForFaceLandmarkImages;
ConstructorInfo? constructorInfo = typeof(PropertyItem).GetConstructor(BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Public, null, [], null) ?? throw new Exception();
_ConstructorInfo = constructorInfo;
}
public override string ToString()
@ -52,46 +56,11 @@ public class D2_FaceParts
public void Update(string dResultsFullGroupDirectory)
{
_FileGroups.Clear();
ReadOnlyDictionary<string, string[]> keyValuePairs = Shared.Models.Stateless.Methods.IPath.GetKeyValuePairs(_PropertyConfiguration, dResultsFullGroupDirectory, [_PropertyConfiguration.ResultContent]);
foreach (KeyValuePair<string, string[]> keyValuePair in keyValuePairs)
ReadOnlyDictionary<string, ReadOnlyCollection<string>> keyValuePairs = Shared.Models.Stateless.Methods.IPath.GetKeyValuePairs(_PropertyConfiguration, dResultsFullGroupDirectory, [_PropertyConfiguration.ResultContent]);
foreach (KeyValuePair<string, ReadOnlyCollection<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 (item.FilePath.DirectoryName is null)
throw new NullReferenceException(nameof(item.FilePath.DirectoryName));
SetAngleBracketCollection(propertyConfiguration, dResultsFullGroupDirectory, item.FilePath.DirectoryName);
}
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)
{
xMinimum = points[0].X;
@ -183,73 +152,238 @@ public class D2_FaceParts
return result;
}
private void SaveFaceParts(int pointSize, FileHolder resizedFileHolder, bool saveRotated, List<(Shared.Models.Face, string, string)> collection)
private void SaveRotated(MappingFromItem mappingFromItem, List<(Shared.Models.Face, string, string)> collection)
{
double? α;
Bitmap rotated;
foreach ((Shared.Models.Face face, string _, string rotatedFileName) in collection)
{
if (face.FaceParts is null)
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;
double? α;
int width;
int height;
Bitmap rotated;
foreach ((Shared.Models.Face face, string fileName, string rotatedFileName) in collection)
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.FaceEncoding is null)
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
{
using (Image image = Image.FromFile(resizedFileHolder.FullName))
if (face.Location is null || face.FaceEncoding is null || face.FaceParts is null || face.FaceParts.Count == 0)
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)
{
using Graphics graphic = Graphics.FromImage(image);
if (face.FaceParts is null || face.FaceParts.Count == 0)
{
if (face.Location is null)
continue;
width = face.Location.Right - face.Location.Left;
height = face.Location.Bottom - face.Location.Top;
graphic.DrawEllipse(Pens.Red, face.Location.Left, face.Location.Top, width, height);
}
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)
foreach (FacePoint facePoint in facePoints)
graphics.FillEllipse(brush, facePoint.X - pointSize, facePoint.Y - pointSize, pointSize * 2, pointSize * 2);
if (facePart == FacePart.Chin)
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();
}
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();
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
public void SaveFaceLandmarkImages(Configuration configuration, FilePath filePath, List<Tuple<string, DateTime>> subFileTuples, List<string> parseExceptions, MappingFromItem mappingFromItem, List<Shared.Models.Face> faces, bool saveRotated)
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;
bool check = false;
const int pointSize = 2;
FileInfo rotatedFileInfo;
DateTime? dateTime = null;
long ticks = DateTime.Now.Ticks;
@ -296,37 +430,12 @@ public class D2_FaceParts
{
if (!directoryExists)
_ = Directory.CreateDirectory(directory);
SaveFaceParts(pointSize, mappingFromItem.ResizedFileHolder, saveRotated, collection);
SaveFaceParts(mappingFromItem, exifDirectory, 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)
{
bool results = false;
@ -360,19 +469,18 @@ public class D2_FaceParts
return results;
}
public void CopyFacesAndSaveFaceLandmarkImage(string facePartsCollectionDirectory, MappingFromItem mappingFromItem, List<(Shared.Models.Face Face, FileHolder?, string, bool)> faceCollection)
public void SaveFaceLandmarkImages(string d2ResultsFullGroupDirectory, MappingFromItem mappingFromItem, ExifDirectory exifDirectory, List<Shared.Models.Face> faces)
{
bool hasNotMapped = GetNotMapped(facePartsCollectionDirectory, faceCollection);
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))
bool any = false;
foreach (Shared.Models.Face face in faces)
{
SaveFaceLandmarkImage(mappingFromItem, faceCollection, fileName);
fileInfo.Refresh();
if (face.Location is null || face.FaceEncoding is null || face.FaceParts is null || face.FaceParts.Count == 0)
continue;
if (!any)
any = true;
}
if (!hasNotMapped && !fileInfo.Attributes.HasFlag(FileAttributes.Hidden) && (fileInfo.Exists || save))
File.SetAttributes(fileName, FileAttributes.Hidden);
if (any)
SaveAllFaceParts(d2ResultsFullGroupDirectory, mappingFromItem, exifDirectory, faces);
}
}

View File

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

View File

@ -88,7 +88,7 @@ public partial class DlibDotNet : IDlibDotNet, IDisposable
_Logger?.LogInformation(configuration.ModelDirectory);
{
(ImageCodecInfo imageCodecInfo, EncoderParameters encoderParameters, string filenameExtension) = C_Resize.GetPngLowQuality();
(ImageCodecInfo hiddenImageCodecInfo, EncoderParameters hiddenEncoderParameters, string hiddenFileNameExtension) = C_Resize.GetGifLowQuality();
(ImageCodecInfo hiddenImageCodecInfo, EncoderParameters hiddenEncoderParameters, string hiddenFileNameExtension) = C_Resize.GetJpegLowQuality();
_Faces = new D_Face(
argZero,
configuration.PropertyConfiguration,
@ -110,10 +110,10 @@ public partial class DlibDotNet : IDlibDotNet, IDisposable
configuration.RectangleIntersectMinimums);
}
{
(ImageCodecInfo imageCodecInfo, EncoderParameters encoderParameters, string filenameExtension) = C_Resize.GetGifLowQuality();
(ImageCodecInfo imageCodecInfo, EncoderParameters encoderParameters, string filenameExtension) = C_Resize.GetJpegLowQuality();
_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.RangeFaceAreaPermyriadTolerance, _Configuration.RangeFaceConfidence, _Configuration.SortingMaximumPerFaceShouldBeHigh);
_DistanceLimits = new(_Configuration.FaceAreaPermyriad, _Configuration.FaceConfidencePercent, _Configuration.FaceDistancePermyriad, _Configuration.RangeDaysDeltaTolerance, _Configuration.RangeDistanceTolerance, _Configuration.RangeFaceAreaTolerance, _Configuration.RangeFaceConfidence, _Configuration.SortingMaximumPerFaceShouldBeHigh);
_MapConfiguration = Get(configuration, _DistanceLimits, _Faces.FileNameExtension, _Faces.HiddenFileNameExtension, _FaceParts.FileNameExtension);
_Distance = new(configuration.DistanceMoveUnableToMatch, configuration.DistanceRenameToMatch, configuration.FaceConfidencePercent, configuration.RangeDistanceTolerance, configuration.RectangleIntersectMinimums);
if (_PropertyRootExistedBefore || !_ArgZeroIsConfigurationRootDirectory)
@ -183,8 +183,8 @@ public partial class DlibDotNet : IDlibDotNet, IDisposable
throw new NullReferenceException(nameof(configuration.RangeDaysDeltaTolerance));
if (configuration.RangeDistanceTolerance.Length != 3)
throw new NullReferenceException(nameof(configuration.RangeDistanceTolerance));
if (configuration.RangeFaceAreaPermyriadTolerance.Length != 3)
throw new NullReferenceException(nameof(configuration.RangeFaceAreaPermyriadTolerance));
if (configuration.RangeFaceAreaTolerance.Length != 3)
throw new NullReferenceException(nameof(configuration.RangeFaceAreaTolerance));
if (configuration.RangeFaceConfidence.Length != 3)
throw new NullReferenceException(nameof(configuration.RangeFaceConfidence));
if (configuration.LocationContainerDistanceTolerance is null && !string.IsNullOrEmpty(configuration.LocationContainerDebugDirectory))
@ -204,6 +204,8 @@ public partial class DlibDotNet : IDlibDotNet, IDisposable
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())
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))
throw new NullReferenceException(nameof(configuration.ModelName));
if (string.IsNullOrEmpty(configuration.OutputExtension))
@ -252,31 +254,6 @@ public partial class DlibDotNet : IDlibDotNet, IDisposable
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)
{
foreach (PersonContainer personContainer in personContainers)
@ -335,9 +312,8 @@ public partial class DlibDotNet : IDlibDotNet, IDisposable
const string directorySearchFilter = "*";
string? filesCollectionRootDirectory = null;
bool configurationOutputResolutionsHas = false;
ReadOnlyCollection<Container> readOnlyContainers;
ReadOnlyCollection<int>? notNineCollection = null;
ReadOnlyDictionary<long, List<int>> personKeyToIds;
ReadOnlyDictionary<int, Identifier>? splatNineIdentifiers = null;
ReadOnlyCollection<ReadOnlyCollection<FilePath>>? filePathsCollection = null;
bool runToDoCollectionFirst = GetRunToDoCollectionFirst(_Configuration, ticks);
(aResultsFullGroupDirectory, bResultsFullGroupDirectory) = GetResultsFullGroupDirectories();
@ -359,7 +335,7 @@ public partial class DlibDotNet : IDlibDotNet, IDisposable
if (!runToDoCollectionFirst)
break;
(filesCollectionRootDirectory, filePathsCollection, filesCollectionCountIsOne) = GetFilesCollectionThenCopyOrMove(ticks, fileSearchFilter, directorySearchFilter, options, outputResolution);
notNineCollection = GetNotNineCollection(filePathsCollection);
splatNineIdentifiers = GetSplatNineIdentifiersAndHideSplatNine(_Configuration.PropertyConfiguration, bResultsFullGroupDirectory, filePathsCollection);
break;
}
fPhotoPrismContentDirectory = Property.Models.Stateless.IResult.GetResultsDateGroupDirectory(_Configuration.PropertyConfiguration, nameof(F_PhotoPrism), _Configuration.PropertyConfiguration.ResultContent);
@ -393,7 +369,7 @@ public partial class DlibDotNet : IDlibDotNet, IDisposable
continue;
(cResultsFullGroupDirectory, _, _, _) = GetResultsFullGroupDirectories(outputResolution);
filesCollectionRootDirectory = Path.Combine(cResultsFullGroupDirectory, _Configuration.PropertyConfiguration.ResultContent);
filePathsCollection = IDirectory.GetFilePathCollections(_Configuration.PropertyConfiguration, filesCollectionRootDirectory, directorySearchFilter, fileSearchFilter, useCeilingAverage: true);
filePathsCollection = IDirectory.GetFilePathCollections(_Configuration.PropertyConfiguration, directorySearchFilter, fileSearchFilter, filesCollectionRootDirectory, useCeilingAverage: true);
break;
}
}
@ -403,10 +379,9 @@ public partial class DlibDotNet : IDlibDotNet, IDisposable
if (!Directory.Exists(aPropertySingletonDirectory))
_ = Directory.CreateDirectory(aPropertySingletonDirectory);
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)";
_ProgressBar = new(count, message, options);
readOnlyContainers = Shared.Models.Stateless.Methods.IContainer.GetContainers(this, _Configuration.PropertyConfiguration, aPropertySingletonDirectory, filesCollectionRootDirectory, filePathsCollection);
ReadOnlyCollection<Container> readOnlyContainers = Shared.Models.Stateless.Methods.IContainer.GetContainers(this, _Configuration.PropertyConfiguration, aPropertySingletonDirectory, filesCollectionRootDirectory, splatNineIdentifiers, filePathsCollection);
_ProgressBar.Dispose();
mapLogic ??= new(_AppSettings.MaxDegreeOfParallelism, _Configuration.PropertyConfiguration, _MapConfiguration, _Distance, personContainers, ticks, a2PeopleContentDirectory, a2PeopleSingletonDirectory, eDistanceContentDirectory);
DeleteContinueFiles(personContainers);
@ -453,8 +428,8 @@ public partial class DlibDotNet : IDlibDotNet, IDisposable
&& _Configuration.LoadOrCreateThenSaveDistanceResultsForOutputResolutions.Contains(outputResolution)
&& _Exceptions.Count == 0)
MapLogic(ticks, readOnlyContainers, fPhotoPrismContentDirectory, mapLogic, outputResolution, new(personKeyToIds), distinctValidImageFaces, distinctValidImageMappingCollection);
if (runToDoCollectionFirst && _Configuration.SaveRandomForOutputResolutions.Contains(outputResolution) && personKeyToIds.Count > 0 && distinctValidImageMappingCollection.Count > 0)
_Random.Random(_Configuration.PropertyConfiguration, _Configuration.ImmichAssetsFile, _Configuration.RadomUseBirthdayMinimum, _Configuration.ValidKeyWordsToIgnoreInRandom, personKeyToIds, notNineCollection, distinctValidImageMappingCollection);
if (runToDoCollectionFirst && _Configuration.SaveRandomForOutputResolutions.Contains(outputResolution) && personKeyToIds.Count > 0 && splatNineIdentifiers is not null && distinctValidImageMappingCollection.Count > 0)
_Random.Random(_Configuration.PropertyConfiguration, _Configuration.ImmichAssetsFile, _Configuration.ImmichOwnerId, _Configuration.ImmichRoot, _Configuration.RadomUseBirthdayMinimum, _Configuration.ValidKeyWordsToIgnoreInRandom, personKeyToIds, splatNineIdentifiers, distinctValidImageMappingCollection);
if (_IsEnvironment.Development)
continue;
if (!_IsEnvironment.Development)
@ -496,8 +471,7 @@ public partial class DlibDotNet : IDlibDotNet, IDisposable
[
Path.Combine(rootDirectory, "Ancestry"),
Path.Combine(rootDirectory, "Facebook"),
Path.Combine(rootDirectory, "LinkedIn"),
rootDirectory,
Path.Combine(rootDirectory, "LinkedIn")
];
foreach (string checkDirectory in checkDirectories)
{
@ -534,7 +508,7 @@ public partial class DlibDotNet : IDlibDotNet, IDisposable
string result;
if (filePaths.Count == 0)
throw new NotSupportedException();
string? sourceDirectory = filePaths[0].DirectoryName;
string? sourceDirectory = filePaths[0].DirectoryFullPath;
if (string.IsNullOrEmpty(sourceDirectory))
throw new NotSupportedException();
Uri uri;
@ -568,7 +542,7 @@ public partial class DlibDotNet : IDlibDotNet, IDisposable
isValidImageFormatExtension = _Configuration.PropertyConfiguration.ValidImageFormatExtensions.Contains(extensionLowered);
fileHolder = Shared.Models.Stateless.Methods.IFileHolder.Get(sourceDirectoryFile);
filePath = FilePath.Get(_Configuration.PropertyConfiguration, fileHolder, index: null);
_ = new Item(filePath, fileHolder, relativePath, isValidImageFormatExtension);
_ = Item.Get(filePath, fileHolder, relativePath, isValidImageFormatExtension);
// container.Items.Add(item);
}
_Logger?.LogInformation(". . .");
@ -630,7 +604,6 @@ public partial class DlibDotNet : IDlibDotNet, IDisposable
outputResolution,
outputResolutionHasNumber,
cResultsFullGroupDirectory,
dResultsFullGroupDirectory,
d2ResultsFullGroupDirectory,
sourceDirectoryChanges,
fileNameToCollection,
@ -663,14 +636,11 @@ public partial class DlibDotNet : IDlibDotNet, IDisposable
}
}
private static void SaveDistinctIds(Property.Models.Configuration propertyConfiguration, string bResultsFullGroupDirectory, ReadOnlyCollection<ReadOnlyCollection<FilePath>> filePathsCollection)
private static ReadOnlyDictionary<int, ReadOnlyCollection<FilePath>> GetKeyValuePairs(ReadOnlyCollection<ReadOnlyCollection<FilePath>> filePathsCollection)
{
string paddedId;
List<int> distinct = [];
List<Identifier> identifiers = [];
string bMetadataCollectionDirectory = Path.Combine(bResultsFullGroupDirectory, propertyConfiguration.ResultCollection);
if (!Directory.Exists(bMetadataCollectionDirectory))
_ = Directory.CreateDirectory(bMetadataCollectionDirectory);
Dictionary<int, ReadOnlyCollection<FilePath>> results = [];
List<FilePath>? collection;
Dictionary<int, List<FilePath>> keyValuePairs = [];
foreach (ReadOnlyCollection<FilePath> filePaths in filePathsCollection)
{
if (filePaths.Count == 0)
@ -679,15 +649,69 @@ public partial class DlibDotNet : IDlibDotNet, IDisposable
{
if (filePath.Id is null)
continue;
if (distinct.Contains(filePath.Id.Value))
continue;
distinct.Add(filePath.Id.Value);
paddedId = IId.GetPaddedId(propertyConfiguration, filePath.Id.Value, filePath.HasIgnoreKeyword, filePath.HasDateTimeOriginal, index: null);
identifiers.Add(new(filePath.Id.Value, paddedId));
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);
}
}
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);
foreach (KeyValuePair<int, List<FilePath>> keyValuePair in keyValuePairs)
results.Add(keyValuePair.Key, new(keyValuePair.Value));
return new(results);
}
private static ReadOnlyDictionary<int, Identifier> GetSplatNineIdentifiersAndHideSplatNine(Property.Models.Configuration propertyConfiguration, string bResultsFullGroupDirectory, ReadOnlyCollection<ReadOnlyCollection<FilePath>> filePathsCollection)
{
Dictionary<int, Identifier> results = [];
ReadOnlyDictionary<int, ReadOnlyCollection<FilePath>> keyValuePairs = GetKeyValuePairs(filePathsCollection);
if (keyValuePairs.Count > 0)
{
string json;
string paddedId;
FileInfo fileInfo;
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++)
{
filePath = keyValuePair.Value[0];
if (filePath.Id is null)
continue;
directoryNames = keyValuePair.Value.Select(l => l.DirectoryFullPath.Replace('\\', '/')).ToArray();
paddedId = IId.GetPaddedId(propertyConfiguration, filePath.Id.Value, filePath.HasIgnoreKeyword, filePath.HasDateTimeOriginal, index: null);
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 new(results);
}
private ReadOnlyCollection<Mapping> GetMappings(Property.Models.Configuration propertyConfiguration, string eDistanceContentDirectory, ReadOnlyCollection<Container> readOnlyContainers, MapLogic mapLogic, bool distinctItems)
@ -905,7 +929,7 @@ public partial class DlibDotNet : IDlibDotNet, IDisposable
results = [];
else
{
DistanceLimits distanceLimits = new(_Configuration.FaceAreaPermyriad, _Configuration.FaceConfidencePercent, _Configuration.FaceDistancePermyriad, _Configuration.RangeDaysDeltaTolerance, _Configuration.RangeDistanceTolerance, _Configuration.RangeFaceAreaPermyriadTolerance, _Configuration.RangeFaceConfidence, _Configuration.SortingMaximumPerFaceShouldBeHigh);
DistanceLimits distanceLimits = new(_Configuration.FaceAreaPermyriad, _Configuration.FaceConfidencePercent, _Configuration.FaceDistancePermyriad, _Configuration.RangeDaysDeltaTolerance, _Configuration.RangeDistanceTolerance, _Configuration.RangeFaceAreaTolerance, _Configuration.RangeFaceConfidence, _Configuration.SortingMaximumPerFaceShouldBeHigh);
List<LocationContainer> postFiltered = E_Distance.GetPostFilterLocationContainer(mapLogic, preFiltered, distanceLimits);
if (postFiltered.Count == 0)
results = [];
@ -920,7 +944,7 @@ public partial class DlibDotNet : IDlibDotNet, IDisposable
results = [];
else
{
ReadOnlyDictionary<long, PersonContainer> personKeyToPersonContainer = mapLogic.GetPersonKeyToPersonContainer();
ReadOnlyDictionary<long, PersonContainer> personKeyToPersonContainer = PersonContainer.Extract(personContainers);
results = mapLogic.GetSaveContainers(cResultsFullGroupDirectory, dResultsFullGroupDirectory, d2ResultsFullGroupDirectory, distanceLimits, onlyOne, personKeyToPersonContainer);
}
}
@ -933,7 +957,7 @@ public partial class DlibDotNet : IDlibDotNet, IDisposable
(_, _, string dResultsFullGroupDirectory, string d2ResultsFullGroupDirectory) = GetResultsFullGroupDirectories(outputResolution);
string dFacesContentDirectory = Path.Combine(dResultsFullGroupDirectory, _Configuration.PropertyConfiguration.ResultContent);
string d2FacePartsContentDirectory = Path.Combine(d2ResultsFullGroupDirectory, _Configuration.PropertyConfiguration.ResultContent);
string d2FacePartsContentCollectionDirectory = Path.Combine(d2ResultsFullGroupDirectory, "[()]");
string d2FacePartsContentCollectionDirectory = Path.Combine(d2ResultsFullGroupDirectory, _Configuration.PropertyConfiguration.ResultContentCollection);
if (distinctValidImageMappingCollection.Count > 0)
{
Shared.Models.Stateless.Methods.IPath.ChangeDateForEmptyDirectories(d2FacePartsContentDirectory, ticks);
@ -994,11 +1018,10 @@ public partial class DlibDotNet : IDlibDotNet, IDisposable
MappingFromFilterPre mappingFromFilterPre;
MappingFromFilterPost mappingFromFilterPost;
bool? isFocusModel = GetIsFocusModel(item.Property);
ReadOnlyDictionary<int, ReadOnlyCollection<PersonContainer>>? wholePercentagesToPersonContainers = mapLogic.GetWholePercentagesToPersonContainers(item.Property?.Id);
long[] jLinkResolvedPersonKeys = _JLinkResolvedDirectories.Select(l => l.PersonKey).ToArray();
ReadOnlyDictionary<int, ReadOnlyCollection<PersonContainer>>? wholePercentagesToPersonContainers;
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)
{
canReMap = null;
@ -1028,7 +1051,7 @@ public partial class DlibDotNet : IDlibDotNet, IDisposable
isFocusPerson = mapLogic.IsFocusPerson(_Configuration.SkipPersonWithMoreThen, jLinkResolvedPersonKeys, wholePercentagesToPersonContainers, mappingFromLocation);
mappingFromFilterPost = new(canReMap, inSkipCollection, isFocusPerson);
}
mapping = new(item.FilePath, mappingFromFilterPost, mappingFromFilterPre, mappingFromItem, mappingFromLocation, mappingFromPhotoPrismCollection);
mapping = Mapping.Get(item.FilePath, mappingFromFilterPost, mappingFromFilterPre, mappingFromItem, mappingFromLocation, mappingFromPhotoPrismCollection);
notMapped += mapLogic.UpdateMappingFromPerson(wholePercentagesToPersonContainers, mapping);
face.SetMapping(mapping);
}
@ -1079,16 +1102,16 @@ public partial class DlibDotNet : IDlibDotNet, IDisposable
int faceAreaPermyriad = 0;
bool? isFocusModel = GetIsFocusModel(item.Property);
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);
string deterministicHashCodeKey = IMapping.GetDeterministicHashCodeKey(item.FilePath, Shared.Models.Stateless.ILocation.Digits);
MappingFromLocation? mappingFromLocation = new(faceAreaPermyriad, confidencePercent, deterministicHashCodeKey, eyeα, eyeReview, wholePercentRectangle);
bool? inSkipCollection = mapLogic.InSkipCollection(mappingFromItem.Id, mappingFromLocation);
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? isFocusPerson = mapLogic.IsFocusPerson(_Configuration.SkipPersonWithMoreThen, jLinkResolvedPersonKeys, wholePercentagesToPersonContainers, mappingFromLocation);
MappingFromFilterPost mappingFromFilterPost = new(canReMap, inSkipCollection, isFocusPerson);
result = new(item.FilePath, mappingFromFilterPost, mappingFromFilterPre, mappingFromItem, mappingFromLocation, mappingFromPhotoPrismCollection: null);
result = Mapping.Get(item.FilePath, mappingFromFilterPost, mappingFromFilterPre, mappingFromItem, mappingFromLocation, mappingFromPhotoPrismCollection: null);
int notMapped = mapLogic.UpdateMappingFromPerson(wholePercentagesToPersonContainers, result);
return (result, notMapped);
}
@ -1099,7 +1122,6 @@ public partial class DlibDotNet : IDlibDotNet, IDisposable
string outputResolution,
bool outputResolutionHasNumber,
string cResultsFullGroupDirectory,
string dResultsFullGroupDirectory,
string d2ResultsFullGroupDirectory,
List<Tuple<string, DateTime>> sourceDirectoryChanges,
Dictionary<int, List<MappingFromPhotoPrism>> fileNameToCollection,
@ -1107,8 +1129,7 @@ public partial class DlibDotNet : IDlibDotNet, IDisposable
int index,
Item item,
DateTime[] containerDateTimes,
bool? isFocusRelativePath,
string facePartsCollectionDirectory)
bool? isFocusRelativePath)
{
int result = 0;
List<Shared.Models.Face> faces;
@ -1166,7 +1187,7 @@ public partial class DlibDotNet : IDlibDotNet, IDisposable
}
if (resizedFileHolder.Exists && item.FilePath.HasIgnoreKeyword is not null && item.FilePath.HasIgnoreKeyword.Value != shouldIgnore.Value)
{
if (!item.FilePath.DirectoryName.Contains("Results") || !item.FilePath.DirectoryName.Contains("Resize"))
if (!item.FilePath.DirectoryFullPath.Contains("Results") || !item.FilePath.DirectoryFullPath.Contains("Resize"))
throw new NotSupportedException($"Rename File! <{item.FilePath.FileNameFirstSegment}>");
else
{
@ -1219,11 +1240,9 @@ public partial class DlibDotNet : IDlibDotNet, IDisposable
if (!fileNameToCollection.TryGetValue(mappingFromItem.Id, out mappingFromPhotoPrismCollection))
mappingFromPhotoPrismCollection = null;
bool move = _Configuration.DistanceMoveUnableToMatch || _Configuration.DistanceRenameToMatch && _Configuration.LoadOrCreateThenSaveDistanceResultsForOutputResolutions.Contains(outputResolution);
faces = _Faces.GetFaces(outputResolution, cResultsFullGroupDirectory, dResultsFullGroupDirectory, item.FilePath, subFileTuples, parseExceptions, property, mappingFromItem, outputResolutionToResize, mappingFromPhotoPrismCollection);
faces = _Faces.GetFaces(outputResolution, cResultsFullGroupDirectory, item.FilePath, subFileTuples, parseExceptions, property, mappingFromItem, outputResolutionToResize, mappingFromPhotoPrismCollection);
result = GetNotMappedCountAndUpdateMappingFromPersonThenSetMapping(mapLogic, item, isFocusRelativePath, mappingFromItem, mappingFromPhotoPrismCollection, faces);
List<(Shared.Models.Face, FileHolder?, string, bool Saved)> faceCollection = _Faces.SaveFaces(_FaceParts.FileNameExtension, dResultsFullGroupDirectory, item.FilePath, subFileTuples, parseExceptions, mappingFromItem, exifDirectory, faces);
if (_Configuration.CopyFacesAndSaveFaceLandmarkForOutputResolutions.Contains(outputResolution))
_FaceParts.CopyFacesAndSaveFaceLandmarkImage(facePartsCollectionDirectory, mappingFromItem, faceCollection);
List<(Shared.Models.Face, FileHolder?, string, bool Saved)> faceCollection = _Faces.SaveFaces(item.FilePath, subFileTuples, parseExceptions, mappingFromItem, exifDirectory, faces);
if (move && faceCollection.All(l => !l.Saved))
{
ReadOnlyCollection<LocationContainer> locationContainers = mapLogic.GetLocationContainers(item);
@ -1240,8 +1259,10 @@ public partial class DlibDotNet : IDlibDotNet, IDisposable
{
bool saveRotated = false;
string sourceDirectorySegment = Property.Models.Stateless.IResult.GetRelativePath(_Configuration.PropertyConfiguration, container.SourceDirectory);
_FaceParts.SaveFaceLandmarkImages(_Configuration.PropertyConfiguration, item.FilePath, subFileTuples, parseExceptions, mappingFromItem, faces, saveRotated);
_FaceParts.SaveFaceLandmarkImages(_Configuration.PropertyConfiguration, d2ResultsFullGroupDirectory, item.FilePath, subFileTuples, parseExceptions, mappingFromItem, exifDirectory, faces, saveRotated);
}
if (_Configuration.SaveFaceLandmarkForOutputResolutionsV2.Contains(outputResolution))
_FaceParts.SaveFaceLandmarkImages(d2ResultsFullGroupDirectory, mappingFromItem, exifDirectory, faces);
}
lock (sourceDirectoryChanges)
{
@ -1258,7 +1279,6 @@ public partial class DlibDotNet : IDlibDotNet, IDisposable
string outputResolution,
bool outputResolutionHasNumber,
string cResultsFullGroupDirectory,
string dResultsFullGroupDirectory,
string d2ResultsFullGroupDirectory,
List<Tuple<string, DateTime>> sourceDirectoryChanges,
Dictionary<int, List<MappingFromPhotoPrism>> fileNameToCollection,
@ -1273,7 +1293,6 @@ public partial class DlibDotNet : IDlibDotNet, IDisposable
ProgressBarOptions options = new() { ProgressCharacter = '─', ProgressBarOnBottom = true, DisableBottomPercentage = true };
string focusRelativePath = Path.GetFullPath(string.Concat(_Configuration.PropertyConfiguration.RootDirectory, _Configuration.FocusDirectory));
bool? isFocusRelativePath = string.IsNullOrEmpty(_Configuration.FocusDirectory) ? null : container.SourceDirectory.StartsWith(focusRelativePath);
string facePartsCollectionDirectory = _Configuration.CopyFacesAndSaveFaceLandmarkForOutputResolutions.Contains(outputResolution) ? _FaceParts.GetFacePartsDirectory(_Configuration.PropertyConfiguration, d2ResultsFullGroupDirectory, item: filteredItems.First(), includeNameWithoutExtension: false) : string.Empty;
bool anyPropertiesChangedForX = _Configuration.PropertyConfiguration.PropertiesChangedForProperty || _Configuration.PropertiesChangedForDistance || _Configuration.PropertiesChangedForFaces || _Configuration.PropertiesChangedForIndex || _Configuration.PropertiesChangedForMetadata || _Configuration.PropertiesChangedForResize;
using ProgressBar progressBar = new(filteredItems.Count, message, options);
_ = Parallel.For(0, filteredItems.Count, parallelOptions, (i, state) =>
@ -1286,7 +1305,6 @@ public partial class DlibDotNet : IDlibDotNet, IDisposable
outputResolution,
outputResolutionHasNumber,
cResultsFullGroupDirectory,
dResultsFullGroupDirectory,
d2ResultsFullGroupDirectory,
sourceDirectoryChanges,
fileNameToCollection,
@ -1294,8 +1312,7 @@ public partial class DlibDotNet : IDlibDotNet, IDisposable
index: i,
filteredItems[i],
containerDateTimes,
isFocusRelativePath,
facePartsCollectionDirectory);
isFocusRelativePath);
if (!anyPropertiesChangedForX && (i == 0 || sourceDirectoryChanges.Count > 0))
progressBar.Tick();
}
@ -1368,7 +1385,7 @@ public partial class DlibDotNet : IDlibDotNet, IDisposable
ReadOnlyCollection<SortingContainer> sortingContainers;
FaceDistanceContainer[] filteredFaceDistanceContainers;
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.RangeFaceAreaPermyriadTolerance, _Configuration.RangeFaceConfidence, _Configuration.SortingMaximumPerFaceShouldBeHigh);
distanceLimits = new(_Configuration.FaceAreaPermyriad, _Configuration.FaceConfidencePercent, _Configuration.FaceDistancePermyriad, _Configuration.RangeDaysDeltaTolerance, _Configuration.RangeDistanceTolerance, _Configuration.RangeFaceAreaTolerance, _Configuration.RangeFaceConfidence, _Configuration.SortingMaximumPerFaceShouldBeHigh);
filteredFaceDistanceContainers = E_Distance.FilteredPostLoadFaceDistanceContainers(mapLogic, faceDistanceContainers, skipOlderThan, distanceLimits);
if (filteredFaceDistanceContainers.Length == 0)
_Logger?.LogInformation("All images have been filtered!");
@ -1379,7 +1396,7 @@ public partial class DlibDotNet : IDlibDotNet, IDisposable
{
for (useFiltersCounter = 1; useFiltersCounter < _Configuration.UseFilterTries; useFiltersCounter++)
{
distanceLimits = new(_Configuration.FaceAreaPermyriad, _Configuration.FaceConfidencePercent, _Configuration.FaceDistancePermyriad, _Configuration.RangeDaysDeltaTolerance, _Configuration.RangeDistanceTolerance, _Configuration.RangeFaceAreaPermyriadTolerance, _Configuration.RangeFaceConfidence, _Configuration.SortingMaximumPerFaceShouldBeHigh, useFiltersCounter);
distanceLimits = new(_Configuration.FaceAreaPermyriad, _Configuration.FaceConfidencePercent, _Configuration.FaceDistancePermyriad, _Configuration.RangeDaysDeltaTolerance, _Configuration.RangeDistanceTolerance, _Configuration.RangeFaceAreaTolerance, _Configuration.RangeFaceConfidence, _Configuration.SortingMaximumPerFaceShouldBeHigh, useFiltersCounter);
filteredFaceDistanceContainers = E_Distance.FilteredPostLoadFaceDistanceContainers(mapLogic, faceDistanceContainers, skipOlderThan, distanceLimits);
if (filteredFaceDistanceContainers.Length == 0)
_Logger?.LogInformation("All images have been filtered!");
@ -1474,13 +1491,13 @@ public partial class DlibDotNet : IDlibDotNet, IDisposable
ProgressBar progressBar;
string filesCollectionRootDirectory = _Configuration.PropertyConfiguration.RootDirectory;
(string cResultsFullGroupDirectory, _, _, _) = GetResultsFullGroupDirectories(outputResolution);
IReadOnlyDictionary<string, string[]> fileGroups = Shared.Models.Stateless.Methods.IPath.GetKeyValuePairs(_Configuration.PropertyConfiguration, cResultsFullGroupDirectory, [_Configuration.PropertyConfiguration.ResultContent]);
ReadOnlyCollection<ReadOnlyCollection<FilePath>> filePathsCollection = IDirectory.GetFilePathCollections(_Configuration.PropertyConfiguration, filesCollectionRootDirectory, directorySearchFilter, fileSearchFilter, useCeilingAverage: false);
IReadOnlyDictionary<string, ReadOnlyCollection<string>> fileGroups = Shared.Models.Stateless.Methods.IPath.GetKeyValuePairs(_Configuration.PropertyConfiguration, cResultsFullGroupDirectory, [_Configuration.PropertyConfiguration.ResultContent, _Configuration.PropertyConfiguration.ResultContentCollection]);
ReadOnlyCollection<ReadOnlyCollection<FilePath>> filePathsCollection = IDirectory.GetFilePathCollections(_Configuration.PropertyConfiguration, directorySearchFilter, fileSearchFilter, filesCollectionRootDirectory, useCeilingAverage: false);
int count = filePathsCollection.Select(l => l.Count).Sum();
bool filesCollectionCountIsOne = IsFilesCollectionCountIsOne(filePathsCollection);
string message = $") Selecting for ## pattern directory - {(int)Math.Floor(new TimeSpan(DateTime.Now.Ticks - ticks).TotalSeconds)} total second(s)";
progressBar = new(count, message, options);
(string[] distinctDirectories, List<(FilePath, string)> toDoCollection) = IDirectory.GetToDoCollection(_Configuration.PropertyConfiguration, filePathsCollection, fileGroups[_Configuration.PropertyConfiguration.ResultContent], () => progressBar.Tick());
(string[] distinctDirectories, List<(FilePath, string)> toDoCollection) = IDirectory.GetToDoCollection(_Configuration.PropertyConfiguration, filePathsCollection, fileGroups, () => progressBar.Tick());
progressBar.Dispose();
foreach (string distinctDirectory in distinctDirectories)
{

View File

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

View File

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

View File

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

View File

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

View File

@ -4,12 +4,12 @@
<Nullable>enable</Nullable>
<OutputType>library</OutputType>
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
<TargetFramework>net8.0</TargetFramework>
<TargetFramework>net9.0</TargetFramework>
</PropertyGroup>
<PropertyGroup>
<PackageId>Phares.View.by.Distance.Map</PackageId>
<GeneratePackageOnBuild>false</GeneratePackageOnBuild>
<Version>8.0.101.1</Version>
<Version>9.0.100.1</Version>
<Authors>Mike Phares</Authors>
<Company>Phares</Company>
<IncludeSymbols>true</IncludeSymbols>
@ -37,7 +37,7 @@
<PackageReference Include="MetadataExtractor" Version="2.8.1" />
<PackageReference Include="ShellProgressBar" Version="5.2.0" />
<PackageReference Include="WindowsShortcutFactory" Version="1.2.0" />
<PackageReference Include="System.Text.Json" Version="8.0.4" />
<PackageReference Include="System.Text.Json" Version="9.0.0" />
</ItemGroup>
<ItemGroup>
<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}");
fileName = Path.Combine(directory, $"{mapping.MappingFromItem.FilePath.Name}.lnk");
results.Add(new(mapping.MappingFromItem.FilePath.FullName, directory, dateTime, fileName, description, MakeAllHidden: false));
if (mapping.MappingFromItem.FilePath.DirectoryName is null)
if (mapping.MappingFromItem.FilePath.DirectoryFullPath is null)
continue;
directoryName = Path.GetFileName(mapping.MappingFromItem.FilePath.DirectoryName);
directoryName = Path.GetFileName(mapping.MappingFromItem.FilePath.DirectoryFullPath);
if (!string.IsNullOrEmpty(mapping.MappingFromItem.Model) && !string.IsNullOrEmpty(mapping.MappingFromItem.Model.Trim()))
{
// Remove-Item -LiteralPath "\\?\D:\Tmp\a\EX-Z70 "
@ -264,7 +264,7 @@ public partial class MapLogic : Shared.Models.Methods.IMapLogic
{
List<string> personKeyFormattedCollection = [];
Dictionary<string, string> personKeyFormattedToNewestPersonKeyFormatted = [];
Stateless.MapLogic.SetPersonCollections(configuration, personContainers, personKeyFormattedToNewestPersonKeyFormatted, personKeyFormattedCollection);
Stateless.MapLogic.SetPersonCollectionsAfterSetSkipCollections(configuration, personContainers, personKeyFormattedToNewestPersonKeyFormatted, personKeyFormattedCollection);
readOnlyPersonKeyFormattedCollection = new(personKeyFormattedCollection);
readOnlyPersonKeyFormattedToNewestPersonKeyFormatted = new(personKeyFormattedToNewestPersonKeyFormatted);
}
@ -359,12 +359,6 @@ public partial class MapLogic : Shared.Models.Methods.IMapLogic
return new(results);
}
public ReadOnlyDictionary<long, PersonContainer> GetPersonKeyToPersonContainer()
{
Dictionary<long, PersonContainer> results = [];
return new(results);
}
public ReadOnlyDictionary<long, List<int>> GetPersonKeyToIds()
{
Dictionary<long, List<int>> results = [];
@ -900,7 +894,7 @@ public partial class MapLogic : Shared.Models.Methods.IMapLogic
continue;
}
results.Add(new(record.PersonDirectory));
facesDirectory = locationContainer.LengthSource.DirectoryName;
facesDirectory = locationContainer.LengthSource.DirectoryFullPath;
faceFileHolder = IFileHolder.Get(locationContainer.LengthSource.FullName);
checkFile = Path.Combine(directory, $"{locationContainer.LengthSource.Name}");
shortcutFile = Path.Combine(record.PersonDirectory, $"{locationContainer.LengthSource.Name}.lnk");
@ -1265,6 +1259,7 @@ public partial class MapLogic : Shared.Models.Methods.IMapLogic
{
if (_Configuration is null)
throw new NullReferenceException(nameof(_Configuration));
int? updated = null;
FileHolder fileHolder;
SaveContainer? saveContainer;
List<SaveContainer> saveContainers = [];
@ -1277,7 +1272,7 @@ public partial class MapLogic : Shared.Models.Methods.IMapLogic
saveContainer = new(fileHolder, filteredOriginalImage.CheckFile, filteredOriginalImage.Directory);
saveContainers.Add(saveContainer);
}
SaveContainers(null, saveContainers);
SaveContainers(updated, saveContainers);
}
public void SaveShortcutsForOutputResolutionsPreMapLogic(string eDistanceContentDirectory, ReadOnlyDictionary<long, List<int>> personKeyToIds, ReadOnlyCollection<Mapping> distinctValidImageMappingCollection)
@ -1348,16 +1343,16 @@ public partial class MapLogic : Shared.Models.Methods.IMapLogic
directoryName = Path.GetDirectoryName(face.Mapping.MappingFromItem.RelativePath);
if (directoryName is null)
throw new NotSupportedException();
if (item.ResizedFileHolder?.DirectoryName is null || !item.ResizedFileHolder.Exists)
if (item.ResizedFileHolder?.DirectoryFullPath is null || !item.ResizedFileHolder.Exists)
continue;
directory = Path.Combine(item.ResizedFileHolder.DirectoryName, $"{_PropertyConfiguration.ResultAllInOne}Shortcuts", _PropertyConfiguration.ResultAllInOne);
directory = Path.Combine(item.ResizedFileHolder.DirectoryFullPath, $"{_PropertyConfiguration.ResultAllInOne}Shortcuts", _PropertyConfiguration.ResultAllInOne);
personDirectory = Path.Combine(directory, "No Faces");
fileName = Path.Combine(personDirectory, $"{item.ResizedFileHolder.Name}.lnk");
collection.Add(new(item.ResizedFileHolder.FullName, personDirectory, new(item.FilePath.LastWriteTicks), fileName, face.Mapping.MappingFromItem.Id.ToString(), MakeAllHidden: false));
if (face.Mapping.MappingFromItem.ContainerDateTimes.Length > 0 && !distinct.Contains(item.ResizedFileHolder.DirectoryName))
if (face.Mapping.MappingFromItem.ContainerDateTimes.Length > 0 && !distinct.Contains(item.ResizedFileHolder.DirectoryFullPath))
{
distinct.Add(item.ResizedFileHolder.DirectoryName);
directoriesAndDateTimes.Add(new(item.ResizedFileHolder.DirectoryName, face.Mapping.MappingFromItem.ContainerDateTimes));
distinct.Add(item.ResizedFileHolder.DirectoryFullPath);
directoriesAndDateTimes.Add(new(item.ResizedFileHolder.DirectoryFullPath, face.Mapping.MappingFromItem.ContainerDateTimes));
}
}
}
@ -1366,17 +1361,17 @@ public partial class MapLogic : Shared.Models.Methods.IMapLogic
directoryName = Path.GetDirectoryName(mapping.MappingFromItem.RelativePath);
if (directoryName is null)
throw new NotSupportedException();
if (mapping.MappingFromItem.ResizedFileHolder.DirectoryName is null || !mapping.MappingFromItem.ResizedFileHolder.Exists)
if (mapping.MappingFromItem.ResizedFileHolder.DirectoryFullPath is null || !mapping.MappingFromItem.ResizedFileHolder.Exists)
continue;
dateTime = mapping.MappingFromItem.GetDateTimeOriginalThenMinimumDateTime();
if (mapping.By is null or Shared.Models.Stateless.IMapLogic.Sorting || mapping.MappingFromPerson?.ApproximateYears is null)
{
if (mapping.MappingFromItem.ContainerDateTimes.Length > 0 && !distinct.Contains(mapping.MappingFromItem.ResizedFileHolder.DirectoryName))
if (mapping.MappingFromItem.ContainerDateTimes.Length > 0 && !distinct.Contains(mapping.MappingFromItem.ResizedFileHolder.DirectoryFullPath))
{
distinct.Add(mapping.MappingFromItem.ResizedFileHolder.DirectoryName);
directoriesAndDateTimes.Add(new(mapping.MappingFromItem.ResizedFileHolder.DirectoryName, mapping.MappingFromItem.ContainerDateTimes));
distinct.Add(mapping.MappingFromItem.ResizedFileHolder.DirectoryFullPath);
directoriesAndDateTimes.Add(new(mapping.MappingFromItem.ResizedFileHolder.DirectoryFullPath, mapping.MappingFromItem.ContainerDateTimes));
}
directory = Path.Combine(mapping.MappingFromItem.ResizedFileHolder.DirectoryName, $"{_PropertyConfiguration.ResultAllInOne}Shortcuts", _PropertyConfiguration.ResultAllInOne);
directory = Path.Combine(mapping.MappingFromItem.ResizedFileHolder.DirectoryFullPath, $"{_PropertyConfiguration.ResultAllInOne}Shortcuts", _PropertyConfiguration.ResultAllInOne);
personDirectory = Path.Combine(directory, "Unknown");
fileName = Path.Combine(personDirectory, $"{mapping.MappingFromItem.ResizedFileHolder.Name}.lnk");
collection.Add(new(mapping.MappingFromItem.ResizedFileHolder.FullName, personDirectory, dateTime, fileName, mapping.MappingFromLocation?.DeterministicHashCodeKey, MakeAllHidden: false));
@ -1394,12 +1389,12 @@ public partial class MapLogic : Shared.Models.Methods.IMapLogic
if (string.IsNullOrEmpty(mapping.MappingFromPerson.DisplayDirectoryName))
throw new NotSupportedException();
personKeyFormatted = IPersonBirthday.GetFormatted(_Configuration.PersonBirthdayFormat, mapping.MappingFromPerson.PersonKey);
if (mapping.MappingFromItem.ContainerDateTimes.Length > 0 && !distinct.Contains(mapping.MappingFromItem.ResizedFileHolder.DirectoryName))
if (mapping.MappingFromItem.ContainerDateTimes.Length > 0 && !distinct.Contains(mapping.MappingFromItem.ResizedFileHolder.DirectoryFullPath))
{
distinct.Add(mapping.MappingFromItem.ResizedFileHolder.DirectoryName);
directoriesAndDateTimes.Add(new(mapping.MappingFromItem.ResizedFileHolder.DirectoryName, mapping.MappingFromItem.ContainerDateTimes));
distinct.Add(mapping.MappingFromItem.ResizedFileHolder.DirectoryFullPath);
directoriesAndDateTimes.Add(new(mapping.MappingFromItem.ResizedFileHolder.DirectoryFullPath, mapping.MappingFromItem.ContainerDateTimes));
}
directory = Path.Combine(mapping.MappingFromItem.ResizedFileHolder.DirectoryName, $"{_PropertyConfiguration.ResultAllInOne}Shortcuts", personKeyFormatted);
directory = Path.Combine(mapping.MappingFromItem.ResizedFileHolder.DirectoryFullPath, $"{_PropertyConfiguration.ResultAllInOne}Shortcuts", personKeyFormatted);
if (!personKeyToIds.TryGetValue(mapping.MappingFromPerson.PersonKey, out ids))
personDirectory = Path.Combine(directory, mapping.MappingFromPerson.DisplayDirectoryName);
else

View File

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

View File

@ -64,21 +64,22 @@ internal abstract class FaceFileLogic
exifDirectory = Metadata.Models.Stateless.Methods.IMetadata.GetExifDirectory(mappedFile.FilePath);
RectangleF? rectangle = ILocation.GetPercentagesRectangle(configuration.LocationDigits, wholePercentages.Value);
personDisplayDirectoryName = mappedFile.PersonDisplayDirectoryName is null ? configuration.MappingDefaultName : mappedFile.PersonDisplayDirectoryName;
LocationContainer locationContainer = new(dateOnly,
exifDirectory,
mappedFile.DirectoryNumber,
personDisplayDirectoryName,
null,
null,
mappedFile.FilePath,
fromDistanceContent,
id.Value,
null,
null,
mappedFile.PersonKey,
rectangle,
wholePercentages.Value);
lock (locationContainers)
locationContainers.Add(new(dateOnly,
exifDirectory,
mappedFile.DirectoryNumber,
personDisplayDirectoryName,
null,
null,
mappedFile.FilePath,
fromDistanceContent,
id.Value,
null,
null,
mappedFile.PersonKey,
rectangle,
wholePercentages.Value));
locationContainers.Add(locationContainer);
}
private static ReadOnlyDictionary<int, ReadOnlyDictionary<int, LocationContainer>> GetReadOnly(Dictionary<int, Dictionary<int, LocationContainer>> keyValuePairs)
@ -93,33 +94,26 @@ internal abstract class FaceFileLogic
{
Dictionary<int, Dictionary<int, LocationContainer>> results = [];
List<LocationContainer> locationContainers = [];
List<string> personKeyFormattedCollection = [];
Dictionary<int, LocationContainer>? keyValuePairs;
Dictionary<int, List<(string, int)>> skipCollection = [];
Dictionary<int, List<(string, int)>> skipNotSkipCollection = [];
ReadOnlyCollection<string> readOnlyPersonKeyFormattedCollection;
ReadOnlyDictionary<string, string> readOnlyPersonKeyFormattedToNewestPersonKeyFormatted;
Dictionary<string, string> personKeyFormattedToNewestPersonKeyFormatted = [];
SetSkipCollections(configuration, personContainers, a2PeopleSingletonDirectory, skipCollection, skipNotSkipCollection);
{
List<string> personKeyFormattedCollection = [];
Dictionary<string, string> personKeyFormattedToNewestPersonKeyFormatted = [];
SetPersonCollections(configuration, personContainers, personKeyFormattedToNewestPersonKeyFormatted, personKeyFormattedCollection);
readOnlyPersonKeyFormattedCollection = new(personKeyFormattedCollection);
readOnlyPersonKeyFormattedToNewestPersonKeyFormatted = new(personKeyFormattedToNewestPersonKeyFormatted);
}
List<Record> records = DistanceLogic.DeleteEmptyDirectoriesAndGetCollection(propertyConfiguration, configuration, ticks, eDistanceContentDirectory, readOnlyPersonKeyFormattedToNewestPersonKeyFormatted, readOnlyPersonKeyFormattedCollection);
SetPersonCollectionsAfterSetSkipCollections(configuration, personContainers, personKeyFormattedToNewestPersonKeyFormatted, personKeyFormattedCollection);
List<Record> records = DistanceLogic.DeleteEmptyDirectoriesAndGetCollection(propertyConfiguration, configuration, ticks, eDistanceContentDirectory, personKeyFormattedToNewestPersonKeyFormatted.AsReadOnly(), personKeyFormattedCollection.AsReadOnly());
List<MappedFile> mappedFiles = GetMappedFiles(propertyConfiguration, configuration, personContainers, records);
if (mappedFiles.Count > 0)
{
int totalSeconds = (int)Math.Floor(new TimeSpan(DateTime.Now.Ticks - ticks).TotalSeconds);
string message = $") Building Mapped Face Files Collection - {totalSeconds} total second(s)";
ParallelOptions parallelOptions = new() { MaxDegreeOfParallelism = maxDegreeOfParallelism };
ReadOnlyDictionary<int, List<(string, int)>> readOnlySkipNotSkipCollection = new(skipCollection);
ProgressBarOptions options = new() { ProgressCharacter = '─', ProgressBarOnBottom = true, DisableBottomPercentage = true };
using ProgressBar progressBar = new(mappedFiles.Count, message, options);
_ = Parallel.For(0, mappedFiles.Count, parallelOptions, (i, state) =>
{
progressBar.Tick();
MappedParallelFor(propertyConfiguration, configuration, readOnlySkipNotSkipCollection, locationContainers, mappedFiles[i]);
MappedParallelFor(propertyConfiguration, configuration, skipCollection.AsReadOnly(), locationContainers, mappedFiles[i]);
});
}
foreach (LocationContainer locationContainer in locationContainers)
@ -176,21 +170,22 @@ internal abstract class FaceFileLogic
RectangleF? rectangle = ILocation.GetPercentagesRectangle(configuration.LocationDigits, wholePercentages.Value);
if (rectangle is null)
return;
LocationContainer locationContainer = new(dateOnly,
exifDirectory,
null,
null,
null,
faceFile,
filePath,
fromDistanceContent,
filePath.Id.Value,
null,
null,
null,
rectangle,
wholePercentages.Value);
lock (locationContainers)
locationContainers.Add(new(dateOnly,
exifDirectory,
null,
null,
null,
faceFile,
filePath,
fromDistanceContent,
filePath.Id.Value,
null,
null,
null,
rectangle,
wholePercentages.Value));
locationContainers.Add(locationContainer);
}
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 SetPersonCollections(Configuration configuration, ReadOnlyCollection<PersonContainer> personContainers, Dictionary<string, string> personKeyFormattedToNewestPersonKeyFormatted, List<string> personKeyFormattedCollection)
internal static void SetPersonCollectionsAfterSetSkipCollections(Configuration configuration, ReadOnlyCollection<PersonContainer> personContainers, Dictionary<string, string> personKeyFormattedToNewestPersonKeyFormatted, List<string> personKeyFormattedCollection)
{
string personKeyFormatted;
string newestPersonKeyFormatted;
@ -215,21 +215,21 @@ internal abstract class MapLogic
{
if (duplicate.Percent is null)
continue;
_ = Process.Start("explorer.exe", string.Concat("\"", duplicate.FilePath.DirectoryName, "\""));
_ = Process.Start("explorer.exe", string.Concat("\"", duplicate.FilePath.DirectoryFullPath, "\""));
personKeyFormatted = IPersonBirthday.GetFormatted(configuration.PersonBirthdayFormat, duplicate.PersonKey);
}
foreach ((long personKey, int id, FilePath filePath, float? percent) in duplicates)
{
if (percent is not null && percent.Value == 0)
continue;
_ = Process.Start("explorer.exe", string.Concat("\"", filePath.DirectoryName, "\""));
_ = Process.Start("explorer.exe", string.Concat("\"", filePath.DirectoryFullPath, "\""));
personKeyFormatted = IPersonBirthday.GetFormatted(configuration.PersonBirthdayFormat, personKey);
}
foreach ((long personKey, int id, FilePath filePath, float? percent) in duplicates)
{
if (percent is not null && percent.Value > 0)
continue;
_ = Process.Start("explorer.exe", string.Concat("\"", filePath.DirectoryName, "\""));
_ = Process.Start("explorer.exe", string.Concat("\"", filePath.DirectoryFullPath, "\""));
personKeyFormatted = IPersonBirthday.GetFormatted(configuration.PersonBirthdayFormat, personKey);
}
}
@ -418,7 +418,7 @@ internal abstract class MapLogic
if (check)
continue;
personBirthday = IPersonBirthday.GetPersonBirthday(personKey + (oneHour * 2));
personContainer = new(approximateYears, [personBirthday], new(personDisplayDirectoryAllFilePaths), configuration.MappingDefaultName, personKey);
personContainer = PersonContainer.Get(approximateYears, [personBirthday], new(personDisplayDirectoryAllFilePaths), configuration.MappingDefaultName, personKey);
results.Add(personContainer);
if (results.Count > 99)
break;
@ -447,6 +447,9 @@ internal abstract class MapLogic
FileHolder fileHolder;
List<string> distinct = [];
PersonBirthday? personBirthday;
PersonContainer? personContainer;
string? personDisplayDirectoryName;
ReadOnlyDictionary<long, PersonContainer> keyValuePairs = PersonContainer.Extract(personContainers);
results.AddRange(GetDisplayDirectoryAllFiles(configuration.FacesFileNameExtension, configuration.PersonBirthdayFormat, personContainers));
foreach (Record record in records)
{
@ -455,9 +458,13 @@ internal abstract class MapLogic
continue;
if (distinct.Contains(record.MappedFaceFilePath.Name))
continue;
distinct.Add(record.MappedFaceFilePath.Name);
personKey = personBirthday.Value.Ticks;
results.Add(new(personKey, record.PersonKeyFormatted, record.PersonDisplayDirectoryName, record.DirectoryNumber, record.MappedFaceFilePath));
distinct.Add(record.MappedFaceFilePath.Name);
if (!keyValuePairs.TryGetValue(personKey, out personContainer))
personDisplayDirectoryName = record.PersonDisplayDirectoryName;
else
personDisplayDirectoryName = personContainer.DisplayDirectoryName;
results.Add(new(personKey, record.PersonKeyFormatted, personDisplayDirectoryName, record.DirectoryNumber, record.MappedFaceFilePath));
}
for (int i = results.Count - 1; i > -1; i--)
{
@ -535,21 +542,22 @@ internal abstract class MapLogic
exifDirectory = Metadata.Models.Stateless.Methods.IMetadata.GetExifDirectory(mappedFile.FilePath);
RectangleF? rectangle = ILocation.GetPercentagesRectangle(configuration.LocationDigits, wholePercentages.Value);
personDisplayDirectoryName = mappedFile.PersonDisplayDirectoryName is null ? configuration.MappingDefaultName : mappedFile.PersonDisplayDirectoryName;
LocationContainer locationContainer = new(dateOnly,
exifDirectory,
mappedFile.DirectoryNumber,
personDisplayDirectoryName,
null,
null,
mappedFile.FilePath,
fromDistanceContent,
id.Value,
null,
null,
mappedFile.PersonKey,
rectangle,
wholePercentages.Value);
lock (locationContainers)
locationContainers.Add(new(dateOnly,
exifDirectory,
mappedFile.DirectoryNumber,
personDisplayDirectoryName,
null,
null,
mappedFile.FilePath,
fromDistanceContent,
id.Value,
null,
null,
mappedFile.PersonKey,
rectangle,
wholePercentages.Value));
locationContainers.Add(locationContainer);
}
private static void LookForPossibleDuplicates(Configuration configuration, ReadOnlyCollection<LocationContainer> locationContainers)
@ -739,7 +747,7 @@ internal abstract class MapLogic
group = IPerson.GetHourGroup(personKeyFormattedIdThenWholePercentages.PersonDisplayDirectoryName, personBirthday.Value.Hour);
(status, sex, first) = IPerson.GetPersonHour(personKeyFormattedIdThenWholePercentages.PersonDisplayDirectoryName, personBirthday.Value.Hour);
personDirectory = new(matches.First(), group, status, sex, first);
personContainer = new(configuration.PersonCharacters.ToArray(), personBirthday, personDisplayDirectoryName, personDirectory);
personContainer = PersonContainer.Get(configuration.PersonCharacters.ToArray(), personBirthday, personDisplayDirectoryName, personDirectory);
personKeyFormattedToPersonContainer.Add(personKeyFormattedIdThenWholePercentages.PersonKeyFormatted, personContainer);
}
if (personContainer.Key is null)
@ -839,9 +847,9 @@ internal abstract class MapLogic
continue;
personBirthday = IPersonBirthday.GetPersonBirthday(keyValuePair.Key);
if (!personKeyToPersonContainerCollection.TryGetValue(keyValuePair.Key, out collection))
personContainer = new(approximateYears, personBirthday, displayDirectoryName, keyValuePair.Key);
personContainer = PersonContainer.Get(approximateYears, personBirthday, displayDirectoryName, keyValuePair.Key);
else
personContainer = new(approximateYears, personBirthday, collection[zero].PersonDirectory, displayDirectoryName, keyValuePair.Key);
personContainer = PersonContainer.Get(approximateYears, personBirthday, collection[zero].PersonDirectory, displayDirectoryName, keyValuePair.Key);
personKeyToPersonContainer.Add(keyValuePair.Key, personContainer);
}
}
@ -955,7 +963,7 @@ internal abstract class MapLogic
if (distinct.Contains(personContainer.DisplayDirectoryAllFilePaths[i].Name))
continue;
distinct.Add(personContainer.DisplayDirectoryAllFilePaths[i].Name);
directoryName = Path.GetFileName(personContainer.DisplayDirectoryAllFilePaths[i].DirectoryName);
directoryName = Path.GetFileName(personContainer.DisplayDirectoryAllFilePaths[i].DirectoryFullPath);
if (directoryName != personContainer.DisplayDirectoryName)
continue;
personBirthday = IPersonBirthday.GetPersonBirthday(personContainer.Key.Value);

View File

@ -104,7 +104,7 @@ internal abstract class RelationLogic
string? personKeyFormattedDirectory;
foreach ((FileHolder fileHolder, _) in relationContainers)
{
personNameDirectory = fileHolder.DirectoryName;
personNameDirectory = fileHolder.DirectoryFullPath;
yearDirectory = Path.GetDirectoryName(personNameDirectory);
personNameDirectoryName = Path.GetFileName(personNameDirectory);
personKeyFormattedDirectory = Path.GetDirectoryName(yearDirectory);

View File

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

View File

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

View File

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

View File

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

View File

@ -16,8 +16,8 @@ public class B_Metadata : IMetadata<MetadataExtractor.Directory>
private readonly bool _PropertiesChangedForMetadata;
private readonly IPropertyConfiguration _PropertyConfiguration;
private readonly bool _ForceMetadataLastWriteTimeToCreationTime;
private readonly ReadOnlyDictionary<string, string[]> _FileGroups;
private readonly JsonSerializerOptions _WriteIndentedJsonSerializerOptions;
private readonly ReadOnlyDictionary<string, ReadOnlyCollection<string>> _FileGroups;
public B_Metadata(IPropertyConfiguration propertyConfiguration)
{

View File

@ -502,12 +502,12 @@ internal abstract class Exif
result = new(aviDirectories,
exifBaseDirectories,
fileMetadataDirectories,
filePath,
gifHeaderDirectories,
gpsDirectories,
size?.Height,
jpegDirectories,
makernoteDirectories,
filePath.Name,
photoshopDirectories,
pngDirectories,
quickTimeMovieHeaderDirectories,

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -216,6 +216,17 @@ public class OffsetDateTimeOriginal
{
TimeSpan timeSpan = new(targetDateTimeOriginal.Value.Ticks - badDateTimeOriginal.Value.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>
<OutputType>library</OutputType>
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
<TargetFramework>net8.0</TargetFramework>
<TargetFramework>net9.0</TargetFramework>
</PropertyGroup>
<PropertyGroup>
<PackageId>Phares.View.by.Distance.PhotoPrism</PackageId>
<GeneratePackageOnBuild>false</GeneratePackageOnBuild>
<Version>8.0.101.1</Version>
<Version>9.0.100.1</Version>
<Authors>Mike Phares</Authors>
<Company>Phares</Company>
<IncludeSymbols>true</IncludeSymbols>
@ -37,7 +37,7 @@
<PackageReference Include="MetadataExtractor" Version="2.8.1" />
<PackageReference Include="ShellProgressBar" Version="5.2.0" />
<PackageReference Include="WindowsShortcutFactory" Version="1.2.0" />
<PackageReference Include="System.Text.Json" Version="8.0.4" />
<PackageReference Include="System.Text.Json" Version="9.0.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Shared\View-by-Distance.Shared.csproj" />

View File

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

View File

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

View File

@ -22,7 +22,7 @@ public class A_Property
private readonly Configuration _Configuration;
private readonly List<string> _AngleBracketCollection;
private readonly IPropertyConfiguration _PropertyConfiguration;
private readonly ReadOnlyDictionary<string, string[]> _FileGroups;
private readonly ReadOnlyDictionary<string, ReadOnlyCollection<string>> _FileGroups;
public A_Property(int maxDegreeOfParallelism, Configuration propertyConfiguration, string outputExtension, bool reverse, string aResultsFullGroupDirectory)
{
@ -277,9 +277,9 @@ public class A_Property
bool angleBracketCollectionAny = _AngleBracketCollection.Count != 0;
if (!angleBracketCollectionAny)
{
if (item.FilePath.DirectoryName is null)
throw new NullReferenceException(nameof(item.FilePath.DirectoryName));
SetAngleBracketCollection(item.FilePath.DirectoryName, !item.IsUniqueFileName);
if (item.FilePath.DirectoryFullPath is null)
throw new NullReferenceException(nameof(item.FilePath.DirectoryFullPath));
SetAngleBracketCollection(item.FilePath.DirectoryFullPath, !item.IsUniqueFileName);
}
bool isIgnoreExtension = item.IsValidImageFormatExtension && _PropertyConfiguration.IgnoreExtensions.Contains(item.FilePath.ExtensionLowered);
result = GetImageProperty(metadata, item, sourceDirectoryFileTuples, parseExceptions, isIgnoreExtension);

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -37,10 +37,10 @@ public class C_Resize
private readonly int _OutputResolutionHeightIndex;
private readonly EncoderParameters _EncoderParameters;
private readonly int _OutputResolutionOrientationIndex;
private readonly Dictionary<string, string[]> _FileGroups;
private readonly bool _ForceResizeLastWriteTimeToCreationTime;
private readonly IPropertyConfiguration _PropertyConfiguration;
private readonly JsonSerializerOptions _WriteIndentedJsonSerializerOptions;
private readonly Dictionary<string, ReadOnlyCollection<string>> _FileGroups;
public C_Resize(IPropertyConfiguration propertyConfiguration, bool forceResizeLastWriteTimeToCreationTime, bool overrideForResizeImages, bool propertiesChangedForResize, string[] validResolutions, ImageCodecInfo imageCodecInfo, EncoderParameters encoderParameters, string filenameExtension)
{
@ -75,8 +75,8 @@ public class C_Resize
public void Update(string cResultsFullGroupDirectory)
{
_FileGroups.Clear();
ReadOnlyDictionary<string, string[]> keyValuePairs = Shared.Models.Stateless.Methods.IPath.GetKeyValuePairs(_PropertyConfiguration, cResultsFullGroupDirectory, [_PropertyConfiguration.ResultSingleton]);
foreach (KeyValuePair<string, string[]> keyValuePair in keyValuePairs)
ReadOnlyDictionary<string, ReadOnlyCollection<string>> keyValuePairs = Shared.Models.Stateless.Methods.IPath.GetKeyValuePairs(_PropertyConfiguration, cResultsFullGroupDirectory, [_PropertyConfiguration.ResultSingleton]);
foreach (KeyValuePair<string, ReadOnlyCollection<string>> keyValuePair in keyValuePairs)
_FileGroups.Add(keyValuePair.Key, keyValuePair.Value);
}
@ -94,11 +94,12 @@ public class C_Resize
#pragma warning disable CA1416
public static (ImageCodecInfo imageCodecInfo, EncoderParameters encoderParameters, string filenameExtension) GetGifLowQuality()
public static (ImageCodecInfo imageCodecInfo, EncoderParameters encoderParameters, string filenameExtension) GetJpegLowQuality()
{
(ImageCodecInfo, EncoderParameters, string) result;
ImageFormat imageFormat = ImageFormat.Gif;
ImageCodecInfo imageCodecInfo = (from l in ImageCodecInfo.GetImageEncoders() where l.FormatID == imageFormat.Guid select l).First();
ImageFormat imageFormat = ImageFormat.Jpeg;
ImageCodecInfo[] imageCodecInfoCollection = ImageCodecInfo.GetImageEncoders();
ImageCodecInfo imageCodecInfo = (from l in imageCodecInfoCollection where l.FormatID == imageFormat.Guid select l).First();
EncoderParameters encoderParameters = new(1);
encoderParameters.Param[0] = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, 75L);
if (string.IsNullOrEmpty(imageCodecInfo.FilenameExtension))
@ -111,7 +112,8 @@ public class C_Resize
{
(ImageCodecInfo, EncoderParameters, string) result;
ImageFormat imageFormat = ImageFormat.Png;
ImageCodecInfo imageCodecInfo = (from l in ImageCodecInfo.GetImageEncoders() where l.FormatID == imageFormat.Guid select l).First();
ImageCodecInfo[] imageCodecInfoCollection = ImageCodecInfo.GetImageEncoders();
ImageCodecInfo imageCodecInfo = (from l in imageCodecInfoCollection where l.FormatID == imageFormat.Guid select l).First();
EncoderParameters encoderParameters = new(1);
encoderParameters.Param[0] = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, 75L);
if (string.IsNullOrEmpty(imageCodecInfo.FilenameExtension))
@ -135,7 +137,8 @@ public class C_Resize
".tiff" => ImageFormat.Tiff,
_ => throw new Exception(),
};
ImageCodecInfo imageCodecInfo = (from l in ImageCodecInfo.GetImageEncoders() where l.FormatID == imageFormat.Guid select l).First();
ImageCodecInfo[] imageCodecInfoCollection = ImageCodecInfo.GetImageEncoders();
ImageCodecInfo imageCodecInfo = (from l in imageCodecInfoCollection where l.FormatID == imageFormat.Guid select l).First();
EncoderParameters encoderParameters = new(1);
// encoderParameters.Param[0] = New EncoderParameter(Encoder.Quality, CType(75L, Int32)) 'Default
// encoderParameters.Param[0] = New EncoderParameter(Encoder.Quality, CType(95L, Int32)) 'Paint

View File

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

View File

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

View File

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

View File

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

View File

@ -21,8 +21,8 @@ public class SetCreatedDate
private readonly Configuration _Configuration;
private readonly IsEnvironment _IsEnvironment;
private readonly IConfigurationRoot _ConfigurationRoot;
private readonly ReadOnlyDictionary<string, string[]> _FileGroups;
private readonly Property.Models.Configuration _PropertyConfiguration;
private readonly ReadOnlyDictionary<string, ReadOnlyCollection<string>> _FileGroups;
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();
fileHolder = Shared.Models.Stateless.Methods.IFileHolder.Get(file);
if (fileHolder.ExtensionLowered == ".id" || fileHolder.ExtensionLowered == ".lsv" || fileHolder.DirectoryName is null)
if (fileHolder.ExtensionLowered == ".id" || fileHolder.ExtensionLowered == ".lsv" || fileHolder.DirectoryFullPath is null)
continue;
if (_PropertyConfiguration.IgnoreExtensions.Contains(fileHolder.ExtensionLowered))
continue;

View File

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

View File

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

View File

@ -1,27 +1,11 @@
using System.Text.Json;
using System.Text.Json.Serialization;
namespace View_by_Distance.Shared.Models;
public class FaceEncoding : Properties.IFaceEncoding
public record FaceEncoding(double[] RawEncoding, int Size);
[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,11 +4,13 @@ namespace View_by_Distance.Shared.Models;
public record FaceFile(int? AreaPermyriad,
int? ConfidencePercent,
DateTime DateTime,
string? DMS,
DateTime DateTime,
FaceEncoding? FaceEncoding,
Dictionary<Stateless.FacePart, FacePoint[]>? FaceParts,
Location? Location,
string? Maker,
MappingFromPerson? MappingFromPerson,
string? Model,
OutputResolution? OutputResolution);
@ -16,4 +18,16 @@ public record FaceFile(int? AreaPermyriad,
[JsonSerializable(typeof(FaceFile))]
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,58 +1,35 @@
using System.Drawing;
using System.Text.Json;
using System.Text.Json.Serialization;
namespace View_by_Distance.Shared.Models;
public class FacePoint : Properties.IFacePoint
[method: JsonConstructor]
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;
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)
{ }
private readonly Point _Point = new(x, y);
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
public override int GetHashCode()
#pragma warning restore IDE0070
{
int hashCode = 1861411795;
hashCode = hashCode * -1521134295 + _Point.GetHashCode();
hashCode = hashCode * -1521134295 + _Index.GetHashCode();
hashCode = (hashCode * -1521134295) + _Point.GetHashCode();
hashCode = (hashCode * -1521134295) + Index.GetHashCode();
return hashCode;
}
public bool Equals(FacePoint? facePoint)
{
return facePoint is not null
&& _X == facePoint.X
&& _Y == facePoint.Y
&& _Index == facePoint.Index;
&& X == facePoint.X
&& Y == facePoint.Y
&& Index == facePoint.Index;
}
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;
public record FileHolder(DateTime? CreationTime,
string? DirectoryName,
string? DirectoryFullPath,
bool Exists,
string ExtensionLowered,
string FullName,
@ -49,7 +49,7 @@ public record FileHolder(DateTime? CreationTime,
{
FileHolder result;
result = new(new(filePath.CreationTicks),
filePath.DirectoryName,
filePath.DirectoryFullPath,
true,
filePath.ExtensionLowered,
filePath.FullName,

View File

@ -5,7 +5,7 @@ using View_by_Distance.Shared.Models.Stateless.Methods;
namespace View_by_Distance.Shared.Models;
public record FilePath(long CreationTicks,
string DirectoryName,
string DirectoryFullPath,
string ExtensionLowered,
string FileNameFirstSegment,
string FullName,
@ -39,7 +39,7 @@ public record FilePath(long CreationTicks,
int? sortOder;
string fileNameFirstSegment = fileHolder.Name.Split('.')[0];
int sortOrderOnlyLengthIndex = propertyConfiguration.Offset.ToString().Length;
string fileDirectoryName = fileHolder.DirectoryName ?? throw new NullReferenceException();
string fileDirectoryName = fileHolder.DirectoryFullPath ?? throw new NullReferenceException();
bool isIntelligentIdFormat = IId.NameWithoutExtensionIsIntelligentIdFormat(propertyConfiguration, fileNameFirstSegment);
bool isPaddedIntelligentIdFormat = IId.NameWithoutExtensionIsPaddedIntelligentIdFormat(propertyConfiguration, sortOrderOnlyLengthIndex, fileNameFirstSegment);
bool fileNameFirstSegmentIsIdFormat = !isPaddedIntelligentIdFormat && !isIntelligentIdFormat && IId.NameWithoutExtensionIsIdFormat(propertyConfiguration, fileHolder);

View File

@ -0,0 +1,33 @@
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,11 +5,33 @@ namespace View_by_Distance.Shared.Models;
public record ImmichAsset([property: JsonPropertyName("id")] string Id,
[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("previewPath")] string PreviewPath,
[property: JsonPropertyName("isFavorite")] bool IsFavorite,
[property: JsonPropertyName("thumbnailPath")] string ThumbnailPath,
[property: JsonPropertyName("thumbhash")] string Thumbhash)
// [property: JsonPropertyName("fileCreatedAt")] DateTime FileCreatedAt,
// [property: JsonPropertyName("fileModifiedAt")] DateTime FileModifiedAt,
// [property: JsonPropertyName("isFavorite")] bool IsFavorite,
// [property: JsonPropertyName("duration")] string? Duration,
// [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()

View File

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

View File

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

View File

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

View File

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

View File

@ -1,30 +1,5 @@
using System.Text.Json;
using System.Text.Json.Serialization;
namespace View_by_Distance.Shared.Models;
public class OutputResolution : Properties.IOutputResolution
{
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;
}
}
public record OutputResolution(int Height,
int Orientation,
int Width);

View File

@ -3,23 +3,19 @@ using System.Text.Json.Serialization;
namespace View_by_Distance.Shared.Models;
public class PersonBirthday : Properties.IPersonBirthday
public record PersonBirthday(DateTime Value)
{
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()
{
string result = JsonSerializer.Serialize(this, new JsonSerializerOptions() { WriteIndented = true });
string result = JsonSerializer.Serialize(this, PersonBirthdaySourceGenerationContext.Default.PersonBirthday);
return result;
} // ...
}
}
[JsonSourceGenerationOptions(WriteIndented = true, DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull)]
[JsonSerializable(typeof(PersonBirthday))]
public partial class PersonBirthdaySourceGenerationContext : JsonSerializerContext
{
}

View File

@ -4,53 +4,57 @@ using System.Text.Json.Serialization;
namespace View_by_Distance.Shared.Models;
public class PersonContainer : Properties.IPersonContainer
public record PersonContainer(int? ApproximateYears,
PersonBirthday[]? Birthdays,
ReadOnlyCollection<FilePath> DisplayDirectoryAllFilePaths,
string DisplayDirectoryName,
long? Key,
PersonDirectory? PersonDirectory)
{
public int? ApproximateYears { init; get; }
public PersonBirthday[]? Birthdays { init; get; }
public ReadOnlyCollection<FilePath> DisplayDirectoryAllFilePaths { init; get; }
public string DisplayDirectoryName { init; get; }
public long? Key { init; get; }
public bool? KeyIsMaxBirthday { init; get; }
public PersonDirectory? PersonDirectory { init; get; }
[JsonConstructor]
public PersonContainer(int? approximateYears, PersonBirthday[]? birthdays, ReadOnlyCollection<FilePath> displayDirectoryAllFiles, string displayDirectoryName, long? key, PersonDirectory? personDirectory)
{
ApproximateYears = approximateYears;
Birthdays = birthdays;
DisplayDirectoryAllFilePaths = displayDirectoryAllFiles;
DisplayDirectoryName = displayDirectoryName;
Key = key;
PersonDirectory = personDirectory;
KeyIsMaxBirthday = birthdays is null || key is null ? null : key.Value == birthdays.First().Value.Ticks;
}
public PersonContainer(char[] personCharacters, PersonBirthday birthday, string displayDirectoryName, PersonDirectory personDirectory) :
this(Stateless.Methods.IAge.GetApproximateYears(personCharacters, displayDirectoryName), [birthday], new([]), displayDirectoryName, birthday.Value.Ticks, personDirectory)
{ }
public PersonContainer(int? approximateYears, PersonBirthday birthdays, string displayDirectoryName, long key) :
this(approximateYears, [birthdays], new([]), displayDirectoryName, key, null)
{ }
public PersonContainer(int? approximateYears, PersonBirthday birthdays, PersonDirectory? personDirectory, string displayDirectoryName, long key) :
this(approximateYears, [birthdays], new([]), displayDirectoryName, key, personDirectory)
{ }
public PersonContainer(int? approximateYears, ReadOnlyCollection<FilePath> displayDirectoryAllFiles, string displayDirectoryName, PersonDirectory? personDirectory) :
this(approximateYears, null, displayDirectoryAllFiles, displayDirectoryName, null, personDirectory)
{ }
public PersonContainer(int? approximateYears, PersonBirthday[]? birthdays, ReadOnlyCollection<FilePath> displayDirectoryAllFiles, string displayDirectoryName, long? key) :
this(approximateYears, birthdays, displayDirectoryAllFiles, displayDirectoryName, key, null)
{ }
public override string ToString()
{
string result = JsonSerializer.Serialize(this, new JsonSerializerOptions() { WriteIndented = true });
string result = JsonSerializer.Serialize(this, PersonContainerSourceGenerationContext.Default.PersonContainer);
return result;
}
public static PersonContainer Get(int? approximateYears, PersonBirthday[]? birthdays, ReadOnlyCollection<FilePath> displayDirectoryAllFilePaths, string displayDirectoryName, long? key, PersonDirectory? personDirectory) =>
new(approximateYears, birthdays, displayDirectoryAllFilePaths, displayDirectoryName, key, personDirectory);
public static PersonContainer Get(char[] personCharacters, PersonBirthday birthday, string displayDirectoryName, PersonDirectory personDirectory) =>
new(Stateless.Methods.IAge.GetApproximateYears(personCharacters, displayDirectoryName), [birthday], new([]), displayDirectoryName, birthday.Value.Ticks, personDirectory);
public static PersonContainer Get(int? approximateYears, PersonBirthday birthdays, string displayDirectoryName, long key) =>
new(approximateYears, [birthdays], new([]), displayDirectoryName, key, null);
public static PersonContainer Get(int? approximateYears, PersonBirthday birthdays, PersonDirectory? personDirectory, string displayDirectoryName, long key) =>
new(approximateYears, [birthdays], new([]), displayDirectoryName, key, personDirectory);
public static PersonContainer Get(int? approximateYears, ReadOnlyCollection<FilePath> displayDirectoryAllFilePaths, string displayDirectoryName, PersonDirectory? personDirectory) =>
new(approximateYears, null, displayDirectoryAllFilePaths, displayDirectoryName, null, personDirectory);
public static PersonContainer Get(int? approximateYears, PersonBirthday[]? birthdays, ReadOnlyCollection<FilePath> displayDirectoryAllFilePaths, string displayDirectoryName, long? key) =>
new(approximateYears, birthdays, displayDirectoryAllFilePaths, displayDirectoryName, key, null);
public static bool? IsKeyIsMaxBirthday(PersonContainer personContainer) =>
personContainer.Birthdays is null || personContainer.Key is null ? null : personContainer.Key.Value == personContainer.Birthdays.First().Value.Ticks;
public static ReadOnlyDictionary<long, PersonContainer> Extract(ReadOnlyCollection<PersonContainer> personContainers)
{
Dictionary<long, PersonContainer> results = [];
foreach (PersonContainer personContainer in personContainers)
{
if (personContainer.Key is null || results.ContainsKey(personContainer.Key.Value))
continue;
results.Add(personContainer.Key.Value, personContainer);
}
return results.AsReadOnly();
}
}
[JsonSourceGenerationOptions(WriteIndented = true, DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull)]
[JsonSerializable(typeof(PersonContainer))]
public partial class PersonContainerSourceGenerationContext : JsonSerializerContext
{
}

View File

@ -1,4 +1,5 @@
using System.Text.Json;
using System.Text.Json.Serialization;
namespace View_by_Distance.Shared.Models;
@ -7,8 +8,14 @@ public record PersonDirectory(char Char, string Group, char Status, char Sex, ch
public override string ToString()
{
string result = JsonSerializer.Serialize(this, new JsonSerializerOptions() { WriteIndented = true });
string result = JsonSerializer.Serialize(this, PersonDirectorySourceGenerationContext.Default.PersonDirectory);
return result;
}
}
[JsonSourceGenerationOptions(WriteIndented = true, DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull)]
[JsonSerializable(typeof(PersonDirectory))]
public partial class PersonDirectorySourceGenerationContext : JsonSerializerContext
{
}

View File

@ -1,9 +1,9 @@
namespace View_by_Distance.Shared.Models.Properties;
// namespace View_by_Distance.Shared.Models.Properties;
public interface IFaceEncoding
{
// public interface IFaceEncoding
// {
public double[] RawEncoding { get; }
public int Size { get; }
// public double[] RawEncoding { get; }
// public int Size { get; }
}
// }

View File

@ -6,6 +6,7 @@ public interface IItem
public bool? FileSizeChanged { get; }
public List<Face> Faces { get; }
public FilePath FilePath { get; }
public bool? IsArchive { get; }
public bool? IsNotUniqueAndNeedsReview { get; }
public bool IsUniqueFileName { get; }
public bool IsValidImageFormatExtension { get; }

View File

@ -1,10 +1,10 @@
namespace View_by_Distance.Shared.Models.Properties;
// namespace View_by_Distance.Shared.Models.Properties;
public interface IOutputResolution
{
// public interface IOutputResolution
// {
public int Height { get; }
public int Orientation { get; }
public int Width { get; }
// public int Height { get; }
// public int Orientation { get; }
// public int Width { get; }
}
// }

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