LookForAbandoned,

DateTimeOriginalThenMinimumDateTime and IsNotUniqueAndNeedsReview
This commit is contained in:
Mike Phares 2023-05-07 20:07:48 -07:00
parent 3d6e6ef713
commit 0ca53436e5
45 changed files with 721 additions and 1161 deletions

View File

@ -154,13 +154,14 @@ public class DateGroup
string? check;
string fileName;
string? pathRoot;
DateTime dateTime;
string seasonName;
string weekOfYear;
bool? isWrongYear;
string seasonValue;
string directoryName;
string topDirectoryName;
DateTime minimumDateTime;
List<DateTime> dateTimes;
string[]? matches = null;
string[] directorySegments;
List<string> destinationCollection;
@ -204,12 +205,22 @@ public class DateGroup
directoryNames.Clear();
destinationCollection = new();
_ = destinationDirectoryName.Clear();
if (item.ImageFileHolder.LastWriteTime is not null && item.Property is null)
minimumDateTime = item.ImageFileHolder.LastWriteTime.Value;
if (item.Property is not null)
dateTimes = item.Property.GetDateTimes();
else
minimumDateTime = Shared.Models.Stateless.Methods.IProperty.GetMinimumDateTime(item.Property);
day = minimumDateTime.ToString("MM-dd");
month = minimumDateTime.ToString("MMMM");
{
if (item.ImageFileHolder.LastWriteTime is null)
throw new Exception();
dateTimes = new() { item.ImageFileHolder.LastWriteTime.Value };
}
if (item.ImageFileHolder.LastWriteTime is not null && item.Property is null)
dateTime = item.ImageFileHolder.LastWriteTime.Value;
else if (item.Property is not null && item.Property.DateTimeOriginal is not null)
dateTime = item.Property.DateTimeOriginal.Value;
else
dateTime = Shared.Models.Stateless.Methods.IProperty.GetMinimumDateTime(item.Property);
day = dateTime.ToString("MM-dd");
month = dateTime.ToString("MMMM");
if (item.Property?.Id is null)
{
flag = '#';
@ -217,26 +228,26 @@ public class DateGroup
}
else
{
(isWrongYear, _) = item.Property.IsWrongYear(item.ImageFileHolder, minimumDateTime);
(isWrongYear, _) = Shared.Models.Stateless.Methods.IProperty.IsWrongYear(item.ImageFileHolder, item.Property.DateTimeOriginal, dateTimes);
if (isWrongYear is null)
flag = '#';
else if (isWrongYear.Value)
flag = '~';
else
{
if (item.Property.DateTimeOriginal.HasValue && minimumDateTime.DayOfYear != item.Property.DateTimeOriginal.Value.DayOfYear && Math.Abs(new TimeSpan(minimumDateTime.Ticks - item.Property.DateTimeOriginal.Value.Ticks).TotalHours) > 8)
if (item.Property.DateTimeOriginal is not null && dateTime.DayOfYear != item.Property.DateTimeOriginal.Value.DayOfYear && Math.Abs(new TimeSpan(dateTime.Ticks - item.Property.DateTimeOriginal.Value.Ticks).TotalHours) > 8)
flag = '^';
else
flag = '=';
}
}
(season, seasonName) = Shared.Models.Stateless.Methods.IProperty.GetSeason(minimumDateTime.DayOfYear);
(season, seasonName) = Shared.Models.Stateless.Methods.IProperty.GetSeason(dateTime.DayOfYear);
if ((from l in topDirectorySegments where l == "Christmas" select true).Any())
seasonValue = string.Empty;
else
seasonValue = $".{season}";
if (isWrongYear is null || !isWrongYear.Value)
year = $"{flag}{minimumDateTime:yyyy}{seasonValue}";
year = $"{flag}{dateTime:yyyy}{seasonValue}";
else if (matches is null || matches.Length < 3)
year = "----";
else
@ -247,7 +258,7 @@ public class DateGroup
year = $"{flag}{matches[0][1..].Split('.')[0]}{seasonValue}";
}
topDirectoryName = Path.GetFileName(topDirectory);
weekOfYear = calendar.GetWeekOfYear(minimumDateTime, CalendarWeekRule.FirstDay, DayOfWeek.Sunday).ToString("00");
weekOfYear = calendar.GetWeekOfYear(dateTime, CalendarWeekRule.FirstDay, DayOfWeek.Sunday).ToString("00");
if (_Configuration.ByHash)
directoryNames.Add($"{year} {seasonName}");
else if (_Configuration.BySeason && topDirectoryName.Length == 1 && topDirectoryName[0] == '_')
@ -296,9 +307,9 @@ public class DateGroup
if (item.ImageFileHolder.LastWriteTime is null)
continue;
if (item.Property is not null)
results.Add(new(item, item.Property.LastWriteTime.Ticks, minimumDateTime.Ticks, destinationCollection.ToArray()));
results.Add(new(item, item.Property.LastWriteTime.Ticks, dateTime.Ticks, destinationCollection.ToArray()));
else
results.Add(new(item, item.ImageFileHolder.LastWriteTime.Value.Ticks, minimumDateTime.Ticks, destinationCollection.ToArray()));
results.Add(new(item, item.ImageFileHolder.LastWriteTime.Value.Ticks, dateTime.Ticks, destinationCollection.ToArray()));
}
return results;
}
@ -470,11 +481,11 @@ public class DateGroup
string path;
string fileName;
string directory;
DateTime dateTime;
int selectedTotal;
const int minimum = 3;
List<DateTime> dateTimes;
List<Item> selectedItems;
DateTime? minimumDateTime;
const int maximumHours = 24;
string? relativePathDirectory;
WindowsShortcut windowsShortcut;
@ -499,9 +510,12 @@ public class DateGroup
relativePathDirectory = Path.GetDirectoryName(item.RelativePath);
if (string.IsNullOrEmpty(relativePathDirectory))
continue;
minimumDateTime = Shared.Models.Stateless.Methods.IProperty.GetMinimumDateTime(item.Property);
if (minimumDateTime is null)
continue;
if (item.ImageFileHolder.LastWriteTime is not null && item.Property is null)
dateTime = item.ImageFileHolder.LastWriteTime.Value;
else if (item.Property is not null && item.Property.DateTimeOriginal is not null)
dateTime = item.Property.DateTimeOriginal.Value;
else
dateTime = Shared.Models.Stateless.Methods.IProperty.GetMinimumDateTime(item.Property);
path = Path.GetFullPath($"{configuration.RootDirectory}{item.RelativePath[..^5]}");
directory = Path.Combine($"{aPropertyContentDirectory}{relativePathDirectory}", $"{dateTimes.Min():yyyy-MM-dd_HH-mm-ss}---{dateTimes.Max():yyyy-MM-dd_HH-mm-ss}");
if (!Directory.Exists(directory))
@ -514,7 +528,7 @@ public class DateGroup
windowsShortcut.Dispose();
if (!File.Exists(fileName))
continue;
File.SetLastWriteTime(fileName, minimumDateTime.Value);
File.SetLastWriteTime(fileName, dateTime);
}
}
if (selectedTotal < container.Items.Count && selectedTotal < (from l in container.Items where l.Property is not null select true).Count())

View File

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

View File

@ -67,10 +67,7 @@
"ResultCollection": "[]",
"ResultContent": "()",
"ResultSingleton": "{}",
"xRootDirectory": "C:/Tmp/phares/Pictures",
"xxRootDirectory": "C:/Tmp/Phares/Compare/Images-1e85c0ba",
"RootDirectory": "F:/Tmp/Phares/Compare/Not-Copy-Copy-1e85c0ba",
"xxxxRootDirectory": "F:/Tmp/Phares/2022-11-03-DCIM/DCIM/100D3400 2022",
"RootDirectory": "C:/Tmp/phares/Pictures",
"WriteBitmapDataBytes": false,
"IgnoreExtensions": [
".gif",

View File

@ -58,11 +58,11 @@ public partial class E_Distance
confidencePercent = Shared.Models.Stateless.Methods.ILocation.GetConfidencePercent(_FaceConfidencePercent, _RangeFaceConfidence, face.Location.Confidence);
normalizedRectangle = Shared.Models.Stateless.Methods.ILocation.GetNormalizedRectangle(face.Location, Shared.Models.Stateless.ILocation.Digits, face.OutputResolution);
if (face.FaceDistance?.Encoding is not null && face.FaceDistance.Encoding is FaceRecognitionDotNet.FaceEncoding faceEncoding)
faceDistance = new(confidencePercent, faceEncoding, mappingFromItem.Id, mappingFromItem.IsWrongYear, mappingFromItem.MinimumDateTime, normalizedRectangle);
faceDistance = new(confidencePercent, mappingFromItem.GetDateTimeOriginalThenMinimumDateTime(), faceEncoding, mappingFromItem.Id, mappingFromItem.IsWrongYear, normalizedRectangle);
else
{
faceEncoding = FaceRecognition.LoadFaceEncoding(face.FaceEncoding.RawEncoding);
faceDistance = new(confidencePercent, faceEncoding, mappingFromItem.Id, mappingFromItem.IsWrongYear, mappingFromItem.MinimumDateTime, normalizedRectangle);
faceDistance = new(confidencePercent, mappingFromItem.GetDateTimeOriginalThenMinimumDateTime(), faceEncoding, mappingFromItem.Id, mappingFromItem.IsWrongYear, normalizedRectangle);
lock (intersectFaces)
face.SetFaceDistance(faceDistance);
}
@ -347,11 +347,11 @@ public partial class E_Distance
confidencePercent = Shared.Models.Stateless.Methods.ILocation.GetConfidencePercent(_FaceConfidencePercent, _RangeFaceConfidence, face.Location.Confidence);
normalizedRectangle = Shared.Models.Stateless.Methods.ILocation.GetNormalizedRectangle(face.Location, Shared.Models.Stateless.ILocation.Digits, face.OutputResolution);
if (face.FaceDistance?.Encoding is not null && face.FaceDistance.Encoding is FaceRecognitionDotNet.FaceEncoding faceEncoding)
faceDistance = new(confidencePercent, faceEncoding, id, isWrongYear, face.DateTime, normalizedRectangle);
faceDistance = new(confidencePercent, face.DateTime, faceEncoding, id, isWrongYear, normalizedRectangle);
else
{
faceEncoding = FaceRecognition.LoadFaceEncoding(face.FaceEncoding.RawEncoding);
faceDistance = new(confidencePercent, faceEncoding, id, isWrongYear, face.DateTime, normalizedRectangle);
faceDistance = new(confidencePercent, face.DateTime, faceEncoding, id, isWrongYear, normalizedRectangle);
face.SetFaceDistance(faceDistance);
}
faceDistanceContainer = new(face, faceDistance);
@ -390,7 +390,7 @@ public partial class E_Distance
return;
progressBar.Tick();
faceEncoding = FaceRecognition.LoadFaceEncoding(face.FaceEncoding.RawEncoding);
FaceDistance faceDistance = new(face.Mapping.MappingFromLocation.ConfidencePercent, faceEncoding, face.Mapping.MappingFromItem.Id, face.Mapping.MappingFromItem.IsWrongYear, face.Mapping.MappingFromItem.MinimumDateTime, face.Mapping.MappingFromLocation.NormalizedRectangle);
FaceDistance faceDistance = new(face.Mapping.MappingFromLocation.ConfidencePercent, face.Mapping.MappingFromItem.GetDateTimeOriginalThenMinimumDateTime(), faceEncoding, face.Mapping.MappingFromItem.Id, face.Mapping.MappingFromItem.IsWrongYear, face.Mapping.MappingFromLocation.NormalizedRectangle);
lock (face)
face.SetFaceDistance(faceDistance);
});
@ -447,7 +447,7 @@ public partial class E_Distance
throw new NotSupportedException();
if (face.FaceDistance?.Encoding is not FaceRecognitionDotNet.FaceEncoding faceEncoding)
continue;
faceDistance = new(face.Mapping.MappingFromLocation.ConfidencePercent, faceEncoding, face.Mapping.MappingFromItem.Id, face.Mapping.MappingFromItem.IsWrongYear, face.Mapping.MappingFromItem.MinimumDateTime, face.Mapping.MappingFromLocation.NormalizedRectangle);
faceDistance = new(face.Mapping.MappingFromLocation.ConfidencePercent, face.Mapping.MappingFromItem.GetDateTimeOriginalThenMinimumDateTime(), faceEncoding, face.Mapping.MappingFromItem.Id, face.Mapping.MappingFromItem.IsWrongYear, face.Mapping.MappingFromLocation.NormalizedRectangle);
faceDistanceContainer = new(face, faceDistance);
collection.Add(faceDistanceContainer);
}
@ -480,7 +480,7 @@ public partial class E_Distance
{
if (faceDistanceContainer.FaceDistance is null || faceDistanceContainer.Face.Mapping?.MappingFromLocation is null)
throw new NotSupportedException();
if (skipOlderThan is not null && (faceDistanceContainer.FaceDistance.MinimumDateTime is null || faceDistanceContainer.FaceDistance.MinimumDateTime.Value.Ticks < skipOlderThan.Value))
if (skipOlderThan is not null && faceDistanceContainer.FaceDistance.DateTimeOriginalThenMinimumDateTime.Ticks < skipOlderThan.Value)
continue;
if (faceDistanceContainer.Face.Mapping.MappingFromLocation.ConfidencePercent < distanceLimits.FaceConfidencePercent)
continue;

View File

@ -37,6 +37,7 @@
<PackageReference Include="WindowsShortcutFactory" Version="1.1.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Property\Property.csproj" />
<ProjectReference Include="..\Shared\View-by-Distance.Shared.csproj" />
</ItemGroup>
<ItemGroup>

View File

@ -2,9 +2,11 @@ using Microsoft.Extensions.Configuration;
using Phares.Shared;
using Serilog;
using System.Diagnostics;
using System.Drawing.Imaging;
using System.Reflection;
using System.Text.Json;
using View_by_Distance.Drag_Drop_Explorer.Models;
using View_by_Distance.Shared.Models.Stateless;
using View_by_Distance.Shared.Models.Stateless.Methods;
using WindowsShortcutFactory;
@ -64,7 +66,7 @@ public partial class DragDropMove : Form
Controls.Add(_FirstTextBox);
}
void Form1_Load(object? sender, EventArgs e)
private void Form1_Load(object? sender, EventArgs e)
{
try
{
@ -73,6 +75,8 @@ public partial class DragDropMove : Form
DragEnter += new DragEventHandler(Form1_DragEnter);
_FirstTextBox.LostFocus += new EventHandler(TextBox_LostFocus);
_PathTextBox.LostFocus += new EventHandler(TextBox_LostFocus);
if (_WorkingDirectory is null)
{ }
}
catch (Exception)
{
@ -86,14 +90,14 @@ public partial class DragDropMove : Form
return result;
}
void TextBox_LostFocus(object? sender, EventArgs e)
private void TextBox_LostFocus(object? sender, EventArgs e)
{
try
{
if (sender is TextBox textBox)
{
textBox.Text = GetConverted(textBox.Text);
if (textBox.Text == "ps")
if (textBox.Text == "315360000000000")
throw new NotImplementedException();
}
@ -104,7 +108,7 @@ public partial class DragDropMove : Form
}
}
void Form1_DragEnter(object? sender, DragEventArgs e)
private void Form1_DragEnter(object? sender, DragEventArgs e)
{
try
{
@ -172,12 +176,145 @@ public partial class DragDropMove : Form
}
}
void Form1_DragDrop(object? sender, DragEventArgs e)
public static byte[] GetBytes(string value)
{
byte[] results = new byte[value.Length + 1];
for (int i = 0; i < value.Length; i++)
results[i] = (byte)value[i];
results[value.Length] = 0x00;
return results;
}
private static PropertyItem GetPropertyItem(ConstructorInfo constructorInfo, int id, string value)
{
PropertyItem result = (PropertyItem)constructorInfo.Invoke(null);
byte[] bytes = GetBytes(value);
result.Id = id;
result.Len = value.Length + 1;
result.Type = 2;
result.Value = bytes;
return result;
}
private static List<(string, int, DateTime)> GetCollection(string checkDirectory, DateTime minimumDateTime, DateTime maximumDateTime, long ticks)
{
List<(string, int, DateTime)> results = new();
DateTime dateTime;
Shared.Models.Property property;
string[] files = Directory.GetFiles(checkDirectory, "*", SearchOption.TopDirectoryOnly);
foreach (string file in files)
{
property = Property.Models.A_Property.GetImageProperty(file);
if (property.Id is null || property.DateTimeOriginal is null)
continue;
dateTime = property.DateTimeOriginal.Value.AddTicks(ticks);
if (dateTime < minimumDateTime)
continue;
if (dateTime > maximumDateTime)
continue;
results.Add((file, property.Id.Value, property.DateTimeOriginal.Value.AddTicks(ticks)));
}
if (files.Length != results.Count)
throw new Exception();
return results;
}
private static void DateFix(string sourceDirectory, string checkDirectory, DateTime minimumDateTime, DateTime maximumDateTime, long ticks)
{
Bitmap bitmap;
string checkFile;
PropertyItem? propertyItem;
string? ticksDirectory = null;
Shared.Models.Property property;
int dateTimeOriginal = (int)IExif.Tags.DateTimeOriginal;
for (int i = 0; i < int.MaxValue; i++)
{
ticksDirectory = Path.Combine(sourceDirectory, ticks.ToString());
if (!Directory.Exists(ticksDirectory))
{
_ = Directory.CreateDirectory(ticksDirectory);
break;
}
ticks++;
}
List<(string, int, DateTime)> collection = GetCollection(checkDirectory, minimumDateTime, maximumDateTime, ticks);
ConstructorInfo? constructorInfo = typeof(PropertyItem).GetConstructor(BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Public, null, Array.Empty<Type>(), null) ?? throw new Exception();
foreach ((string file, int id, DateTime dateTime) in collection)
{
if (ticksDirectory is null)
throw new Exception();
checkFile = Path.Combine(ticksDirectory, Path.GetFileName(file));
if (File.Exists(checkFile))
continue;
propertyItem = GetPropertyItem(constructorInfo, dateTimeOriginal, dateTime.ToString("yyyy:MM:dd HH:mm:ss"));
bitmap = new(file);
bitmap.SetPropertyItem(propertyItem);
bitmap.Save(checkFile);
bitmap.Dispose();
property = Property.Models.A_Property.GetImageProperty(checkFile);
if (property.Id is null || property.Id.Value != id)
throw new Exception();
}
}
private void DateFix(string sourceDirectory)
{
string checkDirectory;
long oneYearTicks = DateTime.MinValue.AddYears(1).Ticks;
checkDirectory = Path.Combine(sourceDirectory, oneYearTicks.ToString());
if (Directory.Exists(checkDirectory))
DateFix(sourceDirectory, checkDirectory, DateTime.MinValue, DateTime.MaxValue, new TimeSpan(oneYearTicks - DateTime.MinValue.Ticks).Ticks);
else
{
checkDirectory = Path.Combine(sourceDirectory, "1");
if (!Directory.Exists(checkDirectory))
_Logger.Error($"<{checkDirectory}> doesn't exist!");
else
{
string badDirectory = Path.Combine(sourceDirectory, "Bad");
string targetDirectory = Path.Combine(sourceDirectory, "Target");
string[] minimumDirectory = Directory.GetDirectories(targetDirectory, "*", SearchOption.TopDirectoryOnly);
if (minimumDirectory.Length != 1)
_Logger.Error($"<{checkDirectory}> doesn't exist!");
else
{
string format = "yyyy-MM-dd";
string[] maximumDirectory = Directory.GetDirectories(minimumDirectory.First(), "*", SearchOption.TopDirectoryOnly);
string[] badFiles = !Directory.Exists(badDirectory) ? Array.Empty<string>() : Directory.GetFiles(badDirectory, "*", SearchOption.TopDirectoryOnly);
string[] targetFiles = !Directory.Exists(targetDirectory) ? Array.Empty<string>() : Directory.GetFiles(targetDirectory, "*", SearchOption.TopDirectoryOnly);
if (badFiles.Length != 1 || targetFiles.Length != 1 || maximumDirectory.Length != 1)
_Logger.Error("bad file(s) or target file(s) or maximum directory doesn't equal 1!");
else
{
DateTime minimumDateTime = DateTime.ParseExact(Path.GetFileName(minimumDirectory.First()), format, null, System.Globalization.DateTimeStyles.None);
DateTime maximumDateTime = DateTime.ParseExact(Path.GetFileName(maximumDirectory.First()), format, null, System.Globalization.DateTimeStyles.None).AddHours(23);
Shared.Models.Property badProperty = Property.Models.A_Property.GetImageProperty(badFiles.First());
Shared.Models.Property targetProperty = Property.Models.A_Property.GetImageProperty(targetFiles.First());
if (badProperty.DateTimeOriginal is null || targetProperty.DateTimeOriginal is null)
_Logger.Error("Date is null!");
else
{
TimeSpan timeSpan = new(targetProperty.DateTimeOriginal.Value.Ticks - badProperty.DateTimeOriginal.Value.Ticks);
DateFix(sourceDirectory, checkDirectory, minimumDateTime, maximumDateTime, timeSpan.Ticks);
}
}
}
}
}
}
private void Form1_DragDrop(object? sender, DragEventArgs e)
{
try
{
if (e.Data is not null && e.Data.GetData(DataFormats.FileDrop) is string[] paths && paths.Any())
{
if (paths.Length == 1 && Directory.Exists(paths.First()))
DateFix(paths.First());
else
MovePaths(paths);
}
else
{
_FirstTextBox.Text = string.Empty;
@ -191,5 +328,4 @@ public partial class DragDropMove : Form
throw;
}
}
}

View File

@ -192,7 +192,7 @@ public class DuplicateSearch
if (mappingFromItem is not null)
{
resizedFileHolder = new(mappingFromItem.ResizedFileHolder.FullName.Replace($"0{duplicates}", $"1{duplicates}"));
collection[0] = new(mappingFromItem.ContainerDateTimes, mappingFromItem.Id, mappingFromItem.ImageFileHolder, mappingFromItem.IsWrongYear, mappingFromItem.MinimumDateTime, mappingFromItem.RelativePath, resizedFileHolder);
collection[0] = new(mappingFromItem.ContainerDateTimes, item.Property.DateTimeDigitized, item.Property.DateTimeOriginal, mappingFromItem.Id, mappingFromItem.ImageFileHolder, mappingFromItem.IsWrongYear, mappingFromItem.MinimumDateTime, item.Property.Model, mappingFromItem.RelativePath, resizedFileHolder);
}
}
resizedFileHolder = new(string.Concat(Path.Combine(destinationRoot, directory), item.RelativePath));

