Compare commits

..

13 Commits

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

80
.vscode/launch.json vendored
View File

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

View File

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

50
.vscode/tasks.json vendored
View File

@ -53,7 +53,7 @@
"problemMatcher": "$msCompile"
},
{
"label": "buildSolution",
"label": "build",
"command": "dotnet",
"type": "process",
"args": [
@ -63,54 +63,6 @@
"/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>net9.0</TargetFramework>
<TargetFramework>net8.0</TargetFramework>
</PropertyGroup>
<PropertyGroup>
<PackageId>BlurHash.Core</PackageId>
@ -18,6 +18,6 @@
<PackageLicenseExpression>MIT</PackageLicenseExpression>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="System.Memory" Version="4.6.0" />
<PackageReference Include="System.Memory" Version="4.5.5" />
</ItemGroup>
</Project>

View File

@ -4,7 +4,7 @@
<Nullable>enable</Nullable>
<OutputType>library</OutputType>
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
<TargetFramework>net9.0</TargetFramework>
<TargetFramework>net8.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.10" />
<PackageReference Include="System.Drawing.Common" Version="8.0.7" />
</ItemGroup>
</Project>

View File

@ -4,12 +4,12 @@
<Nullable>enable</Nullable>
<OutputType>library</OutputType>
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
<TargetFramework>net9.0</TargetFramework>
<TargetFramework>net8.0</TargetFramework>
</PropertyGroup>
<PropertyGroup>
<PackageId>Phares.View.by.Distance.BlurHash</PackageId>
<GeneratePackageOnBuild>false</GeneratePackageOnBuild>
<Version>9.0.100.1</Version>
<Version>8.0.101.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.10" />
<PackageReference Include="System.Text.Json" Version="9.0.0" />
<PackageReference Include="System.Drawing.Common" Version="8.0.7" />
<PackageReference Include="System.Text.Json" Version="8.0.4" />
</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, ReadOnlyCollection<string>> keyValuePairs = Shared.Models.Stateless.Methods.IPath.GetKeyValuePairs(_PropertyConfiguration, resultsFullGroupDirectory, [_PropertyConfiguration.ResultContent, _PropertyConfiguration.ResultSingleton]);
foreach (KeyValuePair<string, ReadOnlyCollection<string>> keyValuePair in keyValuePairs)
ReadOnlyDictionary<string, string[]> keyValuePairs = Shared.Models.Stateless.Methods.IPath.GetKeyValuePairs(_PropertyConfiguration, resultsFullGroupDirectory, [_PropertyConfiguration.ResultContent, _PropertyConfiguration.ResultSingleton]);
foreach (KeyValuePair<string, string[]> keyValuePair in keyValuePairs)
_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), propertyConfiguration.ResultContentCollection);
string aPropertyContentCollectionDirectory = Property.Models.Stateless.IResult.GetResultsDateGroupDirectory(propertyConfiguration, nameof(A_Property), "[()]");
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>net9.0</TargetFramework>
<TargetFramework>net8.0</TargetFramework>
</PropertyGroup>
<PropertyGroup>
<PackageId>Phares.View.by.Distance.Compare</PackageId>
<GeneratePackageOnBuild>false</GeneratePackageOnBuild>
<Version>9.0.100.1</Version>
<Version>8.0.101.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="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="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="ShellProgressBar" Version="5.2.0" />
<PackageReference Include="WindowsShortcutFactory" Version="1.2.0" />
<PackageReference Include="System.Drawing.Common" Version="8.0.10" />
<PackageReference Include="System.Text.Json" Version="9.0.0" />
<PackageReference Include="System.Drawing.Common" Version="8.0.7" />
<PackageReference Include="System.Text.Json" Version="8.0.4" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Map\Map.csproj" />

View File

@ -4,13 +4,13 @@
<Nullable>enable</Nullable>
<OutputType>Exe</OutputType>
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
<TargetFramework>net9.0</TargetFramework>
<TargetFramework>net8.0</TargetFramework>
<UserSecretsId>d862524f-2b48-4f47-b4c3-5a8615814ec2</UserSecretsId>
</PropertyGroup>
<PropertyGroup>
<PackageId>Phares.View.by.Distance.Copy.Distinct</PackageId>
<GeneratePackageOnBuild>false</GeneratePackageOnBuild>
<Version>9.0.100.1</Version>
<Version>8.0.101.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="9.0.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.UserSecrets" Version="9.0.0" />
<PackageReference Include="Microsoft.Extensions.Hosting" Version="9.0.0" />
<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" />
</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,10 +179,9 @@ public class CopyDistinct
{
progressBar = new(count, message, options);
string key = string.IsNullOrEmpty(_AppSettings.ResultDirectoryKey) ? _PropertyConfiguration.ResultAllInOne : _AppSettings.ResultDirectoryKey;
if (key != _PropertyConfiguration.ResultContent)
throw new NotImplementedException("Changed but didn't update!");
string[] directories = _FileGroups[key];
ReadOnlyCollection<ReadOnlyCollection<FilePath>> filePathsCollection = IDirectory.GetFilePathCollections(_Configuration.PropertyConfiguration, filesCollection);
(distinctDirectories, toDoCollection) = IDirectory.GetToDoCollection(_PropertyConfiguration, _AppSettings.CopyDuplicates, _AppSettings.IfCanUseId, filePathsCollection, _FileGroups, () => progressBar.Tick());
(distinctDirectories, toDoCollection) = IDirectory.GetToDoCollection(_PropertyConfiguration, _AppSettings.CopyDuplicates, _AppSettings.IfCanUseId, filePathsCollection, directories, () => progressBar.Tick());
progressBar.Dispose();
}
foreach (string distinctDirectory in distinctDirectories)

View File

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

View File

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

View File

