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? check;
string fileName; string fileName;
string? pathRoot; string? pathRoot;
DateTime dateTime;
string seasonName; string seasonName;
string weekOfYear; string weekOfYear;
bool? isWrongYear; bool? isWrongYear;
string seasonValue; string seasonValue;
string directoryName; string directoryName;
string topDirectoryName; string topDirectoryName;
DateTime minimumDateTime; List<DateTime> dateTimes;
string[]? matches = null; string[]? matches = null;
string[] directorySegments; string[] directorySegments;
List<string> destinationCollection; List<string> destinationCollection;
@ -204,12 +205,22 @@ public class DateGroup
directoryNames.Clear(); directoryNames.Clear();
destinationCollection = new(); destinationCollection = new();
_ = destinationDirectoryName.Clear(); _ = destinationDirectoryName.Clear();
if (item.ImageFileHolder.LastWriteTime is not null && item.Property is null) if (item.Property is not null)
minimumDateTime = item.ImageFileHolder.LastWriteTime.Value; dateTimes = item.Property.GetDateTimes();
else else
minimumDateTime = Shared.Models.Stateless.Methods.IProperty.GetMinimumDateTime(item.Property); {
day = minimumDateTime.ToString("MM-dd"); if (item.ImageFileHolder.LastWriteTime is null)
month = minimumDateTime.ToString("MMMM"); 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) if (item.Property?.Id is null)
{ {
flag = '#'; flag = '#';
@ -217,26 +228,26 @@ public class DateGroup
} }
else 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) if (isWrongYear is null)
flag = '#'; flag = '#';
else if (isWrongYear.Value) else if (isWrongYear.Value)
flag = '~'; flag = '~';
else 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 = '^'; flag = '^';
else else
flag = '='; 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()) if ((from l in topDirectorySegments where l == "Christmas" select true).Any())
seasonValue = string.Empty; seasonValue = string.Empty;
else else
seasonValue = $".{season}"; seasonValue = $".{season}";
if (isWrongYear is null || !isWrongYear.Value) if (isWrongYear is null || !isWrongYear.Value)
year = $"{flag}{minimumDateTime:yyyy}{seasonValue}"; year = $"{flag}{dateTime:yyyy}{seasonValue}";
else if (matches is null || matches.Length < 3) else if (matches is null || matches.Length < 3)
year = "----"; year = "----";
else else
@ -247,7 +258,7 @@ public class DateGroup
year = $"{flag}{matches[0][1..].Split('.')[0]}{seasonValue}"; year = $"{flag}{matches[0][1..].Split('.')[0]}{seasonValue}";
} }
topDirectoryName = Path.GetFileName(topDirectory); 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) if (_Configuration.ByHash)
directoryNames.Add($"{year} {seasonName}"); directoryNames.Add($"{year} {seasonName}");
else if (_Configuration.BySeason && topDirectoryName.Length == 1 && topDirectoryName[0] == '_') else if (_Configuration.BySeason && topDirectoryName.Length == 1 && topDirectoryName[0] == '_')
@ -296,9 +307,9 @@ public class DateGroup
if (item.ImageFileHolder.LastWriteTime is null) if (item.ImageFileHolder.LastWriteTime is null)
continue; continue;
if (item.Property is not null) 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 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; return results;
} }
@ -470,11 +481,11 @@ public class DateGroup
string path; string path;
string fileName; string fileName;
string directory; string directory;
DateTime dateTime;
int selectedTotal; int selectedTotal;
const int minimum = 3; const int minimum = 3;
List<DateTime> dateTimes; List<DateTime> dateTimes;
List<Item> selectedItems; List<Item> selectedItems;
DateTime? minimumDateTime;
const int maximumHours = 24; const int maximumHours = 24;
string? relativePathDirectory; string? relativePathDirectory;
WindowsShortcut windowsShortcut; WindowsShortcut windowsShortcut;
@ -499,9 +510,12 @@ public class DateGroup
relativePathDirectory = Path.GetDirectoryName(item.RelativePath); relativePathDirectory = Path.GetDirectoryName(item.RelativePath);
if (string.IsNullOrEmpty(relativePathDirectory)) if (string.IsNullOrEmpty(relativePathDirectory))
continue; continue;
minimumDateTime = Shared.Models.Stateless.Methods.IProperty.GetMinimumDateTime(item.Property); if (item.ImageFileHolder.LastWriteTime is not null && item.Property is null)
if (minimumDateTime is null) dateTime = item.ImageFileHolder.LastWriteTime.Value;
continue; 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]}"); 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}"); 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)) if (!Directory.Exists(directory))
@ -514,7 +528,7 @@ public class DateGroup
windowsShortcut.Dispose(); windowsShortcut.Dispose();
if (!File.Exists(fileName)) if (!File.Exists(fileName))
continue; 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()) 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": { "Logging": {
"LogLevel": { "LogLevel": {
"Default": "Information", "Log4netProvider": "Debug"
"Microsoft": "Warning",
"Log4netProvider": "Debug",
"Microsoft.Hosting.Lifetime": "Information"
} }
}, },
"MaxDegreeOfParallelism": 6, "MaxDegreeOfParallelism": 6,
"Serilog": { "Serilog": {
"Using": [ "MinimumLevel": "Debug"
"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}"
}
},
{
"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": { "Windows": {
"Configuration": { "Configuration": {
"ByCreateDateShortcut": false, "xByHash": false,
"ByDay": false, "ByHash": true,
"ByHash": false, "xPopulatePropertyId": false,
"BySeason": true, "PopulatePropertyId": true,
"ByWeek": false,
"DateGroup": "1e85c0ba",
"FileNameDirectorySeparator": ".Z.",
"ForcePropertyLastWriteTimeToCreationTime": false,
"KeepFullPath": false,
"MaxImagesInDirectoryForTopLevelFirstPass": 10,
"Pattern": "[^ABCDEFGHIJKLMNOPQRSTUVWXYZbcdfghjklmnpqrstvwxyz0-9]",
"PopulatePropertyId": false,
"PropertiesChangedForProperty": false,
"ResultAllInOne": "_ _ _",
"ResultCollection": "[]",
"ResultContent": "()",
"ResultSingleton": "{}",
"xRootDirectory": "C:/Tmp/phares/Pictures", "xRootDirectory": "C:/Tmp/phares/Pictures",
"xxRootDirectory": "C:/Tmp/Phares/Compare/Images-1e85c0ba", "xxRootDirectory": "C:/Tmp/Phares/Compare/Images-1e85c0ba",
"xxxRootDirectory": "F:/Tmp/Phares/Compare/Not-Copy-Copy-1e85c0ba", "xxxRootDirectory": "F:/Tmp/Phares/Compare/Not-Copy-Copy-1e85c0ba",
"xxxxRootDirectory": "C:/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", "xxxxxRootDirectory": "F:/Tmp/Phares/2022-11-03-DCIM/DCIM/100D3400 2022",
"xxxxxxRootDirectory": "E:/- - - Videos/-", "RootDirectory": "D:/1) Images A/Images-1e85c0ba/zzz Mackenzie Laptop !9/_"
"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"
]
} }
} }
} }