View File

@ -3,6 +3,7 @@ using Phares.Shared;
using ShellProgressBar;
using System.Collections.ObjectModel;
using System.Drawing.Imaging;
using System.Text.RegularExpressions;
using View_by_Distance.Distance.Models;
using View_by_Distance.Face.Models;
using View_by_Distance.FaceParts.Models;
@ -14,6 +15,7 @@ using View_by_Distance.Property.Models;
using View_by_Distance.Resize.Models;
using View_by_Distance.Shared.Models;
using View_by_Distance.Shared.Models.Methods;
using WindowsShortcutFactory;
namespace View_by_Distance.Instance;
@ -267,34 +269,19 @@ public partial class DlibDotNet
return result;
}
private bool? GetIsFocusModel(ReadOnlyDictionary<int, List<LocationContainer<MetadataExtractor.Directory>>> idToLocationContainers, MappingFromItem mappingFromItem)
private bool? GetIsFocusModel(Shared.Models.Property? property)
{
bool? result;
string? model;
List<LocationContainer<MetadataExtractor.Directory>>? locationContainers;
IReadOnlyList<MetadataExtractor.Directory> directories;
if (string.IsNullOrEmpty(_Configuration.FocusModel))
result = null;
else if (property is null || string.IsNullOrEmpty(property.Model))
result = null;
else
{
if (!idToLocationContainers.TryGetValue(mappingFromItem.Id, out locationContainers) || !locationContainers.Any())
result = false;
else
{
directories = locationContainers.First().Directories;
model = Metadata.Models.Stateless.Methods.IMetadata.GetModel(directories);
if (model is null)
directories = MetadataExtractor.ImageMetadataReader.ReadMetadata(mappingFromItem.ResizedFileHolder.FullName);
model = Metadata.Models.Stateless.Methods.IMetadata.GetModel(directories);
result = model is not null && model.Contains(_Configuration.FocusModel);
if (result.Value)
result = true;
}
}
result = property.Model.Contains(_Configuration.FocusModel);
return result;
}
private void SetMapping(ReadOnlyDictionary<int, List<LocationContainer<MetadataExtractor.Directory>>> idToLocationContainers, MapLogic mapLogic, Item item, bool? isFocusRelativePath, bool? isIgnoreRelativePath, MappingFromItem mappingFromItem, List<MappingFromPhotoPrism>? mappingFromPhotoPrismCollection, List<Shared.Models.Face> faces)
private void SetMapping(MapLogic mapLogic, Item item, bool? isFocusRelativePath, bool? isIgnoreRelativePath, MappingFromItem mappingFromItem, List<MappingFromPhotoPrism>? mappingFromPhotoPrismCollection, List<Shared.Models.Face> faces)
{
Mapping mapping;
int faceAreaPermyriad;
@ -304,7 +291,7 @@ public partial class DlibDotNet
string deterministicHashCodeKey;
MappingFromFilter mappingFromFilter;
MappingFromLocation? mappingFromLocation;
bool? isFocusModel = GetIsFocusModel(idToLocationContainers, mappingFromItem);
bool? isFocusModel = GetIsFocusModel(item.Property);
foreach (Shared.Models.Face face in faces)
{
if (item.Property?.Id is null || face.FaceEncoding is null || face.Location is null || face.OutputResolution is null)
@ -329,7 +316,7 @@ public partial class DlibDotNet
}
}
private Mapping GetMapping(ReadOnlyDictionary<int, List<LocationContainer<MetadataExtractor.Directory>>> idToLocationContainers, MapLogic mapLogic, Item item, bool? isFocusRelativePath, bool? isIgnoreRelativePath, MappingFromItem mappingFromItem)
private Mapping GetMapping(MapLogic mapLogic, Item item, bool? isFocusRelativePath, bool? isIgnoreRelativePath, MappingFromItem mappingFromItem)
{
Mapping result;
bool? inSkipCollection;
@ -339,7 +326,7 @@ public partial class DlibDotNet
string deterministicHashCodeKey;
MappingFromFilter mappingFromFilter;
MappingFromLocation? mappingFromLocation;
bool? isFocusModel = GetIsFocusModel(idToLocationContainers, mappingFromItem);
bool? isFocusModel = GetIsFocusModel(item.Property);
if (item.Property?.Id is null)
{
inSkipCollection = null;
@ -461,7 +448,7 @@ public partial class DlibDotNet
if (_AppSettings.MaxDegreeOfParallelism < 2)
ticks = LogDelta(ticks, nameof(D_Face.GetFaces));
List<(Shared.Models.Face, FileInfo?, string, bool Saved)> faceCollection = _Faces.SaveFaces(_FaceParts.FileNameExtension, dResultsFullGroupDirectory, subFileTuples, parseExceptions, mappingFromItem, facesDirectory, faces);
SetMapping(idToLocationContainers, mapLogic, item, isFocusRelativePath, isIgnoreRelativePath, mappingFromItem, mappingFromPhotoPrismCollection, faces);
SetMapping(mapLogic, item, isFocusRelativePath, isIgnoreRelativePath, mappingFromItem, mappingFromPhotoPrismCollection, faces);
if (_Configuration.CopyFacesAndSaveFaceLandmarkForOutputResolutions.Contains(outputResolution))
_FaceParts.CopyFacesAndSaveFaceLandmarkImage(facePartsCollectionDirectory, mappingFromItem, faceCollection);
if (_AppSettings.MaxDegreeOfParallelism < 2)
@ -663,8 +650,8 @@ public partial class DlibDotNet
if (!filteredItems.Any())
continue;
sourceDirectoryChanges.Clear();
anyNullOrNoIsUniqueFileName = filteredItems.Any(l => !l.IsUniqueFileName);
totalSeconds = (int)Math.Floor(new TimeSpan(DateTime.Now.Ticks - ticks).TotalSeconds);
anyNullOrNoIsUniqueFileName = filteredItems.Any(l => l.IsUniqueFileName is null || !l.IsUniqueFileName.Value);
message = $"{i + 1:000} [{filteredItems.Length:000} collectionB] / {containersLength:000} - {total} / {t} total collectionB - {totalSeconds} total second(s) - {outputResolution} - {container.SourceDirectory}";
if (_Configuration.LoadOrCreateThenSaveImageFacesResultsForOutputResolutions.Contains(outputResolution))
_Faces.SetAngleBracketCollection(dResultsFullGroupDirectory, container.SourceDirectory);
@ -929,7 +916,7 @@ public partial class DlibDotNet
}
}
private Mapping[] GetMappings(Property.Models.Configuration propertyConfiguration, Container[] containers, MapLogic mapLogic, ReadOnlyDictionary<int, List<LocationContainer<MetadataExtractor.Directory>>> idToLocationContainers, bool distinctItems)
private Mapping[] GetMappings(Property.Models.Configuration propertyConfiguration, Container[] containers, MapLogic mapLogic, bool distinctItems)
{
Mapping[] results;
int count = 0;
@ -976,7 +963,7 @@ public partial class DlibDotNet
}
if (!anyValidFaces)
{
mapping = GetMapping(idToLocationContainers, mapLogic, item, isFocusRelativePath, isIgnoreRelativePath, mappingFromItem);
mapping = GetMapping(mapLogic, item, isFocusRelativePath, isIgnoreRelativePath, mappingFromItem);
mappingCollection.Add(mapping);
}
}
@ -985,6 +972,95 @@ public partial class DlibDotNet
return results;
}
private static void Verify(string eDistanceContentDirectory, List<Item> distinctFilteredItems)
{
#if VerifyItem
bool found;
List<Item> notFound = new();
foreach (Item item in distinctFilteredItems)
{
found = false;
if (item.Property?.Id is null)
continue;
foreach (Mapping mapping in distinctFilteredMappingCollection)
{
if (mapping.MappingFromItem.Id != item.Property.Id.Value)
continue;
found = true;
break;
}
if (!found)
notFound.Add(item);
}
if (notFound.Any())
throw new NotSupportedException();
#endif
string model;
string fileName;
string directory;
bool? isWrongYear;
List<DateTime> dateTimes;
List<string> distinct = new();
WindowsShortcut windowsShortcut;
List<(string, string, string)> collection = new();
foreach (Item item in distinctFilteredItems)
{
if (item.Property?.Id is null || item.ImageFileHolder.LastWriteTime is null)
continue;
if (item.IsNotUniqueAndNeedsReview is null || !item.IsNotUniqueAndNeedsReview.Value)
continue;
directory = Path.Combine($"{eDistanceContentDirectory[..^1]}{nameof(item.IsNotUniqueAndNeedsReview)})", item.ImageFileHolder.NameWithoutExtension);
fileName = Path.Combine(directory, $"{item.ImageFileHolder.Length} {item.ImageFileHolder.LastWriteTime.Value.Ticks}.lnk");
collection.Add((item.ImageFileHolder.FullName, directory, fileName));
if (distinct.Contains(directory))
continue;
distinct.Add(directory);
}
foreach (Item item in distinctFilteredItems)
{
if (item.Property?.Id is null || item.Property.DateTimeOriginal is null)
continue;
dateTimes = item.Property.GetDateTimes();
(isWrongYear, _) = Shared.Models.Stateless.Methods.IProperty.IsWrongYear(item.ImageFileHolder, item.Property.DateTimeOriginal, dateTimes);
if (isWrongYear is null || !isWrongYear.Value)
continue;
// Remove-Item -LiteralPath "\\?\D:\Tmp\a\EX-Z70 "
model = string.IsNullOrEmpty(item.Property.Model) ? "Unknown" : Regex.Replace(item.Property.Model.Trim(), @"[\\,\/,\:,\*,\?,\"",\<,\>,\|]", "_");
directory = Path.Combine($"{eDistanceContentDirectory[..^1]}{nameof(Item)})", item.Property.DateTimeOriginal.Value.Year.ToString(), model);
fileName = item.IsNotUniqueAndNeedsReview is not null && item.IsNotUniqueAndNeedsReview.Value ? Path.Combine(directory, $"{item.ImageFileHolder.Name} {item.ImageFileHolder.Length}.lnk") : Path.Combine(directory, $"{item.ImageFileHolder.Name}.lnk");
collection.Add((item.ImageFileHolder.FullName, directory, fileName));
if (distinct.Contains(directory))
continue;
distinct.Add(directory);
}
#if Mapping
foreach (Mapping mapping in distinctFilteredMappingCollection)
{
if (mapping.MappingFromItem.IsWrongYear is null || !mapping.MappingFromItem.IsWrongYear.Value)
continue;
directory = Path.Combine($"{eDistanceContentDirectory[..^1]}{nameof(Mapping)})", mapping.MappingFromItem.MinimumDateTime.Year.ToString());
fileName = Path.Combine(directory, $"{mapping.MappingFromItem.ResizedFileHolder.Name}.lnk");
collection.Add((mapping.MappingFromItem.ResizedFileHolder.FullName, directory, fileName));
if (distinct.Contains(directory))
continue;
distinct.Add(directory);
}
#endif
foreach (string distinctDirectory in distinct)
{
if (!Directory.Exists(distinctDirectory))
_ = Directory.CreateDirectory(distinctDirectory);
}
foreach ((string path, string checkDirectory, string checkFile) in collection)
{
if (File.Exists(checkFile))
continue;
windowsShortcut = new() { Path = path };
windowsShortcut.Save(checkFile);
windowsShortcut.Dispose();
}
}
private void Search(long ticks, string argZero, string propertyRoot)
{
int t;
@ -1048,13 +1124,15 @@ public partial class DlibDotNet
ReadOnlyDictionary<int, List<LocationContainer<MetadataExtractor.Directory>>> idToLocationContainers = mapLogic.GetIdToLocationContainers();
fileNameToCollection = !Directory.Exists(fPhotoPrismSingletonDirectory) ? fileNameToCollection = new() : F_PhotoPrism.GetFileNameToCollection(fPhotoPrismSingletonDirectory);
FullDoWork(argZero, propertyRoot, ticks, aResultsFullGroupDirectory, bResultsFullGroupDirectory, t, containers, propertyLogic, metadata, eDistanceContentDirectory, fileNameToCollection, idToLocationContainers, mapLogic);
if (_Configuration.LookForAbandoned)
LookForAbandoned(bResultsFullGroupDirectory, containers, idToLocationContainers);
_Distance.Clear();
if (!personKeyToIds.Any())
personKeyToIds = mapLogic.GetPersonKeyToIds();
Mapping[] distinctFilteredMappingCollection = GetMappings(_Configuration.PropertyConfiguration, containers, mapLogic, idToLocationContainers, distinctItems: true);
List<Item> distinctFilteredItems = Shared.Models.Stateless.Methods.IContainer.GetItems(_Configuration.PropertyConfiguration, containers, distinctItems: true, filterItems: true);
Verify(eDistanceContentDirectory, distinctFilteredItems);
List<Shared.Models.Face> distinctFilteredFaces = Map.Models.Stateless.Methods.IMapLogic.GetFaces(distinctFilteredItems);
Mapping[] distinctFilteredMappingCollection = GetMappings(_Configuration.PropertyConfiguration, containers, mapLogic, distinctItems: true);
int totalNotMapped = mapLogic.UpdateMappingFromPerson(distinctFilteredMappingCollection);
string json = System.Text.Json.JsonSerializer.Serialize(distinctFilteredMappingCollection);
File.WriteAllText(Path.Combine(eDistanceContentDirectory, $"{ticks}.json"), json);

View File

@ -36,6 +36,7 @@ public class Configuration
[Display(Name = "Load Or Create Then Save Image Faces Results"), Required] public string[] LoadOrCreateThenSaveImageFacesResultsForOutputResolutions { get; set; }
[Display(Name = "Location Digits"), Required] public int? LocationDigits { get; set; }
[Display(Name = "Location Factor"), Required] public int? LocationFactor { get; set; }
[Display(Name = "Look for Abandoned"), Required] public bool? LookForAbandoned { get; set; }
[Display(Name = "Mapping Default Name"), Required] public string MappingDefaultName { get; set; }
[Display(Name = "Mapping Use Deterministic Hash Code Unknown Face Key Value Pairs for Add to Mapping"), Required] public bool? MappingUseDeterministicHashCodeUnknownFaceKeyValuePairsForAddToMapping { get; set; }
[Display(Name = "Mapping Use Deterministic Hash Code Unknown Face Key Value Pairs for Save Mapping"), Required] public bool? MappingUseDeterministicHashCodeUnknownFaceKeyValuePairsForSaveMapping { get; set; }
@ -146,6 +147,8 @@ public class Configuration
throw new NullReferenceException(nameof(configuration.LocationDigits));
if (configuration.LocationFactor is null)
throw new NullReferenceException(nameof(configuration.LocationFactor));
if (configuration.LookForAbandoned is null)
throw new NullReferenceException(nameof(configuration.LookForAbandoned));
if (configuration.MappingDefaultName is null)
throw new NullReferenceException(nameof(configuration.MappingDefaultName));
if (configuration.MappingUseDeterministicHashCodeUnknownFaceKeyValuePairsForAddToMapping is null)
@ -256,6 +259,7 @@ public class Configuration
configuration.LoadOrCreateThenSaveImageFacesResultsForOutputResolutions,
configuration.LocationDigits.Value,
configuration.LocationFactor.Value,
configuration.LookForAbandoned.Value,
configuration.MappingDefaultName,
configuration.MappingUseDeterministicHashCodeUnknownFaceKeyValuePairsForAddToMapping.Value,
configuration.MappingUseDeterministicHashCodeUnknownFaceKeyValuePairsForSaveMapping.Value,

View File

@ -35,6 +35,7 @@ public class Configuration
public string[] LoadOrCreateThenSaveImageFacesResultsForOutputResolutions { init; get; }
public int LocationDigits { init; get; }
public int LocationFactor { init; get; }
public bool LookForAbandoned { init; get; }
public string MappingDefaultName { init; get; }
public bool MappingUseDeterministicHashCodeUnknownFaceKeyValuePairsForAddToMapping { init; get; }
public bool MappingUseDeterministicHashCodeUnknownFaceKeyValuePairsForSaveMapping { init; get; }
@ -111,6 +112,7 @@ public class Configuration
string[] loadOrCreateThenSaveImageFacesResultsForOutputResolutions,
int locationDigits,
int locationFactor,
bool lookForAbandoned,
string mappingDefaultName,
bool mappingUseDeterministicHashCodeUnknownFaceKeyValuePairsForAddToMapping,
bool mappingUseDeterministicHashCodeUnknownFaceKeyValuePairsForSaveMapping,
@ -186,6 +188,7 @@ public class Configuration
LoadOrCreateThenSaveImageFacesResultsForOutputResolutions = loadOrCreateThenSaveImageFacesResultsForOutputResolutions;
LocationDigits = locationDigits;
LocationFactor = locationFactor;
LookForAbandoned = lookForAbandoned;
MappingDefaultName = mappingDefaultName;
MappingUseDeterministicHashCodeUnknownFaceKeyValuePairsForAddToMapping = mappingUseDeterministicHashCodeUnknownFaceKeyValuePairsForAddToMapping;
MappingUseDeterministicHashCodeUnknownFaceKeyValuePairsForSaveMapping = mappingUseDeterministicHashCodeUnknownFaceKeyValuePairsForSaveMapping;

View File

@ -20,6 +20,7 @@
"xFocusDirectory": "/Hawaii 2022",
"FocusModel": "",
"xFocusModel": "NIKON D3400",
"LookForAbandoned": false,
"xGenealogicalDataCommunicationFile": "",
"GenealogicalDataCommunicationFile": "D:/5) Other Small/RootsMagic/Code-638160743318283885/638160743318283885-Export.ged.cln",
"PersonCharactersCopyCount": 0,
@ -110,230 +111,6 @@
"Scanned Prints",
"Slide in Name Order Originals (622)",
"Slides Pictures"
],
"VerifyToSeason": [
". 2000",
". 2001",
". 2002",
". 2003",
". 2004",
". 2005",
". 2006",
". 2007",
". 2008",
". 2009",
". 2010",
". 2011",
". 2012",
". 2013",
". 2014",
". 2015",
". 2016",
". 2017",
". 2018",
". 2019",
". 2020",
". 2021",
". 2022",
". 2023",
". 2024",
". 2025",
". 2026",
". 2027",
". 2028",
". 2029",
"2000.0 Winter",
"2002.1 Spring",
"2002.4 Winter",
"2003.0 Winter",
"2003.1 Spring",
"2003.3 Fall",
"2003.4 Winter",
"2004.0 Winter",
"2005.1 Spring",
"2005.2 Summer",
"2005.3 Fall",
"2005.4 Winter",
"2006.0 Winter",
"2006.1 Spring",
"2006.3 Fall",
"2007.0 Winter",
"2007.2 Summer Logan Michael",
"2007.2 Summer",
"2007.3 Fall Logan Michael",
"2007.4 Winter Logan Michael",
"2008.0 Winter Logan Michael",
"2008.1 Spring Logan Michael",
"2008.2 Summer Logan Michael",
"2008.2 Summer",
"2008.3 Fall Logan Michael",
"2009.0 Winter Logan Michael",
"2009.0 Winter",
"2009.1 Spring Logan Michael",
"2009.1 Spring",
"2009.2 Summer Logan Michael",
"2009.2 Summer",
"2009.3 Fall Logan Michael",
"2009.3 Fall",
"2009.4 Winter Logan Michael",
"2009.4 Winter",
"2010.0 Winter Logan Michael",
"2010.0 Winter",
"2010.1 Spring Logan Michael",
"2010.1 Spring",
"2010.2 Summer",
"2010.3 Fall Logan Michael",
"2010.3 Fall",
"2010.4 Winter",
"2011.0 Winter",
"2011.1 Spring",
"2011.2 Summer",
"2011.3 Fall",
"2011.4 Winter",
"2012.0 Winter Chelsea 2012",
"2012.0 Winter Chelsea",
"2012.0 Winter",
"2012.1 Spring Chelsea",
"2012.1 Spring",
"2012.2 Summer Chelsea",
"2012.2 Summer",
"2012.3 Fall Chelsea",
"2012.3 Fall",
"2012.4 Winter Chelsea",
"2012.4 Winter",
"2013.0 Winter Chelsea 2013",
"2013.0 Winter Chelsea",
"2013.0 Winter",
"2013.1 Spring",
"2013.2 Summer Chelsea",
"2013.2 Summer",
"2013.3 Fall Chelsea",
"2013.3 Fall",
"2013.4 Winter",
"2014.0 Winter",
"2014.1 Spring",
"2014.2 Summer",
"2014.3 Fall",
"2014.4 Winter",
"2015.0 Winter",
"2015.1 Spring",
"2015.2 Summer",
"2015.3 Fall",
"2015.4 Winter",
"2016.0 Winter",
"2016.1 Spring",
"2016.2 Summer",
"2016.3 Fall",
"2016.4 Winter",
"2017.1 Spring",
"2017.2 Summer",
"2017.3 Fall",
"2017.4 Winter",
"2018.0 Winter",
"2018.1 Spring",
"2018.3 Fall",
"2018.4 Winter",
"2019.0 Winter",
"2019.1 Spring",
"2019.2 Summer",
"2019.3 Fall",
"2019.4 Winter",
"2020.0 Winter",
"2020.1 Spring",
"2020.2 Summer",
"2020.3 Fall",
"2020.4 Winter",
"2021.1 Spring",
"2021.2 Summer",
"2021.3 Fall",
"2021.4 Winter",
"2022.0 Winter",
"2022.1 Spring",
"Anthem 2015",
"April 2010",
"April 2013",
"December 2006",
"December 2010",
"Fall 2005",
"Fall 2015",
"Fall 2016",
"Fall 2017",
"Fall 2018",
"Fall 2019",
"Fall 2020",
"Fall 2021",
"February 2010",
"January 2015",
"July 2010",
"June 2010",
"Kids 2005",
"March 2013",
"May 2010",
"May 2011",
"May 2013",
"October 2005",
"October 2014",
"Spring 2013",
"Spring 2014",
"Spring 2016",
"Spring 2018",
"Spring 2019",
"Spring 2020",
"Summer 2011",
"Summer 2012",
"Summer 2013",
"Summer 2014",
"Summer 2015",
"Summer 2016",
"Summer 2017",
"Summer 2018",
"Summer 2020",
"Summer 2021",
"Winter 2015",
"Winter 2016",
"Winter 2017",
"Winter 2018",
"Winter 2019-2020",
"Winter 2020",
"zzz 2005.0 Winter Tracy Pictures",
"zzz 2005.1 Spring Tracy Pictures",
"zzz 2005.2 Summer Tracy Pictures",
"zzz 2005.3 Fall Tracy Pictures",
"zzz 2005.4 Winter Tracy Pictures",
"zzz 2006.1 Spring Tracy Pictures",
"zzz 2007.0 Winter Tracy Pictures",
"zzz 2007.2 Summer Tracy Pictures",
"zzz 2008.0 Winter Tracy Pictures",
"zzz 2008.2 Summer Tracy Pictures",
"zzz 2009.0 Winter Tracy Pictures",
"zzz 2009.2 Summer Tracy Pictures",
"zzz 2009.3 Fall Tracy Pictures",
"zzz 2009.4 Winter Tracy Pictures",
"zzz 2010.0 Winter Tracy Pictures",
"zzz 2010.1 Spring Tracy Pictures",
"zzz 2010.2 Summer Tracy Pictures",
"zzz 2010.3 Fall Tracy Pictures",
"zzz 2011.0 Winter Tracy Pictures",
"zzz 2011.1 Spring Tracy Pictures",
"zzz 2011.2 Summer Tracy Pictures",
"zzz 2011.3 Fall Tracy Pictures",
"zzz 2011.4 Winter Tracy Pictures",
"zzz 2012.0 Winter Tracy Pictures",
"zzz 2012.1 Spring Tracy Pictures",
"zzz 2012.2 Summer Tracy Pictures",
"zzz 2012.3 Fall Tracy Pictures",
"zzz 2012.4 Winter Tracy Pictures",
"zzz 2013.0 Winter Tracy Pictures",
"zzz 2013.1 Spring Tracy Pictures",
"zzz 2013.2 Summer Tracy Pictures",
"zzz 2013.3 Fall Tracy Pictures",
"zzz 2013.4 Winter Tracy Pictures",
"zzz 2014.0 Winter Tracy Pictures",
"zzz 2014.1 Spring Tracy Pictures",
"zzz 2014.2 Summer Tracy Pictures",
"zzz 2014.3 Fall Tracy Pictures",
"zzz 2014.4 Winter Tracy Pictures",
"zzz 2015.0 Winter Tracy Pictures"
]
}
}