@ -4,13 +4,13 @@
<Nullable>enable</Nullable>
<OutputType>Exe</OutputType>
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
<TargetFramework>net9.0</TargetFramework>
<TargetFramework>net8.0</TargetFramework>
<UserSecretsId>8004d966-1a9e-4545-a220-83f32b6a13e9</UserSecretsId>
</PropertyGroup>
<PropertyGroup>
<PackageId>Phares.View.by.Distance.Date.Group</PackageId>
<GeneratePackageOnBuild>false</GeneratePackageOnBuild>
<Version>9.0.100.1</Version>
<Version>8.0.101.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="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="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="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.10" />
<PackageReference Include="System.Text.Json" Version="9.0.0" />
<PackageReference Include="System.Drawing.Common" Version="8.0.7" />
<PackageReference Include="System.Text.Json" Version="8.0.4" />
</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.DirectoryFullPath, Description = item.FilePath.Name };
windowsShortcut = new() { Path = item.FilePath.DirectoryName, 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>net9.0</TargetFramework>
<TargetFramework>net8.0</TargetFramework>
<UserSecretsId>0589ecff-b296-48be-a3f7-7bf27f453975</UserSecretsId>
</PropertyGroup>
<PropertyGroup>
<PackageId>Phares.View.by.Distance.Delete.By.Distinct</PackageId>
<GeneratePackageOnBuild>false</GeneratePackageOnBuild>
<Version>9.0.100.1</Version>
<Version>8.0.101.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="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="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="ShellProgressBar" Version="5.2.0" />
<PackageReference Include="WindowsShortcutFactory" Version="1.2.0" />
<PackageReference Include="System.Drawing.Common" Version="8.0.10" />
<PackageReference Include="System.Text.Json" Version="9.0.0" />
<PackageReference Include="System.Drawing.Common" Version="8.0.7" />
<PackageReference Include="System.Text.Json" Version="8.0.4" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Property\Property.csproj" />

View File

@ -4,13 +4,13 @@
<Nullable>enable</Nullable>
<OutputType>Exe</OutputType>
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
<TargetFramework>net9.0</TargetFramework>
<TargetFramework>net8.0</TargetFramework>
<UserSecretsId>ead2e5ee-5f40-4151-bdb6-31d630d94f28</UserSecretsId>
</PropertyGroup>
<PropertyGroup>
<PackageId>Phares.View.by.Distance.Delete.By.Relative</PackageId>
<GeneratePackageOnBuild>false</GeneratePackageOnBuild>
<Version>9.0.100.1</Version>
<Version>8.0.101.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="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="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="ShellProgressBar" Version="5.2.0" />
<PackageReference Include="WindowsShortcutFactory" Version="1.2.0" />
<PackageReference Include="System.Drawing.Common" Version="8.0.10" />
<PackageReference Include="System.Text.Json" Version="9.0.0" />
<PackageReference Include="System.Drawing.Common" Version="8.0.7" />
<PackageReference Include="System.Text.Json" Version="8.0.4" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Property\Property.csproj" />

View File

@ -4,12 +4,12 @@
<Nullable>enable</Nullable>
<OutputType>library</OutputType>
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
<TargetFramework>net9.0</TargetFramework>
<TargetFramework>net8.0</TargetFramework>
</PropertyGroup>
<PropertyGroup>
<PackageId>Phares.View.by.Distance.Distance</PackageId>
<GeneratePackageOnBuild>false</GeneratePackageOnBuild>
<Version>9.0.100.1</Version>
<Version>8.0.101.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="9.0.0" />
<PackageReference Include="System.Text.Json" Version="8.0.4" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\FaceRecognitionDotNet\FaceRecognitionDotNet.csproj" />

View File

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

View File

@ -400,7 +400,7 @@ public partial class E_Distance : IDistance
}
if (!string.IsNullOrEmpty(focusDirectory))
{
if (!locationContainer.FilePath.DirectoryFullPath.Contains(focusDirectory))
if (!locationContainer.FilePath.DirectoryName.Contains(focusDirectory))
continue;
}
json = Metadata.Models.Stateless.Methods.IMetadata.GetFaceEncoding(locationContainer.ExifDirectory);
@ -426,10 +426,11 @@ 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!");
// throw new NotSupportedException($"{face.FaceEncoding} should not be null!");
continue;
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>net9.0-windows</TargetFramework>
<TargetFramework>net8.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="9.0.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.UserSecrets" Version="9.0.0" />
<PackageReference Include="Microsoft.Extensions.Hosting" Version="9.0.0" />
<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" />
</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>net9.0-windows</TargetFramework>
<TargetFramework>net8.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="9.0.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.UserSecrets" Version="9.0.0" />
<PackageReference Include="Microsoft.Extensions.Hosting" Version="9.0.0" />
<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="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>net9.0-windows</TargetFramework>
<TargetFramework>net8.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="9.0.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.UserSecrets" Version="9.0.0" />
<PackageReference Include="Microsoft.Extensions.Hosting" Version="9.0.0" />
<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" />
</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.DirectoryFullPath))
_ = Process.Start("explorer.exe", string.Concat("\"", item.FilePath.DirectoryFullPath, "\""));
if (!string.IsNullOrEmpty(item.FilePath.DirectoryName))
_ = Process.Start("explorer.exe", string.Concat("\"", item.FilePath.DirectoryName, "\""));
}
}
}

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>net9.0-windows</TargetFramework>
<TargetFramework>net8.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="9.0.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.UserSecrets" Version="9.0.0" />
<PackageReference Include="Microsoft.Extensions.Hosting" Version="9.0.0" />
<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" />
</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>net9.0</TargetFramework>
<TargetFramework>net8.0</TargetFramework>
</PropertyGroup>
<PropertyGroup>
<PackageId>Phares.View.by.Distance.Duplicate-Search</PackageId>
<GeneratePackageOnBuild>false</GeneratePackageOnBuild>
<Version>9.0.100.1</Version>
<Version>8.0.101.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="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="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="ShellProgressBar" Version="5.2.0" />
<PackageReference Include="WindowsShortcutFactory" Version="1.2.0" />
<PackageReference Include="System.Drawing.Common" Version="8.0.10" />
<PackageReference Include="System.Text.Json" Version="9.0.0" />
<PackageReference Include="System.Drawing.Common" Version="8.0.7" />
<PackageReference Include="System.Text.Json" Version="8.0.4" />
</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.IsArchive, mappingFromItem.FilePath, mappingFromItem.IsWrongYear, item.Property.Keywords ?? [], mappingFromItem.MinimumDateTime, item.Property.Model, mappingFromItem.RelativePath, resizedFileHolder);
collection[0] = new(mappingFromItem.ContainerDateTimes, item.Property.DateTimeDigitized, item.Property.DateTimeOriginal, mappingFromItem.Id, mappingFromItem.FilePath, mappingFromItem.IsWrongYear, item.Property.Keywords ?? [], mappingFromItem.MinimumDateTime, item.Property.Model, mappingFromItem.RelativePath, resizedFileHolder);
}
}
resizedFileHolder = Shared.Models.Stateless.Methods.IFileHolder.Get(string.Concat(Path.Combine(destinationRoot, directory), item.RelativePath));
@ -208,11 +208,11 @@ public class DuplicateSearch
{
foreach (MappingFromItem? mappingFromItem in keyValuePair.Value)
{
if (mappingFromItem?.ResizedFileHolder.DirectoryFullPath is null)
if (mappingFromItem?.ResizedFileHolder.DirectoryName is null)
continue;
if (mappingFromItem.ResizedFileHolder.Exists)
continue;
collection.Add(mappingFromItem.ResizedFileHolder.DirectoryFullPath);
collection.Add(mappingFromItem.ResizedFileHolder.DirectoryName);
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>net9.0</TargetFramework>
<TargetFramework>net8.0</TargetFramework>
</PropertyGroup>
<PropertyGroup>
<PackageId>Phares.View.by.Distance.Face</PackageId>
<GeneratePackageOnBuild>false</GeneratePackageOnBuild>
<Version>9.0.100.1</Version>
<Version>8.0.101.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="9.0.0" />
<PackageReference Include="System.Text.Json" Version="8.0.4" />
</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, ReadOnlyCollection<string>> keyValuePairs = Shared.Models.Stateless.Methods.IPath.GetKeyValuePairs(_PropertyConfiguration, dResultsFullGroupDirectory, [_PropertyConfiguration.ResultCollection, _PropertyConfiguration.ResultContent]);
foreach (KeyValuePair<string, ReadOnlyCollection<string>> keyValuePair in keyValuePairs)
ReadOnlyDictionary<string, string[]> keyValuePairs = Shared.Models.Stateless.Methods.IPath.GetKeyValuePairs(_PropertyConfiguration, dResultsFullGroupDirectory, [_PropertyConfiguration.ResultCollection, _PropertyConfiguration.ResultContent]);
foreach (KeyValuePair<string, string[]> keyValuePair in keyValuePairs)
_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<PredictorModel>();
array = Enum.GetValues(typeof(PredictorModel));
foreach (PredictorModel check in array)
{
if (predictorModelName.Contains(check.ToString()))
@ -193,13 +193,11 @@ public class D_Face : IFaceD
rectangle = new Rectangle(location.Left, location.Top, width, height);
faceFile = new(face.Mapping?.MappingFromLocation?.AreaPermyriad,
face.Mapping?.MappingFromLocation?.ConfidencePercent,
geoLocation?.ToDmsString(),
face.DateTime,
null,
geoLocation?.ToDmsString(),
face.FaceParts,
face.Location,
maker,
null,
model,
face.OutputResolution);
faceFileJson = JsonSerializer.Serialize(faceFile, FaceFileGenerationContext.Default.FaceFile);
@ -295,9 +293,11 @@ public class D_Face : IFaceD
#pragma warning restore CA1416
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)
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)
{
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(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(string f, string dResultsFullGroupDirectory, FilePath filePath, List<Tuple<string, DateTime>> subFileTuples, List<string> parseExceptions, MappingFromItem mappingFromItem, ExifDirectory exifDirectory, List<Shared.Models.Face> faces)
{
List<(Shared.Models.Face, FileHolder?, string, bool Save)> results = [];
bool save;
@ -453,13 +453,11 @@ public class D_Face : IFaceD
MetadataExtractor.GeoLocation? geoLocation = IMetadata.GeoLocation(exifDirectory);
FaceFile faceFile = new(face.Mapping?.MappingFromLocation?.AreaPermyriad,
face.Mapping?.MappingFromLocation?.ConfidencePercent,
geoLocation?.ToDmsString(),
face.DateTime,
null,
geoLocation?.ToDmsString(),
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>net9.0</TargetFramework>
<TargetFramework>net8.0</TargetFramework>
</PropertyGroup>
<PropertyGroup>
<PackageId>Phares.View.by.Distance.FaceParts</PackageId>
<GeneratePackageOnBuild>false</GeneratePackageOnBuild>
<Version>9.0.100.1</Version>
<Version>8.0.101.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="9.0.0" />
<PackageReference Include="System.Text.Json" Version="8.0.4" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\FaceRecognitionDotNet\FaceRecognitionDotNet.csproj" />

View File

@ -2,12 +2,9 @@ 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;
@ -28,11 +25,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)
{
@ -40,11 +37,10 @@ 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()
@ -56,11 +52,46 @@ public class D2_FaceParts
public void Update(string dResultsFullGroupDirectory)
{
_FileGroups.Clear();
ReadOnlyDictionary<string, ReadOnlyCollection<string>> keyValuePairs = Shared.Models.Stateless.Methods.IPath.GetKeyValuePairs(_PropertyConfiguration, dResultsFullGroupDirectory, [_PropertyConfiguration.ResultContent]);
foreach (KeyValuePair<string, ReadOnlyCollection<string>> keyValuePair in keyValuePairs)
ReadOnlyDictionary<string, string[]> keyValuePairs = Shared.Models.Stateless.Methods.IPath.GetKeyValuePairs(_PropertyConfiguration, dResultsFullGroupDirectory, [_PropertyConfiguration.ResultContent]);
foreach (KeyValuePair<string, string[]> keyValuePair in keyValuePairs)
_FileGroups.Add(keyValuePair.Key, keyValuePair.Value);
}
public void SetAngleBracketCollection(IPropertyConfiguration propertyConfiguration, string d2ResultsFullGroupDirectory, string sourceDirectory)
{
_AngleBracketCollection.Clear();
_AngleBracketCollection.AddRange(IResult.GetDirectoryInfoCollection(propertyConfiguration,
sourceDirectory,
d2ResultsFullGroupDirectory,
contentDescription: "n gif file(s) for each face found",
singletonDescription: string.Empty,
collectionDescription: string.Empty,
converted: true));
}
public string GetFacePartsDirectory(IPropertyConfiguration propertyConfiguration, string dResultsFullGroupDirectory, Item item, bool includeNameWithoutExtension)
{
string result;
bool angleBracketCollectionAny = _AngleBracketCollection.Count != 0;
if (!angleBracketCollectionAny)
{
if (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;
@ -152,238 +183,73 @@ public class D2_FaceParts
return result;
}
private void SaveRotated(MappingFromItem mappingFromItem, List<(Shared.Models.Face, string, string)> collection)
private void SaveFaceParts(int pointSize, FileHolder resizedFileHolder, bool saveRotated, List<(Shared.Models.Face, string, string)> collection)
{
int x;
int y;
double? α;
int width;
int height;
Bitmap rotated;
foreach ((Shared.Models.Face face, string _, string rotatedFileName) in collection)
foreach ((Shared.Models.Face face, string fileName, string rotatedFileName) in collection)
{
if (face.FaceParts is null)
if (face.FaceEncoding is null)
continue;
(_, α) = Shared.Models.Stateless.Methods.IFace.GetEyeα(face.FaceParts);
if (α is null)
continue;
using Image image = Image.FromFile(mappingFromItem.ResizedFileHolder.FullName);
rotated = RotateBitmap(image, (float)α.Value);
if (rotated is not null)
{
rotated.Save(rotatedFileName, _ImageCodecInfo, _EncoderParameters);
rotated.Dispose();
}
}
}
private string GetSeasonDirectory(string d2ResultsFullGroupDirectory, MappingFromItem mappingFromItem, bool any)
{
string result;
string minimumDateYear = mappingFromItem.MinimumDateTime.ToString("yyyy");
DateTime dateTime = mappingFromItem.DateTimeOriginal is null ? mappingFromItem.MinimumDateTime : mappingFromItem.DateTimeOriginal.Value;
(int season, string seasonName) = Shared.Models.Stateless.Methods.IProperty.GetSeason(dateTime.DayOfYear);
string year = mappingFromItem.DateTimeOriginal is null ? $"{minimumDateYear[1..]}{minimumDateYear[0]}" : mappingFromItem.DateTimeOriginal.Value.ToString("yyyy");
string directory = Path.Combine(d2ResultsFullGroupDirectory, $"[{_PropertyConfiguration.ResultContent}]", $"{year}.{season} {seasonName}");
result = any ? Path.Combine(directory, "---") : Path.Combine(directory, "Complete");
if (!Directory.Exists(result))
_ = Directory.CreateDirectory(result);
return result;
}
private void SaveImage(MappingFromItem mappingFromItem, string directory, Image image, List<FaceFile> faceFiles)
{
short type = 2;
string faceFileJson;
PropertyItem? propertyItem;
const int artist = MetadataExtractor.Formats.Exif.ExifDirectoryBase.TagArtist; // 315
string fileName = Path.Combine(directory, $"{mappingFromItem.FilePath.Name}{_FileNameExtension}");
try
{
foreach (int propertyId in image.PropertyIdList)
{
if (propertyId == MetadataExtractor.Formats.Exif.ExifDirectoryBase.TagOrientation)
continue;
image.RemovePropertyItem(propertyId);
}
faceFileJson = JsonSerializer.Serialize(faceFiles.ToArray(), FaceFileCollectionGenerationContext.Default.FaceFileArray);
propertyItem = IProperty.GetPropertyItem(_ConstructorInfo, artist, type, faceFileJson);
image.SetPropertyItem(propertyItem);
image.Save(fileName, _ImageCodecInfo, _EncoderParameters);
}
catch (Exception ex)
{
if (ex is not null && !string.IsNullOrEmpty(fileName) && File.Exists(fileName))
File.Delete(fileName);
faceFileJson = JsonSerializer.Serialize(faceFiles.ToArray(), FaceFileCollectionGenerationContext.Default.FaceFileArray);
if (!string.IsNullOrEmpty(faceFileJson))
File.WriteAllText($"{fileName}.json", faceFileJson);
}
}
private void SaveAllFaceParts(string d2ResultsFullGroupDirectory, MappingFromItem mappingFromItem, ExifDirectory exifDirectory, List<Shared.Models.Face> faces)
{
int x;
int y;
Brush brush;
int pointSize;
bool any = false;
FaceFile faceFile;
bool? isDefaultName;
List<long> personKeys = [];
List<FaceFile> faceFiles = [];
StringBuilder stringBuilder = new();
MappingFromPerson? mappingFromPerson;
string? maker = IMetadata.GetMaker(exifDirectory);
string? model = IMetadata.GetModel(exifDirectory);
MetadataExtractor.GeoLocation? geoLocation = IMetadata.GeoLocation(exifDirectory);
using Image image = Image.FromFile(mappingFromItem.ResizedFileHolder.FullName);
using Graphics graphics = Graphics.FromImage(image);
foreach (Shared.Models.Face face in faces)
{
if (face.Location is null || face.FaceEncoding is null || face.FaceParts is null || face.FaceParts.Count == 0)
continue;
if (!any && face.Mapping?.MappingFromPerson is null)
any = true;
mappingFromPerson = face.Mapping?.MappingFromPerson;
brush = mappingFromPerson is null ? Brushes.Red : Brushes.GreenYellow;
isDefaultName = mappingFromPerson is null ? null : Shared.Models.Stateless.Methods.IPerson.IsDefaultName(mappingFromPerson);
if (mappingFromPerson is not null && isDefaultName is not null && !isDefaultName.Value)
personKeys.Add(mappingFromPerson.PersonKey);
faceFile = new(face.Mapping?.MappingFromLocation?.AreaPermyriad,
face.Mapping?.MappingFromLocation?.ConfidencePercent,
geoLocation?.ToDmsString(),
face.DateTime,
face.FaceEncoding,
face.FaceParts,
face.Location,
maker,
mappingFromPerson,
model,
face.OutputResolution);
faceFiles.Add(faceFile);
pointSize = GetPointSize(face.FaceParts, defaultPointSize: 2);
foreach ((FacePart facePart, FacePoint[] facePoints) in face.FaceParts)
{
foreach (FacePoint facePoint in facePoints)
graphics.FillEllipse(brush, facePoint.X - pointSize, facePoint.Y - pointSize, pointSize * 2, pointSize * 2);
if (facePart == FacePart.Chin)
continue;
if (facePoints.Length < 3)
continue;
x = (int)(from l in facePoints select l.X).Average();
y = (int)(from l in facePoints select l.Y).Average();
graphics.FillEllipse(Brushes.Purple, x - pointSize, y - pointSize, pointSize * 2, pointSize * 2);
}
}
_ = graphics.Save();
string directory = GetSeasonDirectory(d2ResultsFullGroupDirectory, mappingFromItem, any);
SaveImage(mappingFromItem, directory, image, faceFiles);
}
private void SaveImage(string fileName, Image image, FaceFile faceFile)
{
short type = 2;
string faceFileJson;
PropertyItem? propertyItem;
const int artist = MetadataExtractor.Formats.Exif.ExifDirectoryBase.TagArtist; // 315
try
{
foreach (int propertyId in image.PropertyIdList)
{
if (propertyId == MetadataExtractor.Formats.Exif.ExifDirectoryBase.TagOrientation)
continue;
image.RemovePropertyItem(propertyId);
}
faceFileJson = JsonSerializer.Serialize(faceFile, FaceFileGenerationContext.Default.FaceFile);
propertyItem = IProperty.GetPropertyItem(_ConstructorInfo, artist, type, faceFileJson);
image.SetPropertyItem(propertyItem);
image.Save(fileName, _ImageCodecInfo, _EncoderParameters);
}
catch (Exception ex)
{
if (ex is not null && !string.IsNullOrEmpty(fileName) && File.Exists(fileName))
File.Delete(fileName);
faceFileJson = JsonSerializer.Serialize(faceFile, FaceFileGenerationContext.Default.FaceFile);
if (!string.IsNullOrEmpty(faceFileJson))
File.WriteAllText($"{fileName}.json", faceFileJson);
}
}
private void SaveFaceParts(MappingFromItem mappingFromItem, ExifDirectory exifDirectory, List<(Shared.Models.Face, string, string)> collection)
{
int x;
int y;
Brush brush;
int pointSize;
FaceFile faceFile;
MappingFromPerson? mappingFromPerson;
string? maker = IMetadata.GetMaker(exifDirectory);
string? model = IMetadata.GetModel(exifDirectory);
MetadataExtractor.GeoLocation? geoLocation = IMetadata.GeoLocation(exifDirectory);
foreach ((Shared.Models.Face face, string fileName, string _) in collection)
{
try
{
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 (Image image = Image.FromFile(resizedFileHolder.FullName))
{
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);
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)
continue;
using Image image = Image.FromFile(resizedFileHolder.FullName);
rotated = RotateBitmap(image, (float)α.Value);
if (rotated is not null)
{
rotated.Save(rotatedFileName, _ImageCodecInfo, _EncoderParameters);
rotated.Dispose();
}
}
_ = graphics.Save();
SaveImage(fileName, image, faceFile);
}
catch (Exception)
{
if (File.Exists(fileName))
File.Delete(fileName);
}
catch (Exception) { }
}
}
private int GetPointSize(Dictionary<FacePart, FacePoint[]> faceParts, int defaultPointSize)
{
int result;
FacePoint[]? facePoints;
if (faceParts.TryGetValue(FacePart.LeftEye, out facePoints))
result = (int)Math.Ceiling((facePoints.Max(l => l.X) - facePoints.Min(l => l.X)) * .05);
else
{
if (faceParts.TryGetValue(FacePart.RightEye, out facePoints))
result = (int)Math.Ceiling((facePoints.Max(l => l.X) - facePoints.Min(l => l.X)) * .05);
else
result = defaultPointSize;
}
return result;
}
#pragma warning restore CA1416
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)
public void SaveFaceLandmarkImages(Configuration configuration, FilePath filePath, List<Tuple<string, DateTime>> subFileTuples, List<string> parseExceptions, MappingFromItem mappingFromItem, 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;
@ -430,12 +296,37 @@ public class D2_FaceParts
{
if (!directoryExists)
_ = Directory.CreateDirectory(directory);
SaveFaceParts(mappingFromItem, exifDirectory, collection);
if (saveRotated)
SaveRotated(mappingFromItem, collection);
SaveFaceParts(pointSize, mappingFromItem.ResizedFileHolder, saveRotated, 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;
@ -469,18 +360,19 @@ public class D2_FaceParts
return results;
}
public void SaveFaceLandmarkImages(string d2ResultsFullGroupDirectory, MappingFromItem mappingFromItem, ExifDirectory exifDirectory, List<Shared.Models.Face> faces)
public void CopyFacesAndSaveFaceLandmarkImage(string facePartsCollectionDirectory, MappingFromItem mappingFromItem, List<(Shared.Models.Face Face, FileHolder?, string, bool)> faceCollection)
{
bool any = false;
foreach (Shared.Models.Face face in 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))
{
if (face.Location is null || face.FaceEncoding is null || face.FaceParts is null || face.FaceParts.Count == 0)
continue;
if (!any)
any = true;
SaveFaceLandmarkImage(mappingFromItem, faceCollection, fileName);
fileInfo.Refresh();
}
if (any)
SaveAllFaceParts(d2ResultsFullGroupDirectory, mappingFromItem, exifDirectory, faces);
if (!hasNotMapped && !fileInfo.Attributes.HasFlag(FileAttributes.Hidden) && (fileInfo.Exists || save))
File.SetAttributes(fileName, FileAttributes.Hidden);
}
}

View File

@ -4,12 +4,12 @@
<Nullable>enable</Nullable>
<OutputType>library</OutputType>
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
<TargetFramework>net9.0</TargetFramework>
<TargetFramework>net8.0</TargetFramework>
</PropertyGroup>
<PropertyGroup>
<PackageId>Phares.View.by.Distance.FaceRecognitionDotNet</PackageId>
<GeneratePackageOnBuild>false</GeneratePackageOnBuild>
<Version>9.0.100.1</Version>
<Version>8.0.101.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.GetJpegLowQuality();
(ImageCodecInfo hiddenImageCodecInfo, EncoderParameters hiddenEncoderParameters, string hiddenFileNameExtension) = C_Resize.GetGifLowQuality();
_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.GetJpegLowQuality();
(ImageCodecInfo imageCodecInfo, EncoderParameters encoderParameters, string filenameExtension) = C_Resize.GetGifLowQuality();
_FaceParts = new D2_FaceParts(_Configuration.PropertyConfiguration, imageCodecInfo, encoderParameters, filenameExtension, configuration.CheckDFaceAndUpWriteDates, configuration.OverrideForFaceLandmarkImages);
}
_DistanceLimits = new(_Configuration.FaceAreaPermyriad, _Configuration.FaceConfidencePercent, _Configuration.FaceDistancePermyriad, _Configuration.RangeDaysDeltaTolerance, _Configuration.RangeDistanceTolerance, _Configuration.RangeFaceAreaTolerance, _Configuration.RangeFaceConfidence, _Configuration.SortingMaximumPerFaceShouldBeHigh);
_DistanceLimits = new(_Configuration.FaceAreaPermyriad, _Configuration.FaceConfidencePercent, _Configuration.FaceDistancePermyriad, _Configuration.RangeDaysDeltaTolerance, _Configuration.RangeDistanceTolerance, _Configuration.RangeFaceAreaPermyriadTolerance, _Configuration.RangeFaceConfidence, _Configuration.SortingMaximumPerFaceShouldBeHigh);
_MapConfiguration = Get(configuration, _DistanceLimits, _Faces.FileNameExtension, _Faces.HiddenFileNameExtension, _FaceParts.FileNameExtension);
_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.RangeFaceAreaTolerance.Length != 3)
throw new NullReferenceException(nameof(configuration.RangeFaceAreaTolerance));
if (configuration.RangeFaceAreaPermyriadTolerance.Length != 3)
throw new NullReferenceException(nameof(configuration.RangeFaceAreaPermyriadTolerance));
if (configuration.RangeFaceConfidence.Length != 3)
throw new NullReferenceException(nameof(configuration.RangeFaceConfidence));
if (configuration.LocationContainerDistanceTolerance is null && !string.IsNullOrEmpty(configuration.LocationContainerDebugDirectory))
@ -204,8 +204,6 @@ public partial class DlibDotNet : IDlibDotNet, IDisposable
throw new Exception($"One or more {nameof(configuration.SaveShortcutsForOutputResolutions)} are not in the ValidResolutions list!");
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))
@ -254,6 +252,31 @@ 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)
@ -312,8 +335,9 @@ 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();
@ -335,7 +359,7 @@ public partial class DlibDotNet : IDlibDotNet, IDisposable
if (!runToDoCollectionFirst)
break;
(filesCollectionRootDirectory, filePathsCollection, filesCollectionCountIsOne) = GetFilesCollectionThenCopyOrMove(ticks, fileSearchFilter, directorySearchFilter, options, outputResolution);
splatNineIdentifiers = GetSplatNineIdentifiersAndHideSplatNine(_Configuration.PropertyConfiguration, bResultsFullGroupDirectory, filePathsCollection);
notNineCollection = GetNotNineCollection(filePathsCollection);
break;
}
fPhotoPrismContentDirectory = Property.Models.Stateless.IResult.GetResultsDateGroupDirectory(_Configuration.PropertyConfiguration, nameof(F_PhotoPrism), _Configuration.PropertyConfiguration.ResultContent);
@ -369,7 +393,7 @@ public partial class DlibDotNet : IDlibDotNet, IDisposable
continue;
(cResultsFullGroupDirectory, _, _, _) = GetResultsFullGroupDirectories(outputResolution);
filesCollectionRootDirectory = Path.Combine(cResultsFullGroupDirectory, _Configuration.PropertyConfiguration.ResultContent);
filePathsCollection = IDirectory.GetFilePathCollections(_Configuration.PropertyConfiguration, directorySearchFilter, fileSearchFilter, filesCollectionRootDirectory, useCeilingAverage: true);
filePathsCollection = IDirectory.GetFilePathCollections(_Configuration.PropertyConfiguration, filesCollectionRootDirectory, directorySearchFilter, fileSearchFilter, useCeilingAverage: true);
break;
}
}
@ -379,9 +403,10 @@ 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);
ReadOnlyCollection<Container> readOnlyContainers = Shared.Models.Stateless.Methods.IContainer.GetContainers(this, _Configuration.PropertyConfiguration, aPropertySingletonDirectory, filesCollectionRootDirectory, splatNineIdentifiers, filePathsCollection);
readOnlyContainers = Shared.Models.Stateless.Methods.IContainer.GetContainers(this, _Configuration.PropertyConfiguration, aPropertySingletonDirectory, filesCollectionRootDirectory, filePathsCollection);
_ProgressBar.Dispose();
mapLogic ??= new(_AppSettings.MaxDegreeOfParallelism, _Configuration.PropertyConfiguration, _MapConfiguration, _Distance, personContainers, ticks, a2PeopleContentDirectory, a2PeopleSingletonDirectory, eDistanceContentDirectory);
DeleteContinueFiles(personContainers);
@ -428,8 +453,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 && 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 (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 (_IsEnvironment.Development)
continue;
if (!_IsEnvironment.Development)
@ -471,7 +496,8 @@ public partial class DlibDotNet : IDlibDotNet, IDisposable
[
Path.Combine(rootDirectory, "Ancestry"),
Path.Combine(rootDirectory, "Facebook"),
Path.Combine(rootDirectory, "LinkedIn")
Path.Combine(rootDirectory, "LinkedIn"),
rootDirectory,
];
foreach (string checkDirectory in checkDirectories)
{
@ -508,7 +534,7 @@ public partial class DlibDotNet : IDlibDotNet, IDisposable
string result;
if (filePaths.Count == 0)
throw new NotSupportedException();
string? sourceDirectory = filePaths[0].DirectoryFullPath;
string? sourceDirectory = filePaths[0].DirectoryName;
if (string.IsNullOrEmpty(sourceDirectory))
throw new NotSupportedException();
Uri uri;
@ -542,7 +568,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);
_ = Item.Get(filePath, fileHolder, relativePath, isValidImageFormatExtension);
_ = new Item(filePath, fileHolder, relativePath, isValidImageFormatExtension);
// container.Items.Add(item);
}
_Logger?.LogInformation(". . .");
@ -604,6 +630,7 @@ public partial class DlibDotNet : IDlibDotNet, IDisposable
outputResolution,
outputResolutionHasNumber,
cResultsFullGroupDirectory,
dResultsFullGroupDirectory,
d2ResultsFullGroupDirectory,
sourceDirectoryChanges,
fileNameToCollection,
@ -636,11 +663,14 @@ public partial class DlibDotNet : IDlibDotNet, IDisposable
}
}
private static ReadOnlyDictionary<int, ReadOnlyCollection<FilePath>> GetKeyValuePairs(ReadOnlyCollection<ReadOnlyCollection<FilePath>> filePathsCollection)
private static void SaveDistinctIds(Property.Models.Configuration propertyConfiguration, string bResultsFullGroupDirectory, ReadOnlyCollection<ReadOnlyCollection<FilePath>> filePathsCollection)
{
Dictionary<int, ReadOnlyCollection<FilePath>> results = [];
List<FilePath>? collection;
Dictionary<int, List<FilePath>> keyValuePairs = [];
string paddedId;
List<int> distinct = [];
List<Identifier> identifiers = [];
string bMetadataCollectionDirectory = Path.Combine(bResultsFullGroupDirectory, propertyConfiguration.ResultCollection);
if (!Directory.Exists(bMetadataCollectionDirectory))
_ = Directory.CreateDirectory(bMetadataCollectionDirectory);
foreach (ReadOnlyCollection<FilePath> filePaths in filePathsCollection)
{
if (filePaths.Count == 0)
@ -649,69 +679,15 @@ public partial class DlibDotNet : IDlibDotNet, IDisposable
{
if (filePath.Id is null)
continue;
if (!keyValuePairs.TryGetValue(filePath.Id.Value, out collection))
{
keyValuePairs.Add(filePath.Id.Value, []);
if (!keyValuePairs.TryGetValue(filePath.Id.Value, out collection))
throw new Exception();
}
collection.Add(filePath);
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));
}
}
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);
string json = JsonSerializer.Serialize(identifiers.OrderBy(l => l.PaddedId).ToArray(), IdentifierCollectionSourceGenerationContext.Default.IdentifierArray);
_ = Shared.Models.Stateless.Methods.IPath.WriteAllText(Path.Combine(bMetadataCollectionDirectory, ".json"), json, updateDateWhenMatches: false, compareBeforeWrite: true, updateToWhenMatches: null);
}
private ReadOnlyCollection<Mapping> GetMappings(Property.Models.Configuration propertyConfiguration, string eDistanceContentDirectory, ReadOnlyCollection<Container> readOnlyContainers, MapLogic mapLogic, bool distinctItems)
@ -929,7 +905,7 @@ public partial class DlibDotNet : IDlibDotNet, IDisposable
results = [];
else
{
DistanceLimits distanceLimits = new(_Configuration.FaceAreaPermyriad, _Configuration.FaceConfidencePercent, _Configuration.FaceDistancePermyriad, _Configuration.RangeDaysDeltaTolerance, _Configuration.RangeDistanceTolerance, _Configuration.RangeFaceAreaTolerance, _Configuration.RangeFaceConfidence, _Configuration.SortingMaximumPerFaceShouldBeHigh);
DistanceLimits distanceLimits = new(_Configuration.FaceAreaPermyriad, _Configuration.FaceConfidencePercent, _Configuration.FaceDistancePermyriad, _Configuration.RangeDaysDeltaTolerance, _Configuration.RangeDistanceTolerance, _Configuration.RangeFaceAreaPermyriadTolerance, _Configuration.RangeFaceConfidence, _Configuration.SortingMaximumPerFaceShouldBeHigh);
List<LocationContainer> postFiltered = E_Distance.GetPostFilterLocationContainer(mapLogic, preFiltered, distanceLimits);
if (postFiltered.Count == 0)
results = [];
@ -944,7 +920,7 @@ public partial class DlibDotNet : IDlibDotNet, IDisposable
results = [];
else
{
ReadOnlyDictionary<long, PersonContainer> personKeyToPersonContainer = PersonContainer.Extract(personContainers);
ReadOnlyDictionary<long, PersonContainer> personKeyToPersonContainer = mapLogic.GetPersonKeyToPersonContainer();
results = mapLogic.GetSaveContainers(cResultsFullGroupDirectory, dResultsFullGroupDirectory, d2ResultsFullGroupDirectory, distanceLimits, onlyOne, personKeyToPersonContainer);
}
}
@ -957,7 +933,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, _Configuration.PropertyConfiguration.ResultContentCollection);
string d2FacePartsContentCollectionDirectory = Path.Combine(d2ResultsFullGroupDirectory, "[()]");
if (distinctValidImageMappingCollection.Count > 0)
{
Shared.Models.Stateless.Methods.IPath.ChangeDateForEmptyDirectories(d2FacePartsContentDirectory, ticks);
@ -1018,10 +994,11 @@ 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;
@ -1051,7 +1028,7 @@ public partial class DlibDotNet : IDlibDotNet, IDisposable
isFocusPerson = mapLogic.IsFocusPerson(_Configuration.SkipPersonWithMoreThen, jLinkResolvedPersonKeys, wholePercentagesToPersonContainers, mappingFromLocation);
mappingFromFilterPost = new(canReMap, inSkipCollection, isFocusPerson);
}
mapping = Mapping.Get(item.FilePath, mappingFromFilterPost, mappingFromFilterPre, mappingFromItem, mappingFromLocation, mappingFromPhotoPrismCollection);
mapping = new(item.FilePath, mappingFromFilterPost, mappingFromFilterPre, mappingFromItem, mappingFromLocation, mappingFromPhotoPrismCollection);
notMapped += mapLogic.UpdateMappingFromPerson(wholePercentagesToPersonContainers, mapping);
face.SetMapping(mapping);
}
@ -1102,16 +1079,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 = Mapping.Get(item.FilePath, mappingFromFilterPost, mappingFromFilterPre, mappingFromItem, mappingFromLocation, mappingFromPhotoPrismCollection: null);
result = new(item.FilePath, mappingFromFilterPost, mappingFromFilterPre, mappingFromItem, mappingFromLocation, mappingFromPhotoPrismCollection: null);
int notMapped = mapLogic.UpdateMappingFromPerson(wholePercentagesToPersonContainers, result);
return (result, notMapped);
}
@ -1122,6 +1099,7 @@ 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,
@ -1129,7 +1107,8 @@ public partial class DlibDotNet : IDlibDotNet, IDisposable
int index,
Item item,
DateTime[] containerDateTimes,
bool? isFocusRelativePath)
bool? isFocusRelativePath,
string facePartsCollectionDirectory)
{
int result = 0;
List<Shared.Models.Face> faces;
@ -1187,7 +1166,7 @@ public partial class DlibDotNet : IDlibDotNet, IDisposable
}
if (resizedFileHolder.Exists && item.FilePath.HasIgnoreKeyword is not null && item.FilePath.HasIgnoreKeyword.Value != shouldIgnore.Value)
{
if (!item.FilePath.DirectoryFullPath.Contains("Results") || !item.FilePath.DirectoryFullPath.Contains("Resize"))
if (!item.FilePath.DirectoryName.Contains("Results") || !item.FilePath.DirectoryName.Contains("Resize"))
throw new NotSupportedException($"Rename File! <{item.FilePath.FileNameFirstSegment}>");
else
{
@ -1240,9 +1219,11 @@ 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, item.FilePath, subFileTuples, parseExceptions, property, mappingFromItem, outputResolutionToResize, mappingFromPhotoPrismCollection);
faces = _Faces.GetFaces(outputResolution, cResultsFullGroupDirectory, dResultsFullGroupDirectory, item.FilePath, subFileTuples, parseExceptions, property, mappingFromItem, outputResolutionToResize, mappingFromPhotoPrismCollection);
result = GetNotMappedCountAndUpdateMappingFromPersonThenSetMapping(mapLogic, item, isFocusRelativePath, mappingFromItem, mappingFromPhotoPrismCollection, faces);
List<(Shared.Models.Face, FileHolder?, string, bool Saved)> faceCollection = _Faces.SaveFaces(item.FilePath, subFileTuples, parseExceptions, mappingFromItem, exifDirectory, faces);
List<(Shared.Models.Face, FileHolder?, string, bool Saved)> faceCollection = _Faces.SaveFaces(_FaceParts.FileNameExtension, dResultsFullGroupDirectory, item.FilePath, subFileTuples, parseExceptions, mappingFromItem, exifDirectory, faces);
if (_Configuration.CopyFacesAndSaveFaceLandmarkForOutputResolutions.Contains(outputResolution))
_FaceParts.CopyFacesAndSaveFaceLandmarkImage(facePartsCollectionDirectory, mappingFromItem, faceCollection);
if (move && faceCollection.All(l => !l.Saved))
{
ReadOnlyCollection<LocationContainer> locationContainers = mapLogic.GetLocationContainers(item);
@ -1259,10 +1240,8 @@ public partial class DlibDotNet : IDlibDotNet, IDisposable
{
bool saveRotated = false;
string sourceDirectorySegment = Property.Models.Stateless.IResult.GetRelativePath(_Configuration.PropertyConfiguration, container.SourceDirectory);
_FaceParts.SaveFaceLandmarkImages(_Configuration.PropertyConfiguration, d2ResultsFullGroupDirectory, item.FilePath, subFileTuples, parseExceptions, mappingFromItem, exifDirectory, faces, saveRotated);
_FaceParts.SaveFaceLandmarkImages(_Configuration.PropertyConfiguration, item.FilePath, subFileTuples, parseExceptions, mappingFromItem, faces, saveRotated);
}
if (_Configuration.SaveFaceLandmarkForOutputResolutionsV2.Contains(outputResolution))
_FaceParts.SaveFaceLandmarkImages(d2ResultsFullGroupDirectory, mappingFromItem, exifDirectory, faces);
}
lock (sourceDirectoryChanges)
{
@ -1279,6 +1258,7 @@ 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,
@ -1293,6 +1273,7 @@ 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) =>
@ -1305,6 +1286,7 @@ public partial class DlibDotNet : IDlibDotNet, IDisposable
outputResolution,
outputResolutionHasNumber,
cResultsFullGroupDirectory,
dResultsFullGroupDirectory,
d2ResultsFullGroupDirectory,
sourceDirectoryChanges,
fileNameToCollection,
@ -1312,7 +1294,8 @@ public partial class DlibDotNet : IDlibDotNet, IDisposable
index: i,
filteredItems[i],
containerDateTimes,
isFocusRelativePath);
isFocusRelativePath,
facePartsCollectionDirectory);
if (!anyPropertiesChangedForX && (i == 0 || sourceDirectoryChanges.Count > 0))
progressBar.Tick();
}
@ -1385,7 +1368,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.RangeFaceAreaTolerance, _Configuration.RangeFaceConfidence, _Configuration.SortingMaximumPerFaceShouldBeHigh);
distanceLimits = new(_Configuration.FaceAreaPermyriad, _Configuration.FaceConfidencePercent, _Configuration.FaceDistancePermyriad, _Configuration.RangeDaysDeltaTolerance, _Configuration.RangeDistanceTolerance, _Configuration.RangeFaceAreaPermyriadTolerance, _Configuration.RangeFaceConfidence, _Configuration.SortingMaximumPerFaceShouldBeHigh);
filteredFaceDistanceContainers = E_Distance.FilteredPostLoadFaceDistanceContainers(mapLogic, faceDistanceContainers, skipOlderThan, distanceLimits);
if (filteredFaceDistanceContainers.Length == 0)
_Logger?.LogInformation("All images have been filtered!");
@ -1396,7 +1379,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.RangeFaceAreaTolerance, _Configuration.RangeFaceConfidence, _Configuration.SortingMaximumPerFaceShouldBeHigh, useFiltersCounter);
distanceLimits = new(_Configuration.FaceAreaPermyriad, _Configuration.FaceConfidencePercent, _Configuration.FaceDistancePermyriad, _Configuration.RangeDaysDeltaTolerance, _Configuration.RangeDistanceTolerance, _Configuration.RangeFaceAreaPermyriadTolerance, _Configuration.RangeFaceConfidence, _Configuration.SortingMaximumPerFaceShouldBeHigh, useFiltersCounter);
filteredFaceDistanceContainers = E_Distance.FilteredPostLoadFaceDistanceContainers(mapLogic, faceDistanceContainers, skipOlderThan, distanceLimits);
if (filteredFaceDistanceContainers.Length == 0)
_Logger?.LogInformation("All images have been filtered!");
@ -1491,13 +1474,13 @@ public partial class DlibDotNet : IDlibDotNet, IDisposable
ProgressBar progressBar;
string filesCollectionRootDirectory = _Configuration.PropertyConfiguration.RootDirectory;
(string cResultsFullGroupDirectory, _, _, _) = GetResultsFullGroupDirectories(outputResolution);
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);
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);
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, () => progressBar.Tick());
(string[] distinctDirectories, List<(FilePath, string)> toDoCollection) = IDirectory.GetToDoCollection(_Configuration.PropertyConfiguration, filePathsCollection, fileGroups[_Configuration.PropertyConfiguration.ResultContent], () => 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>net9.0</TargetFramework>
<TargetFramework>net8.0</TargetFramework>
<UserSecretsId>2999dda1-5329-4d9f-9d68-cccfabe0e47f</UserSecretsId>
</PropertyGroup>
<PropertyGroup>
<PackageId>Phares.View.by.Distance.Instance</PackageId>
<GeneratePackageOnBuild>false</GeneratePackageOnBuild>
<Version>9.0.100.1</Version>
<Version>8.0.101.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="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="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="MetadataExtractor" Version="2.8.1" />
<PackageReference Include="ShellProgressBar" Version="5.2.0" />
<PackageReference Include="WindowsShortcutFactory" Version="1.2.0" />

View File

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

View File

@ -3,6 +3,7 @@ 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,
@ -21,8 +22,6 @@ public record Configuration(Property.Models.Configuration PropertyConfiguration,
bool ForceResizeLastWriteTimeToCreationTime,
string GenealogicalDataCommunicationFile,
string ImmichAssetsFile,
string ImmichOwnerId,
string ImmichRoot,
string[] IgnoreExtensions,
string[] JLinks,
string? LinkedAlpha,
@ -64,7 +63,7 @@ public record Configuration(Property.Models.Configuration PropertyConfiguration,
int RadomUseBirthdayMinimum,
int[] RangeDaysDeltaTolerance,
float[] RangeDistanceTolerance,
float[] RangeFaceAreaTolerance,
float[] RangeFaceAreaPermyriadTolerance,
float[] RangeFaceConfidence,
float[] RectangleIntersectMinimums,
bool ReMap,
@ -72,7 +71,6 @@ public record Configuration(Property.Models.Configuration PropertyConfiguration,
string[] SaveBlurHashForOutputResolutions,
string[] SaveFaceDistancesForOutputResolutions,
string[] SaveFaceLandmarkForOutputResolutions,
string[] SaveFaceLandmarkForOutputResolutionsV2,
string[] SaveFilteredOriginalImagesFromJLinksForOutputResolutions,
bool SaveFullYearOfRandomFiles,
bool SaveIndividually,

View File

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

View File

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

View File

@ -4,12 +4,12 @@
<Nullable>enable</Nullable>
<OutputType>library</OutputType>
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
<TargetFramework>net9.0</TargetFramework>
<TargetFramework>net8.0</TargetFramework>
</PropertyGroup>
<PropertyGroup>
<PackageId>Phares.View.by.Distance.Map</PackageId>
<GeneratePackageOnBuild>false</GeneratePackageOnBuild>
<Version>9.0.100.1</Version>
<Version>8.0.101.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="9.0.0" />
<PackageReference Include="System.Text.Json" Version="8.0.4" />
</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.DirectoryFullPath is null)
if (mapping.MappingFromItem.FilePath.DirectoryName is null)
continue;
directoryName = Path.GetFileName(mapping.MappingFromItem.FilePath.DirectoryFullPath);
directoryName = Path.GetFileName(mapping.MappingFromItem.FilePath.DirectoryName);
if (!string.IsNullOrEmpty(mapping.MappingFromItem.Model) && !string.IsNullOrEmpty(mapping.MappingFromItem.Model.Trim()))
{
// 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.SetPersonCollectionsAfterSetSkipCollections(configuration, personContainers, personKeyFormattedToNewestPersonKeyFormatted, personKeyFormattedCollection);
Stateless.MapLogic.SetPersonCollections(configuration, personContainers, personKeyFormattedToNewestPersonKeyFormatted, personKeyFormattedCollection);
readOnlyPersonKeyFormattedCollection = new(personKeyFormattedCollection);
readOnlyPersonKeyFormattedToNewestPersonKeyFormatted = new(personKeyFormattedToNewestPersonKeyFormatted);
}
@ -359,6 +359,12 @@ 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 = [];
@ -894,7 +900,7 @@ public partial class MapLogic : Shared.Models.Methods.IMapLogic
continue;
}
results.Add(new(record.PersonDirectory));
facesDirectory = locationContainer.LengthSource.DirectoryFullPath;
facesDirectory = locationContainer.LengthSource.DirectoryName;
faceFileHolder = IFileHolder.Get(locationContainer.LengthSource.FullName);
checkFile = Path.Combine(directory, $"{locationContainer.LengthSource.Name}");
shortcutFile = Path.Combine(record.PersonDirectory, $"{locationContainer.LengthSource.Name}.lnk");
@ -1259,7 +1265,6 @@ 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 = [];
@ -1272,7 +1277,7 @@ public partial class MapLogic : Shared.Models.Methods.IMapLogic
saveContainer = new(fileHolder, filteredOriginalImage.CheckFile, filteredOriginalImage.Directory);
saveContainers.Add(saveContainer);
}
SaveContainers(updated, saveContainers);
SaveContainers(null, saveContainers);
}
public void SaveShortcutsForOutputResolutionsPreMapLogic(string eDistanceContentDirectory, ReadOnlyDictionary<long, List<int>> personKeyToIds, ReadOnlyCollection<Mapping> distinctValidImageMappingCollection)
@ -1343,16 +1348,16 @@ public partial class MapLogic : Shared.Models.Methods.IMapLogic
directoryName = Path.GetDirectoryName(face.Mapping.MappingFromItem.RelativePath);
if (directoryName is null)
throw new NotSupportedException();
if (item.ResizedFileHolder?.DirectoryFullPath is null || !item.ResizedFileHolder.Exists)
if (item.ResizedFileHolder?.DirectoryName is null || !item.ResizedFileHolder.Exists)
continue;
directory = Path.Combine(item.ResizedFileHolder.DirectoryFullPath, $"{_PropertyConfiguration.ResultAllInOne}Shortcuts", _PropertyConfiguration.ResultAllInOne);
directory = Path.Combine(item.ResizedFileHolder.DirectoryName, $"{_PropertyConfiguration.ResultAllInOne}Shortcuts", _PropertyConfiguration.ResultAllInOne);
personDirectory = Path.Combine(directory, "No Faces");
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.DirectoryFullPath))
if (face.Mapping.MappingFromItem.ContainerDateTimes.Length > 0 && !distinct.Contains(item.ResizedFileHolder.DirectoryName))
{
distinct.Add(item.ResizedFileHolder.DirectoryFullPath);
directoriesAndDateTimes.Add(new(item.ResizedFileHolder.DirectoryFullPath, face.Mapping.MappingFromItem.ContainerDateTimes));
distinct.Add(item.ResizedFileHolder.DirectoryName);
directoriesAndDateTimes.Add(new(item.ResizedFileHolder.DirectoryName, face.Mapping.MappingFromItem.ContainerDateTimes));
}
}
}
@ -1361,17 +1366,17 @@ public partial class MapLogic : Shared.Models.Methods.IMapLogic
directoryName = Path.GetDirectoryName(mapping.MappingFromItem.RelativePath);
if (directoryName is null)
throw new NotSupportedException();
if (mapping.MappingFromItem.ResizedFileHolder.DirectoryFullPath is null || !mapping.MappingFromItem.ResizedFileHolder.Exists)
if (mapping.MappingFromItem.ResizedFileHolder.DirectoryName is null || !mapping.MappingFromItem.ResizedFileHolder.Exists)
continue;
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.DirectoryFullPath))
if (mapping.MappingFromItem.ContainerDateTimes.Length > 0 && !distinct.Contains(mapping.MappingFromItem.ResizedFileHolder.DirectoryName))
{
distinct.Add(mapping.MappingFromItem.ResizedFileHolder.DirectoryFullPath);
directoriesAndDateTimes.Add(new(mapping.MappingFromItem.ResizedFileHolder.DirectoryFullPath, mapping.MappingFromItem.ContainerDateTimes));
distinct.Add(mapping.MappingFromItem.ResizedFileHolder.DirectoryName);
directoriesAndDateTimes.Add(new(mapping.MappingFromItem.ResizedFileHolder.DirectoryName, mapping.MappingFromItem.ContainerDateTimes));
}
directory = Path.Combine(mapping.MappingFromItem.ResizedFileHolder.DirectoryFullPath, $"{_PropertyConfiguration.ResultAllInOne}Shortcuts", _PropertyConfiguration.ResultAllInOne);
directory = Path.Combine(mapping.MappingFromItem.ResizedFileHolder.DirectoryName, $"{_PropertyConfiguration.ResultAllInOne}Shortcuts", _PropertyConfiguration.ResultAllInOne);
personDirectory = Path.Combine(directory, "Unknown");
fileName = Path.Combine(personDirectory, $"{mapping.MappingFromItem.ResizedFileHolder.Name}.lnk");
collection.Add(new(mapping.MappingFromItem.ResizedFileHolder.FullName, personDirectory, dateTime, fileName, mapping.MappingFromLocation?.DeterministicHashCodeKey, MakeAllHidden: false));
@ -1389,12 +1394,12 @@ public partial class MapLogic : Shared.Models.Methods.IMapLogic
if (string.IsNullOrEmpty(mapping.MappingFromPerson.DisplayDirectoryName))
throw new NotSupportedException();
personKeyFormatted = IPersonBirthday.GetFormatted(_Configuration.PersonBirthdayFormat, mapping.MappingFromPerson.PersonKey);
if (mapping.MappingFromItem.ContainerDateTimes.Length > 0 && !distinct.Contains(mapping.MappingFromItem.ResizedFileHolder.DirectoryFullPath))
if (mapping.MappingFromItem.ContainerDateTimes.Length > 0 && !distinct.Contains(mapping.MappingFromItem.ResizedFileHolder.DirectoryName))
{
distinct.Add(mapping.MappingFromItem.ResizedFileHolder.DirectoryFullPath);
directoriesAndDateTimes.Add(new(mapping.MappingFromItem.ResizedFileHolder.DirectoryFullPath, mapping.MappingFromItem.ContainerDateTimes));
distinct.Add(mapping.MappingFromItem.ResizedFileHolder.DirectoryName);
directoriesAndDateTimes.Add(new(mapping.MappingFromItem.ResizedFileHolder.DirectoryName, mapping.MappingFromItem.ContainerDateTimes));
}
directory = Path.Combine(mapping.MappingFromItem.ResizedFileHolder.DirectoryFullPath, $"{_PropertyConfiguration.ResultAllInOne}Shortcuts", personKeyFormatted);
directory = Path.Combine(mapping.MappingFromItem.ResizedFileHolder.DirectoryName, $"{_PropertyConfiguration.ResultAllInOne}Shortcuts", personKeyFormatted);
if (!personKeyToIds.TryGetValue(mapping.MappingFromPerson.PersonKey, out ids))
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.DirectoryFullPath))
if (string.IsNullOrEmpty(locationContainer.FilePath.DirectoryName))
continue;
personNameDirectoryName = Path.GetFileName(locationContainer.FilePath.DirectoryFullPath);
yearDirectory = Path.GetDirectoryName(locationContainer.FilePath.DirectoryFullPath);
personNameDirectoryName = Path.GetFileName(locationContainer.FilePath.DirectoryName);
yearDirectory = Path.GetDirectoryName(locationContainer.FilePath.DirectoryName);
if (string.IsNullOrEmpty(yearDirectory))
continue;
yearDirectoryName = Path.GetFileName(yearDirectory);