View File

@ -67,10 +67,7 @@
"ResultCollection": "[]", "ResultCollection": "[]",
"ResultContent": "()", "ResultContent": "()",
"ResultSingleton": "{}", "ResultSingleton": "{}",
"xRootDirectory": "C:/Tmp/phares/Pictures", "RootDirectory": "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",
"WriteBitmapDataBytes": false, "WriteBitmapDataBytes": false,
"IgnoreExtensions": [ "IgnoreExtensions": [
".gif", ".gif",

View File

@ -58,11 +58,11 @@ public partial class E_Distance
confidencePercent = Shared.Models.Stateless.Methods.ILocation.GetConfidencePercent(_FaceConfidencePercent, _RangeFaceConfidence, face.Location.Confidence); 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); 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) 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 else
{ {
faceEncoding = FaceRecognition.LoadFaceEncoding(face.FaceEncoding.RawEncoding); 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) lock (intersectFaces)
face.SetFaceDistance(faceDistance); face.SetFaceDistance(faceDistance);
} }
@ -347,11 +347,11 @@ public partial class E_Distance
confidencePercent = Shared.Models.Stateless.Methods.ILocation.GetConfidencePercent(_FaceConfidencePercent, _RangeFaceConfidence, face.Location.Confidence); 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); 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) 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 else
{ {
faceEncoding = FaceRecognition.LoadFaceEncoding(face.FaceEncoding.RawEncoding); 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); face.SetFaceDistance(faceDistance);
} }
faceDistanceContainer = new(face, faceDistance); faceDistanceContainer = new(face, faceDistance);
@ -390,7 +390,7 @@ public partial class E_Distance
return; return;
progressBar.Tick(); progressBar.Tick();
faceEncoding = FaceRecognition.LoadFaceEncoding(face.FaceEncoding.RawEncoding); 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) lock (face)
face.SetFaceDistance(faceDistance); face.SetFaceDistance(faceDistance);
}); });
@ -447,7 +447,7 @@ public partial class E_Distance
throw new NotSupportedException(); throw new NotSupportedException();
if (face.FaceDistance?.Encoding is not FaceRecognitionDotNet.FaceEncoding faceEncoding) if (face.FaceDistance?.Encoding is not FaceRecognitionDotNet.FaceEncoding faceEncoding)
continue; 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); faceDistanceContainer = new(face, faceDistance);
collection.Add(faceDistanceContainer); collection.Add(faceDistanceContainer);
} }
@ -480,7 +480,7 @@ public partial class E_Distance
{ {
if (faceDistanceContainer.FaceDistance is null || faceDistanceContainer.Face.Mapping?.MappingFromLocation is null) if (faceDistanceContainer.FaceDistance is null || faceDistanceContainer.Face.Mapping?.MappingFromLocation is null)
throw new NotSupportedException(); 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; continue;
if (faceDistanceContainer.Face.Mapping.MappingFromLocation.ConfidencePercent < distanceLimits.FaceConfidencePercent) if (faceDistanceContainer.Face.Mapping.MappingFromLocation.ConfidencePercent < distanceLimits.FaceConfidencePercent)
continue; continue;

View File

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

View File

@ -2,9 +2,11 @@ using Microsoft.Extensions.Configuration;
using Phares.Shared; using Phares.Shared;
using Serilog; using Serilog;
using System.Diagnostics; using System.Diagnostics;
using System.Drawing.Imaging;
using System.Reflection; using System.Reflection;
using System.Text.Json; using System.Text.Json;
using View_by_Distance.Drag_Drop_Explorer.Models; using View_by_Distance.Drag_Drop_Explorer.Models;
using View_by_Distance.Shared.Models.Stateless;
using View_by_Distance.Shared.Models.Stateless.Methods; using View_by_Distance.Shared.Models.Stateless.Methods;
using WindowsShortcutFactory; using WindowsShortcutFactory;
@ -64,7 +66,7 @@ public partial class DragDropMove : Form
Controls.Add(_FirstTextBox); Controls.Add(_FirstTextBox);
} }
void Form1_Load(object? sender, EventArgs e) private void Form1_Load(object? sender, EventArgs e)
{ {
try try
{ {
@ -73,6 +75,8 @@ public partial class DragDropMove : Form
DragEnter += new DragEventHandler(Form1_DragEnter); DragEnter += new DragEventHandler(Form1_DragEnter);
_FirstTextBox.LostFocus += new EventHandler(TextBox_LostFocus); _FirstTextBox.LostFocus += new EventHandler(TextBox_LostFocus);
_PathTextBox.LostFocus += new EventHandler(TextBox_LostFocus); _PathTextBox.LostFocus += new EventHandler(TextBox_LostFocus);
if (_WorkingDirectory is null)
{ }
} }
catch (Exception) catch (Exception)
{ {
@ -86,14 +90,14 @@ public partial class DragDropMove : Form
return result; return result;
} }
void TextBox_LostFocus(object? sender, EventArgs e) private void TextBox_LostFocus(object? sender, EventArgs e)
{ {
try try
{ {
if (sender is TextBox textBox) if (sender is TextBox textBox)
{ {
textBox.Text = GetConverted(textBox.Text); textBox.Text = GetConverted(textBox.Text);
if (textBox.Text == "ps") if (textBox.Text == "315360000000000")
throw new NotImplementedException(); 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 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 try
{ {
if (e.Data is not null && e.Data.GetData(DataFormats.FileDrop) is string[] paths && paths.Any()) if (e.Data is not null && e.Data.GetData(DataFormats.FileDrop) is string[] paths && paths.Any())
MovePaths(paths); {
if (paths.Length == 1 && Directory.Exists(paths.First()))
DateFix(paths.First());
else
MovePaths(paths);
}
else else
{ {
_FirstTextBox.Text = string.Empty; _FirstTextBox.Text = string.Empty;
@ -191,5 +328,4 @@ public partial class DragDropMove : Form
throw; throw;
} }
} }
} }

View File

@ -192,7 +192,7 @@ public class DuplicateSearch
if (mappingFromItem is not null) if (mappingFromItem is not null)
{ {
resizedFileHolder = new(mappingFromItem.ResizedFileHolder.FullName.Replace($"0{duplicates}", $"1{duplicates}")); 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)); resizedFileHolder = new(string.Concat(Path.Combine(destinationRoot, directory), item.RelativePath));

View File

@ -3,6 +3,7 @@ using Phares.Shared;
using ShellProgressBar; using ShellProgressBar;
using System.Collections.ObjectModel; using System.Collections.ObjectModel;
using System.Drawing.Imaging; using System.Drawing.Imaging;
using System.Text.RegularExpressions;
using View_by_Distance.Distance.Models; using View_by_Distance.Distance.Models;
using View_by_Distance.Face.Models; using View_by_Distance.Face.Models;
using View_by_Distance.FaceParts.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.Resize.Models;
using View_by_Distance.Shared.Models; using View_by_Distance.Shared.Models;
using View_by_Distance.Shared.Models.Methods; using View_by_Distance.Shared.Models.Methods;
using WindowsShortcutFactory;
namespace View_by_Distance.Instance; namespace View_by_Distance.Instance;
@ -267,34 +269,19 @@ public partial class DlibDotNet
return result; return result;
} }
private bool? GetIsFocusModel(ReadOnlyDictionary<int, List<LocationContainer<MetadataExtractor.Directory>>> idToLocationContainers, MappingFromItem mappingFromItem) private bool? GetIsFocusModel(Shared.Models.Property? property)
{ {
bool? result; bool? result;
string? model;
List<LocationContainer<MetadataExtractor.Directory>>? locationContainers;
IReadOnlyList<MetadataExtractor.Directory> directories;
if (string.IsNullOrEmpty(_Configuration.FocusModel)) if (string.IsNullOrEmpty(_Configuration.FocusModel))
result = null; result = null;
else if (property is null || string.IsNullOrEmpty(property.Model))
result = null;
else else
{ result = property.Model.Contains(_Configuration.FocusModel);
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;
}
}
return result; 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; Mapping mapping;
int faceAreaPermyriad; int faceAreaPermyriad;
@ -304,7 +291,7 @@ public partial class DlibDotNet
string deterministicHashCodeKey; string deterministicHashCodeKey;
MappingFromFilter mappingFromFilter; MappingFromFilter mappingFromFilter;
MappingFromLocation? mappingFromLocation; MappingFromLocation? mappingFromLocation;
bool? isFocusModel = GetIsFocusModel(idToLocationContainers, mappingFromItem); bool? isFocusModel = GetIsFocusModel(item.Property);
foreach (Shared.Models.Face face in faces) 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) 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; Mapping result;
bool? inSkipCollection; bool? inSkipCollection;
@ -339,7 +326,7 @@ public partial class DlibDotNet
string deterministicHashCodeKey; string deterministicHashCodeKey;
MappingFromFilter mappingFromFilter; MappingFromFilter mappingFromFilter;
MappingFromLocation? mappingFromLocation; MappingFromLocation? mappingFromLocation;
bool? isFocusModel = GetIsFocusModel(idToLocationContainers, mappingFromItem); bool? isFocusModel = GetIsFocusModel(item.Property);
if (item.Property?.Id is null) if (item.Property?.Id is null)
{ {
inSkipCollection = null; inSkipCollection = null;
@ -461,7 +448,7 @@ public partial class DlibDotNet
if (_AppSettings.MaxDegreeOfParallelism < 2) if (_AppSettings.MaxDegreeOfParallelism < 2)
ticks = LogDelta(ticks, nameof(D_Face.GetFaces)); 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); 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)) if (_Configuration.CopyFacesAndSaveFaceLandmarkForOutputResolutions.Contains(outputResolution))
_FaceParts.CopyFacesAndSaveFaceLandmarkImage(facePartsCollectionDirectory, mappingFromItem, faceCollection); _FaceParts.CopyFacesAndSaveFaceLandmarkImage(facePartsCollectionDirectory, mappingFromItem, faceCollection);
if (_AppSettings.MaxDegreeOfParallelism < 2) if (_AppSettings.MaxDegreeOfParallelism < 2)
@ -663,8 +650,8 @@ public partial class DlibDotNet
if (!filteredItems.Any()) if (!filteredItems.Any())
continue; continue;
sourceDirectoryChanges.Clear(); sourceDirectoryChanges.Clear();
anyNullOrNoIsUniqueFileName = filteredItems.Any(l => !l.IsUniqueFileName);
totalSeconds = (int)Math.Floor(new TimeSpan(DateTime.Now.Ticks - ticks).TotalSeconds); 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}"; 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)) if (_Configuration.LoadOrCreateThenSaveImageFacesResultsForOutputResolutions.Contains(outputResolution))
_Faces.SetAngleBracketCollection(dResultsFullGroupDirectory, container.SourceDirectory); _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; Mapping[] results;
int count = 0; int count = 0;
@ -976,7 +963,7 @@ public partial class DlibDotNet
} }
if (!anyValidFaces) if (!anyValidFaces)
{ {
mapping = GetMapping(idToLocationContainers, mapLogic, item, isFocusRelativePath, isIgnoreRelativePath, mappingFromItem); mapping = GetMapping(mapLogic, item, isFocusRelativePath, isIgnoreRelativePath, mappingFromItem);
mappingCollection.Add(mapping); mappingCollection.Add(mapping);
} }
} }
@ -985,6 +972,95 @@ public partial class DlibDotNet
return results; 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) private void Search(long ticks, string argZero, string propertyRoot)
{ {
int t; int t;
@ -1048,13 +1124,15 @@ public partial class DlibDotNet
ReadOnlyDictionary<int, List<LocationContainer<MetadataExtractor.Directory>>> idToLocationContainers = mapLogic.GetIdToLocationContainers(); ReadOnlyDictionary<int, List<LocationContainer<MetadataExtractor.Directory>>> idToLocationContainers = mapLogic.GetIdToLocationContainers();
fileNameToCollection = !Directory.Exists(fPhotoPrismSingletonDirectory) ? fileNameToCollection = new() : F_PhotoPrism.GetFileNameToCollection(fPhotoPrismSingletonDirectory); fileNameToCollection = !Directory.Exists(fPhotoPrismSingletonDirectory) ? fileNameToCollection = new() : F_PhotoPrism.GetFileNameToCollection(fPhotoPrismSingletonDirectory);
FullDoWork(argZero, propertyRoot, ticks, aResultsFullGroupDirectory, bResultsFullGroupDirectory, t, containers, propertyLogic, metadata, eDistanceContentDirectory, fileNameToCollection, idToLocationContainers, mapLogic); FullDoWork(argZero, propertyRoot, ticks, aResultsFullGroupDirectory, bResultsFullGroupDirectory, t, containers, propertyLogic, metadata, eDistanceContentDirectory, fileNameToCollection, idToLocationContainers, mapLogic);
LookForAbandoned(bResultsFullGroupDirectory, containers, idToLocationContainers); if (_Configuration.LookForAbandoned)
LookForAbandoned(bResultsFullGroupDirectory, containers, idToLocationContainers);
_Distance.Clear(); _Distance.Clear();
if (!personKeyToIds.Any()) if (!personKeyToIds.Any())
personKeyToIds = mapLogic.GetPersonKeyToIds(); 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); 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); 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); int totalNotMapped = mapLogic.UpdateMappingFromPerson(distinctFilteredMappingCollection);
string json = System.Text.Json.JsonSerializer.Serialize(distinctFilteredMappingCollection); string json = System.Text.Json.JsonSerializer.Serialize(distinctFilteredMappingCollection);
File.WriteAllText(Path.Combine(eDistanceContentDirectory, $"{ticks}.json"), json); 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 = "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 Digits"), Required] public int? LocationDigits { get; set; }
[Display(Name = "Location Factor"), Required] public int? LocationFactor { 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 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 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; } [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)); throw new NullReferenceException(nameof(configuration.LocationDigits));
if (configuration.LocationFactor is null) if (configuration.LocationFactor is null)
throw new NullReferenceException(nameof(configuration.LocationFactor)); throw new NullReferenceException(nameof(configuration.LocationFactor));
if (configuration.LookForAbandoned is null)
throw new NullReferenceException(nameof(configuration.LookForAbandoned));
if (configuration.MappingDefaultName is null) if (configuration.MappingDefaultName is null)
throw new NullReferenceException(nameof(configuration.MappingDefaultName)); throw new NullReferenceException(nameof(configuration.MappingDefaultName));
if (configuration.MappingUseDeterministicHashCodeUnknownFaceKeyValuePairsForAddToMapping is null) if (configuration.MappingUseDeterministicHashCodeUnknownFaceKeyValuePairsForAddToMapping is null)
@ -256,6 +259,7 @@ public class Configuration
configuration.LoadOrCreateThenSaveImageFacesResultsForOutputResolutions, configuration.LoadOrCreateThenSaveImageFacesResultsForOutputResolutions,
configuration.LocationDigits.Value, configuration.LocationDigits.Value,
configuration.LocationFactor.Value, configuration.LocationFactor.Value,
configuration.LookForAbandoned.Value,
configuration.MappingDefaultName, configuration.MappingDefaultName,
configuration.MappingUseDeterministicHashCodeUnknownFaceKeyValuePairsForAddToMapping.Value, configuration.MappingUseDeterministicHashCodeUnknownFaceKeyValuePairsForAddToMapping.Value,
configuration.MappingUseDeterministicHashCodeUnknownFaceKeyValuePairsForSaveMapping.Value, configuration.MappingUseDeterministicHashCodeUnknownFaceKeyValuePairsForSaveMapping.Value,