View File

@ -73,6 +73,7 @@
"GenealogicalDataCommunicationFile": "",
"LocationDigits": 9,
"LocationFactor": 10000,
"LookForAbandoned": true,
"MappingDefaultName": "John Doe~25",
"MappingUseDeterministicHashCodeUnknownFaceKeyValuePairsForAddToMapping": false,
"MappingUseDeterministicHashCodeUnknownFaceKeyValuePairsForSaveMapping": false,

View File

@ -37,8 +37,6 @@ public class MapLogic : Shared.Models.Methods.IMapLogic
_PropertyConfiguration = propertyConfiguration;
if (_Log is null)
{ }
if (propertyConfiguration.VerifyToSeason is null || !propertyConfiguration.VerifyToSeason.Any())
throw new NullReferenceException(nameof(propertyConfiguration.VerifyToSeason));
string json;
string fullPath;
List<KeyValuePair<int, int[]>>? collection;
@ -812,7 +810,7 @@ public class MapLogic : Shared.Models.Methods.IMapLogic
windowsShortcut.Dispose();
if (!File.Exists(shortcutFile))
continue;
File.SetLastWriteTime(shortcutFile, mapping.MappingFromItem.MinimumDateTime);
File.SetLastWriteTime(shortcutFile, mapping.MappingFromItem.GetDateTimeOriginalThenMinimumDateTime());
}
}
}
@ -1129,45 +1127,35 @@ public class MapLogic : Shared.Models.Methods.IMapLogic
if (_Configuration is null)
throw new NullReferenceException(nameof(_Configuration));
int season;
string? model;
long personKey;
string fileName;
string directory;
int dateCount = 0;
string weekOfYear;
DateTime dateTime;
string description;
DateTime? dateTime;
string directoryName;
List<long>? personKeys;
string personKeyFormatted;
Calendar calendar = new CultureInfo("en-US").Calendar;
IReadOnlyList<MetadataExtractor.Directory> directories;
Dictionary<int, List<long>> idToPersonKeys = Stateless.Methods.IMapLogic.GetIdToPersonKeys(personKeyToIds);
foreach (Mapping mapping in mappingCollection)
{
directories = MetadataExtractor.ImageMetadataReader.ReadMetadata(mapping.MappingFromItem.ResizedFileHolder.FullName);
dateTime = Metadata.Models.Stateless.Methods.IMetadata.GetMinimumDateTime(directories);
dateTime = mapping.MappingFromItem.GetDateTimeOriginalThenMinimumDateTime();
description = mapping.MappingFromLocation is null ? mapping.MappingFromItem.Id.ToString() : mapping.MappingFromLocation.DeterministicHashCodeKey;
if (dateTime is not null)
{
dateCount++;
(season, _) = IProperty.GetSeason(dateTime.Value.DayOfYear);
weekOfYear = calendar.GetWeekOfYear(dateTime.Value, CalendarWeekRule.FirstDay, DayOfWeek.Sunday).ToString("00");
directory = Path.Combine($"{eDistanceContentDirectory}---", "Date Shortcuts", $"{dateTime.Value.Year}.{season}-MM{dateTime.Value.Month:00}-WW{weekOfYear}");
(season, _) = IProperty.GetSeason(dateTime.DayOfYear);
weekOfYear = calendar.GetWeekOfYear(dateTime, CalendarWeekRule.FirstDay, DayOfWeek.Sunday).ToString("00");
directory = Path.Combine($"{eDistanceContentDirectory}---", "Date Shortcuts", $"{dateTime.Year}.{season}-MM{dateTime.Month:00}-WW{weekOfYear}");
fileName = Path.Combine(directory, $"{mapping.MappingFromItem.ImageFileHolder.Name}.lnk");
results.Add(new(mapping.MappingFromItem.ImageFileHolder.FullName, directory, mapping.MappingFromItem.MinimumDateTime, fileName, description, MakeAllHidden: false));
}
model = Metadata.Models.Stateless.Methods.IMetadata.GetModel(directories);
results.Add(new(mapping.MappingFromItem.ImageFileHolder.FullName, directory, dateTime, fileName, description, MakeAllHidden: false));
if (mapping.MappingFromItem.ImageFileHolder.DirectoryName is null)
continue;
directoryName = Path.GetFileName(mapping.MappingFromItem.ImageFileHolder.DirectoryName);
if (!string.IsNullOrEmpty(model) && !string.IsNullOrEmpty(model.Trim()))
if (!string.IsNullOrEmpty(mapping.MappingFromItem.Model) && !string.IsNullOrEmpty(mapping.MappingFromItem.Model.Trim()))
{
// Remove-Item -LiteralPath "\\?\D:\Tmp\a\EX-Z70 "
model = Regex.Replace(model.Trim(), @"[\\,\/,\:,\*,\?,\"",\<,\>,\|]", "_");
directory = Path.Combine($"{eDistanceContentDirectory}---", "Model Shortcuts", model, directoryName);
directory = Path.Combine($"{eDistanceContentDirectory}---", "Model Shortcuts", Regex.Replace(mapping.MappingFromItem.Model.Trim(), @"[\\,\/,\:,\*,\?,\"",\<,\>,\|]", "_"), directoryName);
fileName = Path.Combine(directory, $"{mapping.MappingFromItem.ImageFileHolder.Name}.lnk");
results.Add(new(mapping.MappingFromItem.ImageFileHolder.FullName, directory, mapping.MappingFromItem.MinimumDateTime, fileName, description, MakeAllHidden: false));
results.Add(new(mapping.MappingFromItem.ImageFileHolder.FullName, directory, dateTime, fileName, description, MakeAllHidden: false));
}
if (mapping.MappingFromPerson is null)
continue;
@ -1179,12 +1167,12 @@ public class MapLogic : Shared.Models.Methods.IMapLogic
personKeyFormatted = IPersonBirthday.GetFormatted(_Configuration.PersonBirthdayFormat, mapping.MappingFromPerson.PersonBirthday);
directory = Path.Combine($"{eDistanceContentDirectory}---", "Person Key Shortcuts", personKeyFormatted, directoryName);
fileName = Path.Combine(directory, $"{mapping.MappingFromItem.ImageFileHolder.Name}.lnk");
results.Add(new(mapping.MappingFromItem.ImageFileHolder.FullName, directory, mapping.MappingFromItem.MinimumDateTime, fileName, description, MakeAllHidden: false));
results.Add(new(mapping.MappingFromItem.ImageFileHolder.FullName, directory, mapping.MappingFromItem.GetDateTimeOriginalThenMinimumDateTime(), fileName, description, MakeAllHidden: false));
if (IPerson.IsDefaultName(_Configuration.MappingDefaultName, mapping.MappingFromPerson.DisplayDirectoryName))
continue;
directory = Path.Combine($"{eDistanceContentDirectory}---", "Name Shortcuts", mapping.MappingFromPerson.DisplayDirectoryName, directoryName);
fileName = Path.Combine(directory, $"{mapping.MappingFromItem.ImageFileHolder.Name}.lnk");
results.Add(new(mapping.MappingFromItem.ImageFileHolder.FullName, directory, mapping.MappingFromItem.MinimumDateTime, fileName, description, MakeAllHidden: false));
results.Add(new(mapping.MappingFromItem.ImageFileHolder.FullName, directory, mapping.MappingFromItem.GetDateTimeOriginalThenMinimumDateTime(), fileName, description, MakeAllHidden: false));
}
return results;
}
@ -1286,13 +1274,13 @@ public class MapLogic : Shared.Models.Methods.IMapLogic
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, mapping.MappingFromItem.MinimumDateTime, fileName, mapping.MappingFromLocation?.DeterministicHashCodeKey, MakeAllHidden: false));
collection.Add(new(mapping.MappingFromItem.ResizedFileHolder.FullName, personDirectory, mapping.MappingFromItem.GetDateTimeOriginalThenMinimumDateTime(), fileName, mapping.MappingFromLocation?.DeterministicHashCodeKey, MakeAllHidden: false));
facesDirectory = Stateless.MapLogic.GetFacesDirectory(dFacesContentDirectory, mapping.MappingFromItem);
if (facesDirectory is null || mapping.MappingFromLocation is null)
continue;
fullName = Path.Combine(facesDirectory, $"{mapping.MappingFromLocation.DeterministicHashCodeKey}{mapping.MappingFromItem.ImageFileHolder.ExtensionLowered}{_Configuration.FacesFileNameExtension}");
fileName = Path.Combine(personDirectory, $"{mapping.MappingFromLocation.DeterministicHashCodeKey}{mapping.MappingFromItem.ResizedFileHolder.ExtensionLowered}{_Configuration.FacesFileNameExtension}.lnk");
collection.Add(new(fullName, personDirectory, mapping.MappingFromItem.MinimumDateTime, fileName, mapping.MappingFromLocation.DeterministicHashCodeKey, MakeAllHidden: true));
collection.Add(new(fullName, personDirectory, mapping.MappingFromItem.GetDateTimeOriginalThenMinimumDateTime(), fileName, mapping.MappingFromLocation.DeterministicHashCodeKey, MakeAllHidden: true));
}
else
{
@ -1313,7 +1301,7 @@ public class MapLogic : Shared.Models.Methods.IMapLogic
else
personDirectory = Path.Combine(directory, mapping.MappingFromPerson.DisplayDirectoryName, $"{personKeyToIds[personKey].Count} Face(s)");
fileName = Path.Combine(directory, $"{mapping.MappingFromItem.ResizedFileHolder.Name}.lnk");
collection.Add(new(mapping.MappingFromItem.ResizedFileHolder.FullName, personDirectory, mapping.MappingFromItem.MinimumDateTime, fileName, mapping.MappingFromLocation?.DeterministicHashCodeKey, MakeAllHidden: false));
collection.Add(new(mapping.MappingFromItem.ResizedFileHolder.FullName, personDirectory, mapping.MappingFromItem.GetDateTimeOriginalThenMinimumDateTime(), fileName, mapping.MappingFromLocation?.DeterministicHashCodeKey, MakeAllHidden: false));
}
}
return new(directoriesAndDateTimes, collection);