View File

@ -64,22 +64,21 @@ 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(locationContainer);
locationContainers.Add(new(dateOnly,
exifDirectory,
mappedFile.DirectoryNumber,
personDisplayDirectoryName,
null,
null,
mappedFile.FilePath,
fromDistanceContent,
id.Value,
null,
null,
mappedFile.PersonKey,
rectangle,
wholePercentages.Value));
}
private static ReadOnlyDictionary<int, ReadOnlyDictionary<int, LocationContainer>> GetReadOnly(Dictionary<int, Dictionary<int, LocationContainer>> keyValuePairs)
@ -94,26 +93,33 @@ 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 = [];
Dictionary<string, string> personKeyFormattedToNewestPersonKeyFormatted = [];
ReadOnlyCollection<string> readOnlyPersonKeyFormattedCollection;
ReadOnlyDictionary<string, string> readOnlyPersonKeyFormattedToNewestPersonKeyFormatted;
SetSkipCollections(configuration, personContainers, a2PeopleSingletonDirectory, skipCollection, skipNotSkipCollection);
SetPersonCollectionsAfterSetSkipCollections(configuration, personContainers, personKeyFormattedToNewestPersonKeyFormatted, personKeyFormattedCollection);
List<Record> records = DistanceLogic.DeleteEmptyDirectoriesAndGetCollection(propertyConfiguration, configuration, ticks, eDistanceContentDirectory, personKeyFormattedToNewestPersonKeyFormatted.AsReadOnly(), personKeyFormattedCollection.AsReadOnly());
{
List<string> personKeyFormattedCollection = [];
Dictionary<string, string> personKeyFormattedToNewestPersonKeyFormatted = [];
SetPersonCollections(configuration, personContainers, personKeyFormattedToNewestPersonKeyFormatted, personKeyFormattedCollection);
readOnlyPersonKeyFormattedCollection = new(personKeyFormattedCollection);
readOnlyPersonKeyFormattedToNewestPersonKeyFormatted = new(personKeyFormattedToNewestPersonKeyFormatted);
}
List<Record> records = DistanceLogic.DeleteEmptyDirectoriesAndGetCollection(propertyConfiguration, configuration, ticks, eDistanceContentDirectory, readOnlyPersonKeyFormattedToNewestPersonKeyFormatted, readOnlyPersonKeyFormattedCollection);
List<MappedFile> mappedFiles = GetMappedFiles(propertyConfiguration, configuration, personContainers, records);
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, skipCollection.AsReadOnly(), locationContainers, mappedFiles[i]);
MappedParallelFor(propertyConfiguration, configuration, readOnlySkipNotSkipCollection, locationContainers, mappedFiles[i]);
});
}
foreach (LocationContainer locationContainer in locationContainers)
@ -170,22 +176,21 @@ 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(locationContainer);
locationContainers.Add(new(dateOnly,
exifDirectory,
null,
null,
null,
faceFile,
filePath,
fromDistanceContent,
filePath.Id.Value,
null,
null,
null,
rectangle,
wholePercentages.Value));
}
internal static List<LocationContainer> GetAvailable(int maxDegreeOfParallelism, Configuration configuration, IFaceD dFace, long ticks, ReadOnlyCollection<FilePath> filePaths)