View File

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

View File

@ -20,6 +20,7 @@
"xFocusDirectory": "/Hawaii 2022", "xFocusDirectory": "/Hawaii 2022",
"FocusModel": "", "FocusModel": "",
"xFocusModel": "NIKON D3400", "xFocusModel": "NIKON D3400",
"LookForAbandoned": false,
"xGenealogicalDataCommunicationFile": "", "xGenealogicalDataCommunicationFile": "",
"GenealogicalDataCommunicationFile": "D:/5) Other Small/RootsMagic/Code-638160743318283885/638160743318283885-Export.ged.cln", "GenealogicalDataCommunicationFile": "D:/5) Other Small/RootsMagic/Code-638160743318283885/638160743318283885-Export.ged.cln",
"PersonCharactersCopyCount": 0, "PersonCharactersCopyCount": 0,
@ -110,230 +111,6 @@
"Scanned Prints", "Scanned Prints",
"Slide in Name Order Originals (622)", "Slide in Name Order Originals (622)",
"Slides Pictures" "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": "", "GenealogicalDataCommunicationFile": "",
"LocationDigits": 9, "LocationDigits": 9,
"LocationFactor": 10000, "LocationFactor": 10000,
"LookForAbandoned": true,
"MappingDefaultName": "John Doe~25", "MappingDefaultName": "John Doe~25",
"MappingUseDeterministicHashCodeUnknownFaceKeyValuePairsForAddToMapping": false, "MappingUseDeterministicHashCodeUnknownFaceKeyValuePairsForAddToMapping": false,
"MappingUseDeterministicHashCodeUnknownFaceKeyValuePairsForSaveMapping": false, "MappingUseDeterministicHashCodeUnknownFaceKeyValuePairsForSaveMapping": false,

