Mostly Sorting

Video Merge as 4, 5, and 6
This commit is contained in:
2025-03-22 16:50:47 -07:00
parent d5fa108f81
commit 130e3b6528
24 changed files with 6223 additions and 6119 deletions

@ -14,56 +14,53 @@ namespace View_by_Distance.Property.Models.Stateless;
internal partial class Property
{
[GeneratedRegex(@"\D+")]
private static partial Regex Digit();
private static List<DateTime> GetDateTimes(DateTime dateTimeFromName, DateTime?[] dateTimes)
internal static TimeSpan GetThreeStandardDeviationHigh(int minimum, Container.Models.Container container)
{
List<DateTime> results = [dateTimeFromName];
foreach (DateTime? dateTime in dateTimes)
TimeSpan result;
DateTime? minimumDateTime;
List<long> ticksCollection = [];
foreach (Item item in container.Items)
{
if (dateTime is null)
if (item.Property is null)
continue;
results.Add(dateTime.Value);
minimumDateTime = Shared.Models.Stateless.Methods.IProperty.GetMinimumDateTime(item.Property);
if (minimumDateTime is null)
continue;
ticksCollection.Add(minimumDateTime.Value.Ticks);
}
return results;
long threeStandardDeviationHigh;
long min;
if (ticksCollection.Count == 0)
min = 0;
else
min = ticksCollection.Min();
if (ticksCollection.Count < minimum)
threeStandardDeviationHigh = long.MaxValue;
else
threeStandardDeviationHigh = GetThreeStandardDeviationHigh(ref ticksCollection, min);
result = new TimeSpan(threeStandardDeviationHigh - min);
return result;
}
private static List<DateTime> GetDateTimes(DateTime?[] dateTimes, DateTime?[] metadataDateTimes)
private static long GetThreeStandardDeviationHigh(ref List<long> ticksCollection, long min)
{
List<DateTime> results = [];
foreach (DateTime? dateTime in metadataDateTimes)
{
if (dateTime is null || results.Contains(dateTime.Value))
continue;
results.Add(dateTime.Value);
}
foreach (DateTime? dateTime in dateTimes)
{
if (dateTime is null || results.Contains(dateTime.Value))
continue;
results.Add(dateTime.Value);
}
return results;
long result;
ticksCollection = (from l in ticksCollection select l - min).ToList();
double sum = ticksCollection.Sum();
double average = sum / ticksCollection.Count;
double standardDeviation = GetStandardDeviation(ticksCollection, average);
result = (long)Math.Ceiling(average + min + (standardDeviation * 3));
return result;
}
private static List<DateTime> GetDateTimes(FilePath filePath, DateTime?[] dateTimes)
internal static double GetStandardDeviation(List<long> values, double average)
{
List<DateTime> results = [];
string[] digits = Digit().Split(filePath.FullName);
foreach (string digit in digits)
{
if (digit.Length != 4 || digit[..2] is not "19" and not "20" || !int.TryParse(digit, out int year))
continue;
results.Add(new(year, 1, 1));
}
foreach (DateTime? dateTime in dateTimes)
{
if (dateTime is null)
continue;
results.Add(dateTime.Value);
}
return results;
double result = 0;
if (values.Count == 0)
throw new Exception("Collection must have at least one value!");
double sum = values.Sum(l => (l - average) * (l - average));
result = Math.Sqrt(sum / values.Count);
return result;
}
internal static byte[] GetBytes(string value)
@ -126,22 +123,40 @@ internal partial class Property
return result;
}
private static List<DateTime> GetDateTimes(DateTime?[] metadataDateTimes)
internal static bool Any(Container.Models.Container[] containers)
{
List<DateTime> results = [];
foreach (DateTime? dateTime in metadataDateTimes)
bool result = false;
foreach (Container.Models.Container container in containers)
{
if (dateTime is null || results.Contains(dateTime.Value))
if (container.Items.Count == 0)
continue;
results.Add(dateTime.Value);
if ((from l in container.Items where l.Any() select true).Any())
{
result = true;
break;
}
}
return results;
return result;
}
#pragma warning disable CA1416
internal static DateTime? GetDateTime(string dateTimeFormat, string? value)
{
DateTime? result;
string alternateFormat = "ddd MMM dd HH:mm:ss yyyy";
if (value is not null && DateTime.TryParse(value, out DateTime dateTime))
result = dateTime;
else if (value is not null && value.Length == dateTimeFormat.Length && DateTime.TryParseExact(value, dateTimeFormat, CultureInfo.InvariantCulture, DateTimeStyles.None, out dateTime))
result = dateTime;
else if (value is not null && value.Length == alternateFormat.Length && DateTime.TryParseExact(value, alternateFormat, CultureInfo.InvariantCulture, DateTimeStyles.None, out dateTime))
result = dateTime;
else
result = null;
return result;
}
internal static PropertyItem GetPropertyItem(ConstructorInfo constructorInfo, int id, short type, string value)
{
#pragma warning disable CA1416
PropertyItem result = (PropertyItem)constructorInfo.Invoke(null);
int length;
byte[] bytes;
@ -161,27 +176,65 @@ internal partial class Property
result.Len = length;
result.Type = type;
result.Value = bytes;
return result;
}
#pragma warning restore CA1416
internal static DateTime? GetDateTime(string dateTimeFormat, string? value)
{
DateTime? result;
string alternateFormat = "ddd MMM dd HH:mm:ss yyyy";
if (value is not null && DateTime.TryParse(value, out DateTime dateTime))
result = dateTime;
else if (value is not null && value.Length == dateTimeFormat.Length && DateTime.TryParseExact(value, dateTimeFormat, CultureInfo.InvariantCulture, DateTimeStyles.None, out dateTime))
result = dateTime;
else if (value is not null && value.Length == alternateFormat.Length && DateTime.TryParseExact(value, alternateFormat, CultureInfo.InvariantCulture, DateTimeStyles.None, out dateTime))
result = dateTime;
else
result = null;
return result;
}
#pragma warning disable CA1416
internal static (int, List<DateTime>, List<Item>) Get(Container.Models.Container container, TimeSpan threeStandardDeviationHigh, int i)
{
List<Item> results = [];
int j = i;
long? ticks;
TimeSpan timeSpan;
Item item;
DateTime? minimumDateTime;
Item nextItem;
DateTime? nextMinimumDateTime;
List<DateTime> dateTimes = [];
for (; j < container.Items.Count; j++)
{
ticks = null;
item = container.Items[j];
if (item.Property is null)
continue;
minimumDateTime = Shared.Models.Stateless.Methods.IProperty.GetMinimumDateTime(item.Property);
if (minimumDateTime is null)
continue;
for (int k = j + 1; k < container.Items.Count; k++)
{
nextItem = container.Items[k];
if (nextItem.Property is null)
continue;
nextMinimumDateTime = Shared.Models.Stateless.Methods.IProperty.GetMinimumDateTime(nextItem.Property);
if (nextMinimumDateTime is null)
continue;
ticks = nextMinimumDateTime.Value.Ticks;
break;
}
results.Add(item);
dateTimes.Add(minimumDateTime.Value);
if (ticks.HasValue)
{
timeSpan = new(ticks.Value - minimumDateTime.Value.Ticks);
if (timeSpan > threeStandardDeviationHigh)
break;
}
}
return new(j, dateTimes, results);
}
internal static (DateTime?, DateTime[], int?, string?) Get(bool populateId, IMetadata<MetadataExtractor.Directory>? metadata, FilePath filePath, bool isIgnoreExtension, bool isValidImageFormatExtension, ASCIIEncoding asciiEncoding)
{
int? id = null;
string? message;
DateTime[] dateTimes;
Shared.Models.Property? property = null;
if (isIgnoreExtension || !isValidImageFormatExtension)
(message, dateTimes, property) = (null, [], null);
else
(message, dateTimes, property) = GetProperty(populateId, metadata, filePath, property, isIgnoreExtension, isValidImageFormatExtension, id, asciiEncoding);
return new(property?.DateTimeOriginal, dateTimes, property?.Id, message);
}
internal static (string?, DateTime[], Shared.Models.Property) GetProperty(bool populateId, IMetadata<MetadataExtractor.Directory>? metadata, FilePath filePath, Shared.Models.Property? property, bool isIgnoreExtension, bool isValidImageFormatExtension, int? id, ASCIIEncoding asciiEncoding)
{
@ -225,6 +278,7 @@ internal partial class Property
{
try
{
#pragma warning disable CA1416
using Image image = Image.FromFile(filePath.FullName);
width = image.Width;
height = image.Height;
@ -240,7 +294,7 @@ internal partial class Property
bitmap.UnlockBits(bitmapData);
id ??= Shared.Models.Stateless.Methods.IId.GetDeterministicHashCode(bytes);
}
dateTimeFormat = IProperty.DateTimeFormat();
dateTimeFormat = IProperty.DateTimeFormat;
if (image.PropertyIdList.Contains(MetadataExtractor.Formats.Exif.ExifDirectoryBase.TagDateTime))
{
propertyItem = image.GetPropertyItem(MetadataExtractor.Formats.Exif.ExifDirectoryBase.TagDateTime);
@ -318,6 +372,7 @@ internal partial class Property
keywords = Encoding.Unicode.GetString(propertyItem.Value).Trim('\0', ' ').Split(';');
}
}
#pragma warning restore CA1416
message = null;
dateTimes = [new(filePath.LastWriteTicks), new(filePath.CreationTicks), dateTime, dateTimeDigitized, dateTimeOriginal, gpsDateStamp];
}
@ -351,127 +406,68 @@ internal partial class Property
return (message, dateTimesByLogic.ToArray(), result);
}
#pragma warning restore CA1416
internal static (DateTime?, DateTime[], int?, string?) Get(bool populateId, IMetadata<MetadataExtractor.Directory>? metadata, FilePath filePath, bool isIgnoreExtension, bool isValidImageFormatExtension, ASCIIEncoding asciiEncoding)
private static List<DateTime> GetDateTimes(DateTime?[] metadataDateTimes)
{
int? id = null;
string? message;
DateTime[] dateTimes;
Shared.Models.Property? property = null;
if (isIgnoreExtension || !isValidImageFormatExtension)
(message, dateTimes, property) = (null, [], null);
else
(message, dateTimes, property) = GetProperty(populateId, metadata, filePath, property, isIgnoreExtension, isValidImageFormatExtension, id, asciiEncoding);
return new(property?.DateTimeOriginal, dateTimes, property?.Id, message);
}
internal static double GetStandardDeviation(List<long> values, double average)
{
double result = 0;
if (values.Count == 0)
throw new Exception("Collection must have at least one value!");
double sum = values.Sum(l => (l - average) * (l - average));
result = Math.Sqrt(sum / values.Count);
return result;
}
private static long GetThreeStandardDeviationHigh(ref List<long> ticksCollection, long min)
{
long result;
ticksCollection = (from l in ticksCollection select l - min).ToList();
double sum = ticksCollection.Sum();
double average = sum / ticksCollection.Count;
double standardDeviation = GetStandardDeviation(ticksCollection, average);
result = (long)Math.Ceiling(average + min + (standardDeviation * 3));
return result;
}
internal static TimeSpan GetThreeStandardDeviationHigh(int minimum, Container.Models.Container container)
{
TimeSpan result;
DateTime? minimumDateTime;
List<long> ticksCollection = [];
foreach (Shared.Models.Item item in container.Items)
List<DateTime> results = [];
foreach (DateTime? dateTime in metadataDateTimes)
{
if (item.Property is null)
if (dateTime is null || results.Contains(dateTime.Value))
continue;
minimumDateTime = Shared.Models.Methods.IProperty.GetMinimumDateTime(item.Property);
if (minimumDateTime is null)
continue;
ticksCollection.Add(minimumDateTime.Value.Ticks);
results.Add(dateTime.Value);
}
long threeStandardDeviationHigh;
long min;
if (ticksCollection.Count == 0)
min = 0;
else
min = ticksCollection.Min();
if (ticksCollection.Count < minimum)
threeStandardDeviationHigh = long.MaxValue;
else
threeStandardDeviationHigh = GetThreeStandardDeviationHigh(ref ticksCollection, min);
result = new TimeSpan(threeStandardDeviationHigh - min);
return result;
return results;
}
internal static (int, List<DateTime>, List<Shared.Models.Item>) Get(Container.Models.Container container, TimeSpan threeStandardDeviationHigh, int i)
private static List<DateTime> GetDateTimes(FilePath filePath, DateTime?[] dateTimes)
{
List<Shared.Models.Item> results = [];
int j = i;
long? ticks;
TimeSpan timeSpan;
Shared.Models.Item item;
DateTime? minimumDateTime;
Shared.Models.Item nextItem;
DateTime? nextMinimumDateTime;
List<DateTime> dateTimes = [];
for (; j < container.Items.Count; j++)
List<DateTime> results = [];
string[] digits = Digit().Split(filePath.FullName);
foreach (string digit in digits)
{
ticks = null;
item = container.Items[j];
if (item.Property is null)
if (digit.Length != 4 || digit[..2] is not "19" and not "20" || !int.TryParse(digit, out int year))
continue;
minimumDateTime = Shared.Models.Methods.IProperty.GetMinimumDateTime(item.Property);
if (minimumDateTime is null)
continue;
for (int k = j + 1; k < container.Items.Count; k++)
{
nextItem = container.Items[k];
if (nextItem.Property is null)
continue;
nextMinimumDateTime = Shared.Models.Methods.IProperty.GetMinimumDateTime(nextItem.Property);
if (nextMinimumDateTime is null)
continue;
ticks = nextMinimumDateTime.Value.Ticks;
break;
}
results.Add(item);
dateTimes.Add(minimumDateTime.Value);
if (ticks.HasValue)
{
timeSpan = new(ticks.Value - minimumDateTime.Value.Ticks);
if (timeSpan > threeStandardDeviationHigh)
break;
}
results.Add(new(year, 1, 1));
}
return new(j, dateTimes, results);
foreach (DateTime? dateTime in dateTimes)
{
if (dateTime is null)
continue;
results.Add(dateTime.Value);
}
return results;
}
internal static bool Any(Container.Models.Container[] containers)
private static List<DateTime> GetDateTimes(DateTime dateTimeFromName, DateTime?[] dateTimes)
{
bool result = false;
foreach (Container.Models.Container container in containers)
List<DateTime> results = [dateTimeFromName];
foreach (DateTime? dateTime in dateTimes)
{
if (container.Items.Count == 0)
if (dateTime is null)
continue;
if ((from l in container.Items where l.Any() select true).Any())
{
result = true;
break;
}
results.Add(dateTime.Value);
}
return result;
return results;
}
private static List<DateTime> GetDateTimes(DateTime?[] dateTimes, DateTime?[] metadataDateTimes)
{
List<DateTime> results = [];
foreach (DateTime? dateTime in metadataDateTimes)
{
if (dateTime is null || results.Contains(dateTime.Value))
continue;
results.Add(dateTime.Value);
}
foreach (DateTime? dateTime in dateTimes)
{
if (dateTime is null || results.Contains(dateTime.Value))
continue;
results.Add(dateTime.Value);
}
return results;
}
[GeneratedRegex(@"\D+")]
private static partial Regex Digit();
}