View File

@ -83,7 +83,7 @@ internal abstract class MapLogic
}
}
internal static void SetPersonCollectionsAfterSetSkipCollections(Configuration configuration, ReadOnlyCollection<PersonContainer> personContainers, Dictionary<string, string> personKeyFormattedToNewestPersonKeyFormatted, List<string> personKeyFormattedCollection)
internal static void SetPersonCollections(Configuration configuration, ReadOnlyCollection<PersonContainer> personContainers, Dictionary<string, string> personKeyFormattedToNewestPersonKeyFormatted, List<string> personKeyFormattedCollection)
{
string personKeyFormatted;
string newestPersonKeyFormatted;
@ -215,21 +215,21 @@ internal abstract class MapLogic
{
if (duplicate.Percent is null)
continue;
_ = Process.Start("explorer.exe", string.Concat("\"", duplicate.FilePath.DirectoryFullPath, "\""));
_ = Process.Start("explorer.exe", string.Concat("\"", duplicate.FilePath.DirectoryName, "\""));
personKeyFormatted = IPersonBirthday.GetFormatted(configuration.PersonBirthdayFormat, duplicate.PersonKey);
}
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.DirectoryFullPath, "\""));
_ = Process.Start("explorer.exe", string.Concat("\"", filePath.DirectoryName, "\""));
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.DirectoryFullPath, "\""));
_ = Process.Start("explorer.exe", string.Concat("\"", filePath.DirectoryName, "\""));
personKeyFormatted = IPersonBirthday.GetFormatted(configuration.PersonBirthdayFormat, personKey);
}
}
@ -418,7 +418,7 @@ internal abstract class MapLogic
if (check)
continue;
personBirthday = IPersonBirthday.GetPersonBirthday(personKey + (oneHour * 2));
personContainer = PersonContainer.Get(approximateYears, [personBirthday], new(personDisplayDirectoryAllFilePaths), configuration.MappingDefaultName, personKey);
personContainer = new(approximateYears, [personBirthday], new(personDisplayDirectoryAllFilePaths), configuration.MappingDefaultName, personKey);
results.Add(personContainer);
if (results.Count > 99)
break;
@ -447,9 +447,6 @@ 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)
{
@ -458,13 +455,9 @@ internal abstract class MapLogic
continue;
if (distinct.Contains(record.MappedFaceFilePath.Name))
continue;
personKey = personBirthday.Value.Ticks;
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));
personKey = personBirthday.Value.Ticks;
results.Add(new(personKey, record.PersonKeyFormatted, record.PersonDisplayDirectoryName, record.DirectoryNumber, record.MappedFaceFilePath));
}
for (int i = results.Count - 1; i > -1; i--)
{
@ -542,22 +535,21 @@ 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(locationContainer);
locationContainers.Add(new(dateOnly,
exifDirectory,
mappedFile.DirectoryNumber,
personDisplayDirectoryName,
null,
null,
mappedFile.FilePath,
fromDistanceContent,
id.Value,
null,
null,
mappedFile.PersonKey,
rectangle,
wholePercentages.Value));
}
private static void LookForPossibleDuplicates(Configuration configuration, ReadOnlyCollection<LocationContainer> locationContainers)
@ -747,7 +739,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 = PersonContainer.Get(configuration.PersonCharacters.ToArray(), personBirthday, personDisplayDirectoryName, personDirectory);
personContainer = new(configuration.PersonCharacters.ToArray(), personBirthday, personDisplayDirectoryName, personDirectory);
personKeyFormattedToPersonContainer.Add(personKeyFormattedIdThenWholePercentages.PersonKeyFormatted, personContainer);
}
if (personContainer.Key is null)
@ -847,9 +839,9 @@ internal abstract class MapLogic
continue;
personBirthday = IPersonBirthday.GetPersonBirthday(keyValuePair.Key);
if (!personKeyToPersonContainerCollection.TryGetValue(keyValuePair.Key, out collection))
personContainer = PersonContainer.Get(approximateYears, personBirthday, displayDirectoryName, keyValuePair.Key);
personContainer = new(approximateYears, personBirthday, displayDirectoryName, keyValuePair.Key);
else
personContainer = PersonContainer.Get(approximateYears, personBirthday, collection[zero].PersonDirectory, displayDirectoryName, keyValuePair.Key);
personContainer = new(approximateYears, personBirthday, collection[zero].PersonDirectory, displayDirectoryName, keyValuePair.Key);
personKeyToPersonContainer.Add(keyValuePair.Key, personContainer);
}
}
@ -963,7 +955,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].DirectoryFullPath);
directoryName = Path.GetFileName(personContainer.DisplayDirectoryAllFilePaths[i].DirectoryName);
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.DirectoryFullPath;
personNameDirectory = fileHolder.DirectoryName;
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>net9.0</TargetFramework>
<TargetFramework>net8.0</TargetFramework>
<UserSecretsId>f89b7242-dbb0-4349-b950-657eb8cf87ef</UserSecretsId>
</PropertyGroup>
<PropertyGroup>
<PackageId>Phares.View.by.Distance.Metadata.Query</PackageId>
<GeneratePackageOnBuild>false</GeneratePackageOnBuild>
<Version>9.0.100.1</Version>
<Version>8.0.101.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="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" />
<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" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Property\Property.csproj" />