View File

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

View File

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

View File

@ -1,5 +1,4 @@
using ShellProgressBar; using ShellProgressBar;
using System.Diagnostics;
using System.Drawing; using System.Drawing;
using System.Drawing.Imaging; using System.Drawing.Imaging;
using System.Globalization; using System.Globalization;
@ -22,7 +21,6 @@ public class A_Property
private readonly Serilog.ILogger? _Log; private readonly Serilog.ILogger? _Log;
private readonly string _OutputExtension; private readonly string _OutputExtension;
private readonly string[] _VerifyToSeason;
private readonly int _MaxDegreeOfParallelism; private readonly int _MaxDegreeOfParallelism;
private readonly ASCIIEncoding _ASCIIEncoding; private readonly ASCIIEncoding _ASCIIEncoding;
private readonly Configuration _Configuration; private readonly Configuration _Configuration;
@ -41,9 +39,6 @@ public class A_Property
_AngleBracketCollection = new List<string>(); _AngleBracketCollection = new List<string>();
_MaxDegreeOfParallelism = maxDegreeOfParallelism; _MaxDegreeOfParallelism = maxDegreeOfParallelism;
_WriteIndentedJsonSerializerOptions = new JsonSerializerOptions { WriteIndented = true }; _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; string checkDirectory;
List<string> collection = new(); List<string> collection = new();
for (int i = 0; i < 12; i++) for (int i = 0; i < 12; i++)
@ -107,27 +102,23 @@ public class A_Property
return results; 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; Shared.Models.Property result;
if (_Log is null)
throw new NullReferenceException(nameof(_Log));
long ticks;
byte[] bytes; byte[] bytes;
string value; string value;
long fileLength; long fileLength;
int encodingHash;
int? width = null; int? width = null;
int? height = null; int? height = null;
string? make = null;
string? model = null;
string dateTimeFormat; string dateTimeFormat;
DateTime checkDateTime; DateTime checkDateTime;
DateTime? dateTime = null; DateTime? dateTime = null;
PropertyItem? propertyItem; PropertyItem? propertyItem;
string make = string.Empty; string? orientation = null;
string model = string.Empty;
DateTime? gpsDateStamp = null; DateTime? gpsDateStamp = null;
DateTime? dateTimeOriginal = null; DateTime? dateTimeOriginal = null;
string orientation = string.Empty;
DateTime? dateTimeDigitized = null; DateTime? dateTimeDigitized = null;
DateTime? dateTimeFromName = Shared.Models.Stateless.Methods.IProperty.GetDateTimeFromName(fileHolder); DateTime? dateTimeFromName = Shared.Models.Stateless.Methods.IProperty.GetDateTimeFromName(fileHolder);
if (!isValidImageFormatExtension && isValidMetadataExtensions && fileHolder.Exists) if (!isValidImageFormatExtension && isValidMetadataExtensions && fileHolder.Exists)
@ -145,7 +136,6 @@ public class A_Property
if (populateId && id is null) if (populateId && id is null)
{ {
using Bitmap bitmap = new(image); using Bitmap bitmap = new(image);
string angleBracket = _AngleBracketCollection[0];
Rectangle rectangle = new(0, 0, image.Width, image.Height); Rectangle rectangle = new(0, 0, image.Width, image.Height);
BitmapData bitmapData = bitmap.LockBits(rectangle, ImageLockMode.ReadOnly, bitmap.PixelFormat); BitmapData bitmapData = bitmap.LockBits(rectangle, ImageLockMode.ReadOnly, bitmap.PixelFormat);
IntPtr intPtr = bitmapData.Scan0; IntPtr intPtr = bitmapData.Scan0;
@ -153,25 +143,12 @@ public class A_Property
bytes = new byte[length]; bytes = new byte[length];
Marshal.Copy(intPtr, bytes, 0, length); Marshal.Copy(intPtr, bytes, 0, length);
bitmap.UnlockBits(bitmapData); bitmap.UnlockBits(bitmapData);
if (id is null) id ??= Shared.Models.Stateless.Methods.IProperty.GetDeterministicHashCode(bytes);
{ if (writeBitmapDataBytes && !string.IsNullOrEmpty(angleBracket))
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)
{ {
FileInfo contentFileInfo = new(Path.Combine(angleBracket.Replace("<>", "()"), fileHolder.Name)); FileInfo contentFileInfo = new(Path.Combine(angleBracket.Replace("<>", "()"), fileHolder.Name));
File.WriteAllBytes(Path.ChangeExtension(contentFileInfo.FullName, string.Empty), bytes); 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; width = image.Width;
height = image.Height; height = image.Height;
@ -181,7 +158,7 @@ public class A_Property
propertyItem = image.GetPropertyItem((int)IExif.Tags.DateTime); propertyItem = image.GetPropertyItem((int)IExif.Tags.DateTime);
if (propertyItem?.Value is not null) 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) if (value.Length > dateTimeFormat.Length)
value = value[..dateTimeFormat.Length]; value = value[..dateTimeFormat.Length];
if (value.Length == dateTimeFormat.Length && DateTime.TryParseExact(value, dateTimeFormat, CultureInfo.InvariantCulture, DateTimeStyles.None, out checkDateTime)) 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); propertyItem = image.GetPropertyItem((int)IExif.Tags.DateTimeDigitized);
if (propertyItem?.Value is not null) 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) if (value.Length > dateTimeFormat.Length)
value = value[..dateTimeFormat.Length]; value = value[..dateTimeFormat.Length];
if (value.Length == dateTimeFormat.Length && DateTime.TryParseExact(value, dateTimeFormat, CultureInfo.InvariantCulture, DateTimeStyles.None, out checkDateTime)) 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); propertyItem = image.GetPropertyItem((int)IExif.Tags.DateTimeOriginal);
if (propertyItem?.Value is not null) 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) if (value.Length > dateTimeFormat.Length)
value = value[..dateTimeFormat.Length]; value = value[..dateTimeFormat.Length];
if (value.Length == dateTimeFormat.Length && DateTime.TryParseExact(value, dateTimeFormat, CultureInfo.InvariantCulture, DateTimeStyles.None, out checkDateTime)) 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); propertyItem = image.GetPropertyItem((int)IExif.Tags.GPSDateStamp);
if (propertyItem?.Value is not null) 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) if (value.Length > dateTimeFormat.Length)
value = value[..dateTimeFormat.Length]; value = value[..dateTimeFormat.Length];
if (value.Length == dateTimeFormat.Length && DateTime.TryParseExact(value, dateTimeFormat, CultureInfo.InvariantCulture, DateTimeStyles.None, out checkDateTime)) 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); propertyItem = image.GetPropertyItem((int)IExif.Tags.Make);
if (propertyItem?.Value is not null) 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; make = value;
} }
} }
@ -238,7 +215,7 @@ public class A_Property
propertyItem = image.GetPropertyItem((int)IExif.Tags.Model); propertyItem = image.GetPropertyItem((int)IExif.Tags.Model);
if (propertyItem?.Value is not null) 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; model = value;
} }
} }
@ -252,10 +229,7 @@ public class A_Property
} }
} }
} }
catch (Exception) catch (Exception) { }
{
_Log.Info(string.Concat(new StackFrame().GetMethod()?.Name, " <", fileHolder.Name, ">"));
}
} }
else else
dateTimeOriginal = null; dateTimeOriginal = null;
@ -276,6 +250,22 @@ public class A_Property
return result; 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 #pragma warning restore CA1416
private Shared.Models.Property GetPropertyOfPrivate(Item item, List<Tuple<string, DateTime>> sourceDirectoryFileTuples, List<string> parseExceptions, bool isIgnoreExtension, bool isValidMetadataExtensions) 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; bool populateId = _Configuration.PopulatePropertyId;
char directory = Shared.Models.Stateless.Methods.IDirectory.GetDirectory(item.ImageFileHolder.Name); char directory = Shared.Models.Stateless.Methods.IDirectory.GetDirectory(item.ImageFileHolder.Name);
int directoryIndex = Shared.Models.Stateless.Methods.IDirectory.GetDirectory(directory); 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")); fileInfo = new(Path.Combine(angleBracket.Replace("<>", "{}"), $"{item.ImageFileHolder.NameWithoutExtension}{item.ImageFileHolder.ExtensionLowered}.json"));
else else
fileInfo = new(Path.Combine(_JsonGroups["{}"][directoryIndex], $"{item.ImageFileHolder.NameWithoutExtension}{item.ImageFileHolder.ExtensionLowered}.json")); 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) if (result is null)
{ {
id ??= item.ImageFileHolder.Id; 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); json = JsonSerializer.Serialize(result, _WriteIndentedJsonSerializerOptions);
if (populateId && Shared.Models.Stateless.Methods.IPath.WriteAllText(fileInfo.FullName, json, updateDateWhenMatches: true, compareBeforeWrite: true)) 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; 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) private void SavePropertyParallelForWork(string sourceDirectory, List<Tuple<string, DateTime>> sourceDirectoryFileTuples, List<Tuple<string, DateTime>> sourceDirectoryChanges, Item item)
{ {
Shared.Models.Property property; Shared.Models.Property property;
@ -579,7 +469,6 @@ public class A_Property
throw new NullReferenceException(nameof(_Log)); throw new NullReferenceException(nameof(_Log));
string message; string message;
int totalSeconds; int totalSeconds;
bool? anyFilesMoved;
Container container; Container container;
bool anyNullOrNoIsUniqueFileName; bool anyNullOrNoIsUniqueFileName;
List<Exception> exceptions = new(); List<Exception> exceptions = new();
@ -594,7 +483,7 @@ public class A_Property
sourceDirectoryChanges.Clear(); sourceDirectoryChanges.Clear();
if (!container.Items.Any()) if (!container.Items.Any())
continue; continue;
anyNullOrNoIsUniqueFileName = container.Items.Any(l => l.IsUniqueFileName is null || !l.IsUniqueFileName.Value); anyNullOrNoIsUniqueFileName = container.Items.Any(l => !l.IsUniqueFileName);
SetAngleBracketCollection(container.SourceDirectory, anyNullOrNoIsUniqueFileName); SetAngleBracketCollection(container.SourceDirectory, anyNullOrNoIsUniqueFileName);
totalSeconds = (int)Math.Truncate(new TimeSpan(DateTime.Now.Ticks - ticks).TotalSeconds); 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}"; 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!")); throw new Exception(string.Concat("All in [", container.SourceDirectory, "]failed!"));
if (exceptions.Count != 0) if (exceptions.Count != 0)
_ExceptionsDirectories.Add(container.SourceDirectory); _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()) if (Directory.GetFiles(propertyRoot, "*.txt", SearchOption.TopDirectoryOnly).Any())
{ {
for (int y = 0; y < int.MaxValue; y++) for (int y = 0; y < int.MaxValue; y++)
@ -630,8 +515,7 @@ public class A_Property
{ {
if (item.ImageFileHolder.DirectoryName is null) if (item.ImageFileHolder.DirectoryName is null)
throw new NullReferenceException(nameof(item.ImageFileHolder.DirectoryName)); throw new NullReferenceException(nameof(item.ImageFileHolder.DirectoryName));
bool anyNullOrNoIsUniqueFileName = item.IsUniqueFileName is null || !item.IsUniqueFileName.Value; SetAngleBracketCollection(item.ImageFileHolder.DirectoryName, !item.IsUniqueFileName);
SetAngleBracketCollection(item.ImageFileHolder.DirectoryName, anyNullOrNoIsUniqueFileName);
} }
bool isValidMetadataExtensions = _Configuration.ValidMetadataExtensions.Contains(item.ImageFileHolder.ExtensionLowered); bool isValidMetadataExtensions = _Configuration.ValidMetadataExtensions.Contains(item.ImageFileHolder.ExtensionLowered);
bool isIgnoreExtension = item.IsValidImageFormatExtension && _Configuration.IgnoreExtensions.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 ResultSingleton { init; get; }
public string[] ValidImageFormatExtensions { init; get; } public string[] ValidImageFormatExtensions { init; get; }
public string[] ValidMetadataExtensions { init; get; } public string[] ValidMetadataExtensions { init; get; }
public string[] VerifyToSeason { init; get; }
public bool WriteBitmapDataBytes { init; get; } public bool WriteBitmapDataBytes { init; get; }
[JsonConstructor] [JsonConstructor]
@ -75,7 +74,6 @@ public class Configuration : Shared.Models.Properties.IPropertyConfiguration
_RootDirectory = rootDirectory; _RootDirectory = rootDirectory;
ValidImageFormatExtensions = validImageFormatExtensions; ValidImageFormatExtensions = validImageFormatExtensions;
ValidMetadataExtensions = validMetadataExtensions; ValidMetadataExtensions = validMetadataExtensions;
VerifyToSeason = verifyToSeason;
WriteBitmapDataBytes = writeBitmapDataBytes; WriteBitmapDataBytes = writeBitmapDataBytes;
} }
@ -110,8 +108,6 @@ public class Configuration : Shared.Models.Properties.IPropertyConfiguration
throw new NullReferenceException(nameof(propertyConfiguration.ValidImageFormatExtensions)); throw new NullReferenceException(nameof(propertyConfiguration.ValidImageFormatExtensions));
if (propertyConfiguration.ValidMetadataExtensions is null || !propertyConfiguration.ValidMetadataExtensions.Any()) if (propertyConfiguration.ValidMetadataExtensions is null || !propertyConfiguration.ValidMetadataExtensions.Any())
throw new NullReferenceException(nameof(propertyConfiguration.ValidMetadataExtensions)); throw new NullReferenceException(nameof(propertyConfiguration.ValidMetadataExtensions));
if (propertyConfiguration.VerifyToSeason is null || !propertyConfiguration.VerifyToSeason.Any())
throw new NullReferenceException(nameof(propertyConfiguration.VerifyToSeason));
if (propertyConfiguration is null) if (propertyConfiguration is null)
throw new NullReferenceException(nameof(propertyConfiguration)); throw new NullReferenceException(nameof(propertyConfiguration));
if (string.IsNullOrEmpty(propertyConfiguration.DateGroup)) 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 subFile, Shared.Models.Property property, Shared.Models.FileHolder? fileHolder
string dateTimeFormat = Shared.Models.Stateless.Methods.IProperty.DateTimeFormat(); 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); string dateTimeValue = dateTime.ToString(dateTimeFormat);
byte[] bytes = _ASCIIEncoding.GetBytes(dateTimeValue); byte[] bytes = _ASCIIEncoding.GetBytes(dateTimeValue);
if (_ASCIIEncoding.GetString(bytes, 0, bytes.Length) != 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 int? ConfidencePercent { init; get; }
public DateTime DateTimeOriginalThenMinimumDateTime { init; get; }
public object? Encoding { init; get; } public object? Encoding { init; get; }
public int Id { init; get; } public int Id { init; get; }
public bool? IsWrongYear { init; get; } public bool? IsWrongYear { init; get; }
public double? Length { init; get; } public double? Length { init; get; }
public DateTime? MinimumDateTime { init; get; }
public int? NormalizedRectangle { init; get; } public int? NormalizedRectangle { init; get; }
[JsonConstructor] [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; ConfidencePercent = confidencePercent;
DateTimeOriginalThenMinimumDateTime = dateTimeOriginalThenMinimumDateTime;
Encoding = encoding; Encoding = encoding;
Id = id; Id = id;
IsWrongYear = isWrongYear; IsWrongYear = isWrongYear;
Length = length; Length = length;
MinimumDateTime = minimumDateTime;
NormalizedRectangle = normalizedRectangle; NormalizedRectangle = normalizedRectangle;
} }
public FaceDistance(int? confidencePercent, object? encoding, int id, bool? isWrongYear, DateTime? minimumDateTime, int? normalizedRectangle) : public FaceDistance(int? confidencePercent, DateTime dateTimeOriginalThenMinimumDateTime, object? encoding, int id, bool? isWrongYear, int? normalizedRectangle) :
this(confidencePercent, encoding, id, isWrongYear, null, minimumDateTime, normalizedRectangle) this(confidencePercent, dateTimeOriginalThenMinimumDateTime, encoding, id, isWrongYear, null, normalizedRectangle)
{ } { }
public FaceDistance(FaceDistance faceDistance, double length) : 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; public FaceDistance(object encoding) => Encoding = encoding;

