PhotoPrism

This commit is contained in:
Mike Phares 2022-12-27 08:57:12 -07:00
parent d08cffe50d
commit e5dc8c1c05
25 changed files with 318 additions and 228 deletions

View File

@ -79,7 +79,7 @@
"/zzz Phares Slides/Slides 2015-06-10/Magazine 01"
],
"Configuration": {
"DateGroup": "2022-12-21",
"DateGroup": "2022-12-25",
"DiffPropertyDirectory": "",
"FileNameDirectorySeparator": ".Z.",
"ForcePropertyLastWriteTimeToCreationTime": false,
@ -87,20 +87,20 @@
"Pattern": "[^ABCDEFGHIJKLMNOPQRSTUVWXYZbcdfghjklmnpqrstvwxyz0-9]",
"PopulatePropertyId": true,
"PropertiesChangedForProperty": false,
"RootDirectory": "C:/Tmp/Phares/Compare/Images-4d49b68",
"RootDirectory": "C:/Tmp/Phares/Compare/Images-37c7b67",
"WriteBitmapDataBytes": false,
"IgnoreExtensions": [
".gif",
".GIF"
],
"PropertyContentCollectionFiles": [
"/Images-4d49b68 - Results/A) Property/2022-12-21/[()]/637869381676042455.json",
"/Not-Copy-Copy/Images 2019-06-08 - 34a9240ac28b52da97428d7725153a80a757ee6b - Not-Copy-Copy - Results/A) Property/2022-12-21/[()]/637869733124119330.json",
"/Not-Copy-Copy/Images 2018-12-25 - 34a9240ac28b52da97428d7725153a80a757ee6b - Not-Copy-Copy - Results/A) Property/2022-12-21/[()]/637869734240700328.json",
"/Not-Copy-Copy/Images 2018-05-12 - b01d4763d8853b6d6057a3870b2723449726da75 - Not-Copy-Copy - Results/A) Property/2022-12-21/[()]/637869734970730630.json",
"/Not-Copy-Copy/Images 2013-12-15 - d02c8791fa0b130c0bce2d39ee684e50f7ee7a97 - Not-Copy-Copy - Results/A) Property/2022-12-21/[()]/637869743752078399.json",
"/Not-Copy-Copy - Delta/Amazon Drive - Results/A) Property/2022-12-21/[()]/637869744751177715.json",
"/Not-Copy-Copy - Delta/Blackberry - Results/A) Property/2022-12-21/[()]/637869745134124462.json"
"/Images-37c7b67 - Results/A) Property/2022-12-25/[()]/637869381676042455.json",
"/Not-Copy-Copy/Images 2019-06-08 - 34a9240ac28b52da97428d7725153a80a757ee6b - Not-Copy-Copy - Results/A) Property/2022-12-25/[()]/637869733124119330.json",
"/Not-Copy-Copy/Images 2018-12-25 - 34a9240ac28b52da97428d7725153a80a757ee6b - Not-Copy-Copy - Results/A) Property/2022-12-25/[()]/637869734240700328.json",
"/Not-Copy-Copy/Images 2018-05-12 - b01d4763d8853b6d6057a3870b2723449726da75 - Not-Copy-Copy - Results/A) Property/2022-12-25/[()]/637869734970730630.json",
"/Not-Copy-Copy/Images 2013-12-15 - d02c8791fa0b130c0bce2d39ee684e50f7ee7a97 - Not-Copy-Copy - Results/A) Property/2022-12-25/[()]/637869743752078399.json",
"/Not-Copy-Copy - Delta/Amazon Drive - Results/A) Property/2022-12-25/[()]/637869744751177715.json",
"/Not-Copy-Copy - Delta/Blackberry - Results/A) Property/2022-12-25/[()]/637869745134124462.json"
],
"ValidImageFormatExtensions": [
".bmp",

View File

@ -50,7 +50,7 @@
"WorkingDirectoryName": "PharesApps",
"Windows": {
"Configuration": {
"DateGroup": "2022-12-21",
"DateGroup": "2022-12-25",
"DiffPropertyDirectory": "",
"FileNameDirectorySeparator": ".Z.",
"ForcePropertyLastWriteTimeToCreationTime": false,
@ -94,13 +94,13 @@
".GIF"
],
"PropertyContentCollectionFiles": [
"/Images-4d49b68 - Results/A) Property/2022-12-21/[()]/637869381676042455.json",
"/Not-Copy-Copy/Images 2019-06-08 - 34a9240ac28b52da97428d7725153a80a757ee6b - Not-Copy-Copy - Results/A) Property/2022-12-21/[()]/637869733124119330.json",
"/Not-Copy-Copy/Images 2018-12-25 - 34a9240ac28b52da97428d7725153a80a757ee6b - Not-Copy-Copy - Results/A) Property/2022-12-21/[()]/637869734240700328.json",
"/Not-Copy-Copy/Images 2018-05-12 - b01d4763d8853b6d6057a3870b2723449726da75 - Not-Copy-Copy - Results/A) Property/2022-12-21/[()]/637869734970730630.json",
"/Not-Copy-Copy/Images 2013-12-15 - d02c8791fa0b130c0bce2d39ee684e50f7ee7a97 - Not-Copy-Copy - Results/A) Property/2022-12-21/[()]/637869743752078399.json",
"/Not-Copy-Copy - Delta/Amazon Drive - Results/A) Property/2022-12-21/[()]/637869744751177715.json",
"/Not-Copy-Copy - Delta/Blackberry - Results/A) Property/2022-12-21/[()]/637869745134124462.json"
"/Images-37c7b67 - Results/A) Property/2022-12-25/[()]/637869381676042455.json",
"/Not-Copy-Copy/Images 2019-06-08 - 34a9240ac28b52da97428d7725153a80a757ee6b - Not-Copy-Copy - Results/A) Property/2022-12-25/[()]/637869733124119330.json",
"/Not-Copy-Copy/Images 2018-12-25 - 34a9240ac28b52da97428d7725153a80a757ee6b - Not-Copy-Copy - Results/A) Property/2022-12-25/[()]/637869734240700328.json",
"/Not-Copy-Copy/Images 2018-05-12 - b01d4763d8853b6d6057a3870b2723449726da75 - Not-Copy-Copy - Results/A) Property/2022-12-25/[()]/637869734970730630.json",
"/Not-Copy-Copy/Images 2013-12-15 - d02c8791fa0b130c0bce2d39ee684e50f7ee7a97 - Not-Copy-Copy - Results/A) Property/2022-12-25/[()]/637869743752078399.json",
"/Not-Copy-Copy - Delta/Amazon Drive - Results/A) Property/2022-12-25/[()]/637869744751177715.json",
"/Not-Copy-Copy - Delta/Blackberry - Results/A) Property/2022-12-25/[()]/637869745134124462.json"
],
"ValidImageFormatExtensions": [
".bmp",

View File

@ -53,9 +53,9 @@
"ByCreateDateShortcut": false,
"ByDay": false,
"ByHash": false,
"BySeason": false,
"BySeason": true,
"ByWeek": false,
"DateGroup": "2022-12-21",
"DateGroup": "2022-12-25",
"FileNameDirectorySeparator": ".Z.",
"ForcePropertyLastWriteTimeToCreationTime": false,
"KeepFullPath": false,
@ -68,10 +68,11 @@
"ResultContent": "()",
"ResultSingleton": "{}",
"xRootDirectory": "C:/Tmp/phares/Pictures",
"xxRootDirectory": "C:/Tmp/Phares/Compare/Images-4d49b68",
"xxxRootDirectory": "F:/Tmp/Phares/Compare/Not-Copy-Copy-4d49b68",
"RootDirectory": "C:/Tmp/Phares/Compare/Not-Copy-Copy-4d49b68",
"xxxxRootDirectory": "F:/Tmp/Phares/2022-11-03-DCIM/DCIM/100D3400 2022",
"xxRootDirectory": "C:/Tmp/Phares/Compare/Images-37c7b67",
"xxxRootDirectory": "F:/Tmp/Phares/Compare/Not-Copy-Copy-37c7b67",
"xxxxRootDirectory": "C:/Tmp/Phares/Compare/Not-Copy-Copy-37c7b67",
"xxxxxRootDirectory": "F:/Tmp/Phares/2022-11-03-DCIM/DCIM/100D3400 2022",
"RootDirectory": "E:/- - - Videos/-",
"WriteBitmapDataBytes": false,
"IgnoreExtensions": [
".gif",

View File

@ -55,7 +55,7 @@
"ByHash": false,
"BySeason": false,
"ByWeek": false,
"DateGroup": "2022-12-21",
"DateGroup": "2022-12-25",
"FileNameDirectorySeparator": ".Z.",
"ForcePropertyLastWriteTimeToCreationTime": false,
"KeepFullPath": false,
@ -68,8 +68,8 @@
"ResultContent": "()",
"ResultSingleton": "{}",
"xRootDirectory": "C:/Tmp/phares/Pictures",
"xxRootDirectory": "C:/Tmp/Phares/Compare/Images-4d49b68",
"RootDirectory": "F:/Tmp/Phares/Compare/Not-Copy-Copy-4d49b68",
"xxRootDirectory": "C:/Tmp/Phares/Compare/Images-37c7b67",
"RootDirectory": "F:/Tmp/Phares/Compare/Not-Copy-Copy-37c7b67",
"xxxxRootDirectory": "F:/Tmp/Phares/2022-11-03-DCIM/DCIM/100D3400 2022",
"WriteBitmapDataBytes": false,
"IgnoreExtensions": [

View File

@ -70,7 +70,8 @@ public class DeleteByDistinct
// if (!fileTicksToNames.TryGetValue(fileInfo.LastWriteTime.Ticks, out fileNames))
// throw new Exception();
// }
checkDate = new DateTime(fileInfo.LastWriteTime.Year, fileInfo.LastWriteTime.Month, fileInfo.LastWriteTime.Day);
checkDate = new DateTime(ticks);
// checkDate = new DateTime(fileInfo.LastWriteTime.Year, fileInfo.LastWriteTime.Month, fileInfo.LastWriteTime.Day);
if (!fileTicksToNames.TryGetValue(checkDate.Ticks, out fileNames))
{
fileTicksToNames.Add(checkDate.Ticks, new());
@ -103,7 +104,11 @@ public class DeleteByDistinct
if (consoleKey is not null && consoleKey.Value == ConsoleKey.Y)
{
foreach (string file in deletedFiles)
File.Delete(file);
{
try
{ File.Delete(file); }
catch (Exception) { }
}
totalSeconds = (int)Math.Floor(new TimeSpan(DateTime.Now.Ticks - ticks).TotalSeconds);
message = $") Looking for empty directories from <{directory}> - {totalSeconds} total second(s)";
progressBar = new(4, message, options);

View File

@ -1,23 +1,21 @@
{
"xCompareRootDirectory": "",
"CompareRootDirectory": "C:/Tmp-x",
"CompareRootDirectory": "F:/7) Question/- - - Images",
"Logging": {
"LogLevel": {
"Log4netProvider": "Debug"
}
},
"MaxDegreeOfParallelism": 6,
"SearchPattern": "*.jpg",
"SearchPattern": "*",
"Serilog": {
"MinimumLevel": "Debug"
},
"Windows": {
"Configuration": {
"xRootDirectory": "C:/Tmp-x",
"xxRootDirectory": "D:/Tmp/Phares/Compare/Not-Copy-Copy-4d49b68",
"xxxRootDirectory": "F:/Tmp/Phares/Compare",
"xxxxRootDirectory": "E:/Tmp/Phares/Compare",
"RootDirectory": "F:/Tmp/Phares/Compare/Images-4d49b68",
"RootDirectory": "D:/2) Images B/Corrupt",
"xxRootDirectory": "D:/2) Images B/Not-Copy-Copy-37c7b67",
"xxxRootDirectory": "G:/1) Images A/Images-37c7b67",
"VerifyToSeason": [
". 2000",
". 2001",

View File

@ -52,7 +52,7 @@
"WorkingDirectoryName": "PharesApps",
"Windows": {
"Configuration": {
"DateGroup": "2022-12-21",
"DateGroup": "2022-12-25",
"DiffPropertyDirectory": "",
"FileNameDirectorySeparator": ".Z.",
"ForcePropertyLastWriteTimeToCreationTime": false,
@ -65,7 +65,7 @@
"ResultCollection": "[]",
"ResultContent": "()",
"ResultSingleton": "{}",
"RootDirectory": "C:/Tmp/Phares/Compare/Images-4d49b68",
"RootDirectory": "C:/Tmp/Phares/Compare/Images-37c7b67",
"WriteBitmapDataBytes": false,
"IgnoreExtensions": [
".gif",

View File

@ -1,7 +1,7 @@
{
"xCompareRootDirectory": "D:/Tmp/Phares/Not-Copy-Copy-4d49b68",
"xCompareRootDirectory": "D:/Tmp/Phares/Not-Copy-Copy-37c7b67",
"xxCompareRootDirectory": "E:/www/Images - Results/C) Resize/2021-11-03/2256 x 1496/()",
"xxxCompareRootDirectory": "C:/Tmp/Phares/Compare/.Delete-Not-Copy-Copy-4d49b68",
"xxxCompareRootDirectory": "C:/Tmp/Phares/Compare/.Delete-Not-Copy-Copy-37c7b67",
"CompareRootDirectory": "C:/Tmp/Phares/Compare/Not-Copy-Copy-Duplicates",
"Logging": {
"LogLevel": {
@ -14,8 +14,8 @@
},
"Windows": {
"Configuration": {
"RootDirectory": "F:/Tmp/Phares/Compare/Images-4d49b68 - Results/A) Property/2022-12-21/{}",
"xRootDirectory": "F:/Tmp/Phares/Compare/Not-Copy-Copy-4d49b68 - Results/A) Property/2022-12-21/{}",
"RootDirectory": "F:/Tmp/Phares/Compare/Images-37c7b67 - Results/A) Property/2022-12-25/{}",
"xRootDirectory": "F:/Tmp/Phares/Compare/Not-Copy-Copy-37c7b67 - Results/A) Property/2022-12-25/{}",
"VerifyToSeason": [
". 2000",
". 2001",

View File

@ -51,7 +51,7 @@
"WorkingDirectoryName": "PharesApps",
"Windows": {
"Configuration": {
"DateGroup": "2022-12-21",
"DateGroup": "2022-12-25",
"DiffPropertyDirectory": "",
"FileNameDirectorySeparator": ".Z.",
"ForcePropertyLastWriteTimeToCreationTime": false,
@ -64,7 +64,7 @@
"ResultCollection": "[]",
"ResultContent": "()",
"ResultSingleton": "{}",
"RootDirectory": "C:/Tmp/Phares/Compare/Images-4d49b68",
"RootDirectory": "C:/Tmp/Phares/Compare/Images-37c7b67",
"WriteBitmapDataBytes": false,
"IgnoreExtensions": [
".gif",

View File

@ -25,6 +25,7 @@ public partial class Form : System.Windows.Forms.Form
private readonly string _WorkingDirectory;
private readonly Configuration _Configuration;
private readonly IsEnvironment _IsEnvironment;
private readonly ProgressBar _InnerProgressBar;
private readonly Dictionary<int, Item> _IdToItem;
private readonly string _ResizeFileNameExtension;
private readonly IConfigurationRoot _ConfigurationRoot;
@ -73,8 +74,10 @@ public partial class Form : System.Windows.Forms.Form
_ResizeFileNameExtension = resizeFileNameExtension;
_TextBox = new() { Location = new(5, 5), Dock = DockStyle.Top };
_ProgressBar = new() { Location = new(5, 5), Dock = DockStyle.Top, Visible = false };
_InnerProgressBar = new() { Location = new(5, 5), Dock = DockStyle.Top, Visible = false };
Load += new EventHandler(Form1_Load);
Controls.Add(_ProgressBar);
Controls.Add(_InnerProgressBar);
Controls.Add(_TextBox);
}
@ -176,15 +179,15 @@ public partial class Form : System.Windows.Forms.Form
string checkFile;
DateTime? dateTime;
FileHolder fileHolder;
_ProgressBar.Step = 1;
bool isIgnoreExtension;
_ProgressBar.Value = 0;
string checkFileExtension;
bool skipOneAllAreNumbers;
DateTime? minimumDateTime;
const string jpg = ".jpg";
_InnerProgressBar.Step = 1;
_InnerProgressBar.Value = 0;
const string jpeg = ".jpeg";
_ProgressBar.Visible = true;
_InnerProgressBar.Visible = true;
bool isValidImageFormatExtension;
string? extraLargeBitmapThumbnail;
string[] files = Directory.GetFiles(directory, searchPattern, SearchOption.TopDirectoryOnly);
@ -193,10 +196,10 @@ public partial class Form : System.Windows.Forms.Form
foreach (string file in files)
File.Delete(file);
}
_ProgressBar.Maximum = files.Length;
_InnerProgressBar.Maximum = files.Length;
foreach (string file in files)
{
_ProgressBar.PerformStep();
_InnerProgressBar.PerformStep();
fileHolder = new(file);
_Lines.Add(fileHolder.NameWithoutExtension);
if (fileHolder.ExtensionLowered == ".id" || fileHolder.DirectoryName is null)
@ -262,7 +265,7 @@ public partial class Form : System.Windows.Forms.Form
File.Move(fileHolder.FullName, checkFile);
File.WriteAllText($"{checkFile}.id", $"{id.Value}{Environment.NewLine}{fileHolder.Name}");
}
_ProgressBar.Visible = false;
_InnerProgressBar.Visible = false;
}
private string? SaveExtraLargeBitmapThumbnail(FileHolder fileHolder)
@ -402,10 +405,15 @@ public partial class Form : System.Windows.Forms.Form
{
string directoryName;
ReadOnlySpan<char> span;
_ProgressBar.Step = 1;
_ProgressBar.Visible = true;
_ProgressBar.Maximum = directories.Count;
for (int i = 1; i < 3; i++)
{
_ProgressBar.Value = 0;
foreach (string directory in directories)
{
_ProgressBar.PerformStep();
if (directory.Length < 6)
continue;
directoryName = Path.GetFileName(directory);
@ -438,6 +446,7 @@ public partial class Form : System.Windows.Forms.Form
}
File.WriteAllLines($"D:/Tmp/Phares/{DateTime.Now.Ticks}.tsv", _Lines);
_Lines.Clear();
_ProgressBar.Visible = false;
}
void Form1_DragDrop(object? sender, DragEventArgs e)

View File

@ -124,8 +124,8 @@
],
"Windows": {
"Configuration": {
"xRootDirectory": "F:/Tmp/Phares/Compare/Images-4d49b68",
"xxRootDirectory": "F:/Tmp/Phares/Compare/Not-Copy-Copy-4d49b68",
"xRootDirectory": "F:/Tmp/Phares/Compare/Images-37c7b67",
"xxRootDirectory": "F:/Tmp/Phares/Compare/Not-Copy-Copy-37c7b67",
"RootDirectory": "E:/",
"VerifyToSeason": [
". 2000",

View File

@ -53,7 +53,7 @@
"WorkingDirectoryName": "PharesApps",
"Windows": {
"Configuration": {
"DateGroup": "2022-12-21",
"DateGroup": "2022-12-25",
"DiffPropertyDirectory": "",
"FileNameDirectorySeparator": ".Z.",
"ForcePropertyLastWriteTimeToCreationTime": false,
@ -66,7 +66,7 @@
"ResultCollection": "[]",
"ResultContent": "()",
"ResultSingleton": "{}",
"RootDirectory": "C:/Tmp/Phares/Compare/Images-4d49b68",
"RootDirectory": "C:/Tmp/Phares/Compare/Images-37c7b67",
"WriteBitmapDataBytes": false,
"IgnoreExtensions": [
".gif",

View File

@ -9,6 +9,7 @@ using View_by_Distance.FaceParts.Models;
using View_by_Distance.Instance.Models;
using View_by_Distance.Map.Models;
using View_by_Distance.Metadata.Models;
using View_by_Distance.PhotoPrism.Models;
using View_by_Distance.Property.Models;
using View_by_Distance.Resize.Models;
using View_by_Distance.Shared.Models;
@ -864,7 +865,7 @@ public partial class DlibDotNet
string dFacesCollectionDirectory = Path.Combine(dResultsFullGroupDirectory, "[]", _Configuration.PropertyConfiguration.ResultAllInOne);
(Dictionary<long, int> personKeyToCount, int totalNotMapped) = mapLogic.AddToMapping(mappingCollection);
if (!string.IsNullOrEmpty(_Configuration.PhotoPrismDirectory) && Directory.Exists(_Configuration.PhotoPrismDirectory))
mapLogic.WriteMatches(ticks, distinctFilteredFaces);
F_PhotoPrism.WriteMatches(_Configuration.PhotoPrismDirectory, _Configuration.PersonBirthdayFormat, ticks, distinctFilteredFaces, mapLogic);
if (_Configuration.SaveShortcutsForOutputResolutions.Contains(outputResolution))
{
List<Item> filteredItems = GetItems(argZero, containers);
@ -1059,8 +1060,7 @@ public partial class DlibDotNet
string d2ResultsFullGroupDirectory;
if (!string.IsNullOrEmpty(_Configuration.PhotoPrismDirectory) && Directory.Exists(_Configuration.PhotoPrismDirectory))
{
Map.Models.MapLogic.SaveMarkers(_Configuration.PhotoPrismDirectory);
Dictionary<string, List<MappingFromPhotoPrism>> fileNameToCollection = Map.Models.MapLogic.GetFileNameToCollection(_Configuration.PhotoPrismDirectory);
Dictionary<string, List<MappingFromPhotoPrism>> fileNameToCollection = F_PhotoPrism.GetFileNameToCollection(_Configuration.PhotoPrismDirectory);
foreach (KeyValuePair<string, List<MappingFromPhotoPrism>> keyValuePair in fileNameToCollection)
_FileNameToCollection.Add(keyValuePair.Key, keyValuePair.Value);
}

View File

@ -55,6 +55,7 @@
<ProjectReference Include="..\FaceParts\FaceParts.csproj" />
<ProjectReference Include="..\Map\Map.csproj" />
<ProjectReference Include="..\Metadata\Metadata.csproj" />
<ProjectReference Include="..\PhotoPrism\PhotoPrism.csproj" />
<ProjectReference Include="..\Property-Compare\Property-Compare.csproj" />
<ProjectReference Include="..\Property\Property.csproj" />
<ProjectReference Include="..\Resize\Resize.csproj" />

View File

@ -12,11 +12,12 @@
"Configuration": {
"DistanceRenameToMatch": false,
"DistanceMoveUnableToMatch": false,
"PhotoPrismDirectory": "G:/photo-prism/Not-Copy-Copy-4d49b68/phpMyAdmin/export",
"PhotoPrismDirectory": "D:/Docker/photoprism/windows/Images/storage/backup",
"xRootDirectory": "D:/Tmp/phares/Pictures",
"RootDirectory": "E:/Tmp/Phares/Compare/Not-Copy-Copy-4d49b68",
"xxxRootDirectory": "E:/Tmp/Phares/Compare/Images-4d49b68",
"xxxxRootDirectory": "F:/Tmp/Phares/Compare/Images-4d49b68/Facebook/=2022.3 Facebook",
"xxRootDirectory": "D:/Tmp/Phares/Compare/Not-Copy-Copy-37c7b67",
"xxxRootDirectory": "D:/Tmp/Phares/Compare/Corrupt",
"RootDirectory": "D:/1) Images A/Images-37c7b67",
"xxxxxRootDirectory": "F:/Tmp/Phares/Compare/Images-37c7b67/Facebook/=2022.3 Facebook",
"JLinks": [
"Julie"
],
@ -37,7 +38,7 @@
],
"RangeDistanceTolerance": [
0,
0.5,
0.4,
0.6
],
"RangeFaceAreaPermilleTolerance": [

View File

@ -53,7 +53,7 @@
"CheckDFaceAndUpWriteDates": false,
"CheckJsonForDistanceResults": false,
"CrossDirectoryMaxItemsInDistanceCollection": 7,
"DateGroup": "2022-12-21",
"DateGroup": "2022-12-25",
"DistanceFactor": 8,
"DistanceMoveUnableToMatch": false,
"DistancePixelDistanceTolerance": 1,

View File

@ -1,6 +1,5 @@
using Humanizer;
using ShellProgressBar;
using System.Text;
using System.Text.Json;
using View_by_Distance.Shared.Models;
using View_by_Distance.Shared.Models.Stateless.Methods;
@ -8,7 +7,7 @@ using WindowsShortcutFactory;
namespace View_by_Distance.Map.Models;
public class MapLogic
public class MapLogic : Shared.Models.Methods.IMapLogic
{
protected readonly Dictionary<int, List<int>> _SkipCollection;
@ -102,6 +101,12 @@ public class MapLogic
return result;
}
(bool, Dictionary<int, PersonContainer[]>?) Shared.Models.Methods.IMapLogic.GetNormalizedRectangleToPersonContainers(int id)
{
bool result = _IdThenNormalizedRectangleToPersonContainers.TryGetValue(id, out Dictionary<int, PersonContainer[]>? normalizedRectangleToPersonContainers);
return new(result, normalizedRectangleToPersonContainers);
}
public (Dictionary<long, int>, int) AddToMapping(Mapping[] mappingCollection)
{
if (_Configuration is null)
@ -1149,168 +1154,6 @@ public class MapLogic
}
}
private static JsonProperty[] GetJsonProperty(string fileName)
{
JsonProperty[] results;
string json = File.ReadAllText(fileName);
JsonElement? jsonElement = JsonSerializer.Deserialize<JsonElement>(json);
results = jsonElement.Value.EnumerateObject().ToArray();
return results;
}
private static Marker[]? GetMarkers(string photoPrismDirectory)
{
Marker[]? results;
string file = Path.Combine(photoPrismDirectory, "markers.json");
JsonProperty[] jsonProperties = GetJsonProperty(file);
results = JsonSerializer.Deserialize<Marker[]>(jsonProperties[1].Value);
return results;
}
public static void SaveMarkers(string photoPrismDirectory)
{
if (string.IsNullOrEmpty(photoPrismDirectory))
throw new Exception();
// double[]? encoding;
// Marker[]? markers = GetMarkers(photoPrismDirectory);
// if (markers is null)
// throw new NullReferenceException(nameof(markers));
// foreach (Marker marker in markers)
// {
// encoding = JsonSerializer.Deserialize<double[]>(marker.EmbeddingsJson[1..^1]);
// File.WriteAllText(Path.Combine(photoPrismDirectory, "EmbeddingsJson", $"{marker.MarkerUid}.json"), marker.EmbeddingsJson);
// if (encoding is null)
// continue;
// }
}
private static Dictionary<string, List<Marker>> GetFileUIdToMarkers(string photoPrismDirectory)
{
Dictionary<string, List<Marker>> results = new();
Marker[]? markers = GetMarkers(photoPrismDirectory);
if (markers is null)
throw new NullReferenceException(nameof(markers));
foreach (Marker marker in markers)
{
if (!results.ContainsKey(marker.FileUid))
results.Add(marker.FileUid, new());
results[marker.FileUid].Add(marker);
}
return results;
}
private static DatabaseFile[]? GetDatabaseFiles(string photoPrismDirectory)
{
DatabaseFile[]? results;
string file = Path.Combine(photoPrismDirectory, "files.json");
JsonProperty[] jsonProperties = GetJsonProperty(file);
results = JsonSerializer.Deserialize<DatabaseFile[]>(jsonProperties[1].Value);
return results;
}
public static Dictionary<string, List<MappingFromPhotoPrism>> GetFileNameToCollection(string photoPrismDirectory)
{
Dictionary<string, List<MappingFromPhotoPrism>> results = new();
List<Marker>? makers;
MappingFromPhotoPrism mappingFromPhotoPrism;
List<MappingFromPhotoPrism>? mappingFromPhotoPrismCollection;
DatabaseFile[]? databaseFiles = GetDatabaseFiles(photoPrismDirectory);
if (databaseFiles is null)
throw new NullReferenceException(nameof(databaseFiles));
Dictionary<string, List<Marker>> fileUIdToMarkers = GetFileUIdToMarkers(photoPrismDirectory);
foreach (DatabaseFile databaseFile in databaseFiles)
{
if (!results.TryGetValue(databaseFile.FileName, out mappingFromPhotoPrismCollection))
{
results.Add(databaseFile.FileName, new());
if (!results.TryGetValue(databaseFile.FileName, out mappingFromPhotoPrismCollection))
throw new Exception();
}
if (!fileUIdToMarkers.TryGetValue(databaseFile.FileUid, out makers))
mappingFromPhotoPrism = new(databaseFile, new());
else
mappingFromPhotoPrism = new(databaseFile, makers);
mappingFromPhotoPrismCollection.Add(mappingFromPhotoPrism);
}
return results;
}
public void WriteMatches(long ticks, Face[] distinctFilteredFaces)
{
if (_Configuration is null)
throw new NullReferenceException(nameof(_Configuration));
long? personKey;
const int zero = 0;
int? normalizedRectangle;
string personKeyFormatted;
List<string> subjects = new();
PersonBirthday personBirthday;
string personDisplayDirectoryName;
StringBuilder stringBuilder = new();
PersonContainer[]? personContainers;
System.Drawing.Rectangle dlibRectangle;
System.Drawing.Rectangle? prismRectangle;
System.Drawing.Rectangle intersectRectangle;
Dictionary<int, PersonContainer[]>? normalizedRectangleToPersonContainers;
(MappingFromPhotoPrism MappingFromPhotoPrism, Marker Marker, double Percent)[] sortedCollection;
List<(MappingFromPhotoPrism MappingFromPhotoPrism, Marker Marker, double Percent)> collection = new();
foreach (Face face in distinctFilteredFaces)
{
collection.Clear();
normalizedRectangle = face.Mapping?.MappingFromLocation.NormalizedRectangle;
if (normalizedRectangle is null)
continue;
if (face.FaceEncoding is null || face.Location is null || face.OutputResolution is null || face.Mapping is null)
continue;
if (face.Mapping.MappingFromPhotoPrismCollection is null)
continue;
_ = _IdThenNormalizedRectangleToPersonContainers.TryGetValue(face.Mapping.MappingFromItem.Id, out normalizedRectangleToPersonContainers);
if (normalizedRectangleToPersonContainers is null || !normalizedRectangleToPersonContainers.TryGetValue(normalizedRectangle.Value, out personContainers))
continue;
dlibRectangle = new(face.Location.Left, face.Location.Top, face.Location.Right - face.Location.Left, face.Location.Bottom - face.Location.Top);
foreach (MappingFromPhotoPrism mappingFromPhotoPrism in face.Mapping.MappingFromPhotoPrismCollection)
{
foreach (Marker marker in mappingFromPhotoPrism.Markers)
{
prismRectangle = ILocation.GetRectangle(face.OutputResolution, mappingFromPhotoPrism.DatabaseFile, marker);
if (prismRectangle is null)
continue;
intersectRectangle = System.Drawing.Rectangle.Intersect(dlibRectangle, prismRectangle.Value);
if (intersectRectangle.Width == 0 || intersectRectangle.Height == 0)
continue;
double percent = (double)intersectRectangle.Width * intersectRectangle.Height / (dlibRectangle.Width * dlibRectangle.Height);
if (percent < 0.000001)
continue;
collection.Add(new(mappingFromPhotoPrism, marker, percent));
}
}
if (!collection.Any())
continue;
sortedCollection = collection.OrderByDescending(l => l.Percent).ToArray();
foreach ((MappingFromPhotoPrism mappingFromPhotoPrism, Marker marker, double percent) in sortedCollection)
{
foreach (PersonContainer personContainer in personContainers)
{
if (personContainer.Key is null || personContainer.Birthdays is null || !personContainer.Birthdays.Any())
continue;
personBirthday = personContainer.Birthdays[zero];
personKey = personBirthday.Value.Ticks;
personDisplayDirectoryName = personContainer.DisplayDirectoryName;
personKeyFormatted = IPersonBirthday.GetFormatted(_Configuration.PersonBirthdayFormat, personBirthday);
subjects.Add($"update `subjects` set subj_alias = '{personKeyFormatted}' where subj_name = '{personDisplayDirectoryName}';");
_ = stringBuilder.
Append("update `markers` set subj_src = 'manual', marker_name = '").
Append(personDisplayDirectoryName).
Append("' where marker_uid = '").
Append(marker.MarkerUid).
AppendLine("';");
}
}
}
File.WriteAllLines(Path.Combine(_Configuration.PhotoPrismDirectory, $"{ticks}-subject_alias_update.sql"), subjects.Distinct());
File.WriteAllText(Path.Combine(_Configuration.PhotoPrismDirectory, $"{ticks}-marker_name_update.sql"), stringBuilder.ToString());
}
public Dictionary<int, Dictionary<int, PersonContainer[]>> GetMissing(Dictionary<int, Dictionary<int, Mapping>> idToNormalizedRectangleToMapping)
{
Dictionary<int, Dictionary<int, PersonContainer[]>> results = new();

View File

@ -50,7 +50,7 @@
"WorkingDirectoryName": "PharesApps",
"Windows": {
"Configuration": {
"DateGroup": "2022-12-21",
"DateGroup": "2022-12-25",
"FileNameDirectorySeparator": ".Z.",
"ForcePropertyLastWriteTimeToCreationTime": false,
"MaxImagesInDirectoryForTopLevelFirstPass": 10,

7
PhotoPrism/.vscode/settings.json vendored Normal file
View File

@ -0,0 +1,7 @@
{
"cSpell.words": [
"dlib",
"Exif",
"Serilog"
]
}

View File

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

View File

@ -0,0 +1,154 @@
using System.Text;
using System.Text.Json;
using View_by_Distance.Shared.Models;
using View_by_Distance.Shared.Models.Stateless.Methods;
namespace View_by_Distance.PhotoPrism.Models;
public class F_PhotoPrism
{
private static JsonProperty[] GetJsonProperty(string fileName)
{
JsonProperty[] results;
string json = File.ReadAllText(fileName);
JsonElement? jsonElement = JsonSerializer.Deserialize<JsonElement>(json);
results = jsonElement.Value.EnumerateObject().ToArray();
return results;
}
private static Marker[]? GetMarkers(string photoPrismDirectory)
{
Marker[]? results;
string file = Path.Combine(photoPrismDirectory, "markers.json");
JsonProperty[] jsonProperties = GetJsonProperty(file);
results = JsonSerializer.Deserialize<Marker[]>(jsonProperties[1].Value);
return results;
}
private static Dictionary<string, List<Marker>> GetFileUIdToMarkers(string photoPrismDirectory)
{
Dictionary<string, List<Marker>> results = new();
Marker[]? markers = GetMarkers(photoPrismDirectory);
if (markers is null)
throw new NullReferenceException(nameof(markers));
foreach (Marker marker in markers)
{
if (!results.ContainsKey(marker.FileUid))
results.Add(marker.FileUid, new());
results[marker.FileUid].Add(marker);
}
return results;
}
private static DatabaseFile[]? GetDatabaseFiles(string photoPrismDirectory)
{
DatabaseFile[]? results;
string file = Path.Combine(photoPrismDirectory, "files.json");
JsonProperty[] jsonProperties = GetJsonProperty(file);
results = JsonSerializer.Deserialize<DatabaseFile[]>(jsonProperties[1].Value);
return results;
}
public static Dictionary<string, List<MappingFromPhotoPrism>> GetFileNameToCollection(string photoPrismDirectory)
{
Dictionary<string, List<MappingFromPhotoPrism>> results = new();
List<Marker>? makers;
MappingFromPhotoPrism mappingFromPhotoPrism;
List<MappingFromPhotoPrism>? mappingFromPhotoPrismCollection;
DatabaseFile[]? databaseFiles = GetDatabaseFiles(photoPrismDirectory);
if (databaseFiles is null)
throw new NullReferenceException(nameof(databaseFiles));
Dictionary<string, List<Marker>> fileUIdToMarkers = GetFileUIdToMarkers(photoPrismDirectory);
foreach (DatabaseFile databaseFile in databaseFiles)
{
if (!results.TryGetValue(databaseFile.FileName, out mappingFromPhotoPrismCollection))
{
results.Add(databaseFile.FileName, new());
if (!results.TryGetValue(databaseFile.FileName, out mappingFromPhotoPrismCollection))
throw new Exception();
}
if (!fileUIdToMarkers.TryGetValue(databaseFile.FileUid, out makers))
mappingFromPhotoPrism = new(databaseFile, new());
else
mappingFromPhotoPrism = new(databaseFile, makers);
mappingFromPhotoPrismCollection.Add(mappingFromPhotoPrism);
}
return results;
}
public static void WriteMatches(string photoPrismDirectory, string personBirthdayFormat, long ticks, Face[] distinctFilteredFaces, Shared.Models.Methods.IMapLogic mapLogic)
{
long? personKey;
const int zero = 0;
int? normalizedRectangle;
string personKeyFormatted;
List<string> subjects = new();
PersonBirthday personBirthday;
string personDisplayDirectoryName;
StringBuilder stringBuilder = new();
PersonContainer[]? personContainers;
System.Drawing.Rectangle dlibRectangle;
System.Drawing.Rectangle? prismRectangle;
System.Drawing.Rectangle intersectRectangle;
Dictionary<int, PersonContainer[]>? normalizedRectangleToPersonContainers;
(MappingFromPhotoPrism MappingFromPhotoPrism, Marker Marker, double Percent)[] sortedCollection;
List<(MappingFromPhotoPrism MappingFromPhotoPrism, Marker Marker, double Percent)> collection = new();
foreach (Face face in distinctFilteredFaces)
{
collection.Clear();
normalizedRectangle = face.Mapping?.MappingFromLocation.NormalizedRectangle;
if (normalizedRectangle is null)
continue;
if (face.FaceEncoding is null || face.Location is null || face.OutputResolution is null || face.Mapping is null)
continue;
if (face.Mapping.MappingFromPhotoPrismCollection is null)
continue;
(_, normalizedRectangleToPersonContainers) = mapLogic.GetNormalizedRectangleToPersonContainers(face.Mapping.MappingFromItem.Id);
if (normalizedRectangleToPersonContainers is null || !normalizedRectangleToPersonContainers.TryGetValue(normalizedRectangle.Value, out personContainers))
continue;
dlibRectangle = new(face.Location.Left, face.Location.Top, face.Location.Right - face.Location.Left, face.Location.Bottom - face.Location.Top);
foreach (MappingFromPhotoPrism mappingFromPhotoPrism in face.Mapping.MappingFromPhotoPrismCollection)
{
foreach (Marker marker in mappingFromPhotoPrism.Markers)
{
prismRectangle = ILocation.GetRectangle(face.OutputResolution, mappingFromPhotoPrism.DatabaseFile, marker);
if (prismRectangle is null)
continue;
intersectRectangle = System.Drawing.Rectangle.Intersect(dlibRectangle, prismRectangle.Value);
if (intersectRectangle.Width == 0 || intersectRectangle.Height == 0)
continue;
double percent = (double)intersectRectangle.Width * intersectRectangle.Height / (dlibRectangle.Width * dlibRectangle.Height);
if (percent < 0.000001)
continue;
collection.Add(new(mappingFromPhotoPrism, marker, percent));
}
}
if (!collection.Any())
continue;
sortedCollection = collection.OrderByDescending(l => l.Percent).ToArray();
foreach ((MappingFromPhotoPrism mappingFromPhotoPrism, Marker marker, double percent) in sortedCollection)
{
foreach (PersonContainer personContainer in personContainers)
{
if (personContainer.Key is null || personContainer.Birthdays is null || !personContainer.Birthdays.Any())
continue;
personBirthday = personContainer.Birthdays[zero];
personKey = personBirthday.Value.Ticks;
personDisplayDirectoryName = personContainer.DisplayDirectoryName;
personKeyFormatted = IPersonBirthday.GetFormatted(personBirthdayFormat, personBirthday);
subjects.Add($"update `subjects` set subj_alias = '{personKeyFormatted}' where subj_name = '{personDisplayDirectoryName}';");
_ = stringBuilder.
Append("update `markers` set subj_src = 'manual', marker_name = '").
Append(personDisplayDirectoryName).
Append("' where marker_uid = '").
Append(marker.MarkerUid).
AppendLine("';");
}
}
}
File.WriteAllLines(Path.Combine(photoPrismDirectory, $"{ticks}-subject_alias_update.sql"), subjects.Distinct());
File.WriteAllText(Path.Combine(photoPrismDirectory, $"{ticks}-marker_name_update.sql"), stringBuilder.ToString());
}
}

View File

@ -0,0 +1,47 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<ImplicitUsings>enable</ImplicitUsings>
<LangVersion>10.0</LangVersion>
<Nullable>enable</Nullable>
<OutputType>library</OutputType>
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
<TargetFramework>net7.0</TargetFramework>
</PropertyGroup>
<PropertyGroup>
<PackageId>Phares.View.by.Distance.PhotoPrism</PackageId>
<GeneratePackageOnBuild>false</GeneratePackageOnBuild>
<Version>6.0.100.1</Version>
<Authors>Mike Phares</Authors>
<Company>Phares</Company>
<IncludeSymbols>true</IncludeSymbols>
<SymbolPackageFormat>snupkg</SymbolPackageFormat>
</PropertyGroup>
<PropertyGroup>
<IsWindows Condition="'$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::Windows)))' == 'true'">true</IsWindows>
<IsOSX Condition="'$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::OSX)))' == 'true'">true</IsOSX>
<IsLinux Condition="'$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::Linux)))' == 'true'">true</IsLinux>
</PropertyGroup>
<PropertyGroup Condition="'$(IsWindows)'=='true'">
<DefineConstants>Windows</DefineConstants>
</PropertyGroup>
<PropertyGroup Condition="'$(IsOSX)'=='true'">
<DefineConstants>OSX</DefineConstants>
</PropertyGroup>
<PropertyGroup Condition="'$(IsLinux)'=='true'">
<DefineConstants>Linux</DefineConstants>
</PropertyGroup>
<ItemGroup Condition="'$(RuntimeIdentifier)' == 'browser-wasm'">
<SupportedPlatform Include="browser" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Humanizer.Core" Version="2.14.1" />
<PackageReference Include="MetadataExtractor" Version="2.7.2" />
<PackageReference Include="Serilog" Version="2.12.0" />
<PackageReference Include="ShellProgressBar" Version="5.2.0" />
<PackageReference Include="WindowsShortcutFactory" Version="1.1.0" />
<PackageReference Include="System.Text.Json" Version="7.0.1" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Shared\View-by-Distance.Shared.csproj" />
</ItemGroup>
</Project>

View File

@ -50,7 +50,7 @@
"WorkingDirectoryName": "PharesApps",
"Windows": {
"Configuration": {
"DateGroup": "2022-12-21",
"DateGroup": "2022-12-25",
"FileNameDirectorySeparator": ".Z.",
"ForcePropertyLastWriteTimeToCreationTime": false,
"KeepFullPath": false,

View File

@ -0,0 +1,8 @@
namespace View_by_Distance.Shared.Models.Methods;
public interface IMapLogic
{
(bool, Dictionary<int, PersonContainer[]>?) GetNormalizedRectangleToPersonContainers(int id);
}

View File

@ -43,6 +43,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Delete-By-Relative", "Delet
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Delete-By-Distinct", "Delete-By-Distinct\Delete-By-Distinct.csproj", "{3F00BDD5-75F8-470C-ACED-1A26FDC8D7B3}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PhotoPrism", "PhotoPrism\PhotoPrism.csproj", "{DF4B0776-E0E5-4220-8721-8D1E491FF263}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@ -132,5 +134,9 @@ Global
{3F00BDD5-75F8-470C-ACED-1A26FDC8D7B3}.Debug|Any CPU.Build.0 = Debug|Any CPU
{3F00BDD5-75F8-470C-ACED-1A26FDC8D7B3}.Release|Any CPU.ActiveCfg = Release|Any CPU
{3F00BDD5-75F8-470C-ACED-1A26FDC8D7B3}.Release|Any CPU.Build.0 = Release|Any CPU
{DF4B0776-E0E5-4220-8721-8D1E491FF263}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{DF4B0776-E0E5-4220-8721-8D1E491FF263}.Debug|Any CPU.Build.0 = Debug|Any CPU
{DF4B0776-E0E5-4220-8721-8D1E491FF263}.Release|Any CPU.ActiveCfg = Release|Any CPU
{DF4B0776-E0E5-4220-8721-8D1E491FF263}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
EndGlobal