View File

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

View File

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

View File

@ -4,12 +4,12 @@
<Nullable>enable</Nullable>
<OutputType>library</OutputType>
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
<TargetFramework>net9.0</TargetFramework>
<TargetFramework>net8.0</TargetFramework>
</PropertyGroup>
<PropertyGroup>
<PackageId>Phares.View.by.Distance.Metadata</PackageId>
<GeneratePackageOnBuild>false</GeneratePackageOnBuild>
<Version>9.0.100.1</Version>
<Version>8.0.101.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="9.0.0" />
<PackageReference Include="System.Text.Json" Version="8.0.4" />
</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>net9.0</TargetFramework>
<TargetFramework>net8.0</TargetFramework>
<UserSecretsId>fa06c6db-0226-42ca-8728-68b1e336184d</UserSecretsId>
</PropertyGroup>
<PropertyGroup>
<PackageId>Phares.View.by.Distance.Mirror.Length</PackageId>
<GeneratePackageOnBuild>false</GeneratePackageOnBuild>
<Version>9.0.100.1</Version>
<Version>8.0.101.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="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" />
<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" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Property\Property.csproj" />

View File

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

View File

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

View File

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

View File

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

View File

@ -4,13 +4,13 @@
<Nullable>enable</Nullable>
<OutputType>Exe</OutputType>
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
<TargetFramework>net9.0</TargetFramework>
<TargetFramework>net8.0</TargetFramework>
<UserSecretsId>ce31220e-ef92-4e68-89c5-91b027a94dca</UserSecretsId>
</PropertyGroup>
<PropertyGroup>
<PackageId>Phares.View.by.Distance.Move.By.Id</PackageId>
<GeneratePackageOnBuild>false</GeneratePackageOnBuild>
<Version>9.0.100.1</Version>
<Version>8.0.101.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="9.0.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.UserSecrets" Version="9.0.0" />
<PackageReference Include="Microsoft.Extensions.Hosting" Version="9.0.0" />
<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" />
</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.DirectoryFullPath is null)
if (fileHolder.ExtensionLowered == ".id" || fileHolder.DirectoryName is null)
continue;
if (allFiles.Contains($"{fileHolder.FullName}.id"))
continue;