View File

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

View File

@ -3,142 +3,6 @@ using System.Text.Json.Serialization;
namespace View_by_Distance.Shared.Models; 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 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 int? ConfidencePercent { init; get; }
public DateTime DateTimeOriginalThenMinimumDateTime { init; get; }
public object? Encoding { init; get; } public object? Encoding { init; get; }
public int Id { init; get; } public int Id { init; get; }
public bool? IsWrongYear { init; get; } public bool? IsWrongYear { init; get; }
public double? Length { init; get; } public double? Length { init; get; }
public DateTime? MinimumDateTime { init; get; }
public int? NormalizedRectangle { init; get; } public int? NormalizedRectangle { init; get; }
} }

View File

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

View File

@ -1,56 +1,5 @@
namespace View_by_Distance.Shared.Models.Properties; 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 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 interface IProperty
{ {
public DateTime CreationTime { get; } public DateTime CreationTime { init; get; }
public DateTime? DateTime { get; } public DateTime? DateTime { init; get; }
public DateTime? DateTimeDigitized { get; } public DateTime? DateTimeDigitized { init; get; }
public DateTime? DateTimeFromName { get; } public DateTime? DateTimeFromName { init; get; }
public DateTime? DateTimeOriginal { get; } public DateTime? DateTimeOriginal { init; get; }
public long FileSize { get; } public long FileSize { init; get; }
public DateTime? GPSDateStamp { get; } public DateTime? GPSDateStamp { init; get; }
public int? Height { get; } public int? Height { init; get; }
public int? Id { get; } public int? Id { init; get; }
public DateTime LastWriteTime { get; } public DateTime LastWriteTime { init; get; }
public string Make { get; } public string? Make { init; get; }
public string Model { get; } public string? Model { init; get; }
public string Orientation { get; } public string? Orientation { init; get; }
public int? Width { get; } public int? Width { init; get; }
} }