View File

@ -765,41 +765,41 @@ internal abstract class MapLogic
SavePossiblyNewPersonContainers(configuration.PersonBirthdayFormat, configuration.FacesFileNameExtension, a2PeopleSingletonDirectory, possiblyNewPersonDisplayDirectoryNamesAndPersonContainer);
}
private static string GetMappingSegmentB(long ticks, PersonBirthday personBirthday, int? approximateYears, long minimumDateTimeTicks, bool? isWrongYear)
private static string GetMappingSegmentB(long ticks, PersonBirthday personBirthday, int? approximateYears, long dateTimeOriginalThenMinimumDateTimeTicks, bool? isWrongYear)
{
int years;
string result;
TimeSpan? timeSpan = IPersonBirthday.GetTimeSpan(minimumDateTimeTicks, isWrongYear, personBirthday);
TimeSpan? timeSpan = IPersonBirthday.GetTimeSpan(dateTimeOriginalThenMinimumDateTimeTicks, isWrongYear, personBirthday);
if (timeSpan.HasValue && timeSpan.Value.Ticks < 0)
result = "!---";
else if (timeSpan.HasValue)
{
(years, _) = IPersonBirthday.GetAge(minimumDateTimeTicks, personBirthday);
(years, _) = IPersonBirthday.GetAge(dateTimeOriginalThenMinimumDateTimeTicks, personBirthday);
result = $"^{years:000}";
}
else if (approximateYears.HasValue)
{
DateTime dateTime = new(ticks);
(years, _) = IAge.GetAge(minimumDateTimeTicks, dateTime.AddYears(-approximateYears.Value));
(years, _) = IAge.GetAge(dateTimeOriginalThenMinimumDateTimeTicks, dateTime.AddYears(-approximateYears.Value));
result = $"~{years:000}";
}
else
{
string isWrongYearFlag = IItem.GetWrongYearFlag(isWrongYear);
result = $"{isWrongYearFlag}{new DateTime(minimumDateTimeTicks):yyyy}";
result = $"{isWrongYearFlag}{new DateTime(dateTimeOriginalThenMinimumDateTimeTicks):yyyy}";
}
return result;
}
internal static string GetMappingSegmentB(long ticks, PersonBirthday personBirthday, int? approximateYears, DateTime minimumDateTime, bool? isWrongYear)
internal static string GetMappingSegmentB(long ticks, PersonBirthday personBirthday, int? approximateYears, DateTime dateTimeOriginalThenMinimumDateTime, bool? isWrongYear)
{
string result = GetMappingSegmentB(ticks, personBirthday, approximateYears, minimumDateTime.Ticks, isWrongYear);
string result = GetMappingSegmentB(ticks, personBirthday, approximateYears, dateTimeOriginalThenMinimumDateTime.Ticks, isWrongYear);
return result;
}
internal static string GetMappingSegmentB(long ticks, PersonBirthday personBirthday, int? approximateYears, MappingFromItem mappingFromItem)
{
string result = GetMappingSegmentB(ticks, personBirthday, approximateYears, mappingFromItem.MinimumDateTime, mappingFromItem.IsWrongYear);
string result = GetMappingSegmentB(ticks, personBirthday, approximateYears, mappingFromItem.GetDateTimeOriginalThenMinimumDateTime(), mappingFromItem.IsWrongYear);
return result;
}