View File

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

View File

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

View File

@ -4,13 +4,13 @@
<Nullable>enable</Nullable>
<OutputType>Exe</OutputType>
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
<TargetFramework>net9.0</TargetFramework>
<TargetFramework>net8.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>9.0.100.1</Version>
<Version>8.0.101.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="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" />
<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" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Property\Property.csproj" />

View File

@ -216,17 +216,6 @@ 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>net9.0</TargetFramework>
<TargetFramework>net8.0</TargetFramework>
</PropertyGroup>
<PropertyGroup>
<PackageId>Phares.View.by.Distance.PhotoPrism</PackageId>
<GeneratePackageOnBuild>false</GeneratePackageOnBuild>
<Version>9.0.100.1</Version>
<Version>8.0.101.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="9.0.0" />
<PackageReference Include="System.Text.Json" Version="8.0.4" />
</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>net9.0</TargetFramework>
<TargetFramework>net8.0</TargetFramework>
</PropertyGroup>
<PropertyGroup>
<PackageId>Phares.View.by.Distance.PrepareForOld</PackageId>
<GeneratePackageOnBuild>false</GeneratePackageOnBuild>
<Version>9.0.100.1</Version>
<Version>8.0.101.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="9.0.0" />
<PackageReference Include="Microsoft.Extensions.Hosting" Version="8.0.0" />
<PackageReference Include="ShellProgressBar" Version="5.2.0" />
<PackageReference Include="System.Drawing.Common" Version="8.0.10" />
<PackageReference Include="System.Text.Json" Version="9.0.0" />
<PackageReference Include="System.Drawing.Common" Version="8.0.7" />
<PackageReference Include="System.Text.Json" Version="8.0.4" />
<PackageReference Include="MetadataExtractor" Version="2.8.1" />
<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="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" />
</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>net9.0</TargetFramework>
<TargetFramework>net8.0</TargetFramework>
</PropertyGroup>
<PropertyGroup>
<PackageId>Phares.View.by.Distance.Property.Compare</PackageId>
<GeneratePackageOnBuild>false</GeneratePackageOnBuild>
<Version>9.0.100.1</Version>
<Version>8.0.101.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.10" />
<PackageReference Include="System.Text.Json" Version="9.0.0" />
<PackageReference Include="System.Drawing.Common" Version="8.0.7" />
<PackageReference Include="System.Text.Json" Version="8.0.4" />
</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, ReadOnlyCollection<string>> _FileGroups;
private readonly ReadOnlyDictionary<string, 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.DirectoryFullPath is null)
throw new NullReferenceException(nameof(item.FilePath.DirectoryFullPath));
SetAngleBracketCollection(item.FilePath.DirectoryFullPath, !item.IsUniqueFileName);
if (item.FilePath.DirectoryName is null)
throw new NullReferenceException(nameof(item.FilePath.DirectoryName));
SetAngleBracketCollection(item.FilePath.DirectoryName, !item.IsUniqueFileName);
}
bool isIgnoreExtension = item.IsValidImageFormatExtension && _PropertyConfiguration.IgnoreExtensions.Contains(item.FilePath.ExtensionLowered);
result = GetImageProperty(metadata, item, sourceDirectoryFileTuples, parseExceptions, isIgnoreExtension);