View File

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

View File

@ -6,52 +6,38 @@ namespace View_by_Distance.Shared.Models;
public class Property : Properties.IProperty public class Property : Properties.IProperty
{ {
protected DateTime _CreationTime; public DateTime CreationTime { init; get; }
protected DateTime? _DateTime; public DateTime? DateTime { init; get; }
protected DateTime? _DateTimeDigitized; public DateTime? DateTimeDigitized { init; get; }
protected DateTime? _DateTimeFromName; public DateTime? DateTimeFromName { init; get; }
protected DateTime? _DateTimeOriginal; public DateTime? DateTimeOriginal { init; get; }
protected long _FileSize; public long FileSize { init; get; }
protected DateTime? _GPSDateStamp; public DateTime? GPSDateStamp { init; get; }
protected int? _Height; public int? Height { init; get; }
protected int? _Id; public int? Id { init; get; }
protected DateTime _LastWriteTime; public DateTime LastWriteTime { init; get; }
protected string _Make; public string? Make { init; get; }
protected string _Model; public string? Model { init; get; }
protected string _Orientation; public string? Orientation { init; get; }
protected int? _Width; public int? Width { init; get; }
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;
[JsonConstructor] [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; DateTimeFromName = dateTimeFromName;
_CreationTime = creationTime; CreationTime = creationTime;
_DateTime = dateTime; DateTime = dateTime;
_DateTimeDigitized = dateTimeDigitized; DateTimeDigitized = dateTimeDigitized;
_DateTimeOriginal = dateTimeOriginal; DateTimeOriginal = dateTimeOriginal;
_FileSize = fileSize; FileSize = fileSize;
_GPSDateStamp = gpsDateStamp; GPSDateStamp = gpsDateStamp;
_Height = height; Height = height;
_Id = id; Id = id;
_LastWriteTime = lastWriteTime; LastWriteTime = lastWriteTime;
_Make = make; Make = make;
_Model = model; Model = model;
_Orientation = orientation; Orientation = orientation;
_Width = width; Width = width;
} }
public override string ToString() public override string ToString()
@ -60,38 +46,6 @@ public class Property : Properties.IProperty
return result; return result;
} // ... } // ...
public List<DateTime> GetDateTimes() => Stateless.Methods.Property.GetDateTimes(_CreationTime, _LastWriteTime, _DateTime, _DateTimeDigitized, _DateTimeFromName, _DateTimeOriginal, _GPSDateStamp); 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);
}
} }