View File

@ -1,5 +1,4 @@
using ShellProgressBar;
using System.Diagnostics;
using System.Drawing;
using System.Drawing.Imaging;
using System.Globalization;
@ -22,7 +21,6 @@ public class A_Property
private readonly Serilog.ILogger? _Log;
private readonly string _OutputExtension;
private readonly string[] _VerifyToSeason;
private readonly int _MaxDegreeOfParallelism;
private readonly ASCIIEncoding _ASCIIEncoding;
private readonly Configuration _Configuration;
@ -41,9 +39,6 @@ public class A_Property
_AngleBracketCollection = new List<string>();
_MaxDegreeOfParallelism = maxDegreeOfParallelism;
_WriteIndentedJsonSerializerOptions = new JsonSerializerOptions { WriteIndented = true };
if (configuration.VerifyToSeason is null || !configuration.VerifyToSeason.Any())
throw new Exception();
_VerifyToSeason = configuration.VerifyToSeason.Select(l => Path.Combine(configuration.RootDirectory, l)).ToArray();
string checkDirectory;
List<string> collection = new();
for (int i = 0; i < 12; i++)
@ -107,27 +102,23 @@ public class A_Property
return results;
}
private Shared.Models.Property GetImageProperty(FileHolder fileHolder, Shared.Models.Property? property, bool populateId, bool isIgnoreExtension, bool isValidImageFormatExtension, bool isValidMetadataExtensions, int? id)
private static Shared.Models.Property GetImageProperty(FileHolder fileHolder, Shared.Models.Property? property, bool populateId, bool isIgnoreExtension, bool isValidImageFormatExtension, bool isValidMetadataExtensions, int? id, ASCIIEncoding asciiEncoding, bool writeBitmapDataBytes, string? angleBracket)
{
Shared.Models.Property result;
if (_Log is null)
throw new NullReferenceException(nameof(_Log));
long ticks;
byte[] bytes;
string value;
long fileLength;
int encodingHash;
int? width = null;
int? height = null;
string? make = null;
string? model = null;
string dateTimeFormat;
DateTime checkDateTime;
DateTime? dateTime = null;
PropertyItem? propertyItem;
string make = string.Empty;
string model = string.Empty;
string? orientation = null;
DateTime? gpsDateStamp = null;
DateTime? dateTimeOriginal = null;
string orientation = string.Empty;
DateTime? dateTimeDigitized = null;
DateTime? dateTimeFromName = Shared.Models.Stateless.Methods.IProperty.GetDateTimeFromName(fileHolder);
if (!isValidImageFormatExtension && isValidMetadataExtensions && fileHolder.Exists)
@ -145,7 +136,6 @@ public class A_Property
if (populateId && id is null)
{
using Bitmap bitmap = new(image);
string angleBracket = _AngleBracketCollection[0];
Rectangle rectangle = new(0, 0, image.Width, image.Height);
BitmapData bitmapData = bitmap.LockBits(rectangle, ImageLockMode.ReadOnly, bitmap.PixelFormat);
IntPtr intPtr = bitmapData.Scan0;
@ -153,25 +143,12 @@ public class A_Property
bytes = new byte[length];
Marshal.Copy(intPtr, bytes, 0, length);
bitmap.UnlockBits(bitmapData);
if (id is null)
{
ticks = DateTime.Now.Ticks;
id = Shared.Models.Stateless.Methods.IProperty.GetDeterministicHashCode(bytes);
if (_MaxDegreeOfParallelism < 2)
ticks = LogDelta(ticks, nameof(Shared.Models.Stateless.Methods.IProperty.GetDeterministicHashCode));
}
if (_Configuration.WriteBitmapDataBytes)
id ??= Shared.Models.Stateless.Methods.IProperty.GetDeterministicHashCode(bytes);
if (writeBitmapDataBytes && !string.IsNullOrEmpty(angleBracket))
{
FileInfo contentFileInfo = new(Path.Combine(angleBracket.Replace("<>", "()"), fileHolder.Name));
File.WriteAllBytes(Path.ChangeExtension(contentFileInfo.FullName, string.Empty), bytes);
}
ticks = DateTime.Now.Ticks;
string encoding = Encoding.Default.GetString(bytes);
if (_MaxDegreeOfParallelism < 2)
ticks = LogDelta(ticks, nameof(Encoding.Default.GetString));
encodingHash = Shared.Models.Stateless.Methods.IProperty.GetDeterministicHashCode(encoding);
if (_MaxDegreeOfParallelism < 2)
ticks = LogDelta(ticks, nameof(Shared.Models.Stateless.Methods.IProperty.GetDeterministicHashCode));
}
width = image.Width;
height = image.Height;
@ -181,7 +158,7 @@ public class A_Property
propertyItem = image.GetPropertyItem((int)IExif.Tags.DateTime);
if (propertyItem?.Value is not null)
{
value = _ASCIIEncoding.GetString(propertyItem.Value, 0, propertyItem.Len - 1);
value = asciiEncoding.GetString(propertyItem.Value, 0, propertyItem.Len - 1);
if (value.Length > dateTimeFormat.Length)
value = value[..dateTimeFormat.Length];
if (value.Length == dateTimeFormat.Length && DateTime.TryParseExact(value, dateTimeFormat, CultureInfo.InvariantCulture, DateTimeStyles.None, out checkDateTime))
@ -193,7 +170,7 @@ public class A_Property
propertyItem = image.GetPropertyItem((int)IExif.Tags.DateTimeDigitized);
if (propertyItem?.Value is not null)
{
value = _ASCIIEncoding.GetString(propertyItem.Value, 0, propertyItem.Len - 1);
value = asciiEncoding.GetString(propertyItem.Value, 0, propertyItem.Len - 1);
if (value.Length > dateTimeFormat.Length)
value = value[..dateTimeFormat.Length];
if (value.Length == dateTimeFormat.Length && DateTime.TryParseExact(value, dateTimeFormat, CultureInfo.InvariantCulture, DateTimeStyles.None, out checkDateTime))
@ -205,7 +182,7 @@ public class A_Property
propertyItem = image.GetPropertyItem((int)IExif.Tags.DateTimeOriginal);
if (propertyItem?.Value is not null)
{
value = _ASCIIEncoding.GetString(propertyItem.Value, 0, propertyItem.Len - 1);
value = asciiEncoding.GetString(propertyItem.Value, 0, propertyItem.Len - 1);
if (value.Length > dateTimeFormat.Length)
value = value[..dateTimeFormat.Length];
if (value.Length == dateTimeFormat.Length && DateTime.TryParseExact(value, dateTimeFormat, CultureInfo.InvariantCulture, DateTimeStyles.None, out checkDateTime))
@ -217,7 +194,7 @@ public class A_Property
propertyItem = image.GetPropertyItem((int)IExif.Tags.GPSDateStamp);
if (propertyItem?.Value is not null)
{
value = _ASCIIEncoding.GetString(propertyItem.Value, 0, propertyItem.Len - 1);
value = asciiEncoding.GetString(propertyItem.Value, 0, propertyItem.Len - 1);
if (value.Length > dateTimeFormat.Length)
value = value[..dateTimeFormat.Length];
if (value.Length == dateTimeFormat.Length && DateTime.TryParseExact(value, dateTimeFormat, CultureInfo.InvariantCulture, DateTimeStyles.None, out checkDateTime))
@ -229,7 +206,7 @@ public class A_Property
propertyItem = image.GetPropertyItem((int)IExif.Tags.Make);
if (propertyItem?.Value is not null)
{
value = _ASCIIEncoding.GetString(propertyItem.Value, 0, propertyItem.Len - 1);
value = asciiEncoding.GetString(propertyItem.Value, 0, propertyItem.Len - 1);
make = value;
}
}
@ -238,7 +215,7 @@ public class A_Property
propertyItem = image.GetPropertyItem((int)IExif.Tags.Model);
if (propertyItem?.Value is not null)
{
value = _ASCIIEncoding.GetString(propertyItem.Value, 0, propertyItem.Len - 1);
value = asciiEncoding.GetString(propertyItem.Value, 0, propertyItem.Len - 1);
model = value;
}
}
@ -252,10 +229,7 @@ public class A_Property
}
}
}
catch (Exception)
{
_Log.Info(string.Concat(new StackFrame().GetMethod()?.Name, " <", fileHolder.Name, ">"));
}
catch (Exception) { }
}
else
dateTimeOriginal = null;
@ -276,6 +250,22 @@ public class A_Property
return result;
}
public static Shared.Models.Property GetImageProperty(string fileName)
{
int? id = null;
bool populateId = true;
string? angleBracket = null;
bool isIgnoreExtension = false;
bool writeBitmapDataBytes = false;
ASCIIEncoding asciiEncoding = new();
bool isValidMetadataExtensions = true;
FileHolder fileHolder = new(fileName);
bool isValidImageFormatExtension = true;
Shared.Models.Property? property = null;
Shared.Models.Property result = GetImageProperty(fileHolder, property, populateId, isIgnoreExtension, isValidImageFormatExtension, isValidMetadataExtensions, id, asciiEncoding, writeBitmapDataBytes, angleBracket);
return result;
}
#pragma warning restore CA1416
private Shared.Models.Property GetPropertyOfPrivate(Item item, List<Tuple<string, DateTime>> sourceDirectoryFileTuples, List<string> parseExceptions, bool isIgnoreExtension, bool isValidMetadataExtensions)
@ -290,7 +280,7 @@ public class A_Property
bool populateId = _Configuration.PopulatePropertyId;
char directory = Shared.Models.Stateless.Methods.IDirectory.GetDirectory(item.ImageFileHolder.Name);
int directoryIndex = Shared.Models.Stateless.Methods.IDirectory.GetDirectory(directory);
if (item.IsUniqueFileName is null || !item.IsUniqueFileName.Value)
if (!item.IsUniqueFileName)
fileInfo = new(Path.Combine(angleBracket.Replace("<>", "{}"), $"{item.ImageFileHolder.NameWithoutExtension}{item.ImageFileHolder.ExtensionLowered}.json"));
else
fileInfo = new(Path.Combine(_JsonGroups["{}"][directoryIndex], $"{item.ImageFileHolder.NameWithoutExtension}{item.ImageFileHolder.ExtensionLowered}.json"));
@ -369,7 +359,7 @@ public class A_Property
if (result is null)
{
id ??= item.ImageFileHolder.Id;
result = GetImageProperty(item.ImageFileHolder, result, populateId, isIgnoreExtension, item.IsValidImageFormatExtension, isValidMetadataExtensions, id);
result = GetImageProperty(item.ImageFileHolder, result, populateId, isIgnoreExtension, item.IsValidImageFormatExtension, isValidMetadataExtensions, id, _ASCIIEncoding, _Configuration.WriteBitmapDataBytes, angleBracket);
json = JsonSerializer.Serialize(result, _WriteIndentedJsonSerializerOptions);
if (populateId && Shared.Models.Stateless.Methods.IPath.WriteAllText(fileInfo.FullName, json, updateDateWhenMatches: true, compareBeforeWrite: true))
{
@ -398,106 +388,6 @@ public class A_Property
return result;
}
private bool AnyFilesMoved(string sourceDirectory, List<Item> items)
{
bool result = false;
if (_Log is null)
throw new NullReferenceException(nameof(_Log));
int season;
string[] matches;
string deleteFile;
bool? isWrongYear;
string seasonName;
DateTime dateTime;
string destinationFile;
DateTime minimumDateTime;
string destinationDirectory;
string[] sourceDirectorySegments;
DateTime directoryMaximumOfMinimumDateTime = DateTime.MinValue;
foreach (Item item in items)
{
if (!item.IsValidImageFormatExtension || item.Property is null || !item.ImageFileHolder.Exists)
continue;
minimumDateTime = Shared.Models.Stateless.Methods.IProperty.GetMinimumDateTime(item.Property);
if (minimumDateTime > directoryMaximumOfMinimumDateTime)
directoryMaximumOfMinimumDateTime = minimumDateTime;
if (minimumDateTime != item.ImageFileHolder.CreationTime)
{
(isWrongYear, matches) = item.Property.IsWrongYear(item.ImageFileHolder, minimumDateTime);
if (isWrongYear is null || !isWrongYear.Value)
dateTime = minimumDateTime;
else
{
if (!matches.Any())
continue;
if (!DateTime.TryParseExact(matches[0], "yyyy", CultureInfo.InvariantCulture, DateTimeStyles.None, out dateTime))
continue;
}
try
{ File.SetCreationTime(item.ImageFileHolder.FullName, dateTime); }
catch (Exception)
{ }
}
if (!_VerifyToSeason.Contains(sourceDirectory))
continue;
if (!item.ImageFileHolder.FullName.Contains("zzz ") && !item.ImageFileHolder.FullName.Contains("Camera ") && item.Property.DateTimeOriginal.HasValue)
{
TimeSpan timeSpan = new(item.Property.DateTimeOriginal.Value.Ticks - item.Property.LastWriteTime.Ticks);
if (timeSpan.TotalHours > 7.2f)
{
_Log.Warning($"*** propertyHolder.FileInfo.FullName <{item.ImageFileHolder.FullName}>");
_Log.Warning($"*** DateTimeOriginal <{item.Property.DateTimeOriginal.Value}>");
_Log.Warning($"*** LastWriteTime <{item.Property.LastWriteTime}>");
_Log.Warning($"*** TotalHours <{timeSpan.TotalHours}>");
}
}
sourceDirectorySegments = Path.GetFileName(sourceDirectory).Split(' ');
(season, seasonName) = Shared.Models.Stateless.Methods.IProperty.GetSeason(minimumDateTime.DayOfYear);
if (sourceDirectorySegments[0] == "zzz")
destinationDirectory = Path.Combine(_Configuration.RootDirectory, $"zzz ={minimumDateTime:yyyy}.{season} {seasonName} {string.Join(' ', sourceDirectorySegments.Skip(3))}");
else if (sourceDirectorySegments.Length > 2)
destinationDirectory = Path.Combine(_Configuration.RootDirectory, $"={minimumDateTime:yyyy}.{season} {seasonName} {string.Join(' ', sourceDirectorySegments.Skip(2))}");
else
destinationDirectory = Path.Combine(_Configuration.RootDirectory, $"={minimumDateTime:yyyy}.{season} {seasonName}");
if (destinationDirectory == sourceDirectory)
continue;
lock (item)
item.SetMoved(true);
if (!result)
result = true;
if (!Directory.Exists(destinationDirectory))
_ = Directory.CreateDirectory(destinationDirectory);
destinationFile = Path.Combine(destinationDirectory, item.ImageFileHolder.Name);
if (File.Exists(destinationFile))
{
if (_OutputExtension is not ".jpg" and not ".jpeg")
throw new Exception();
if (destinationFile.EndsWith(".jpg", ignoreCase: true, CultureInfo.CurrentCulture))
destinationFile = Path.Combine(destinationDirectory, Path.ChangeExtension(item.ImageFileHolder.Name, ".jpeg"));
else if (destinationFile.EndsWith(".jpeg", ignoreCase: true, CultureInfo.CurrentCulture))
destinationFile = Path.Combine(destinationDirectory, Path.ChangeExtension(item.ImageFileHolder.Name, ".jpg"));
}
_Log.Information($"*** source <{item.ImageFileHolder.FullName}>");
_Log.Information($"*** destination <{destinationFile}>");
if (!File.Exists(destinationFile))
File.Move(item.ImageFileHolder.FullName, destinationFile);
else
{
deleteFile = Path.ChangeExtension(item.ImageFileHolder.FullName, ".delete");
if (File.Exists(deleteFile))
File.Delete(deleteFile);
File.Move(item.ImageFileHolder.FullName, destinationFile);
}
}
if (directoryMaximumOfMinimumDateTime != DateTime.MinValue)
{
DirectoryInfo directoryInfo = new(sourceDirectory);
if (directoryInfo.LastWriteTime != directoryMaximumOfMinimumDateTime)
Directory.SetLastWriteTime(sourceDirectory, directoryMaximumOfMinimumDateTime);
}
return result;
}
private void SavePropertyParallelForWork(string sourceDirectory, List<Tuple<string, DateTime>> sourceDirectoryFileTuples, List<Tuple<string, DateTime>> sourceDirectoryChanges, Item item)
{
Shared.Models.Property property;
@ -579,7 +469,6 @@ public class A_Property
throw new NullReferenceException(nameof(_Log));
string message;
int totalSeconds;
bool? anyFilesMoved;
Container container;
bool anyNullOrNoIsUniqueFileName;
List<Exception> exceptions = new();
@ -594,7 +483,7 @@ public class A_Property
sourceDirectoryChanges.Clear();
if (!container.Items.Any())
continue;
anyNullOrNoIsUniqueFileName = container.Items.Any(l => l.IsUniqueFileName is null || !l.IsUniqueFileName.Value);
anyNullOrNoIsUniqueFileName = container.Items.Any(l => !l.IsUniqueFileName);
SetAngleBracketCollection(container.SourceDirectory, anyNullOrNoIsUniqueFileName);
totalSeconds = (int)Math.Truncate(new TimeSpan(DateTime.Now.Ticks - ticks).TotalSeconds);
message = $"{i + 1:000} / {containersCount:000}) {container.Items.Count:000} file(s) - {totalSeconds} total second(s) - {container.SourceDirectory}";
@ -605,10 +494,6 @@ public class A_Property
throw new Exception(string.Concat("All in [", container.SourceDirectory, "]failed!"));
if (exceptions.Count != 0)
_ExceptionsDirectories.Add(container.SourceDirectory);
if (exceptions.Count != 0)
anyFilesMoved = null;
else
anyFilesMoved = AnyFilesMoved(container.SourceDirectory, container.Items);
if (Directory.GetFiles(propertyRoot, "*.txt", SearchOption.TopDirectoryOnly).Any())
{
for (int y = 0; y < int.MaxValue; y++)
@ -630,8 +515,7 @@ public class A_Property
{
if (item.ImageFileHolder.DirectoryName is null)
throw new NullReferenceException(nameof(item.ImageFileHolder.DirectoryName));
bool anyNullOrNoIsUniqueFileName = item.IsUniqueFileName is null || !item.IsUniqueFileName.Value;
SetAngleBracketCollection(item.ImageFileHolder.DirectoryName, anyNullOrNoIsUniqueFileName);
SetAngleBracketCollection(item.ImageFileHolder.DirectoryName, !item.IsUniqueFileName);
}
bool isValidMetadataExtensions = _Configuration.ValidMetadataExtensions.Contains(item.ImageFileHolder.ExtensionLowered);
bool isIgnoreExtension = item.IsValidImageFormatExtension && _Configuration.IgnoreExtensions.Contains(item.ImageFileHolder.ExtensionLowered);

View File

@ -34,7 +34,6 @@ public class Configuration : Shared.Models.Properties.IPropertyConfiguration
public string ResultSingleton { init; get; }
public string[] ValidImageFormatExtensions { init; get; }
public string[] ValidMetadataExtensions { init; get; }
public string[] VerifyToSeason { init; get; }
public bool WriteBitmapDataBytes { init; get; }
[JsonConstructor]
@ -75,7 +74,6 @@ public class Configuration : Shared.Models.Properties.IPropertyConfiguration
_RootDirectory = rootDirectory;
ValidImageFormatExtensions = validImageFormatExtensions;
ValidMetadataExtensions = validMetadataExtensions;
VerifyToSeason = verifyToSeason;
WriteBitmapDataBytes = writeBitmapDataBytes;
}
@ -110,8 +108,6 @@ public class Configuration : Shared.Models.Properties.IPropertyConfiguration
throw new NullReferenceException(nameof(propertyConfiguration.ValidImageFormatExtensions));
if (propertyConfiguration.ValidMetadataExtensions is null || !propertyConfiguration.ValidMetadataExtensions.Any())
throw new NullReferenceException(nameof(propertyConfiguration.ValidMetadataExtensions));
if (propertyConfiguration.VerifyToSeason is null || !propertyConfiguration.VerifyToSeason.Any())
throw new NullReferenceException(nameof(propertyConfiguration.VerifyToSeason));
if (propertyConfiguration is null)
throw new NullReferenceException(nameof(propertyConfiguration));
if (string.IsNullOrEmpty(propertyConfiguration.DateGroup))

View File

@ -284,7 +284,7 @@ public class C_Resize
{
// string subFile, Shared.Models.Property property, Shared.Models.FileHolder? fileHolder
string dateTimeFormat = Shared.Models.Stateless.Methods.IProperty.DateTimeFormat();
DateTime dateTime = Shared.Models.Stateless.Methods.IProperty.GetMinimumDateTime(property);
DateTime dateTime = property.DateTimeOriginal is not null ? property.DateTimeOriginal.Value : Shared.Models.Stateless.Methods.IProperty.GetMinimumDateTime(property);
string dateTimeValue = dateTime.ToString(dateTimeFormat);
byte[] bytes = _ASCIIEncoding.GetBytes(dateTimeValue);
if (_ASCIIEncoding.GetString(bytes, 0, bytes.Length) != dateTimeValue)

View File

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

View File

@ -1,3 +1,3 @@
namespace View_by_Distance.Shared.Models;
public record FilePair(string Path, bool IsUnique, List<string> Collection, string? Match) { }
public record FilePair(string Path, bool IsUnique, bool? IsNotUniqueAndNeedsReview, List<string> Collection, string? Match) { }

View File

@ -9,7 +9,8 @@ public class Item : Properties.IItem
protected List<Face> _Faces;
protected readonly bool? _FileSizeChanged;
protected readonly FileHolder _ImageFileHolder;
protected bool? _IsUniqueFileName;
protected bool? _IsNotUniqueAndNeedsReview;
protected bool _IsUniqueFileName;
protected bool _IsValidImageFormatExtension;
protected bool? _LastWriteTimeChanged;
protected bool? _Moved;
@ -20,7 +21,8 @@ public class Item : Properties.IItem
public List<Face> Faces => _Faces;
public bool? FileSizeChanged => _FileSizeChanged;
public FileHolder ImageFileHolder => _ImageFileHolder;
public bool? IsUniqueFileName => _IsUniqueFileName;
public bool? IsNotUniqueAndNeedsReview => _IsNotUniqueAndNeedsReview;
public bool IsUniqueFileName => _IsUniqueFileName;
public bool IsValidImageFormatExtension => _IsValidImageFormatExtension;
public bool? LastWriteTimeChanged => _LastWriteTimeChanged;
public bool? Moved => _Moved;
@ -30,11 +32,12 @@ public class Item : Properties.IItem
public FileHolder SourceDirectoryFileHolder => _SourceDirectoryFileHolder;
[JsonConstructor]
public Item(List<Face> faces, bool? fileSizeChanged, FileHolder imageFileHolder, bool? isUniqueFileName, bool isValidImageFormatExtension, bool? lastWriteTimeChanged, bool? moved, Property? property, string relativePath, FileHolder? resizedFileHolder, FileHolder sourceDirectoryFileHolder)
public Item(List<Face> faces, bool? fileSizeChanged, FileHolder imageFileHolder, bool? isNotUniqueAndNeedsReview, bool isUniqueFileName, bool isValidImageFormatExtension, bool? lastWriteTimeChanged, bool? moved, Property? property, string relativePath, FileHolder? resizedFileHolder, FileHolder sourceDirectoryFileHolder)
{
_Faces = faces;
_FileSizeChanged = fileSizeChanged;
_ImageFileHolder = imageFileHolder;
_IsNotUniqueAndNeedsReview = isNotUniqueAndNeedsReview;
_IsUniqueFileName = isUniqueFileName;
_IsValidImageFormatExtension = isValidImageFormatExtension;
_LastWriteTimeChanged = lastWriteTimeChanged;
@ -45,8 +48,8 @@ public class Item : Properties.IItem
_SourceDirectoryFileHolder = sourceDirectoryFileHolder;
}
public Item(FileHolder sourceDirectoryFileHolder, string relativePath, FileHolder imageFileInfo, bool? isUniqueFileName, bool isValidImageFormatExtension, Property? property, bool? abandoned, bool? fileSizeChanged, bool? lastWriteTimeChanged) :
this(new(), fileSizeChanged, imageFileInfo, isUniqueFileName, isValidImageFormatExtension, lastWriteTimeChanged, null, property, relativePath, null, sourceDirectoryFileHolder)
public Item(FileHolder sourceDirectoryFileHolder, string relativePath, FileHolder imageFileInfo, bool? isNotUniqueAndNeedsReview, bool isUniqueFileName, bool isValidImageFormatExtension, Property? property, bool? abandoned, bool? fileSizeChanged, bool? lastWriteTimeChanged) :
this(new(), fileSizeChanged, imageFileInfo, isNotUniqueAndNeedsReview, isUniqueFileName, isValidImageFormatExtension, lastWriteTimeChanged, null, property, relativePath, null, sourceDirectoryFileHolder)
{
if (relativePath.EndsWith(".json"))
throw new ArgumentException("Can not be a *.json file!");
@ -55,7 +58,7 @@ public class Item : Properties.IItem
}
public Item(FileHolder sourceDirectoryFileHolder, string relativePath, bool isValidImageFormatExtension) :
this(sourceDirectoryFileHolder, relativePath, sourceDirectoryFileHolder, null, isValidImageFormatExtension, null, null, null, null)
this(sourceDirectoryFileHolder, relativePath, sourceDirectoryFileHolder, null, false, isValidImageFormatExtension, null, null, null, null)
{ }
public override string ToString()

View File

@ -3,142 +3,6 @@ using System.Text.Json.Serialization;
namespace View_by_Distance.Shared.Models;
public class MappingFromItem : Properties.IMappingFromItem
{
public DateTime[] ContainerDateTimes { init; get; }
public int Id { init; get; }
public FileHolder ImageFileHolder { init; get; }
public bool? IsWrongYear { init; get; }
public DateTime MinimumDateTime { init; get; }
public string RelativePath { init; get; }
public FileHolder ResizedFileHolder { init; get; }
[JsonConstructor]
public MappingFromItem(DateTime[] containerDateTimes, int id, FileHolder imageFileHolder, bool? isWrongYear, DateTime minimumDateTime, string relativePath, FileHolder resizedFileHolder)
{
ContainerDateTimes = containerDateTimes;
Id = id;
ImageFileHolder = imageFileHolder;
IsWrongYear = isWrongYear;
MinimumDateTime = minimumDateTime;
RelativePath = relativePath;
ResizedFileHolder = resizedFileHolder;
}
public override string ToString()
{
string result = JsonSerializer.Serialize(this, new JsonSerializerOptions() { WriteIndented = true });
return result;
}
internal static MappingFromItem GetMappingFromItem(DateTime[] containerDateTimes, Item item, FileHolder? resizedFileHolder)
{
MappingFromItem result;
bool? isWrongYear;
DateTime minimumDateTime;
if (item.Property?.Id is null)
throw new NotSupportedException();
if (resizedFileHolder is null)
throw new NotSupportedException();
minimumDateTime = Stateless.Methods.IProperty.GetMinimumDateTime(item.Property);
(isWrongYear, _) = item.Property.IsWrongYear(item.ImageFileHolder, minimumDateTime);
result = new(containerDateTimes, item.Property.Id.Value, item.ImageFileHolder, isWrongYear, minimumDateTime, item.RelativePath, resizedFileHolder);
return result;
}
}
public class MappingFromLocation : Properties.IMappingFromLocation
{
public int AreaPermyriad { init; get; }
public int ConfidencePercent { init; get; }
public string DeterministicHashCodeKey { init; get; }
public int NormalizedRectangle { init; get; }
[JsonConstructor]
public MappingFromLocation(int areaPermyriad, int confidencePercent, string deterministicHashCodeKey, int normalizedRectangle)
{
AreaPermyriad = areaPermyriad;
ConfidencePercent = confidencePercent;
DeterministicHashCodeKey = deterministicHashCodeKey;
NormalizedRectangle = normalizedRectangle;
}
public override string ToString()
{
string result = JsonSerializer.Serialize(this, new JsonSerializerOptions() { WriteIndented = true });
return result;
}
}
public class MappingFromFilter : Properties.IMappingFromFilter
{
public bool? IsFocusModel { init; get; }
public bool? IsFocusRelativePath { init; get; }
public bool? IsIgnoreRelativePath { init; get; }
public bool? InSkipCollection { init; get; }
[JsonConstructor]
public MappingFromFilter(bool? isFocusModel, bool? isFocusRelativePath, bool? isIgnoreRelativePath, bool? inSkipCollection)
{
IsFocusModel = isFocusModel;
IsFocusRelativePath = isFocusRelativePath;
IsIgnoreRelativePath = isIgnoreRelativePath;
InSkipCollection = inSkipCollection;
}
public override string ToString()
{
string result = JsonSerializer.Serialize(this, new JsonSerializerOptions() { WriteIndented = true });
return result;
}
}
public class MappingFromPhotoPrism : Properties.IMappingFromPhotoPrism
{
public DatabaseFile DatabaseFile { init; get; }
public List<Marker> Markers { init; get; }
[JsonConstructor]
public MappingFromPhotoPrism(DatabaseFile databaseFile, List<Marker> markers)
{
DatabaseFile = databaseFile;
Markers = markers;
}
}
public class MappingFromPerson : Properties.IMappingFromPerson
{
public int? ApproximateYears { init; get; }
public string DisplayDirectoryName { init; get; }
public PersonBirthday PersonBirthday { init; get; }
public string SegmentB { init; get; }
[JsonConstructor]
public MappingFromPerson(int? approximateYears, string displayDirectoryName, PersonBirthday personBirthday, string segmentB)
{
ApproximateYears = approximateYears;
DisplayDirectoryName = displayDirectoryName;
PersonBirthday = personBirthday;
SegmentB = segmentB;
}
public override string ToString()
{
string result = JsonSerializer.Serialize(this, new JsonSerializerOptions() { WriteIndented = true });
return result;
}
}
public class Mapping : Properties.IMapping
{

View File

@ -0,0 +1,29 @@
using System.Text.Json;
using System.Text.Json.Serialization;
namespace View_by_Distance.Shared.Models;
public class MappingFromFilter : Properties.IMappingFromFilter
{
public bool? IsFocusModel { init; get; }
public bool? IsFocusRelativePath { init; get; }
public bool? IsIgnoreRelativePath { init; get; }
public bool? InSkipCollection { init; get; }
[JsonConstructor]
public MappingFromFilter(bool? isFocusModel, bool? isFocusRelativePath, bool? isIgnoreRelativePath, bool? inSkipCollection)
{
IsFocusModel = isFocusModel;
IsFocusRelativePath = isFocusRelativePath;
IsIgnoreRelativePath = isIgnoreRelativePath;
InSkipCollection = inSkipCollection;
}
public override string ToString()
{
string result = JsonSerializer.Serialize(this, new JsonSerializerOptions() { WriteIndented = true });
return result;
}
}

View File

@ -0,0 +1,58 @@
using System.Text.Json;
using System.Text.Json.Serialization;
namespace View_by_Distance.Shared.Models;
public class MappingFromItem : Properties.IMappingFromItem
{
public DateTime[] ContainerDateTimes { init; get; }
public DateTime? DateTimeDigitized { init; get; }
public DateTime? DateTimeOriginal { init; get; }
public int Id { init; get; }
public FileHolder ImageFileHolder { init; get; }
public bool? IsWrongYear { init; get; }
public DateTime MinimumDateTime { init; get; }
public string? Model { init; get; }
public string RelativePath { init; get; }
public FileHolder ResizedFileHolder { init; get; }
[JsonConstructor]
public MappingFromItem(DateTime[] containerDateTimes, DateTime? dateTimeDigitized, DateTime? dateTimeOriginal, int id, FileHolder imageFileHolder, bool? isWrongYear, DateTime minimumDateTime, string? model, string relativePath, FileHolder resizedFileHolder)
{
ContainerDateTimes = containerDateTimes;
DateTimeDigitized = dateTimeDigitized;
DateTimeOriginal = dateTimeOriginal;
Id = id;
ImageFileHolder = imageFileHolder;
IsWrongYear = isWrongYear;
MinimumDateTime = minimumDateTime;
Model = model;
RelativePath = relativePath;
ResizedFileHolder = resizedFileHolder;
}
public override string ToString()
{
string result = JsonSerializer.Serialize(this, new JsonSerializerOptions() { WriteIndented = true });
return result;
}
public DateTime GetDateTimeOriginalThenMinimumDateTime() =>
DateTimeOriginal is not null ? DateTimeOriginal.Value : MinimumDateTime;
internal static MappingFromItem GetMappingFromItem(DateTime[] containerDateTimes, Item item, FileHolder? resizedFileHolder)
{
MappingFromItem result;
if (item.Property?.Id is null)
throw new NotSupportedException();
if (resizedFileHolder is null)
throw new NotSupportedException();
List<DateTime> dateTimes = item.Property.GetDateTimes();
DateTime minimumDateTime = Stateless.Methods.IProperty.GetMinimumDateTime(item.Property);
(bool? isWrongYear, _) = Stateless.Methods.IProperty.IsWrongYear(item.ImageFileHolder, item.Property.DateTimeOriginal, dateTimes);
result = new(containerDateTimes, item.Property.DateTimeDigitized, item.Property.DateTimeOriginal, item.Property.Id.Value, item.ImageFileHolder, isWrongYear, minimumDateTime, item.Property.Model, item.RelativePath, resizedFileHolder);
return result;
}
}

View File

@ -0,0 +1,29 @@
using System.Text.Json;
using System.Text.Json.Serialization;
namespace View_by_Distance.Shared.Models;
public class MappingFromLocation : Properties.IMappingFromLocation
{
public int AreaPermyriad { init; get; }
public int ConfidencePercent { init; get; }
public string DeterministicHashCodeKey { init; get; }
public int NormalizedRectangle { init; get; }
[JsonConstructor]
public MappingFromLocation(int areaPermyriad, int confidencePercent, string deterministicHashCodeKey, int normalizedRectangle)
{
AreaPermyriad = areaPermyriad;
ConfidencePercent = confidencePercent;
DeterministicHashCodeKey = deterministicHashCodeKey;
NormalizedRectangle = normalizedRectangle;
}
public override string ToString()
{
string result = JsonSerializer.Serialize(this, new JsonSerializerOptions() { WriteIndented = true });
return result;
}
}

View File

@ -0,0 +1,29 @@
using System.Text.Json;
using System.Text.Json.Serialization;
namespace View_by_Distance.Shared.Models;
public class MappingFromPerson : Properties.IMappingFromPerson
{
public int? ApproximateYears { init; get; }
public string DisplayDirectoryName { init; get; }
public PersonBirthday PersonBirthday { init; get; }
public string SegmentB { init; get; }
[JsonConstructor]
public MappingFromPerson(int? approximateYears, string displayDirectoryName, PersonBirthday personBirthday, string segmentB)
{
ApproximateYears = approximateYears;
DisplayDirectoryName = displayDirectoryName;
PersonBirthday = personBirthday;
SegmentB = segmentB;
}
public override string ToString()
{
string result = JsonSerializer.Serialize(this, new JsonSerializerOptions() { WriteIndented = true });
return result;
}
}

View File

@ -0,0 +1,18 @@
using System.Text.Json.Serialization;
namespace View_by_Distance.Shared.Models;
public class MappingFromPhotoPrism : Properties.IMappingFromPhotoPrism
{
public DatabaseFile DatabaseFile { init; get; }
public List<Marker> Markers { init; get; }
[JsonConstructor]
public MappingFromPhotoPrism(DatabaseFile databaseFile, List<Marker> markers)
{
DatabaseFile = databaseFile;
Markers = markers;
}
}

View File

@ -4,11 +4,11 @@ public interface IFaceDistance
{
public int? ConfidencePercent { init; get; }
public DateTime DateTimeOriginalThenMinimumDateTime { init; get; }
public object? Encoding { init; get; }
public int Id { init; get; }
public bool? IsWrongYear { init; get; }
public double? Length { init; get; }
public DateTime? MinimumDateTime { init; get; }
public int? NormalizedRectangle { init; get; }
}

View File

@ -6,7 +6,8 @@ public interface IItem
public bool? FileSizeChanged { get; }
public List<Face> Faces { get; }
public FileHolder ImageFileHolder { get; }
public bool? IsUniqueFileName { get; }
public bool? IsNotUniqueAndNeedsReview { get; }
public bool IsUniqueFileName { get; }
public bool IsValidImageFormatExtension { get; }
public bool? Moved { get; }
public Property? Property { get; }

View File

@ -1,56 +1,5 @@
namespace View_by_Distance.Shared.Models.Properties;
public interface IMappingFromItem
{
public DateTime[] ContainerDateTimes { init; get; }
public int Id { init; get; }
public FileHolder ImageFileHolder { init; get; }
public bool? IsWrongYear { init; get; }
public DateTime MinimumDateTime { init; get; }
public string RelativePath { init; get; }
public FileHolder ResizedFileHolder { init; get; }
}
public interface IMappingFromFilter
{
public bool? IsFocusModel { init; get; }
public bool? IsFocusRelativePath { init; get; }
public bool? IsIgnoreRelativePath { init; get; }
public bool? InSkipCollection { init; get; }
}
public interface IMappingFromLocation
{
public int AreaPermyriad { init; get; }
public int ConfidencePercent { init; get; }
public string DeterministicHashCodeKey { init; get; }
public int NormalizedRectangle { init; get; }
}
public interface IMappingFromPhotoPrism
{
public DatabaseFile DatabaseFile { init; get; }
public List<Marker> Markers { init; get; }
}
public interface IMappingFromPerson
{
public int? ApproximateYears { init; get; }
public string DisplayDirectoryName { init; get; }
public PersonBirthday PersonBirthday { init; get; }
public string SegmentB { init; get; }
}
public interface IMapping
{

View File

@ -0,0 +1,11 @@
namespace View_by_Distance.Shared.Models.Properties;
public interface IMappingFromFilter
{
public bool? IsFocusModel { init; get; }
public bool? IsFocusRelativePath { init; get; }
public bool? IsIgnoreRelativePath { init; get; }
public bool? InSkipCollection { init; get; }
}

View File

@ -0,0 +1,17 @@
namespace View_by_Distance.Shared.Models.Properties;
public interface IMappingFromItem
{
public DateTime[] ContainerDateTimes { init; get; }
public DateTime? DateTimeDigitized { init; get; }
public DateTime? DateTimeOriginal { init; get; }
public int Id { init; get; }
public FileHolder ImageFileHolder { init; get; }
public bool? IsWrongYear { init; get; }
public DateTime MinimumDateTime { init; get; }
public string? Model { init; get; }
public string RelativePath { init; get; }
public FileHolder ResizedFileHolder { init; get; }
}

View File

@ -0,0 +1,11 @@
namespace View_by_Distance.Shared.Models.Properties;
public interface IMappingFromLocation
{
public int AreaPermyriad { init; get; }
public int ConfidencePercent { init; get; }
public string DeterministicHashCodeKey { init; get; }
public int NormalizedRectangle { init; get; }
}

View File

@ -0,0 +1,11 @@
namespace View_by_Distance.Shared.Models.Properties;
public interface IMappingFromPerson
{
public int? ApproximateYears { init; get; }
public string DisplayDirectoryName { init; get; }
public PersonBirthday PersonBirthday { init; get; }
public string SegmentB { init; get; }
}

View File

@ -0,0 +1,9 @@
namespace View_by_Distance.Shared.Models.Properties;
public interface IMappingFromPhotoPrism
{
public DatabaseFile DatabaseFile { init; get; }
public List<Marker> Markers { init; get; }
}

View File

@ -3,19 +3,19 @@ namespace View_by_Distance.Shared.Models.Properties;
public interface IProperty
{
public DateTime CreationTime { get; }
public DateTime? DateTime { get; }
public DateTime? DateTimeDigitized { get; }
public DateTime? DateTimeFromName { get; }
public DateTime? DateTimeOriginal { get; }
public long FileSize { get; }
public DateTime? GPSDateStamp { get; }
public int? Height { get; }
public int? Id { get; }
public DateTime LastWriteTime { get; }
public string Make { get; }
public string Model { get; }
public string Orientation { get; }
public int? Width { get; }
public DateTime CreationTime { init; get; }
public DateTime? DateTime { init; get; }
public DateTime? DateTimeDigitized { init; get; }
public DateTime? DateTimeFromName { init; get; }
public DateTime? DateTimeOriginal { init; get; }
public long FileSize { init; get; }
public DateTime? GPSDateStamp { init; get; }
public int? Height { init; get; }
public int? Id { init; get; }
public DateTime LastWriteTime { init; get; }
public string? Make { init; get; }
public string? Model { init; get; }
public string? Orientation { init; get; }
public int? Width { init; get; }
}

View File

@ -13,7 +13,6 @@ public interface IPropertyConfiguration
public string ResultContent { init; get; }
public string ResultSingleton { init; get; }
public string[] ValidImageFormatExtensions { init; get; }
public string[] VerifyToSeason { init; get; }
public string? ModelName { get; }
public int? NumberOfJitters { get; }
public int? NumberOfTimesToUpsample { get; }

View File

@ -6,52 +6,38 @@ namespace View_by_Distance.Shared.Models;
public class Property : Properties.IProperty
{
protected DateTime _CreationTime;
protected DateTime? _DateTime;
protected DateTime? _DateTimeDigitized;
protected DateTime? _DateTimeFromName;
protected DateTime? _DateTimeOriginal;
protected long _FileSize;
protected DateTime? _GPSDateStamp;
protected int? _Height;
protected int? _Id;
protected DateTime _LastWriteTime;
protected string _Make;
protected string _Model;
protected string _Orientation;
protected int? _Width;
public DateTime CreationTime => _CreationTime;
public DateTime? DateTime => _DateTime;
public DateTime? DateTimeDigitized => _DateTimeDigitized;
public DateTime? DateTimeFromName => _DateTimeFromName;
public DateTime? DateTimeOriginal => _DateTimeOriginal;
public long FileSize => _FileSize;
public DateTime? GPSDateStamp => _GPSDateStamp;
public int? Height => _Height;
public int? Id => _Id;
public DateTime LastWriteTime => _LastWriteTime;
public string Make => _Make;
public string Model => _Model;
public string Orientation => _Orientation;
public int? Width => _Width;
public DateTime CreationTime { init; get; }
public DateTime? DateTime { init; get; }
public DateTime? DateTimeDigitized { init; get; }
public DateTime? DateTimeFromName { init; get; }
public DateTime? DateTimeOriginal { init; get; }
public long FileSize { init; get; }
public DateTime? GPSDateStamp { init; get; }
public int? Height { init; get; }
public int? Id { init; get; }
public DateTime LastWriteTime { init; get; }
public string? Make { init; get; }
public string? Model { init; get; }
public string? Orientation { init; get; }
public int? Width { init; get; }
[JsonConstructor]
public Property(DateTime creationTime, DateTime? dateTime, DateTime? dateTimeDigitized, DateTime? dateTimeFromName, DateTime? dateTimeOriginal, long fileSize, DateTime? gpsDateStamp, int? height, int? id, DateTime lastWriteTime, string make, string model, string orientation, int? width)
public Property(DateTime creationTime, DateTime? dateTime, DateTime? dateTimeDigitized, DateTime? dateTimeFromName, DateTime? dateTimeOriginal, long fileSize, DateTime? gpsDateStamp, int? height, int? id, DateTime lastWriteTime, string? make, string? model, string? orientation, int? width)
{
_DateTimeFromName = dateTimeFromName;
_CreationTime = creationTime;
_DateTime = dateTime;
_DateTimeDigitized = dateTimeDigitized;
_DateTimeOriginal = dateTimeOriginal;
_FileSize = fileSize;
_GPSDateStamp = gpsDateStamp;
_Height = height;
_Id = id;
_LastWriteTime = lastWriteTime;
_Make = make;
_Model = model;
_Orientation = orientation;
_Width = width;
DateTimeFromName = dateTimeFromName;
CreationTime = creationTime;
DateTime = dateTime;
DateTimeDigitized = dateTimeDigitized;
DateTimeOriginal = dateTimeOriginal;
FileSize = fileSize;
GPSDateStamp = gpsDateStamp;
Height = height;
Id = id;
LastWriteTime = lastWriteTime;
Make = make;
Model = model;
Orientation = orientation;
Width = width;
}
public override string ToString()
@ -60,38 +46,6 @@ public class Property : Properties.IProperty
return result;
} // ...
public List<DateTime> GetDateTimes() => Stateless.Methods.Property.GetDateTimes(_CreationTime, _LastWriteTime, _DateTime, _DateTimeDigitized, _DateTimeFromName, _DateTimeOriginal, _GPSDateStamp);
public (bool?, string[]) IsWrongYear(FileHolder fileHolder, DateTime? minimumDateTime)
{
string[] results = Array.Empty<string>();
bool? result = null;
string year;
string directoryName;
string[] directorySegments;
string? check = Path.GetFullPath(fileHolder.FullName);
string? pathRoot = Path.GetPathRoot(fileHolder.FullName);
if (string.IsNullOrEmpty(pathRoot))
throw new Exception();
if (minimumDateTime.HasValue)
year = minimumDateTime.Value.ToString("yyyy");
else
{
List<DateTime> dateTimes = GetDateTimes();
year = dateTimes.Min().ToString("yyyy");
}
for (int i = 0; i < int.MaxValue; i++)
{
check = Path.GetDirectoryName(check);
if (string.IsNullOrEmpty(check) || check == pathRoot)
break;
directoryName = Path.GetFileName(check);
directorySegments = directoryName.Split(' ');
(result, results) = Stateless.Methods.Property.IsWrongYear(directorySegments, year);
if (result.HasValue)
break;
}
return new(result, results);
}
public List<DateTime> GetDateTimes() => Stateless.Methods.Property.GetDateTimes(CreationTime, LastWriteTime, DateTime, DateTimeDigitized, DateTimeFromName, DateTimeOriginal, GPSDateStamp);
}

View File

@ -144,7 +144,7 @@ internal abstract class Container
File.SetCreationTime(sourceDirectoryFileHolder.FullName, imageFileInfo.LastWriteTime.Value);
File.SetLastWriteTime(sourceDirectoryFileHolder.FullName, sourceDirectoryFileHolder.LastWriteTime.Value);
}
Models.Item item = new(sourceDirectoryFileHolder, relativePath, imageFileInfo, filePair.IsUnique, isValidImageFormatExtension, property, abandoned, fileSizeChanged, lastWriteTimeChanged);
Models.Item item = new(sourceDirectoryFileHolder, relativePath, imageFileInfo, filePair.IsNotUniqueAndNeedsReview, filePair.IsUnique, isValidImageFormatExtension, property, abandoned, fileSizeChanged, lastWriteTimeChanged);
lock (results)
results.Add(new(filePair.Path, imageFileInfo.DirectoryName, filePair.IsUnique, filePair.Collection, item));
}

View File

@ -11,11 +11,6 @@ public interface IProperty
static int GetDeterministicHashCode(byte[] value) =>
Property.GetDeterministicHashCode(value);
int TestStatic_GetDeterministicHashCode(string value) =>
GetDeterministicHashCode(value);
static int GetDeterministicHashCode(string value) =>
Property.GetDeterministicHashCode(value);
DateTime TestStatic_GetDateTime(Models.Property? property) =>
GetDateTime(property);
static DateTime GetDateTime(Models.Property? property) =>
@ -46,6 +41,11 @@ public interface IProperty
static (bool?, string[]) IsWrongYear(string[] segments, string year) =>
Property.IsWrongYear(segments, year);
(bool?, string[]) TestStatic_IsWrongYear(Models.FileHolder fileHolder, DateTime? dateTimeOriginal, List<DateTime> dateTimes) =>
IsWrongYear(fileHolder, dateTimeOriginal, dateTimes);
static (bool?, string[]) IsWrongYear(Models.FileHolder fileHolder, DateTime? dateTimeOriginal, List<DateTime> dateTimes) =>
Property.IsWrongYear(fileHolder, dateTimeOriginal, dateTimes);
(DateTime?[], int?, string?) TestStatic_Get(Models.FileHolder fileHolder, bool isIgnoreExtension, bool isValidImageFormatExtension) =>
Get(fileHolder, isIgnoreExtension, isValidImageFormatExtension);
static (DateTime?[], int?, string?) Get(Models.FileHolder fileHolder, bool isIgnoreExtension, bool isValidImageFormatExtension) =>

View File

@ -42,25 +42,6 @@ internal abstract class Property
return result;
}
internal static int GetDeterministicHashCode(string value)
{
int result;
unchecked
{
int hash1 = (5381 << 16) + 5381;
int hash2 = hash1;
for (int i = 0; i < value.Length; i += 2)
{
hash1 = ((hash1 << 5) + hash1) ^ value[i];
if (i == value.Length - 1)
break;
hash2 = ((hash2 << 5) + hash2) ^ value[i + 1];
}
result = hash1 + (hash2 * 1566083941);
}
return result;
}
internal static (bool?, string[]) IsWrongYear(string[] segments, string year)
{
bool? result;
@ -92,6 +73,45 @@ internal abstract class Property
return new(result, results);
}
internal static (bool?, string[]) IsWrongYear(Models.FileHolder fileHolder, DateTime? dateTimeOriginal, List<DateTime> dateTimes)
{
string[] results = Array.Empty<string>();
bool? result = null;
string year;
string directoryName;
string[] directorySegments;
List<DateTime> collection = new();
string? check = Path.GetFullPath(fileHolder.FullName);
string? pathRoot = Path.GetPathRoot(fileHolder.FullName);
if (string.IsNullOrEmpty(pathRoot))
throw new Exception();
if (dateTimeOriginal is not null)
collection.Add(dateTimeOriginal.Value);
else
{
foreach (DateTime dateTime in dateTimes)
collection.Add(dateTime);
}
foreach (DateTime dateTime in collection)
{
year = dateTime.ToString("yyyy");
for (int i = 0; i < int.MaxValue; i++)
{
check = Path.GetDirectoryName(check);
if (string.IsNullOrEmpty(check) || check == pathRoot)
break;
directoryName = Path.GetFileName(check);
directorySegments = directoryName.Split(' ');
(result, results) = IsWrongYear(directorySegments, year);
if (result is not null)
break;
}
if (result is not null && result.Value)
break;
}
return new(result, results);
}
internal static DateTime? GetDateTimeFromName(Models.FileHolder fileHolder)
{
DateTime? result = null;

View File

@ -10,10 +10,7 @@ internal abstract class Sorting
throw new NotSupportedException();
if (faceDistanceLength.NormalizedRectangle is null)
throw new NotSupportedException();
if (faceDistanceEncoding.MinimumDateTime is null || faceDistanceLength.MinimumDateTime is null)
throw new NotSupportedException();
long ticks = faceDistanceEncoding.MinimumDateTime.Value.Ticks;
TimeSpan timeSpan = new(faceDistanceLength.MinimumDateTime.Value.Ticks - ticks);
TimeSpan timeSpan = new(faceDistanceLength.DateTimeOriginalThenMinimumDateTime.Ticks - faceDistanceEncoding.DateTimeOriginalThenMinimumDateTime.Ticks);
bool older = timeSpan.TotalMilliseconds < 0;
int daysDelta = (int)Math.Round(Math.Abs(timeSpan.TotalDays), 0);
int distancePermyriad = (int)(faceDistanceLength.Length.Value / rangeDistanceTolerance * faceDistancePermyriad);

View File

@ -95,9 +95,9 @@ internal abstract partial class XDirectory
return renameCollection.Count;
}
private static void IsNotUniqueLoop(string file, List<string> collection)
private static bool GetIsNotUniqueAndNeedsReview(string file, List<string> collection)
{
TimeSpan timeSpan;
bool result = false;
FileInfo possibleFileInfo;
FileInfo fileInfo = new(file);
foreach (string possible in collection)
@ -105,18 +105,14 @@ internal abstract partial class XDirectory
if (possible == file)
continue;
possibleFileInfo = new(possible);
if (possibleFileInfo.LastWriteTime != fileInfo.LastWriteTime)
File.SetLastWriteTime(file, new DateTime[] { possibleFileInfo.LastWriteTime, fileInfo.LastWriteTime }.Max());
if (possibleFileInfo.LastWriteTime == fileInfo.LastWriteTime && possibleFileInfo.Length == fileInfo.Length)
continue;
timeSpan = new(possibleFileInfo.LastWriteTime.Ticks - fileInfo.LastWriteTime.Ticks);
if (possibleFileInfo.Length != fileInfo.Length)
throw new Exception(Path.GetFileNameWithoutExtension(file));
if (timeSpan.TotalMinutes < 61)
{
File.SetLastWriteTime(file, new DateTime[] { possibleFileInfo.LastWriteTime, fileInfo.LastWriteTime }.Min());
continue;
}
throw new Exception(Path.GetFileNameWithoutExtension(file));
if (!result)
result = true;
}
return result;
}
private static string? GetMatch(string file, List<string> collection)
@ -148,28 +144,30 @@ internal abstract partial class XDirectory
string fileName;
bool uniqueFileName;
List<string>? collection;
bool? isNotUniqueAndNeedsReview;
foreach (string[] files in filesCollection)
{
foreach (string file in files)
{
isNotUniqueAndNeedsReview = null;
fileName = Path.GetFileName(file);
if (!fileNamesToFiles.TryGetValue(fileName, out collection))
throw new Exception();
uniqueFileName = collection.Count == 1;
if (!uniqueFileName)
IsNotUniqueLoop(file, collection);
isNotUniqueAndNeedsReview = GetIsNotUniqueAndNeedsReview(file, collection);
if (!compareFileNamesToFiles.TryGetValue(string.Concat(fileName, extension), out collection))
results.Add(new(file, uniqueFileName, new(), null));
results.Add(new(file, uniqueFileName, isNotUniqueAndNeedsReview, new(), null));
else
{
if (!collection.Any())
results.Add(new(file, uniqueFileName, collection, null));
results.Add(new(file, uniqueFileName, isNotUniqueAndNeedsReview, collection, null));
else if (uniqueFileName && collection.Count == 1)
results.Add(new(file, uniqueFileName, collection, collection.First()));
results.Add(new(file, uniqueFileName, isNotUniqueAndNeedsReview, collection, collection.First()));
else
{
match = GetMatch(file, collection);
results.Add(new(file, uniqueFileName, collection, match));
results.Add(new(file, uniqueFileName, isNotUniqueAndNeedsReview, collection, match));
}
}
}

View File

@ -762,13 +762,13 @@ public partial class UnitTestHardCoded
public void TestMethodRename()
{
// string[] directories = Directory.GetDirectories(@"D:\2) Images B\Not-Copy-Copy-1e85c0ba", "*;*", SearchOption.AllDirectories);
// string[] directories = Directory.GetDirectories(@"D:\1) Images A\Images-1e85c0ba", "*;*", SearchOption.AllDirectories);
string[] directories = Directory.GetDirectories(@"D:\2) Images B\Not-Copy-Copy-1e85c0ba", "*", SearchOption.AllDirectories);
string[] directories = Directory.GetDirectories(@"D:\1) Images A\Images-1e85c0ba", "*;*", SearchOption.AllDirectories);
// string[] directories = Directory.GetDirectories(@"D:\2) Images B\Not-Copy-Copy-1e85c0ba", "*", SearchOption.AllDirectories);
foreach (string directory in directories.OrderByDescending(l => l.Length - l.Replace(@"\", string.Empty).Length))
{
if (directory.EndsWith(";9"))
if (!directory.EndsWith(";9"))
continue;
Directory.Move(directory, $"{directory};9");
Directory.Move(directory, $"{directory[..^2]} !9");
}
NonThrowTryCatch();
}

View File

@ -157,14 +157,15 @@ public class UnitTestResize
_ = metadata.ToString();
C_Resize resize = new(_Configuration.ForceResizeLastWriteTimeToCreationTime, _Configuration.OverrideForResizeImages, _Configuration.PropertiesChangedForResize, _Configuration.ValidResolutions, imageCodecInfo, encoderParameters, filenameExtension);
_ = resize.ToString();
bool? isUniqueFileName = null;
bool isUniqueFileName = false;
bool? isNotUniqueAndNeedsReview = null;
FileHolder sourceDirectoryFileHolder = new(".json");
FileHolder fileHolder = new(Path.Combine(sourceDirectory, sourceFileName));
string relativePath = IPath.GetRelativePath(fileHolder.FullName, length);
sourceDirectory = Path.Combine(aPropertySingletonDirectory, sourceDirectoryName);
propertyLogic.SetAngleBracketCollection(aResultsFullGroupDirectory, sourceDirectory);
resize.SetAngleBracketCollection(_Configuration.PropertyConfiguration, cResultsFullGroupDirectory, sourceDirectory);
item = new(sourceDirectoryFileHolder, relativePath, fileHolder, isUniqueFileName, isValidImageFormatExtension, property, false, false, false);
item = new(sourceDirectoryFileHolder, relativePath, fileHolder, isNotUniqueAndNeedsReview, isUniqueFileName, isValidImageFormatExtension, property, false, false, false);
Assert.IsNotNull(item.ImageFileHolder);
if (item.Property is null)
{

View File

@ -232,7 +232,8 @@ public class UnitTestFace
_ = metadata.ToString();
C_Resize resize = new(_Configuration.ForceResizeLastWriteTimeToCreationTime, _Configuration.OverrideForResizeImages, _Configuration.PropertiesChangedForResize, _Configuration.ValidResolutions, imageCodecInfo, encoderParameters, filenameExtension);
_ = resize.ToString();
bool? isUniqueFileName = null;
bool isUniqueFileName = false;
bool? isNotUniqueAndNeedsReview = null;
bool anyNullOrNoIsUniqueFileName = true;
FileHolder sourceDirectoryFileHolder = new(".json");
FileHolder fileHolder = new(Path.Combine(sourceDirectory, sourceFileName));
@ -240,7 +241,7 @@ public class UnitTestFace
sourceDirectory = Path.Combine(aPropertySingletonDirectory, sourceDirectoryName);
propertyLogic.SetAngleBracketCollection(aResultsFullGroupDirectory, sourceDirectory, anyNullOrNoIsUniqueFileName);
resize.SetAngleBracketCollection(_Configuration.PropertyConfiguration, cResultsFullGroupDirectory, sourceDirectory);
item = new(sourceDirectoryFileHolder, relativePath, fileHolder, isUniqueFileName, isValidImageFormatExtension, property, false, false, false);
item = new(sourceDirectoryFileHolder, relativePath, fileHolder, isNotUniqueAndNeedsReview, isUniqueFileName, isValidImageFormatExtension, property, false, false, false);
Assert.IsNotNull(item.ImageFileHolder);
if (item.Property is null)
{