View File

@ -28,11 +28,9 @@ 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()
@ -83,11 +81,9 @@ 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,
@ -110,11 +106,9 @@ 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,10 +31,8 @@ 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,
@ -58,11 +56,9 @@ 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;
@ -86,11 +82,9 @@ 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>net9.0</TargetFramework>
<TargetFramework>net8.0</TargetFramework>
</PropertyGroup>
<PropertyGroup>
<PackageId>Phares.View.by.Distance.Property</PackageId>
<GeneratePackageOnBuild>false</GeneratePackageOnBuild>
<Version>9.0.100.1</Version>
<Version>8.0.101.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="9.0.0" />
<PackageReference Include="Microsoft.Extensions.Hosting" Version="8.0.0" />
<PackageReference Include="ShellProgressBar" Version="5.2.0" />
<PackageReference Include="System.Drawing.Common" Version="8.0.10" />
<PackageReference Include="System.Text.Json" Version="9.0.0" />
<PackageReference Include="System.Drawing.Common" Version="8.0.7" />
<PackageReference Include="System.Text.Json" Version="8.0.4" />
</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 FastForwardMovingPictureExpertsGroupFilesPresent,
bool FfmpegFilesPresent,
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.DirectoryFullPath is null)
if (fileHolder.ExtensionLowered == ".paddedId" || fileHolder.ExtensionLowered == ".lsv" || fileHolder.DirectoryName 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)
fastForwardMovingPictureExpertsGroupFiles = null;
ffmpegFiles = 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.DirectoryFullPath)
.WithWorkingDirectory(fileHolder.DirectoryName)
.ExecuteAsync();
result.Task.Wait();
fastForwardMovingPictureExpertsGroupFiles = Directory.GetFiles(fileHolder.DirectoryFullPath, $"{fileHolder.Name}-*.jpg", SearchOption.TopDirectoryOnly);
if (fastForwardMovingPictureExpertsGroupFiles.Length == 0)
ffmpegFiles = Directory.GetFiles(fileHolder.DirectoryName, $"{fileHolder.Name}-*.jpg", SearchOption.TopDirectoryOnly);
if (ffmpegFiles.Length == 0)
continue;
fileHolder = Shared.Models.Stateless.Methods.IFileHolder.Get(fastForwardMovingPictureExpertsGroupFiles.First());
fileHolder = Shared.Models.Stateless.Methods.IFileHolder.Get(ffmpegFiles.First());
if (!fileHolder.Name.EndsWith("-0001.jpg"))
throw new Exception();
isValidImageFormatExtension = _PropertyConfiguration.ValidImageFormatExtensions.Contains(fileHolder.ExtensionLowered);
isIgnoreExtension = isValidImageFormatExtension && _PropertyConfiguration.IgnoreExtensions.Contains(fileHolder.ExtensionLowered);
if (isIgnoreExtension || !isValidImageFormatExtension)
continue;
if (fileHolder.DirectoryFullPath is null)
if (fileHolder.DirectoryName is null)
continue;
}
(dateTimeOriginal, dateTimes, id, message) = Property.Models.Stateless.IProperty.Get(_PropertyConfiguration, _PropertyConfiguration.PopulatePropertyId, metadata, fileHolder, isIgnoreExtension, isValidImageFormatExtension, asciiEncoding);
if (fastForwardMovingPictureExpertsGroupFiles is not null)
if (ffmpegFiles is not null)
{
fileHolder = Shared.Models.Stateless.Methods.IFileHolder.Get(files[i]);
foreach (string fastForwardMovingPictureExpertsGroupFile in fastForwardMovingPictureExpertsGroupFiles)
File.Delete(fastForwardMovingPictureExpertsGroupFile);
foreach (string ffmpegFile in ffmpegFiles)
File.Delete(ffmpegFile);
}
if (message is not null)
throw new Exception(message);
results.Add(new(i + offset, isIgnoreExtension, isValidImageFormatExtension, [fileHolder], fastForwardMovingPictureExpertsGroupFiles is null, dateTimeOriginal, dateTimes, id));
results.Add(new(i + offset, isIgnoreExtension, isValidImageFormatExtension, [fileHolder], ffmpegFiles is null, dateTimeOriginal, dateTimes, id));
}
return results;
}
@ -311,7 +311,7 @@ public class Rename
fileHolder = record.FileHolders.First();
if (!fileHolder.Exists)
continue;
if (string.IsNullOrEmpty(fileHolder.DirectoryFullPath))
if (string.IsNullOrEmpty(fileHolder.DirectoryName))
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.DirectoryFullPath, $"{fileHolder.NameWithoutExtension}{jpg}.paddedId");
checkFile = Path.Combine(fileHolder.DirectoryName, $"{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.DirectoryFullPath, checkFile));
results.Add(new(Shared.Models.Stateless.Methods.IFileHolder.Get($"{fileHolder.FullName}.paddedId"), fileHolder.DirectoryName, checkFile));
}
checkFile = Path.Combine(fileHolder.DirectoryFullPath, $"{fileHolder.NameWithoutExtension}{jpg}");
checkFile = Path.Combine(fileHolder.DirectoryName, $"{fileHolder.NameWithoutExtension}{jpg}");
if (File.Exists(checkFile))
continue;
if (distinct.Contains(checkFile))
continue;
distinct.Add(checkFile);
results.Add(new(fileHolder, fileHolder.DirectoryFullPath, checkFile));
results.Add(new(fileHolder, fileHolder.DirectoryName, checkFile));
if (nefPresent)
results.Add(new(Shared.Models.Stateless.Methods.IFileHolder.Get($"{fileHolder.FullName[..^4]}.tif"), fileHolder.DirectoryFullPath, $"{checkFile[..^4]}.tif"));
results.Add(new(Shared.Models.Stateless.Methods.IFileHolder.Get($"{fileHolder.FullName[..^4]}.tif"), fileHolder.DirectoryName, $"{checkFile[..^4]}.tif"));
if (nefPresent)
results.Add(new(Shared.Models.Stateless.Methods.IFileHolder.Get($"{fileHolder.FullName[..^4]}.nef"), fileHolder.DirectoryFullPath, $"{checkFile[..^4]}.nef"));
results.Add(new(Shared.Models.Stateless.Methods.IFileHolder.Get($"{fileHolder.FullName[..^4]}.nef"), fileHolder.DirectoryName, $"{checkFile[..^4]}.nef"));
if (File.Exists(checkFile))
continue;
File.Move(fileHolder.FullName, checkFile);
fileHolder = Shared.Models.Stateless.Methods.IFileHolder.Get(checkFile);
if (fileHolder.DirectoryFullPath is null)
if (fileHolder.DirectoryName 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.DirectoryFullPath);
(isWrongYear, seasonDirectory) = (null, !_AppSettings.ForceIdName ? null : fileHolder.DirectoryName);
else
(isWrongYear, seasonDirectory) = (null, !_AppSettings.ForceIdName ? null : Path.Combine(fileHolder.DirectoryFullPath, _AppSettings.DefaultUnknownDirectoryName));
(isWrongYear, seasonDirectory) = (null, !_AppSettings.ForceIdName ? null : Path.Combine(fileHolder.DirectoryName, _AppSettings.DefaultUnknownDirectoryName));
}
else
{
directoryName = Path.GetFileName(fileHolder.DirectoryFullPath);
directoryName = Path.GetFileName(fileHolder.DirectoryName);
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.DirectoryFullPath, $"{dateTime.Year}.{season} {seasonName}");
seasonDirectory = Path.Combine(fileHolder.DirectoryName, $"{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.DirectoryFullPath, $"{minimumDateTime.Value:yyyy-MM-dd}.{minimumDateTime.Value.Ticks}.{fileHolder.Length}{checkFileExtension}");
checkFile = Path.Combine(fileHolder.DirectoryName, $"{minimumDateTime.Value:yyyy-MM-dd}.{minimumDateTime.Value.Ticks}.{fileHolder.Length}{checkFileExtension}");
if (checkFile == fileHolder.FullName)
continue;
if (distinct.Contains(checkFile))
continue;
distinct.Add(checkFile);
results.Add(new(fileHolder, fileHolder.DirectoryFullPath, checkFile));
results.Add(new(fileHolder, fileHolder.DirectoryName, checkFile));
if (nefPresent)
results.Add(new(Shared.Models.Stateless.Methods.IFileHolder.Get($"{fileHolder.FullName[..^4]}.tif"), fileHolder.DirectoryFullPath, $"{checkFile[..^4]}.tif"));
results.Add(new(Shared.Models.Stateless.Methods.IFileHolder.Get($"{fileHolder.FullName[..^4]}.tif"), fileHolder.DirectoryName, $"{checkFile[..^4]}.tif"));
if (nefPresent)
results.Add(new(Shared.Models.Stateless.Methods.IFileHolder.Get($"{fileHolder.FullName[..^4]}.nef"), fileHolder.DirectoryFullPath, $"{checkFile[..^4]}.nef"));
results.Add(new(Shared.Models.Stateless.Methods.IFileHolder.Get($"{fileHolder.FullName[..^4]}.nef"), fileHolder.DirectoryName, $"{checkFile[..^4]}.nef"));
}
else
{

View File

@ -4,13 +4,13 @@
<Nullable>enable</Nullable>
<OutputType>Exe</OutputType>
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
<TargetFramework>net9.0</TargetFramework>
<TargetFramework>net8.0</TargetFramework>
<UserSecretsId>6e026d2f-9edf-4c6c-a042-162758114e9a</UserSecretsId>
</PropertyGroup>
<PropertyGroup>
<PackageId>Phares.View.by.Distance.Rename</PackageId>
<GeneratePackageOnBuild>false</GeneratePackageOnBuild>
<Version>9.0.100.1</Version>
<Version>8.0.101.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.7.0" />
<PackageReference Include="CliWrap" Version="3.6.6" />
<PackageReference Include="Humanizer.Core" Version="2.14.1" />
<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="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" />
</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, ReadOnlyCollection<string>> keyValuePairs = Shared.Models.Stateless.Methods.IPath.GetKeyValuePairs(_PropertyConfiguration, cResultsFullGroupDirectory, [_PropertyConfiguration.ResultSingleton]);
foreach (KeyValuePair<string, ReadOnlyCollection<string>> keyValuePair in keyValuePairs)
ReadOnlyDictionary<string, string[]> keyValuePairs = Shared.Models.Stateless.Methods.IPath.GetKeyValuePairs(_PropertyConfiguration, cResultsFullGroupDirectory, [_PropertyConfiguration.ResultSingleton]);
foreach (KeyValuePair<string, string[]> keyValuePair in keyValuePairs)
_FileGroups.Add(keyValuePair.Key, keyValuePair.Value);
}
@ -94,12 +94,11 @@ public class C_Resize
#pragma warning disable CA1416
public static (ImageCodecInfo imageCodecInfo, EncoderParameters encoderParameters, string filenameExtension) GetJpegLowQuality()
public static (ImageCodecInfo imageCodecInfo, EncoderParameters encoderParameters, string filenameExtension) GetGifLowQuality()
{
(ImageCodecInfo, EncoderParameters, string) result;
ImageFormat imageFormat = ImageFormat.Jpeg;
ImageCodecInfo[] imageCodecInfoCollection = ImageCodecInfo.GetImageEncoders();
ImageCodecInfo imageCodecInfo = (from l in imageCodecInfoCollection where l.FormatID == imageFormat.Guid select l).First();
ImageFormat imageFormat = ImageFormat.Gif;
ImageCodecInfo imageCodecInfo = (from l in ImageCodecInfo.GetImageEncoders() 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))
@ -112,8 +111,7 @@ public class C_Resize
{
(ImageCodecInfo, EncoderParameters, string) result;
ImageFormat imageFormat = ImageFormat.Png;
ImageCodecInfo[] imageCodecInfoCollection = ImageCodecInfo.GetImageEncoders();
ImageCodecInfo imageCodecInfo = (from l in imageCodecInfoCollection where l.FormatID == imageFormat.Guid select l).First();
ImageCodecInfo imageCodecInfo = (from l in ImageCodecInfo.GetImageEncoders() 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))
@ -137,8 +135,7 @@ public class C_Resize
".tiff" => ImageFormat.Tiff,
_ => throw new Exception(),
};
ImageCodecInfo[] imageCodecInfoCollection = ImageCodecInfo.GetImageEncoders();
ImageCodecInfo imageCodecInfo = (from l in imageCodecInfoCollection where l.FormatID == imageFormat.Guid select l).First();
ImageCodecInfo imageCodecInfo = (from l in ImageCodecInfo.GetImageEncoders() 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>net9.0</TargetFramework>
<TargetFramework>net8.0</TargetFramework>
</PropertyGroup>
<PropertyGroup>
<PackageId>Phares.View.by.Distance.Resize</PackageId>
<GeneratePackageOnBuild>false</GeneratePackageOnBuild>
<Version>9.0.100.1</Version>
<Version>8.0.101.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.10" />
<PackageReference Include="System.Text.Json" Version="9.0.0" />
<PackageReference Include="System.Drawing.Common" Version="8.0.7" />
<PackageReference Include="System.Text.Json" Version="8.0.4" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Shared\View-by-Distance.Shared.csproj" />

View File

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

View File

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

View File

@ -4,13 +4,13 @@
<Nullable>enable</Nullable>
<OutputType>Exe</OutputType>
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
<TargetFramework>net9.0</TargetFramework>
<TargetFramework>net8.0</TargetFramework>
<UserSecretsId>b3bbcc69-1439-4e86-9bbf-75c8e8839cc0</UserSecretsId>
</PropertyGroup>
<PropertyGroup>
<PackageId>Phares.View.by.Distance.Set.Created.Date</PackageId>
<GeneratePackageOnBuild>false</GeneratePackageOnBuild>
<Version>9.0.100.1</Version>
<Version>8.0.101.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="9.0.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.UserSecrets" Version="9.0.0" />
<PackageReference Include="Microsoft.Extensions.Hosting" Version="9.0.0" />
<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" />
</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.DirectoryFullPath is null)
if (fileHolder.ExtensionLowered == ".id" || fileHolder.ExtensionLowered == ".lsv" || fileHolder.DirectoryName 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,14 +40,8 @@ public record class FaceDistance : Properties.IFaceDistance
public override string ToString()
{
string result = JsonSerializer.Serialize(this, FaceDistanceSourceGenerationContext.Default.FaceDistance);
string result = JsonSerializer.Serialize(this, new JsonSerializerOptions() { WriteIndented = true });
return result;
}
}
[JsonSourceGenerationOptions(WriteIndented = true)]
[JsonSerializable(typeof(FaceDistance))]
internal partial class FaceDistanceSourceGenerationContext : JsonSerializerContext
{
}