View File

@ -144,7 +144,7 @@ internal abstract class Container
File.SetCreationTime(sourceDirectoryFileHolder.FullName, imageFileInfo.LastWriteTime.Value); File.SetCreationTime(sourceDirectoryFileHolder.FullName, imageFileInfo.LastWriteTime.Value);
File.SetLastWriteTime(sourceDirectoryFileHolder.FullName, sourceDirectoryFileHolder.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) lock (results)
results.Add(new(filePair.Path, imageFileInfo.DirectoryName, filePair.IsUnique, filePair.Collection, item)); 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) => static int GetDeterministicHashCode(byte[] value) =>
Property.GetDeterministicHashCode(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) => DateTime TestStatic_GetDateTime(Models.Property? property) =>
GetDateTime(property); GetDateTime(property);
static DateTime GetDateTime(Models.Property? property) => static DateTime GetDateTime(Models.Property? property) =>
@ -46,6 +41,11 @@ public interface IProperty
static (bool?, string[]) IsWrongYear(string[] segments, string year) => static (bool?, string[]) IsWrongYear(string[] segments, string year) =>
Property.IsWrongYear(segments, 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) => (DateTime?[], int?, string?) TestStatic_Get(Models.FileHolder fileHolder, bool isIgnoreExtension, bool isValidImageFormatExtension) =>
Get(fileHolder, isIgnoreExtension, isValidImageFormatExtension); Get(fileHolder, isIgnoreExtension, isValidImageFormatExtension);
static (DateTime?[], int?, string?) Get(Models.FileHolder fileHolder, bool isIgnoreExtension, bool 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; 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) internal static (bool?, string[]) IsWrongYear(string[] segments, string year)
{ {
bool? result; bool? result;
@ -92,6 +73,45 @@ internal abstract class Property
return new(result, results); 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) internal static DateTime? GetDateTimeFromName(Models.FileHolder fileHolder)
{ {
DateTime? result = null; DateTime? result = null;

View File

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

View File

@ -95,9 +95,9 @@ internal abstract partial class XDirectory
return renameCollection.Count; 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 possibleFileInfo;
FileInfo fileInfo = new(file); FileInfo fileInfo = new(file);
foreach (string possible in collection) foreach (string possible in collection)
@ -105,18 +105,14 @@ internal abstract partial class XDirectory
if (possible == file) if (possible == file)
continue; continue;
possibleFileInfo = new(possible); 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) if (possibleFileInfo.LastWriteTime == fileInfo.LastWriteTime && possibleFileInfo.Length == fileInfo.Length)
continue; continue;
timeSpan = new(possibleFileInfo.LastWriteTime.Ticks - fileInfo.LastWriteTime.Ticks); if (!result)
if (possibleFileInfo.Length != fileInfo.Length) result = true;
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));
} }
return result;
} }
private static string? GetMatch(string file, List<string> collection) private static string? GetMatch(string file, List<string> collection)
@ -148,28 +144,30 @@ internal abstract partial class XDirectory
string fileName; string fileName;
bool uniqueFileName; bool uniqueFileName;
List<string>? collection; List<string>? collection;
bool? isNotUniqueAndNeedsReview;
foreach (string[] files in filesCollection) foreach (string[] files in filesCollection)
{ {
foreach (string file in files) foreach (string file in files)
{ {
isNotUniqueAndNeedsReview = null;
fileName = Path.GetFileName(file); fileName = Path.GetFileName(file);
if (!fileNamesToFiles.TryGetValue(fileName, out collection)) if (!fileNamesToFiles.TryGetValue(fileName, out collection))
throw new Exception(); throw new Exception();
uniqueFileName = collection.Count == 1; uniqueFileName = collection.Count == 1;
if (!uniqueFileName) if (!uniqueFileName)
IsNotUniqueLoop(file, collection); isNotUniqueAndNeedsReview = GetIsNotUniqueAndNeedsReview(file, collection);
if (!compareFileNamesToFiles.TryGetValue(string.Concat(fileName, extension), out 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 else
{ {
if (!collection.Any()) if (!collection.Any())
results.Add(new(file, uniqueFileName, collection, null)); results.Add(new(file, uniqueFileName, isNotUniqueAndNeedsReview, collection, null));
else if (uniqueFileName && collection.Count == 1) else if (uniqueFileName && collection.Count == 1)
results.Add(new(file, uniqueFileName, collection, collection.First())); results.Add(new(file, uniqueFileName, isNotUniqueAndNeedsReview, collection, collection.First()));
else else
{ {
match = GetMatch(file, collection); 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() public void TestMethodRename()
{ {
// string[] directories = Directory.GetDirectories(@"D:\2) Images B\Not-Copy-Copy-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:\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:\2) Images B\Not-Copy-Copy-1e85c0ba", "*", SearchOption.AllDirectories);
foreach (string directory in directories.OrderByDescending(l => l.Length - l.Replace(@"\", string.Empty).Length)) foreach (string directory in directories.OrderByDescending(l => l.Length - l.Replace(@"\", string.Empty).Length))
{ {
if (directory.EndsWith(";9")) if (!directory.EndsWith(";9"))
continue; continue;
Directory.Move(directory, $"{directory};9"); Directory.Move(directory, $"{directory[..^2]} !9");
} }
NonThrowTryCatch(); NonThrowTryCatch();
} }

View File

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

View File

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