View File

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

View File

@ -4,13 +4,11 @@ namespace View_by_Distance.Shared.Models;
public record FaceFile(int? AreaPermyriad,
int? ConfidencePercent,
string? DMS,
DateTime DateTime,
FaceEncoding? FaceEncoding,
string? DMS,
Dictionary<Stateless.FacePart, FacePoint[]>? FaceParts,
Location? Location,
string? Maker,
MappingFromPerson? MappingFromPerson,
string? Model,
OutputResolution? OutputResolution);
@ -18,16 +16,4 @@ 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,35 +1,58 @@
using System.Drawing;
using System.Text.Json;
using System.Text.Json.Serialization;
namespace View_by_Distance.Shared.Models;
[method: JsonConstructor]
public class FacePoint(int index, int x, int y) : Properties.IFacePoint
public class FacePoint : Properties.IFacePoint
{
public int Index { get; } = index;
public int X { get; } = x;
public int Y { get; } = y;
private readonly Point _Point = new(x, y);
protected int _Index;
protected int _X;
protected int _Y;
public int Index => _Index;
public int X => _X;
public int Y => _Y;
private readonly Point _Point;
[JsonConstructor]
public FacePoint(int index, int x, int y)
{
_Index = index;
_X = x;
_Y = y;
_Point = new(x, y);
}
public FacePoint(Point point, int index) :
this(index, point.X, point.Y)
{ }
public override bool Equals(object? obj) => obj is FacePoint point && Equals(point);
public override 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? DirectoryFullPath,
string? DirectoryName,
bool Exists,
string ExtensionLowered,
string FullName,
@ -49,7 +49,7 @@ public record FileHolder(DateTime? CreationTime,
{
FileHolder result;
result = new(new(filePath.CreationTicks),
filePath.DirectoryFullPath,
filePath.DirectoryName,
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 DirectoryFullPath,
string DirectoryName,
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.DirectoryFullPath ?? throw new NullReferenceException();
string fileDirectoryName = fileHolder.DirectoryName ?? 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

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

View File

@ -5,33 +5,11 @@ namespace View_by_Distance.Shared.Models;
public record ImmichAsset([property: JsonPropertyName("id")] string Id,
[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("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)
[property: JsonPropertyName("previewPath")] string PreviewPath,
[property: JsonPropertyName("isFavorite")] bool IsFavorite,
[property: JsonPropertyName("thumbnailPath")] string ThumbnailPath,
[property: JsonPropertyName("thumbhash")] string Thumbhash)
{
public override string ToString()

View File

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

View File

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

View File

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

View File

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

View File

@ -4,57 +4,53 @@ using System.Text.Json.Serialization;
namespace View_by_Distance.Shared.Models;
public record PersonContainer(int? ApproximateYears,
PersonBirthday[]? Birthdays,
ReadOnlyCollection<FilePath> DisplayDirectoryAllFilePaths,
string DisplayDirectoryName,
long? Key,
PersonDirectory? PersonDirectory)
public class PersonContainer : Properties.IPersonContainer
{
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, PersonContainerSourceGenerationContext.Default.PersonContainer);
string result = JsonSerializer.Serialize(this, new JsonSerializerOptions() { WriteIndented = true });
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,5 +1,4 @@
using System.Text.Json;
using System.Text.Json.Serialization;
namespace View_by_Distance.Shared.Models;
@ -8,14 +7,8 @@ public record PersonDirectory(char Char, string Group, char Status, char Sex, ch
public override string ToString()
{
string result = JsonSerializer.Serialize(this, PersonDirectorySourceGenerationContext.Default.PersonDirectory);
string result = JsonSerializer.Serialize(this, new JsonSerializerOptions() { WriteIndented = true });
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,7 +6,6 @@ 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