NullReferenceException
This commit is contained in:
40
Property/Models/Closest.cs
Normal file
40
Property/Models/Closest.cs
Normal file
@ -0,0 +1,40 @@
|
||||
using System.Text.Json.Serialization;
|
||||
using View_by_Distance.Shared.Models;
|
||||
|
||||
namespace View_by_Distance.Property.Models;
|
||||
|
||||
public class Closest
|
||||
{
|
||||
|
||||
protected readonly double? _Average;
|
||||
protected readonly int? _FaceLocationIndex;
|
||||
protected readonly bool? _IsWrongYear;
|
||||
protected readonly DateTime _MinimumDateTime;
|
||||
protected readonly PersonBirthday? _PersonBirthday;
|
||||
|
||||
public double? Average => _Average;
|
||||
public int? FaceLocationIndex => _FaceLocationIndex;
|
||||
public bool? IsWrongYear => _IsWrongYear;
|
||||
public DateTime MinimumDateTime => _MinimumDateTime;
|
||||
public PersonBirthday? PersonBirthday => _PersonBirthday;
|
||||
|
||||
[JsonConstructor]
|
||||
public Closest(double? average, int? faceLocationIndex, bool? isWrongYear, DateTime minimumDateTime, PersonBirthday? personBirthday)
|
||||
{
|
||||
_Average = average;
|
||||
_FaceLocationIndex = faceLocationIndex;
|
||||
_IsWrongYear = isWrongYear;
|
||||
_MinimumDateTime = minimumDateTime;
|
||||
_PersonBirthday = personBirthday;
|
||||
}
|
||||
|
||||
public Closest(int? faceLocationIndex, DateTime minimumDateTime, bool? isWrongYear, PersonBirthday? personBirthday, double? average)
|
||||
{
|
||||
_Average = average;
|
||||
_FaceLocationIndex = faceLocationIndex;
|
||||
_IsWrongYear = isWrongYear;
|
||||
_MinimumDateTime = minimumDateTime;
|
||||
_PersonBirthday = personBirthday;
|
||||
}
|
||||
|
||||
}
|
@ -65,37 +65,37 @@ public class Configuration
|
||||
public static void Verify(Configuration? propertyConfiguration)
|
||||
{
|
||||
if (propertyConfiguration is null)
|
||||
throw new ArgumentNullException(nameof(propertyConfiguration));
|
||||
throw new NullReferenceException(nameof(propertyConfiguration));
|
||||
if (propertyConfiguration.ForcePropertyLastWriteTimeToCreationTime is null)
|
||||
throw new ArgumentNullException(nameof(propertyConfiguration.ForcePropertyLastWriteTimeToCreationTime));
|
||||
throw new NullReferenceException(nameof(propertyConfiguration.ForcePropertyLastWriteTimeToCreationTime));
|
||||
if (propertyConfiguration.IgnoreExtensions is null || !propertyConfiguration.IgnoreExtensions.Any())
|
||||
throw new ArgumentNullException(nameof(propertyConfiguration.IgnoreExtensions));
|
||||
throw new NullReferenceException(nameof(propertyConfiguration.IgnoreExtensions));
|
||||
if (propertyConfiguration.PopulatePropertyId is null)
|
||||
throw new ArgumentNullException(nameof(propertyConfiguration.PopulatePropertyId));
|
||||
throw new NullReferenceException(nameof(propertyConfiguration.PopulatePropertyId));
|
||||
if (propertyConfiguration.PropertiesChangedForProperty is null)
|
||||
throw new ArgumentNullException(nameof(propertyConfiguration.PropertiesChangedForProperty));
|
||||
throw new NullReferenceException(nameof(propertyConfiguration.PropertiesChangedForProperty));
|
||||
if (propertyConfiguration.PropertyContentCollectionFiles is null)
|
||||
throw new ArgumentNullException(nameof(propertyConfiguration.PropertyContentCollectionFiles));
|
||||
throw new NullReferenceException(nameof(propertyConfiguration.PropertyContentCollectionFiles));
|
||||
if (propertyConfiguration.ValidImageFormatExtensions is null || !propertyConfiguration.ValidImageFormatExtensions.Any())
|
||||
throw new ArgumentNullException(nameof(propertyConfiguration.ValidImageFormatExtensions));
|
||||
throw new NullReferenceException(nameof(propertyConfiguration.ValidImageFormatExtensions));
|
||||
if (propertyConfiguration.ValidMetadataExtensions is null || !propertyConfiguration.ValidMetadataExtensions.Any())
|
||||
throw new ArgumentNullException(nameof(propertyConfiguration.ValidMetadataExtensions));
|
||||
throw new NullReferenceException(nameof(propertyConfiguration.ValidMetadataExtensions));
|
||||
if (propertyConfiguration.VerifyToSeason is null || !propertyConfiguration.VerifyToSeason.Any())
|
||||
throw new ArgumentNullException(nameof(propertyConfiguration.VerifyToSeason));
|
||||
throw new NullReferenceException(nameof(propertyConfiguration.VerifyToSeason));
|
||||
if (propertyConfiguration.WriteBitmapDataBytes is null)
|
||||
throw new ArgumentNullException(nameof(propertyConfiguration.WriteBitmapDataBytes));
|
||||
throw new NullReferenceException(nameof(propertyConfiguration.WriteBitmapDataBytes));
|
||||
if (Path.GetPathRoot(propertyConfiguration.RootDirectory) == propertyConfiguration.RootDirectory)
|
||||
throw new ArgumentNullException(nameof(propertyConfiguration.RootDirectory));
|
||||
throw new NullReferenceException(nameof(propertyConfiguration.RootDirectory));
|
||||
if (propertyConfiguration is null)
|
||||
throw new ArgumentNullException(nameof(propertyConfiguration));
|
||||
throw new NullReferenceException(nameof(propertyConfiguration));
|
||||
if (string.IsNullOrEmpty(propertyConfiguration.DateGroup))
|
||||
throw new ArgumentNullException(nameof(propertyConfiguration.DateGroup));
|
||||
throw new NullReferenceException(nameof(propertyConfiguration.DateGroup));
|
||||
if (string.IsNullOrEmpty(propertyConfiguration.FileNameDirectorySeparator))
|
||||
throw new ArgumentNullException(nameof(propertyConfiguration.FileNameDirectorySeparator));
|
||||
throw new NullReferenceException(nameof(propertyConfiguration.FileNameDirectorySeparator));
|
||||
if (string.IsNullOrEmpty(propertyConfiguration.Pattern))
|
||||
throw new ArgumentNullException(nameof(propertyConfiguration.Pattern));
|
||||
throw new NullReferenceException(nameof(propertyConfiguration.Pattern));
|
||||
if (string.IsNullOrEmpty(propertyConfiguration.RootDirectory) || !Directory.Exists(propertyConfiguration.RootDirectory))
|
||||
throw new ArgumentNullException(nameof(propertyConfiguration.RootDirectory));
|
||||
throw new NullReferenceException(nameof(propertyConfiguration.RootDirectory));
|
||||
}
|
||||
|
||||
public void ChangeRootDirectory(string rootDirectory) => _RootDirectory = rootDirectory;
|
||||
|
34
Property/Models/Container.cs
Normal file
34
Property/Models/Container.cs
Normal file
@ -0,0 +1,34 @@
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace View_by_Distance.Property.Models;
|
||||
|
||||
public class Container
|
||||
{
|
||||
|
||||
protected readonly int _G;
|
||||
protected readonly int _R;
|
||||
protected readonly List<Item> _Items;
|
||||
protected readonly string _SourceDirectory;
|
||||
public int G => _G;
|
||||
public List<Item> Items => _Items;
|
||||
public int R => _R;
|
||||
public string SourceDirectory => _SourceDirectory;
|
||||
|
||||
[JsonConstructor]
|
||||
public Container(int g, int r, List<Item> items, string sourceDirectory)
|
||||
{
|
||||
_G = g;
|
||||
_R = r;
|
||||
_Items = items;
|
||||
_SourceDirectory = sourceDirectory;
|
||||
}
|
||||
|
||||
public Container(int g, int r, string sourceDirectory)
|
||||
{
|
||||
_G = g;
|
||||
_R = r;
|
||||
_Items = new();
|
||||
_SourceDirectory = sourceDirectory;
|
||||
}
|
||||
|
||||
}
|
@ -5,7 +5,7 @@ public class FileHolder
|
||||
protected readonly DateTime _CreationTime;
|
||||
protected readonly string? _DirectoryName;
|
||||
protected readonly bool _Exists;
|
||||
protected readonly string _Extension;
|
||||
protected readonly string _ExtensionLowered;
|
||||
protected readonly string _FullName;
|
||||
protected readonly DateTime _LastWriteTime;
|
||||
protected readonly long? _Length;
|
||||
@ -14,19 +14,19 @@ public class FileHolder
|
||||
public DateTime CreationTime => _CreationTime;
|
||||
public string? DirectoryName => _DirectoryName;
|
||||
public bool Exists => _Exists;
|
||||
public string Extension => _Extension;
|
||||
public string ExtensionLowered => _ExtensionLowered;
|
||||
public string FullName => _FullName;
|
||||
public DateTime LastWriteTime => _LastWriteTime;
|
||||
public long? Length => _Length;
|
||||
public string Name => _Name;
|
||||
public string NameWithoutExtension => _NameWithoutExtension;
|
||||
|
||||
public FileHolder(DateTime creationTime, string? directoryName, bool exists, string extension, string fullName, DateTime lastWriteTime, long? length, string name, string nameWithoutExtension)
|
||||
public FileHolder(DateTime creationTime, string? directoryName, bool exists, string extensionLowered, string fullName, DateTime lastWriteTime, long? length, string name, string nameWithoutExtension)
|
||||
{
|
||||
_CreationTime = creationTime;
|
||||
_DirectoryName = directoryName;
|
||||
_Exists = exists;
|
||||
_Extension = extension;
|
||||
_ExtensionLowered = extensionLowered;
|
||||
_FullName = fullName;
|
||||
_LastWriteTime = lastWriteTime;
|
||||
_Length = length;
|
||||
@ -41,7 +41,7 @@ public class FileHolder
|
||||
_CreationTime = fileInfo.CreationTime;
|
||||
_DirectoryName = fileInfo.DirectoryName;
|
||||
_Exists = fileInfo.Exists;
|
||||
_Extension = fileInfo.Extension;
|
||||
_ExtensionLowered = fileInfo.Extension.ToLower();
|
||||
_FullName = fileInfo.FullName;
|
||||
_LastWriteTime = fileInfo.LastWriteTime;
|
||||
if (fileInfo.Exists)
|
||||
@ -56,7 +56,7 @@ public class FileHolder
|
||||
_CreationTime = fileInfo.CreationTime;
|
||||
_DirectoryName = fileInfo.DirectoryName;
|
||||
_Exists = fileInfo.Exists;
|
||||
_Extension = fileInfo.Extension;
|
||||
_ExtensionLowered = fileInfo.Extension.ToLower();
|
||||
_FullName = fileInfo.FullName;
|
||||
_LastWriteTime = fileInfo.LastWriteTime;
|
||||
if (fileInfo.Exists)
|
||||
|
@ -4,86 +4,72 @@ using View_by_Distance.Shared.Models.Properties;
|
||||
|
||||
namespace View_by_Distance.Property.Models;
|
||||
|
||||
public class PropertyHolder
|
||||
public class Item
|
||||
{
|
||||
|
||||
protected readonly bool? _Abandoned;
|
||||
protected readonly bool? _Changed;
|
||||
protected List<Closest> _Closest;
|
||||
protected List<IFace> _Faces;
|
||||
protected readonly FileHolder? _ImageFileHolder;
|
||||
protected readonly string _ImageFileNameWithoutExtension;
|
||||
protected readonly int _G;
|
||||
protected DateTime? _MinimumDateTime;
|
||||
protected bool? _Moved;
|
||||
protected List<(bool?, DateTime, PersonBirthday, double?)> _Named;
|
||||
protected List<Named> _Named;
|
||||
protected readonly bool? _NoJson;
|
||||
protected A_Property? _Property;
|
||||
protected readonly int _R;
|
||||
protected readonly string _RelativePath;
|
||||
protected FileHolder? _ResizedFileHolder;
|
||||
protected readonly string _SourceDirectory;
|
||||
protected readonly string _SourceDirectoryFile;
|
||||
protected bool? _ValidImageFormatExtension;
|
||||
protected bool _ValidImageFormatExtension;
|
||||
public bool? Abandoned => _Abandoned;
|
||||
public bool? Changed => _Changed;
|
||||
public List<Closest> Closest => _Closest;
|
||||
public List<IFace> Faces => _Faces;
|
||||
public FileHolder? ImageFileHolder => _ImageFileHolder;
|
||||
public string ImageFileNameWithoutExtension => _ImageFileNameWithoutExtension;
|
||||
public int G => _G;
|
||||
public DateTime? MinimumDateTime => _MinimumDateTime;
|
||||
public bool? Moved => _Moved;
|
||||
public bool? NoJson => _NoJson;
|
||||
public List<(bool? isWrongYear, DateTime minimumDateTime, PersonBirthday personBirthday, double? pixelPercentage)> Named => _Named;
|
||||
public List<Named> Named => _Named;
|
||||
public A_Property? Property => _Property;
|
||||
public int R => _R;
|
||||
public string RelativePath => _RelativePath;
|
||||
public FileHolder? ResizedFileHolder => _ResizedFileHolder;
|
||||
public string SourceDirectory => _SourceDirectory;
|
||||
public string SourceDirectoryFile => _SourceDirectoryFile;
|
||||
public bool? ValidImageFormatExtension => _ValidImageFormatExtension;
|
||||
|
||||
public PropertyHolder()
|
||||
{
|
||||
_G = -1;
|
||||
_R = -1;
|
||||
_Faces = new();
|
||||
_Named = new();
|
||||
_RelativePath = string.Empty;
|
||||
_SourceDirectory = string.Empty;
|
||||
_SourceDirectoryFile = string.Empty;
|
||||
_ImageFileNameWithoutExtension = string.Empty;
|
||||
}
|
||||
public bool ValidImageFormatExtension => _ValidImageFormatExtension;
|
||||
|
||||
[JsonConstructor]
|
||||
public PropertyHolder(int g, string sourceDirectory, string sourceDirectoryFile, string relativePath, int r, FileHolder? imageFileInfo, A_Property? property, bool? abandoned, bool? changed, bool? moved, bool? validImageFormatExtension)
|
||||
public Item(bool? abandoned, bool? changed, List<Closest> closest, List<IFace> faces, FileHolder? imageFileHolder, bool? moved, List<Named> named, bool? noJson, A_Property? property, string relativePath, FileHolder? resizedFileHolder, string sourceDirectoryFile, bool validImageFormatExtension)
|
||||
{
|
||||
_G = g;
|
||||
_R = r;
|
||||
_Faces = new();
|
||||
_Moved = moved;
|
||||
_Named = new();
|
||||
_Abandoned = abandoned;
|
||||
_Changed = changed;
|
||||
_Closest = closest;
|
||||
_Faces = faces;
|
||||
_ImageFileHolder = imageFileHolder;
|
||||
_Moved = moved;
|
||||
_Named = named;
|
||||
_NoJson = noJson;
|
||||
_Property = property;
|
||||
_RelativePath = relativePath;
|
||||
_ResizedFileHolder = resizedFileHolder;
|
||||
_SourceDirectoryFile = sourceDirectoryFile;
|
||||
_ValidImageFormatExtension = validImageFormatExtension;
|
||||
}
|
||||
|
||||
public Item(string sourceDirectoryFile, string relativePath, FileHolder? imageFileInfo, bool isValidImageFormatExtension, A_Property? property, bool? abandoned, bool? changed)
|
||||
{
|
||||
_Faces = new();
|
||||
_Named = new();
|
||||
_Closest = new();
|
||||
_Changed = changed;
|
||||
_Abandoned = abandoned;
|
||||
_NoJson = abandoned is null;
|
||||
_RelativePath = relativePath;
|
||||
_ImageFileHolder = imageFileInfo;
|
||||
_SourceDirectory = sourceDirectory;
|
||||
_SourceDirectoryFile = sourceDirectoryFile;
|
||||
_ValidImageFormatExtension = validImageFormatExtension;
|
||||
_MinimumDateTime = Stateless.A_Property.GetMinimumDateTime(property);
|
||||
if (imageFileInfo is null)
|
||||
_ImageFileNameWithoutExtension = string.Empty;
|
||||
else
|
||||
_ImageFileNameWithoutExtension = Path.GetFileNameWithoutExtension(imageFileInfo.FullName);
|
||||
if (imageFileInfo is not null && imageFileInfo.Extension is ".json")
|
||||
_ValidImageFormatExtension = isValidImageFormatExtension;
|
||||
if (relativePath.EndsWith(".json"))
|
||||
throw new ArgumentException("Can not be a *.json file!");
|
||||
if (imageFileInfo is not null && imageFileInfo.ExtensionLowered is ".json")
|
||||
throw new ArgumentException("Can not be a *.json file!");
|
||||
if (!sourceDirectoryFile.EndsWith(".json") && !sourceDirectoryFile.EndsWith(".old"))
|
||||
throw new ArgumentException("Must be a *.json or *.old file!");
|
||||
}
|
||||
|
||||
internal void SetValidImageFormatExtension(bool isValidImageFormatExtension) => _ValidImageFormatExtension = isValidImageFormatExtension;
|
||||
|
||||
internal void SetMoved(bool moved) => _Moved = moved;
|
||||
|
||||
public static string GetWrongYearFlag(bool? isWrongYear) => isWrongYear is null ? "#" : isWrongYear.Value ? "~" : "=";
|
||||
@ -92,42 +78,39 @@ public class PropertyHolder
|
||||
|
||||
public bool Any() => (_Abandoned.HasValue && _Abandoned.Value) || (_Changed.HasValue && _Changed.Value) || (_Moved.HasValue && _Moved.Value) || (_NoJson.HasValue && _NoJson.Value);
|
||||
|
||||
public void Update(A_Property property)
|
||||
{
|
||||
_Property = property;
|
||||
_MinimumDateTime = Stateless.A_Property.GetMinimumDateTime(property);
|
||||
}
|
||||
public void Update(A_Property property) => _Property = property;
|
||||
|
||||
public (bool?, string[]) IsWrongYear()
|
||||
{
|
||||
(bool?, string[]) result;
|
||||
if (_Property is null || _ImageFileHolder is null)
|
||||
throw new ArgumentNullException();
|
||||
result = _Property.IsWrongYear(_ImageFileHolder.FullName, _MinimumDateTime);
|
||||
throw new NullReferenceException();
|
||||
DateTime? minimumDateTime = Stateless.A_Property.GetMinimumDateTime(_Property);
|
||||
result = _Property.IsWrongYear(_ImageFileHolder.FullName, minimumDateTime);
|
||||
return result;
|
||||
}
|
||||
|
||||
public static void AddToNamed(PropertyLogic propertyLogic, PropertyHolder[] filteredPropertyHolderCollection)
|
||||
public static void AddToNamed(PropertyLogic propertyLogic, Item[] filteredItems)
|
||||
{
|
||||
Item item;
|
||||
bool? isWrongYear;
|
||||
string[] segments;
|
||||
string[] personKeys;
|
||||
double? pixelPercentage;
|
||||
DateTime minimumDateTime;
|
||||
PropertyHolder propertyHolder;
|
||||
PersonBirthday? personBirthday;
|
||||
for (int i = 0; i < filteredPropertyHolderCollection.Length; i++)
|
||||
for (int i = 0; i < filteredItems.Length; i++)
|
||||
{
|
||||
propertyHolder = filteredPropertyHolderCollection[i];
|
||||
if (propertyHolder.ImageFileHolder is null)
|
||||
item = filteredItems[i];
|
||||
if (item.ImageFileHolder is null)
|
||||
continue;
|
||||
if (propertyHolder.Property?.Id is null || propertyHolder.MinimumDateTime is null || propertyHolder.ResizedFileHolder is null)
|
||||
if (item.Property?.Id is null || item.ResizedFileHolder is null)
|
||||
continue;
|
||||
if (!propertyLogic.NamedFaceInfoDeterministicHashCodeIndices.ContainsKey(propertyHolder.Property.Id.Value))
|
||||
if (!propertyLogic.NamedFaceInfoDeterministicHashCodeIndices.ContainsKey(item.Property.Id.Value))
|
||||
continue;
|
||||
minimumDateTime = Stateless.A_Property.GetMinimumDateTime(propertyHolder.Property);
|
||||
personKeys = propertyLogic.NamedFaceInfoDeterministicHashCodeIndices[propertyHolder.Property.Id.Value];
|
||||
(isWrongYear, _) = propertyHolder.Property.IsWrongYear(propertyHolder.ImageFileHolder.FullName, minimumDateTime);
|
||||
minimumDateTime = Stateless.A_Property.GetMinimumDateTime(item.Property);
|
||||
personKeys = propertyLogic.NamedFaceInfoDeterministicHashCodeIndices[item.Property.Id.Value];
|
||||
(isWrongYear, _) = item.Property.IsWrongYear(item.ImageFileHolder.FullName, minimumDateTime);
|
||||
for (int j = 0; j < personKeys.Length; j++)
|
||||
{
|
||||
segments = Shared.Models.Stateless.Methods.IPersonBirthday.GetSegments(personKeys[j]);
|
||||
@ -138,14 +121,15 @@ public class PropertyHolder
|
||||
pixelPercentage = null;
|
||||
else
|
||||
pixelPercentage = value;
|
||||
propertyHolder.Named.Add(new(isWrongYear, minimumDateTime, personBirthday, pixelPercentage));
|
||||
item.Named.Add(new(isWrongYear, minimumDateTime, personBirthday, pixelPercentage));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static List<(PropertyHolder, (string, IFace?, (string, string, string, string))[])> GetCollection(PropertyLogic propertyLogic, PropertyHolder[] filteredPropertyHolderCollection, string dFacesContentDirectory)
|
||||
public static List<(Item, (string, IFace?, (string, string, string, string))[])> GetCollection(PropertyLogic propertyLogic, Item[] filteredItems, string dFacesContentDirectory)
|
||||
{
|
||||
List<(PropertyHolder, (string, IFace?, (string, string, string, string))[])> results = new();
|
||||
List<(Item, (string, IFace?, (string, string, string, string))[])> results = new();
|
||||
Item item;
|
||||
string[] keys;
|
||||
string directory;
|
||||
string personKey;
|
||||
@ -160,37 +144,40 @@ public class PropertyHolder
|
||||
string shortcutFileName;
|
||||
string subDirectoryName;
|
||||
List<int> indices = new();
|
||||
DateTime? minimumDateTime;
|
||||
List<IFace> faceCollection;
|
||||
PropertyHolder propertyHolder;
|
||||
PersonBirthday? personBirthday;
|
||||
List<(string, IFace?, (string, string, string, string))> collection;
|
||||
for (int i = 0; i < filteredPropertyHolderCollection.Length; i++)
|
||||
for (int i = 0; i < filteredItems.Length; i++)
|
||||
{
|
||||
indices.Clear();
|
||||
personKey = string.Empty;
|
||||
copyFileName = string.Empty;
|
||||
copyDirectory = string.Empty;
|
||||
propertyHolder = filteredPropertyHolderCollection[i];
|
||||
if (propertyHolder.ImageFileHolder is null)
|
||||
item = filteredItems[i];
|
||||
if (item.ImageFileHolder is null)
|
||||
continue;
|
||||
relativePath = Path.GetDirectoryName($"C:{propertyHolder.RelativePath}");
|
||||
relativePath = Path.GetDirectoryName($"C:{item.RelativePath}");
|
||||
if (string.IsNullOrEmpty(relativePath) || relativePath.Length < 3)
|
||||
continue;
|
||||
if (propertyHolder.Property?.Id is null || propertyHolder.MinimumDateTime is null || propertyHolder.ResizedFileHolder is null)
|
||||
if (item.Property?.Id is null || item.ResizedFileHolder is null)
|
||||
continue;
|
||||
collection = new();
|
||||
if (!propertyLogic.NamedFaceInfoDeterministicHashCodeIndices.ContainsKey(propertyHolder.Property.Id.Value))
|
||||
if (!propertyLogic.NamedFaceInfoDeterministicHashCodeIndices.ContainsKey(item.Property.Id.Value))
|
||||
{
|
||||
faceCollection = new();
|
||||
directory = Path.Combine(dFacesContentDirectory, $"Unnamed{relativePath[2..]}");
|
||||
}
|
||||
else
|
||||
{
|
||||
faceCollection = propertyHolder.Faces;
|
||||
keys = propertyLogic.NamedFaceInfoDeterministicHashCodeIndices[propertyHolder.Property.Id.Value];
|
||||
(isWrongYear, _) = propertyHolder.Property.IsWrongYear(propertyHolder.ImageFileHolder.FullName, propertyHolder.MinimumDateTime.Value);
|
||||
faceCollection = item.Faces;
|
||||
keys = propertyLogic.NamedFaceInfoDeterministicHashCodeIndices[item.Property.Id.Value];
|
||||
minimumDateTime = Stateless.A_Property.GetMinimumDateTime(item.Property);
|
||||
if (minimumDateTime is null)
|
||||
continue;
|
||||
(isWrongYear, _) = item.Property.IsWrongYear(item.ImageFileHolder.FullName, minimumDateTime.Value);
|
||||
isWrongYearFlag = GetWrongYearFlag(isWrongYear);
|
||||
subDirectoryName = $"{isWrongYearFlag}{propertyHolder.MinimumDateTime.Value:yyyy}";
|
||||
subDirectoryName = $"{isWrongYearFlag}{minimumDateTime.Value:yyyy}";
|
||||
if (!faceCollection.Any())
|
||||
directory = Path.Combine(dFacesContentDirectory, $"None{relativePath[2..]}", subDirectoryName);
|
||||
else if (keys.Length != 1)
|
||||
@ -204,7 +191,7 @@ public class PropertyHolder
|
||||
personBirthday = Shared.Models.Stateless.Methods.IPersonBirthday.GetPersonBirthday(keys[zero]);
|
||||
if (personBirthday is null)
|
||||
continue;
|
||||
timeSpan = Shared.Models.Stateless.Methods.IPersonBirthday.GetTimeSpan(propertyHolder.MinimumDateTime.Value, isWrongYear, personBirthday);
|
||||
timeSpan = Shared.Models.Stateless.Methods.IPersonBirthday.GetTimeSpan(minimumDateTime.Value, isWrongYear, personBirthday);
|
||||
if (timeSpan.HasValue)
|
||||
{
|
||||
if (timeSpan.Value.Ticks < 0)
|
||||
@ -218,10 +205,10 @@ public class PropertyHolder
|
||||
copyDirectory = Path.Combine(dFacesContentDirectory, "Images", personKey, subDirectoryName);
|
||||
else
|
||||
copyDirectory = Path.Combine(dFacesContentDirectory, "ImagesBut", personKey, subDirectoryName);
|
||||
copyFileName = Path.Combine(copyDirectory, $"{propertyHolder.Property.Id.Value}{propertyHolder.ResizedFileHolder.Extension}");
|
||||
copyFileName = Path.Combine(copyDirectory, $"{item.Property.Id.Value}{item.ResizedFileHolder.ExtensionLowered}");
|
||||
}
|
||||
}
|
||||
shortcutFileName = Path.Combine(directory, $"{propertyHolder.Property.Id.Value}.lnk");
|
||||
shortcutFileName = Path.Combine(directory, $"{item.Property.Id.Value}.lnk");
|
||||
if (string.IsNullOrEmpty(personKey) || !indices.Any())
|
||||
collection.Add(new(personKey, null, (directory, copyDirectory, copyFileName, shortcutFileName)));
|
||||
else
|
||||
@ -229,56 +216,75 @@ public class PropertyHolder
|
||||
foreach (int index in indices)
|
||||
collection.Add(new(personKey, faceCollection[index], (directory, copyDirectory, copyFileName, shortcutFileName)));
|
||||
}
|
||||
results.Add(new(propertyHolder, collection.ToArray()));
|
||||
results.Add(new(item, collection.ToArray()));
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
public static Dictionary<string, List<(string[], PersonBirthday, IFace)>> GetKeyValuePairs(string argZero, List<PropertyHolder[]> propertyHolderCollections)
|
||||
public static string GetKey(DateTime minimumDateTime, bool? isWrongYear, PersonBirthday personBirthday)
|
||||
{
|
||||
Dictionary<string, List<(string[], PersonBirthday, IFace)>> results = new();
|
||||
string key;
|
||||
string personKey;
|
||||
TimeSpan? timeSpan;
|
||||
string[] directories;
|
||||
string isWrongYearFlag;
|
||||
const string facePopulatedKey = "Images";
|
||||
foreach (PropertyHolder[] propertyHolderCollection in propertyHolderCollections)
|
||||
string result;
|
||||
string personKey = Shared.Models.Stateless.Methods.IPersonBirthday.GetFormatted(personBirthday);
|
||||
TimeSpan? timeSpan = Shared.Models.Stateless.Methods.IPersonBirthday.GetTimeSpan(minimumDateTime, isWrongYear, personBirthday);
|
||||
if (timeSpan.HasValue && timeSpan.Value.Ticks < 0)
|
||||
result = string.Concat(personKey, "!---");
|
||||
else if (timeSpan.HasValue)
|
||||
result = string.Concat(personKey, $"^{Math.Floor(timeSpan.Value.TotalDays / 365):000}");
|
||||
else
|
||||
{
|
||||
if (!propertyHolderCollection.Any())
|
||||
string isWrongYearFlag = GetWrongYearFlag(isWrongYear);
|
||||
result = string.Concat(personKey, $"{isWrongYearFlag}{minimumDateTime:yyyy}");
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public static string GetDirectory(string directory, string subDirectory, DateTime minimumDateTime, bool? isWrongYear, PersonBirthday personBirthday, string personKey)
|
||||
{
|
||||
string result;
|
||||
TimeSpan? timeSpan = Shared.Models.Stateless.Methods.IPersonBirthday.GetTimeSpan(minimumDateTime, isWrongYear, personBirthday);
|
||||
if (timeSpan.HasValue && timeSpan.Value.Ticks < 0)
|
||||
result = Path.Combine(directory, subDirectory, personKey, "!---");
|
||||
else if (timeSpan.HasValue)
|
||||
result = Path.Combine(directory, subDirectory, personKey, $"^{Math.Floor(timeSpan.Value.TotalDays / 365):000}");
|
||||
else
|
||||
{
|
||||
string isWrongYearFlag = GetWrongYearFlag(isWrongYear);
|
||||
result = Path.Combine(directory, subDirectory, personKey, $"{isWrongYearFlag}{minimumDateTime:yyyy}");
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public static Dictionary<string, List<(DateTime, bool?, PersonBirthday, IFace)>> GetKeyValuePairs(string argZero, List<Container> containers)
|
||||
{
|
||||
Dictionary<string, List<(DateTime, bool?, PersonBirthday, IFace)>> results = new();
|
||||
string key;
|
||||
foreach (Container container in containers)
|
||||
{
|
||||
if (!container.Items.Any())
|
||||
continue;
|
||||
if (!propertyHolderCollection[0].SourceDirectory.StartsWith(argZero))
|
||||
if (!container.SourceDirectory.StartsWith(argZero))
|
||||
continue;
|
||||
foreach (PropertyHolder propertyHolder in propertyHolderCollection)
|
||||
foreach (Item item in container.Items)
|
||||
{
|
||||
if (propertyHolder.ImageFileHolder is null || propertyHolder.Property is null || !propertyHolder.Named.Any())
|
||||
if (item.ImageFileHolder is null || item.Property is null || !item.Named.Any())
|
||||
continue;
|
||||
foreach ((bool? isWrongYear, DateTime minimumDateTime, PersonBirthday personBirthday, double? pixelPercentage) in propertyHolder.Named)
|
||||
foreach (Named named in item.Named)
|
||||
{
|
||||
if (pixelPercentage is null && (propertyHolder.Named.Count != 1 || propertyHolder.Faces.Count != 1))
|
||||
if (named.PixelPercentage is null && (item.Named.Count != 1 || item.Faces.Count != 1))
|
||||
continue;
|
||||
foreach (IFace face in propertyHolder.Faces)
|
||||
foreach (IFace face in item.Faces)
|
||||
{
|
||||
if (!face.Populated)
|
||||
continue;
|
||||
if (pixelPercentage.HasValue && pixelPercentage.Value != face.Location.PixelPercentage)
|
||||
if (named.PersonBirthday is null)
|
||||
continue;
|
||||
personKey = Shared.Models.Stateless.Methods.IPersonBirthday.GetFormatted(personBirthday);
|
||||
timeSpan = Shared.Models.Stateless.Methods.IPersonBirthday.GetTimeSpan(minimumDateTime, isWrongYear, personBirthday);
|
||||
if (timeSpan.HasValue && timeSpan.Value.Ticks < 0)
|
||||
directories = new string[] { string.Empty, facePopulatedKey, personKey, "!---" };
|
||||
else if (timeSpan.HasValue)
|
||||
directories = new string[] { string.Empty, facePopulatedKey, personKey, $"^{Math.Floor(timeSpan.Value.TotalDays / 365):000}" };
|
||||
else
|
||||
{
|
||||
isWrongYearFlag = GetWrongYearFlag(isWrongYear);
|
||||
directories = new string[] { string.Empty, facePopulatedKey, personKey, $"{isWrongYearFlag}{minimumDateTime:yyyy}" };
|
||||
}
|
||||
key = string.Join('\t', directories);
|
||||
if (named.PixelPercentage.HasValue && named.PixelPercentage.Value != face.Location.PixelPercentage)
|
||||
continue;
|
||||
key = GetKey(named.MinimumDateTime, named.IsWrongYear, named.PersonBirthday);
|
||||
if (!results.ContainsKey(key))
|
||||
results.Add(key, new());
|
||||
results[key].Add(new(directories, personBirthday, face));
|
||||
if (pixelPercentage is null)
|
||||
results[key].Add(new(named.MinimumDateTime, named.IsWrongYear, named.PersonBirthday, face));
|
||||
if (named.PixelPercentage is null)
|
||||
break;
|
||||
}
|
||||
}
|
27
Property/Models/Named.cs
Normal file
27
Property/Models/Named.cs
Normal file
@ -0,0 +1,27 @@
|
||||
using System.Text.Json.Serialization;
|
||||
using View_by_Distance.Shared.Models;
|
||||
|
||||
namespace View_by_Distance.Property.Models;
|
||||
|
||||
public class Named
|
||||
{
|
||||
|
||||
protected readonly bool? _IsWrongYear;
|
||||
protected readonly DateTime _MinimumDateTime;
|
||||
protected readonly PersonBirthday? _PersonBirthday;
|
||||
protected readonly double? _PixelPercentage;
|
||||
public bool? IsWrongYear => _IsWrongYear;
|
||||
public DateTime MinimumDateTime => _MinimumDateTime;
|
||||
public PersonBirthday? PersonBirthday => _PersonBirthday;
|
||||
public double? PixelPercentage => _PixelPercentage;
|
||||
|
||||
[JsonConstructor]
|
||||
public Named(bool? isWrongYear, DateTime minimumDateTime, PersonBirthday? personBirthday, double? pixelPercentage)
|
||||
{
|
||||
_IsWrongYear = isWrongYear;
|
||||
_MinimumDateTime = minimumDateTime;
|
||||
_PersonBirthday = personBirthday;
|
||||
_PixelPercentage = pixelPercentage;
|
||||
}
|
||||
|
||||
}
|
@ -21,24 +21,30 @@ public class PropertyLogic
|
||||
protected readonly Dictionary<int, string[]> _SixCharacterNamedFaceInfo;
|
||||
protected readonly Dictionary<int, string[]> _NamedFaceInfoDeterministicHashCodeIndices;
|
||||
|
||||
public bool Reverse { get; }
|
||||
public List<string> AngleBracketCollection { get; }
|
||||
public Dictionary<int, int[]> KeyValuePairs => _KeyValuePairs;
|
||||
public Dictionary<int, int[]> IndicesFromNew => _IndicesFromNew;
|
||||
public List<string> ExceptionsDirectories => _ExceptionsDirectories;
|
||||
public Dictionary<int, string[]> NamedFaceInfoDeterministicHashCodeIndices => _NamedFaceInfoDeterministicHashCodeIndices;
|
||||
|
||||
private readonly Model? _Model;
|
||||
private readonly Serilog.ILogger? _Log;
|
||||
private readonly string[] _VerifyToSeason;
|
||||
private readonly int _MaxDegreeOfParallelism;
|
||||
private readonly ASCIIEncoding _ASCIIEncoding;
|
||||
private readonly Configuration _Configuration;
|
||||
private readonly PredictorModel? _PredictorModel;
|
||||
private readonly JsonSerializerOptions _WriteIndentedJsonSerializerOptions;
|
||||
|
||||
public PropertyLogic(int maxDegreeOfParallelism, Configuration configuration)
|
||||
public PropertyLogic(int maxDegreeOfParallelism, Configuration configuration, bool reverse, Model? model, PredictorModel? predictorModel)
|
||||
{
|
||||
_Model = model;
|
||||
Reverse = reverse;
|
||||
_AllCollection = new();
|
||||
_Configuration = configuration;
|
||||
_ExceptionsDirectories = new();
|
||||
_PredictorModel = predictorModel;
|
||||
_ASCIIEncoding = new ASCIIEncoding();
|
||||
AngleBracketCollection = new List<string>();
|
||||
_Log = Serilog.Log.ForContext<A_Property>();
|
||||
@ -57,7 +63,7 @@ public class PropertyLogic
|
||||
Dictionary<int, string[]>? sixCharacterNamedFaceInfo;
|
||||
string? rootDirectoryParent = Path.GetDirectoryName(configuration.RootDirectory);
|
||||
if (string.IsNullOrEmpty(rootDirectoryParent))
|
||||
throw new ArgumentNullException(nameof(rootDirectoryParent));
|
||||
throw new NullReferenceException(nameof(rootDirectoryParent));
|
||||
files = Directory.GetFiles(rootDirectoryParent, "*DeterministicHashCode*.json", SearchOption.TopDirectoryOnly);
|
||||
if (files.Length != 1)
|
||||
namedFaceInfoDeterministicHashCodeIndices = new();
|
||||
@ -66,7 +72,7 @@ public class PropertyLogic
|
||||
json = File.ReadAllText(files[0]);
|
||||
namedFaceInfoDeterministicHashCodeIndices = JsonSerializer.Deserialize<Dictionary<int, string[]>>(json);
|
||||
if (namedFaceInfoDeterministicHashCodeIndices is null)
|
||||
throw new ArgumentNullException(nameof(namedFaceInfoDeterministicHashCodeIndices));
|
||||
throw new NullReferenceException(nameof(namedFaceInfoDeterministicHashCodeIndices));
|
||||
}
|
||||
if (namedFaceInfoDeterministicHashCodeIndices.Any())
|
||||
sixCharacterNamedFaceInfo = new();
|
||||
@ -80,7 +86,7 @@ public class PropertyLogic
|
||||
json = File.ReadAllText(files[0]);
|
||||
sixCharacterNamedFaceInfo = JsonSerializer.Deserialize<Dictionary<int, string[]>>(json);
|
||||
if (sixCharacterNamedFaceInfo is null)
|
||||
throw new ArgumentNullException(nameof(sixCharacterNamedFaceInfo));
|
||||
throw new NullReferenceException(nameof(sixCharacterNamedFaceInfo));
|
||||
}
|
||||
}
|
||||
files = Directory.GetFiles(rootDirectoryParent, "*keyValuePairs*.json", SearchOption.TopDirectoryOnly);
|
||||
@ -91,7 +97,7 @@ public class PropertyLogic
|
||||
json = File.ReadAllText(files[0]);
|
||||
keyValuePairs = JsonSerializer.Deserialize<Dictionary<int, int[]>>(json);
|
||||
if (keyValuePairs is null)
|
||||
throw new ArgumentNullException(nameof(keyValuePairs));
|
||||
throw new NullReferenceException(nameof(keyValuePairs));
|
||||
}
|
||||
foreach (string propertyContentCollectionFile in configuration.PropertyContentCollectionFiles)
|
||||
{
|
||||
@ -103,7 +109,7 @@ public class PropertyLogic
|
||||
json = File.ReadAllText(fullPath);
|
||||
collection = JsonSerializer.Deserialize<List<KeyValuePair<int, int[]>>>(json);
|
||||
if (collection is null)
|
||||
throw new ArgumentNullException(nameof(collection));
|
||||
throw new NullReferenceException(nameof(collection));
|
||||
foreach (KeyValuePair<int, int[]> keyValuePair in collection)
|
||||
{
|
||||
if (indicesFromNew.ContainsKey(keyValuePair.Key))
|
||||
@ -127,7 +133,7 @@ public class PropertyLogic
|
||||
{
|
||||
long result;
|
||||
if (_Log is null)
|
||||
throw new ArgumentNullException(nameof(_Log));
|
||||
throw new NullReferenceException(nameof(_Log));
|
||||
double delta = new TimeSpan(DateTime.Now.Ticks - ticks).TotalMilliseconds;
|
||||
_Log.Debug($"{methodName} took {Math.Floor(delta)} millisecond(s)");
|
||||
result = DateTime.Now.Ticks;
|
||||
@ -168,13 +174,13 @@ public class PropertyLogic
|
||||
|
||||
#pragma warning disable CA1416
|
||||
|
||||
private A_Property GetImageProperty(string angleBracket, FileHolder filteredSourceDirectoryFileHolder, bool populateId, bool isIgnoreExtension, bool isValidImageFormatExtension, bool isValidMetadataExtensions, int? id, List<int> indices)
|
||||
private A_Property GetImageProperty(FileHolder filteredSourceDirectoryFileHolder, bool populateId, bool isIgnoreExtension, bool isValidImageFormatExtension, bool isValidMetadataExtensions, int? id, List<int> indices)
|
||||
{
|
||||
A_Property result;
|
||||
if (_Log is null)
|
||||
throw new ArgumentNullException(nameof(_Log));
|
||||
throw new NullReferenceException(nameof(_Log));
|
||||
if (_Configuration.WriteBitmapDataBytes is null)
|
||||
throw new ArgumentNullException(nameof(_Configuration.WriteBitmapDataBytes));
|
||||
throw new NullReferenceException(nameof(_Configuration.WriteBitmapDataBytes));
|
||||
long ticks;
|
||||
byte[] bytes;
|
||||
string value;
|
||||
@ -201,7 +207,7 @@ public class PropertyLogic
|
||||
}
|
||||
else if (!isIgnoreExtension && isValidImageFormatExtension)
|
||||
{
|
||||
if (!_IndicesFromNew.Any() && !_KeyValuePairs.Any())
|
||||
if (populateId && (id is null || !indices.Any()) && !_IndicesFromNew.Any() && !_KeyValuePairs.Any())
|
||||
throw new Exception("In order to keep six character indices at least one need to have an item!");
|
||||
try
|
||||
{
|
||||
@ -209,6 +215,7 @@ public class PropertyLogic
|
||||
if (populateId && (id is null || !indices.Any()))
|
||||
{
|
||||
using Bitmap bitmap = new(image);
|
||||
string angleBracket = AngleBracketCollection[0];
|
||||
Rectangle rectangle = new(0, 0, image.Width, image.Height);
|
||||
BitmapData bitmapData = bitmap.LockBits(rectangle, ImageLockMode.ReadOnly, bitmap.PixelFormat);
|
||||
IntPtr intPtr = bitmapData.Scan0;
|
||||
@ -341,24 +348,27 @@ public class PropertyLogic
|
||||
|
||||
#pragma warning restore CA1416
|
||||
|
||||
private A_Property GetPropertyOfPrivate(string angleBracket, PropertyHolder propertyHolder, bool firstPass, List<Tuple<string, DateTime>> filteredSourceDirectoryFileTuples, List<string> parseExceptions, bool isIgnoreExtension, bool isValidImageFormatExtension, bool isValidMetadataExtensions, string extensionLowered)
|
||||
private A_Property GetPropertyOfPrivate(Item item, bool firstPass, List<Tuple<string, DateTime>> filteredSourceDirectoryFileTuples, List<string> parseExceptions, bool isIgnoreExtension, bool isValidMetadataExtensions)
|
||||
{
|
||||
A_Property? result;
|
||||
if (_Configuration.ForcePropertyLastWriteTimeToCreationTime is null)
|
||||
throw new ArgumentNullException(nameof(_Configuration.ForcePropertyLastWriteTimeToCreationTime));
|
||||
throw new NullReferenceException(nameof(_Configuration.ForcePropertyLastWriteTimeToCreationTime));
|
||||
if (_Configuration.PopulatePropertyId is null)
|
||||
throw new ArgumentNullException(nameof(_Configuration.PopulatePropertyId));
|
||||
throw new NullReferenceException(nameof(_Configuration.PopulatePropertyId));
|
||||
if (_Configuration.PropertiesChangedForProperty is null)
|
||||
throw new ArgumentNullException(nameof(_Configuration.PropertiesChangedForProperty));
|
||||
throw new NullReferenceException(nameof(_Configuration.PropertiesChangedForProperty));
|
||||
if (item.ImageFileHolder is null)
|
||||
throw new NullReferenceException(nameof(item.ImageFileHolder));
|
||||
string json;
|
||||
int? id = null;
|
||||
List<int> indices = new();
|
||||
bool hasWrongYearProperty = false;
|
||||
string[] changesFrom = Array.Empty<string>();
|
||||
string angleBracket = AngleBracketCollection[0];
|
||||
bool populateId = !firstPass && _Configuration.PopulatePropertyId.Value;
|
||||
string without = Path.Combine(angleBracket.Replace("<>", "{}"), $"{propertyHolder.ImageFileNameWithoutExtension}.json");
|
||||
FileInfo fileInfo = new(Path.Combine(angleBracket.Replace("<>", "{}"), $"{propertyHolder.ImageFileNameWithoutExtension}{extensionLowered}.json"));
|
||||
if (isValidImageFormatExtension && File.Exists(without))
|
||||
string without = Path.Combine(angleBracket.Replace("<>", "{}"), $"{item.ImageFileHolder.NameWithoutExtension}.json");
|
||||
FileInfo fileInfo = new(Path.Combine(angleBracket.Replace("<>", "{}"), $"{item.ImageFileHolder.NameWithoutExtension}{item.ImageFileHolder.ExtensionLowered}.json"));
|
||||
if (item.ValidImageFormatExtension && File.Exists(without))
|
||||
{
|
||||
File.Move(without, fileInfo.FullName);
|
||||
fileInfo.Refresh();
|
||||
@ -398,40 +408,40 @@ public class PropertyLogic
|
||||
json = File.ReadAllText(fileInfo.FullName);
|
||||
try
|
||||
{
|
||||
if (propertyHolder.ImageFileHolder is null)
|
||||
throw new ArgumentException($"{propertyHolder.ImageFileHolder} is null!");
|
||||
if (item.ImageFileHolder is null)
|
||||
throw new NullReferenceException(nameof(item.ImageFileHolder));
|
||||
bool check = true;
|
||||
A_Property? property = JsonSerializer.Deserialize<A_Property>(json);
|
||||
if (!isIgnoreExtension && isValidImageFormatExtension && ((populateId && property?.Id is null) || property?.Width is null || property?.Height is null))
|
||||
if (!isIgnoreExtension && item.ValidImageFormatExtension && ((populateId && property?.Id is null) || property?.Width is null || property?.Height is null))
|
||||
{
|
||||
check = false;
|
||||
id = property?.Id;
|
||||
if (property is not null && property.Indices.Any())
|
||||
indices = property.Indices.ToList();
|
||||
property = GetImageProperty(angleBracket, propertyHolder.ImageFileHolder, populateId, isIgnoreExtension, isValidImageFormatExtension, isValidMetadataExtensions, id, indices);
|
||||
property = GetImageProperty(item.ImageFileHolder, populateId, isIgnoreExtension, item.ValidImageFormatExtension, isValidMetadataExtensions, id, indices);
|
||||
}
|
||||
if (!isIgnoreExtension && isValidImageFormatExtension && populateId && property is not null && !property.Indices.Any())
|
||||
if (!isIgnoreExtension && item.ValidImageFormatExtension && populateId && property is not null && !property.Indices.Any())
|
||||
{
|
||||
check = false;
|
||||
id = property?.Id;
|
||||
if (property is not null && property.Indices.Any())
|
||||
indices = property.Indices.ToList();
|
||||
property = GetImageProperty(angleBracket, propertyHolder.ImageFileHolder, populateId, isIgnoreExtension, isValidImageFormatExtension, isValidMetadataExtensions, id, indices);
|
||||
property = GetImageProperty(item.ImageFileHolder, populateId, isIgnoreExtension, item.ValidImageFormatExtension, isValidMetadataExtensions, id, indices);
|
||||
}
|
||||
if (!isIgnoreExtension && isValidImageFormatExtension && populateId && property is not null && property.LastWriteTime != propertyHolder.ImageFileHolder.LastWriteTime)
|
||||
if (!isIgnoreExtension && item.ValidImageFormatExtension && populateId && property is not null && property.LastWriteTime != item.ImageFileHolder.LastWriteTime)
|
||||
{
|
||||
check = false;
|
||||
id = null;
|
||||
indices.Clear();
|
||||
property = GetImageProperty(angleBracket, propertyHolder.ImageFileHolder, populateId, isIgnoreExtension, isValidImageFormatExtension, isValidMetadataExtensions, id, indices);
|
||||
property = GetImageProperty(item.ImageFileHolder, populateId, isIgnoreExtension, item.ValidImageFormatExtension, isValidMetadataExtensions, id, indices);
|
||||
}
|
||||
if (!isIgnoreExtension && isValidImageFormatExtension && property?.Width is not null && property?.Height is not null && property.Width.Value == property.Height.Value && propertyHolder.ImageFileHolder.Exists)
|
||||
if (!isIgnoreExtension && item.ValidImageFormatExtension && property?.Width is not null && property?.Height is not null && property.Width.Value == property.Height.Value && item.ImageFileHolder.Exists)
|
||||
{
|
||||
check = false;
|
||||
id = property?.Id;
|
||||
if (property is not null && property.Indices.Any())
|
||||
indices = property.Indices.ToList();
|
||||
property = GetImageProperty(angleBracket, propertyHolder.ImageFileHolder, populateId, isIgnoreExtension, isValidImageFormatExtension, isValidMetadataExtensions, id, indices);
|
||||
property = GetImageProperty(item.ImageFileHolder, populateId, isIgnoreExtension, item.ValidImageFormatExtension, isValidMetadataExtensions, id, indices);
|
||||
if (property?.Width is not null && property?.Height is not null && property.Width.Value != property.Height.Value)
|
||||
throw new Exception("Was square!");
|
||||
}
|
||||
@ -440,7 +450,7 @@ public class PropertyLogic
|
||||
// check = false;
|
||||
// id = null;
|
||||
// indices.Clear();
|
||||
// property = GetImagePropertyB(angleBracket, filteredSourceDirectoryFile, populateId, isIgnoreExtension, isValidImageFormatExtension, isValidMetadataExtensions, id, indices);
|
||||
// property = GetImagePropertyB(filteredSourceDirectoryFile, populateId, isIgnoreExtension, isValidImageFormatExtension, isValidMetadataExtensions, id, indices);
|
||||
// }
|
||||
if (json.Contains("WrongYear"))
|
||||
{
|
||||
@ -465,9 +475,9 @@ public class PropertyLogic
|
||||
}
|
||||
if (result is null)
|
||||
{
|
||||
if (propertyHolder.ImageFileHolder is null)
|
||||
throw new ArgumentException($"{propertyHolder.ImageFileHolder} is null!");
|
||||
result = GetImageProperty(angleBracket, propertyHolder.ImageFileHolder, populateId, isIgnoreExtension, isValidImageFormatExtension, isValidMetadataExtensions, id, indices);
|
||||
if (item.ImageFileHolder is null)
|
||||
throw new NullReferenceException(nameof(item.ImageFileHolder));
|
||||
result = GetImageProperty(item.ImageFileHolder, populateId, isIgnoreExtension, item.ValidImageFormatExtension, isValidMetadataExtensions, id, indices);
|
||||
json = JsonSerializer.Serialize(result, _WriteIndentedJsonSerializerOptions);
|
||||
if (populateId && IPath.WriteAllText(fileInfo.FullName, json, updateDateWhenMatches: true, compareBeforeWrite: true))
|
||||
{
|
||||
@ -494,11 +504,11 @@ public class PropertyLogic
|
||||
return result;
|
||||
}
|
||||
|
||||
private bool AnyFilesMoved(string sourceDirectory, PropertyHolder[] filteredPropertyHolderCollection)
|
||||
private bool AnyFilesMoved(string sourceDirectory, Item[] filteredItems)
|
||||
{
|
||||
bool result = false;
|
||||
if (_Log is null)
|
||||
throw new ArgumentNullException(nameof(_Log));
|
||||
throw new NullReferenceException(nameof(_Log));
|
||||
int season;
|
||||
string[] matches;
|
||||
string deleteFile;
|
||||
@ -510,20 +520,16 @@ public class PropertyLogic
|
||||
string destinationDirectory;
|
||||
string[] sourceDirectorySegments;
|
||||
DateTime directoryMaximumOfMinimumDateTime = DateTime.MinValue;
|
||||
foreach (PropertyHolder propertyHolder in filteredPropertyHolderCollection)
|
||||
foreach (Item filteredItem in filteredItems)
|
||||
{
|
||||
if (propertyHolder.ValidImageFormatExtension is null || !propertyHolder.ValidImageFormatExtension.Value)
|
||||
if (!filteredItem.ValidImageFormatExtension || filteredItem.Property is null || filteredItem.ImageFileHolder is null)
|
||||
continue;
|
||||
if (propertyHolder.Property is null)
|
||||
continue;
|
||||
if (propertyHolder.ImageFileHolder is null)
|
||||
continue;
|
||||
minimumDateTime = Stateless.A_Property.GetMinimumDateTime(propertyHolder.Property);
|
||||
minimumDateTime = Stateless.A_Property.GetMinimumDateTime(filteredItem.Property);
|
||||
if (minimumDateTime > directoryMaximumOfMinimumDateTime)
|
||||
directoryMaximumOfMinimumDateTime = minimumDateTime;
|
||||
if (minimumDateTime != propertyHolder.ImageFileHolder.CreationTime)
|
||||
if (minimumDateTime != filteredItem.ImageFileHolder.CreationTime)
|
||||
{
|
||||
(isWrongYear, matches) = propertyHolder.Property.IsWrongYear(propertyHolder.ImageFileHolder.FullName, minimumDateTime);
|
||||
(isWrongYear, matches) = filteredItem.Property.IsWrongYear(filteredItem.ImageFileHolder.FullName, minimumDateTime);
|
||||
if (isWrongYear is null || !isWrongYear.Value)
|
||||
dateTime = minimumDateTime;
|
||||
else
|
||||
@ -534,20 +540,20 @@ public class PropertyLogic
|
||||
continue;
|
||||
}
|
||||
try
|
||||
{ File.SetCreationTime(propertyHolder.ImageFileHolder.FullName, dateTime); }
|
||||
{ File.SetCreationTime(filteredItem.ImageFileHolder.FullName, dateTime); }
|
||||
catch (Exception)
|
||||
{ }
|
||||
}
|
||||
if (!_VerifyToSeason.Contains(sourceDirectory))
|
||||
continue;
|
||||
if (!propertyHolder.ImageFileHolder.FullName.Contains("zzz ") && !propertyHolder.ImageFileHolder.FullName.Contains("Camera ") && propertyHolder.Property.DateTimeOriginal.HasValue)
|
||||
if (!filteredItem.ImageFileHolder.FullName.Contains("zzz ") && !filteredItem.ImageFileHolder.FullName.Contains("Camera ") && filteredItem.Property.DateTimeOriginal.HasValue)
|
||||
{
|
||||
TimeSpan timeSpan = new(propertyHolder.Property.DateTimeOriginal.Value.Ticks - propertyHolder.Property.LastWriteTime.Ticks);
|
||||
TimeSpan timeSpan = new(filteredItem.Property.DateTimeOriginal.Value.Ticks - filteredItem.Property.LastWriteTime.Ticks);
|
||||
if (timeSpan.TotalHours > 6)
|
||||
{
|
||||
_Log.Warning($"*** propertyHolder.FileInfo.FullName <{propertyHolder.ImageFileHolder.FullName}>");
|
||||
_Log.Warning($"*** DateTimeOriginal <{propertyHolder.Property.DateTimeOriginal.Value}>");
|
||||
_Log.Warning($"*** LastWriteTime <{propertyHolder.Property.LastWriteTime}>");
|
||||
_Log.Warning($"*** propertyHolder.FileInfo.FullName <{filteredItem.ImageFileHolder.FullName}>");
|
||||
_Log.Warning($"*** DateTimeOriginal <{filteredItem.Property.DateTimeOriginal.Value}>");
|
||||
_Log.Warning($"*** LastWriteTime <{filteredItem.Property.LastWriteTime}>");
|
||||
_Log.Warning($"*** TotalHours <{timeSpan.TotalHours}>");
|
||||
}
|
||||
}
|
||||
@ -561,41 +567,41 @@ public class PropertyLogic
|
||||
destinationDirectory = Path.Combine(_Configuration.RootDirectory, $"={minimumDateTime:yyyy}.{season} {seasonName}");
|
||||
if (destinationDirectory == sourceDirectory)
|
||||
continue;
|
||||
lock (propertyHolder)
|
||||
propertyHolder.SetMoved(true);
|
||||
lock (filteredItem)
|
||||
filteredItem.SetMoved(true);
|
||||
if (!result)
|
||||
result = true;
|
||||
if (!Directory.Exists(destinationDirectory))
|
||||
_ = Directory.CreateDirectory(destinationDirectory);
|
||||
destinationFile = Path.Combine(destinationDirectory, propertyHolder.ImageFileHolder.Name);
|
||||
destinationFile = Path.Combine(destinationDirectory, filteredItem.ImageFileHolder.Name);
|
||||
if (File.Exists(destinationFile))
|
||||
{
|
||||
if (destinationFile.EndsWith(".jpg", ignoreCase: true, CultureInfo.CurrentCulture))
|
||||
destinationFile = Path.Combine(destinationDirectory, Path.ChangeExtension(propertyHolder.ImageFileHolder.Name, ".jpeg"));
|
||||
destinationFile = Path.Combine(destinationDirectory, Path.ChangeExtension(filteredItem.ImageFileHolder.Name, ".jpeg"));
|
||||
else if (destinationFile.EndsWith(".jpeg", ignoreCase: true, CultureInfo.CurrentCulture))
|
||||
destinationFile = Path.Combine(destinationDirectory, Path.ChangeExtension(propertyHolder.ImageFileHolder.Name, ".jpg"));
|
||||
destinationFile = Path.Combine(destinationDirectory, Path.ChangeExtension(filteredItem.ImageFileHolder.Name, ".jpg"));
|
||||
}
|
||||
if (File.Exists(destinationFile))
|
||||
{
|
||||
_Log.Information($"*** source <{propertyHolder.ImageFileHolder.FullName}>");
|
||||
_Log.Information($"*** source <{filteredItem.ImageFileHolder.FullName}>");
|
||||
_Log.Information($"*** destination <{destinationFile}>");
|
||||
if (propertyHolder.ImageFileHolder.Exists)
|
||||
if (filteredItem.ImageFileHolder.Exists)
|
||||
{
|
||||
deleteFile = Path.ChangeExtension(propertyHolder.ImageFileHolder.FullName, ".delete");
|
||||
deleteFile = Path.ChangeExtension(filteredItem.ImageFileHolder.FullName, ".delete");
|
||||
if (File.Exists(deleteFile))
|
||||
File.Delete(deleteFile);
|
||||
File.Move(propertyHolder.ImageFileHolder.FullName, deleteFile);
|
||||
File.Move(filteredItem.ImageFileHolder.FullName, deleteFile);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
File.Move(propertyHolder.ImageFileHolder.FullName, destinationFile);
|
||||
if (propertyHolder.ImageFileHolder.Exists)
|
||||
File.Move(filteredItem.ImageFileHolder.FullName, destinationFile);
|
||||
if (filteredItem.ImageFileHolder.Exists)
|
||||
{
|
||||
deleteFile = Path.ChangeExtension(propertyHolder.ImageFileHolder.FullName, ".delete");
|
||||
deleteFile = Path.ChangeExtension(filteredItem.ImageFileHolder.FullName, ".delete");
|
||||
if (File.Exists(deleteFile))
|
||||
File.Delete(deleteFile);
|
||||
File.Move(propertyHolder.ImageFileHolder.FullName, deleteFile);
|
||||
File.Move(filteredItem.ImageFileHolder.FullName, deleteFile);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -608,46 +614,42 @@ public class PropertyLogic
|
||||
return result;
|
||||
}
|
||||
|
||||
private void ParallelForWork(bool firstPass, string angleBracket, string sourceDirectory, List<Tuple<string, DateTime>> filteredSourceDirectoryFileTuples, List<Tuple<string, DateTime>> sourceDirectoryChanges, PropertyHolder propertyHolder)
|
||||
private void ParallelForWork(bool firstPass, string sourceDirectory, List<Tuple<string, DateTime>> filteredSourceDirectoryFileTuples, List<Tuple<string, DateTime>> sourceDirectoryChanges, Item item)
|
||||
{
|
||||
if (propertyHolder.ImageFileHolder is null)
|
||||
throw new ArgumentNullException(nameof(propertyHolder.ImageFileHolder));
|
||||
if (item.ImageFileHolder is null)
|
||||
throw new NullReferenceException(nameof(item.ImageFileHolder));
|
||||
A_Property property;
|
||||
List<string> parseExceptions = new();
|
||||
string extensionLowered = propertyHolder.ImageFileHolder.Extension.ToLower();
|
||||
bool isValidMetadataExtensions = _Configuration.ValidMetadataExtensions.Contains(extensionLowered);
|
||||
bool isValidImageFormatExtension = _Configuration.ValidImageFormatExtensions.Contains(extensionLowered);
|
||||
lock (propertyHolder)
|
||||
propertyHolder.SetValidImageFormatExtension(isValidImageFormatExtension);
|
||||
bool isIgnoreExtension = isValidImageFormatExtension && _Configuration.IgnoreExtensions.Contains(extensionLowered);
|
||||
string filteredSourceDirectoryFileExtensionLowered = Path.Combine(sourceDirectory, $"{propertyHolder.ImageFileNameWithoutExtension}{extensionLowered}");
|
||||
if (isValidImageFormatExtension && propertyHolder.ImageFileHolder.FullName.Length == filteredSourceDirectoryFileExtensionLowered.Length && propertyHolder.ImageFileHolder.FullName != filteredSourceDirectoryFileExtensionLowered)
|
||||
File.Move(propertyHolder.ImageFileHolder.FullName, filteredSourceDirectoryFileExtensionLowered);
|
||||
if (propertyHolder.Changed is null || propertyHolder.Changed.Value || propertyHolder.Property is null)
|
||||
bool isValidMetadataExtensions = _Configuration.ValidMetadataExtensions.Contains(item.ImageFileHolder.ExtensionLowered);
|
||||
bool isIgnoreExtension = item.ValidImageFormatExtension && _Configuration.IgnoreExtensions.Contains(item.ImageFileHolder.ExtensionLowered);
|
||||
string filteredSourceDirectoryFileExtensionLowered = Path.Combine(sourceDirectory, $"{item.ImageFileHolder.NameWithoutExtension}{item.ImageFileHolder.ExtensionLowered}");
|
||||
if (item.ValidImageFormatExtension && item.ImageFileHolder.FullName.Length == filteredSourceDirectoryFileExtensionLowered.Length && item.ImageFileHolder.FullName != filteredSourceDirectoryFileExtensionLowered)
|
||||
File.Move(item.ImageFileHolder.FullName, filteredSourceDirectoryFileExtensionLowered);
|
||||
if (item.Changed is null || item.Changed.Value || item.Property is null)
|
||||
{
|
||||
property = GetPropertyOfPrivate(angleBracket, propertyHolder, firstPass, filteredSourceDirectoryFileTuples, parseExceptions, isIgnoreExtension, isValidImageFormatExtension, isValidMetadataExtensions, extensionLowered);
|
||||
property = GetPropertyOfPrivate(item, firstPass, filteredSourceDirectoryFileTuples, parseExceptions, isIgnoreExtension, isValidMetadataExtensions);
|
||||
lock (sourceDirectoryChanges)
|
||||
sourceDirectoryChanges.Add(new Tuple<string, DateTime>(nameof(A_Property), DateTime.Now));
|
||||
lock (propertyHolder)
|
||||
propertyHolder.Update(property);
|
||||
lock (item)
|
||||
item.Update(property);
|
||||
}
|
||||
}
|
||||
|
||||
private void ParallelWork(bool firstPass, List<Exception> exceptions, List<Tuple<string, DateTime>> sourceDirectoryChanges, int propertyHolderCollectionsCount, int g, string sourceDirectory, int r, PropertyHolder[] filteredPropertyHolderCollection, int totalSeconds, string angleBracket)
|
||||
private void ParallelWork(bool firstPass, List<Exception> exceptions, List<Tuple<string, DateTime>> sourceDirectoryChanges, int containersCount, Container container, Item[] filteredItems, int totalSeconds)
|
||||
{
|
||||
List<Tuple<string, DateTime>> filteredSourceDirectoryFileTuples = new();
|
||||
ParallelOptions parallelOptions = new() { MaxDegreeOfParallelism = _MaxDegreeOfParallelism };
|
||||
ProgressBarOptions options = new() { ProgressCharacter = '─', ProgressBarOnBottom = true, DisableBottomPercentage = true };
|
||||
string message = $"{r + 1:000}.{g} / {propertyHolderCollectionsCount:000}) {filteredPropertyHolderCollection.Length:000} file(s) - {totalSeconds} total second(s) - {sourceDirectory}";
|
||||
using ProgressBar progressBar = new(filteredPropertyHolderCollection.Length, message, options);
|
||||
_ = Parallel.For(0, filteredPropertyHolderCollection.Length, parallelOptions, i =>
|
||||
string message = $"{container.R + 1:000}.{container.G} / {containersCount:000}) {filteredItems.Length:000} file(s) - {totalSeconds} total second(s) - {container.SourceDirectory}";
|
||||
using ProgressBar progressBar = new(filteredItems.Length, message, options);
|
||||
_ = Parallel.For(0, filteredItems.Length, parallelOptions, i =>
|
||||
{
|
||||
try
|
||||
{
|
||||
long ticks = DateTime.Now.Ticks;
|
||||
DateTime dateTime = DateTime.Now;
|
||||
List<Tuple<string, DateTime>> collection;
|
||||
ParallelForWork(firstPass, angleBracket, sourceDirectory, sourceDirectoryChanges, filteredSourceDirectoryFileTuples, filteredPropertyHolderCollection[i]);
|
||||
ParallelForWork(firstPass, container.SourceDirectory, sourceDirectoryChanges, filteredSourceDirectoryFileTuples, filteredItems[i]);
|
||||
if (i == 0 || sourceDirectoryChanges.Any())
|
||||
progressBar.Tick();
|
||||
lock (filteredSourceDirectoryFileTuples)
|
||||
@ -663,13 +665,12 @@ public class PropertyLogic
|
||||
});
|
||||
}
|
||||
|
||||
private string SetAngleBracketCollectionAndGetZero(Configuration configuration, Model? model, PredictorModel? predictorModel, string sourceDirectory)
|
||||
private void SetAngleBracketCollection(string sourceDirectory)
|
||||
{
|
||||
string result;
|
||||
AngleBracketCollection.Clear();
|
||||
AngleBracketCollection.AddRange(IResult.GetDirectoryInfoCollection(configuration,
|
||||
model,
|
||||
predictorModel,
|
||||
AngleBracketCollection.AddRange(IResult.GetDirectoryInfoCollection(_Configuration,
|
||||
_Model,
|
||||
_PredictorModel,
|
||||
sourceDirectory,
|
||||
nameof(A_Property),
|
||||
string.Empty,
|
||||
@ -679,54 +680,45 @@ public class PropertyLogic
|
||||
contentDescription: string.Empty,
|
||||
singletonDescription: "Properties for each image",
|
||||
collectionDescription: string.Empty));
|
||||
result = AngleBracketCollection[0];
|
||||
return result;
|
||||
}
|
||||
|
||||
public void ParallelWork(Configuration configuration, Model? model, PredictorModel? predictorModel, long ticks, List<PropertyHolder[]> propertyHolderCollections, bool firstPass)
|
||||
public void ParallelWork(long ticks, List<Container> containers, bool firstPass)
|
||||
{
|
||||
if (_Log is null)
|
||||
throw new ArgumentNullException(nameof(_Log));
|
||||
throw new NullReferenceException(nameof(_Log));
|
||||
if (_Configuration.PopulatePropertyId is null)
|
||||
throw new ArgumentNullException(nameof(_Configuration.PopulatePropertyId));
|
||||
int g;
|
||||
int r;
|
||||
throw new NullReferenceException(nameof(_Configuration.PopulatePropertyId));
|
||||
int totalSeconds;
|
||||
bool? anyFilesMoved;
|
||||
string angleBracket;
|
||||
string sourceDirectory;
|
||||
Item[] filteredItems;
|
||||
List<Exception> exceptions = new();
|
||||
PropertyHolder[] filteredPropertyHolderCollection;
|
||||
int containersCount = containers.Count;
|
||||
List<Tuple<string, DateTime>> sourceDirectoryChanges = new();
|
||||
int propertyHolderCollectionsCount = propertyHolderCollections.Count;
|
||||
string propertyRoot = IResult.GetResultsGroupDirectory(configuration, nameof(A_Property));
|
||||
foreach (PropertyHolder[] propertyHolderCollection in propertyHolderCollections)
|
||||
string propertyRoot = IResult.GetResultsGroupDirectory(_Configuration, nameof(A_Property));
|
||||
foreach (Container container in containers)
|
||||
{
|
||||
if (!propertyHolderCollection.Any())
|
||||
if (!container.Items.Any())
|
||||
continue;
|
||||
sourceDirectoryChanges.Clear();
|
||||
if (firstPass)
|
||||
filteredPropertyHolderCollection = (from l in propertyHolderCollection where l.NoJson is null || !l.NoJson.Value && (l.Changed is null || l.Changed.Value) select l).ToArray();
|
||||
filteredItems = (from l in container.Items where l.NoJson is null || !l.NoJson.Value && (l.Changed is null || l.Changed.Value) select l).ToArray();
|
||||
else
|
||||
filteredPropertyHolderCollection = (from l in propertyHolderCollection where l.ImageFileHolder is not null && !_Configuration.IgnoreExtensions.Contains(l.ImageFileHolder.Extension) select l).ToArray();
|
||||
if (!filteredPropertyHolderCollection.Any())
|
||||
filteredItems = (from l in container.Items where l.ImageFileHolder is not null && !_Configuration.IgnoreExtensions.Contains(l.ImageFileHolder.ExtensionLowered) select l).ToArray();
|
||||
if (!filteredItems.Any())
|
||||
continue;
|
||||
g = filteredPropertyHolderCollection[0].G;
|
||||
r = filteredPropertyHolderCollection[0].R;
|
||||
sourceDirectory = filteredPropertyHolderCollection[0].SourceDirectory;
|
||||
totalSeconds = (int)Math.Truncate(new TimeSpan(DateTime.Now.Ticks - ticks).TotalSeconds);
|
||||
angleBracket = SetAngleBracketCollectionAndGetZero(configuration, model, predictorModel, sourceDirectory);
|
||||
ParallelWork(firstPass, exceptions, sourceDirectoryChanges, propertyHolderCollectionsCount, g, sourceDirectory, r, filteredPropertyHolderCollection, totalSeconds, angleBracket);
|
||||
SetAngleBracketCollection(container.SourceDirectory);
|
||||
ParallelWork(firstPass, exceptions, sourceDirectoryChanges, containersCount, container, filteredItems, totalSeconds);
|
||||
foreach (Exception exception in exceptions)
|
||||
_Log.Error(string.Concat(sourceDirectory, Environment.NewLine, exception.Message, Environment.NewLine, exception.StackTrace), exception);
|
||||
if (exceptions.Count == filteredPropertyHolderCollection.Length)
|
||||
throw new Exception(string.Concat("All in [", sourceDirectory, "]failed!"));
|
||||
_Log.Error(string.Concat(container.SourceDirectory, Environment.NewLine, exception.Message, Environment.NewLine, exception.StackTrace), exception);
|
||||
if (exceptions.Count == filteredItems.Length)
|
||||
throw new Exception(string.Concat("All in [", container.SourceDirectory, "]failed!"));
|
||||
if (exceptions.Count != 0)
|
||||
_ExceptionsDirectories.Add(sourceDirectory);
|
||||
_ExceptionsDirectories.Add(container.SourceDirectory);
|
||||
if (!firstPass || exceptions.Count != 0)
|
||||
anyFilesMoved = null;
|
||||
else
|
||||
anyFilesMoved = AnyFilesMoved(sourceDirectory, filteredPropertyHolderCollection);
|
||||
anyFilesMoved = AnyFilesMoved(container.SourceDirectory, filteredItems);
|
||||
if (Directory.GetFiles(propertyRoot, "*.txt", SearchOption.TopDirectoryOnly).Any())
|
||||
{
|
||||
for (int y = 0; y < int.MaxValue; y++)
|
||||
@ -740,32 +732,30 @@ public class PropertyLogic
|
||||
}
|
||||
}
|
||||
|
||||
public A_Property GetProperty(string angleBracket, PropertyHolder propertyHolder, List<Tuple<string, DateTime>> filteredSourceDirectoryFileTuples, List<string> parseExceptions)
|
||||
public A_Property GetProperty(Item item, List<Tuple<string, DateTime>> filteredSourceDirectoryFileTuples, List<string> parseExceptions)
|
||||
{
|
||||
A_Property result;
|
||||
if (propertyHolder.ImageFileHolder is null)
|
||||
throw new ArgumentException($"{propertyHolder.ImageFileHolder} is null!");
|
||||
if (item.ImageFileHolder is null)
|
||||
throw new NullReferenceException(nameof(item.ImageFileHolder));
|
||||
bool firstPass = false;
|
||||
string extensionLowered = propertyHolder.ImageFileHolder.Extension.ToLower();
|
||||
bool isValidMetadataExtensions = _Configuration.ValidMetadataExtensions.Contains(extensionLowered);
|
||||
bool isValidImageFormatExtension = _Configuration.ValidImageFormatExtensions.Contains(extensionLowered);
|
||||
bool isIgnoreExtension = isValidImageFormatExtension && _Configuration.IgnoreExtensions.Contains(extensionLowered);
|
||||
result = GetPropertyOfPrivate(angleBracket, propertyHolder, firstPass, filteredSourceDirectoryFileTuples, parseExceptions, isIgnoreExtension, isValidImageFormatExtension, isValidMetadataExtensions, extensionLowered);
|
||||
bool isValidMetadataExtensions = _Configuration.ValidMetadataExtensions.Contains(item.ImageFileHolder.ExtensionLowered);
|
||||
bool isIgnoreExtension = item.ValidImageFormatExtension && _Configuration.IgnoreExtensions.Contains(item.ImageFileHolder.ExtensionLowered);
|
||||
result = GetPropertyOfPrivate(item, firstPass, filteredSourceDirectoryFileTuples, parseExceptions, isIgnoreExtension, isValidMetadataExtensions);
|
||||
return result;
|
||||
}
|
||||
|
||||
public (long Ticks, string FilteredSourceDirectoryFile, string PropertyDirectory, int PropertyId)[] GetPropertyIds(Configuration configuration, Model? model, PredictorModel? predictorModel, List<DirectoryInfo> groupCollection, bool saveToCollection)
|
||||
public (long Ticks, string FilteredSourceDirectoryFile, string PropertyDirectory, int PropertyId)[] GetPropertyIds(List<DirectoryInfo> groupCollection, bool saveToCollection)
|
||||
{
|
||||
List<(long Ticks, string FilteredSourceDirectoryFile, string PropertyDirectory, int PropertyId)> results = new();
|
||||
int level;
|
||||
string angleBracket;
|
||||
A_Property? property;
|
||||
string checkDirectory;
|
||||
List<string> directories;
|
||||
string propertyDirectory;
|
||||
string angleBracket = AngleBracketCollection[0];
|
||||
foreach (DirectoryInfo group in groupCollection)
|
||||
{
|
||||
angleBracket = SetAngleBracketCollectionAndGetZero(configuration, model, predictorModel, group.SourceDirectory);
|
||||
SetAngleBracketCollection(group.SourceDirectory);
|
||||
if (string.IsNullOrEmpty(group.SourceDirectory))
|
||||
throw new Exception();
|
||||
if (!saveToCollection)
|
||||
@ -789,23 +779,23 @@ public class PropertyLogic
|
||||
return results.OrderBy(l => l.Ticks).ToArray();
|
||||
}
|
||||
|
||||
public void AddToPropertyLogicAllCollection(PropertyHolder[] filteredPropertyHolderCollection)
|
||||
public void AddToPropertyLogicAllCollection(Item[] filteredItems)
|
||||
{
|
||||
if (_SixCharacterNamedFaceInfo.Any())
|
||||
{
|
||||
string[] keys;
|
||||
PropertyHolder propertyHolder;
|
||||
for (int i = 0; i < filteredPropertyHolderCollection.Length; i++)
|
||||
Item item;
|
||||
for (int i = 0; i < filteredItems.Length; i++)
|
||||
{
|
||||
propertyHolder = filteredPropertyHolderCollection[i];
|
||||
if (propertyHolder.Property?.Id is null)
|
||||
item = filteredItems[i];
|
||||
if (item.Property?.Id is null)
|
||||
continue;
|
||||
foreach (int sixCharacterIndex in propertyHolder.Property.Indices)
|
||||
foreach (int sixCharacterIndex in item.Property.Indices)
|
||||
{
|
||||
if (!_SixCharacterNamedFaceInfo.ContainsKey(sixCharacterIndex))
|
||||
continue;
|
||||
keys = _SixCharacterNamedFaceInfo[sixCharacterIndex];
|
||||
_AllCollection.Add(new(propertyHolder.Property.Id.Value, keys));
|
||||
_AllCollection.Add(new(item.Property.Id.Value, keys));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -818,7 +808,7 @@ public class PropertyLogic
|
||||
string[] keys;
|
||||
string? rootDirectoryParent = Path.GetDirectoryName(_Configuration.RootDirectory);
|
||||
if (string.IsNullOrEmpty(rootDirectoryParent))
|
||||
throw new ArgumentNullException(nameof(rootDirectoryParent));
|
||||
throw new NullReferenceException(nameof(rootDirectoryParent));
|
||||
Dictionary<int, string[]> namedFaceInfoDeterministicHashCodeIndices = new();
|
||||
List<(int, string[])> allCollection = _AllCollection.OrderBy(l => l.Item1).ToList();
|
||||
foreach ((int deterministicHashCode, string[] values) in allCollection)
|
||||
|
@ -1,6 +1,3 @@
|
||||
using System.Text.Json;
|
||||
using View_by_Distance.Shared.Models.Stateless;
|
||||
|
||||
namespace View_by_Distance.Property.Models.Stateless;
|
||||
|
||||
public static class A_Property
|
||||
@ -21,237 +18,14 @@ public static class A_Property
|
||||
return result;
|
||||
}
|
||||
|
||||
public static List<(int g, string sourceDirectory, string[] sourceDirectoryFiles, int r)> GetGroupCollection(string rootDirectory, string searchPattern, List<string> topDirectories, int maxImagesInDirectoryForTopLevelFirstPass = 50, bool reverse = false)
|
||||
public static List<Models.Container> Get(Models.Configuration configuration, PropertyLogic propertyLogic)
|
||||
{
|
||||
List<(int g, string sourceDirectory, string[] sourceDirectoryFiles, int r)> results = new();
|
||||
string? parentDirectory;
|
||||
string[] subDirectories;
|
||||
string[] sourceDirectoryFiles;
|
||||
List<string[]> fileCollections = new();
|
||||
if (!topDirectories.Any())
|
||||
topDirectories.AddRange(from l in Directory.GetDirectories(rootDirectory, "*", SearchOption.TopDirectoryOnly) select Path.GetFullPath(l));
|
||||
for (int g = 1; g < 5; g++)
|
||||
{
|
||||
if (g == 4)
|
||||
{
|
||||
for (int i = fileCollections.Count - 1; i > -1; i--)
|
||||
{
|
||||
parentDirectory = Path.GetDirectoryName(fileCollections[i][0]);
|
||||
if (string.IsNullOrEmpty(parentDirectory))
|
||||
continue;
|
||||
results.Add(new(g, parentDirectory, fileCollections[i], results.Count));
|
||||
fileCollections.RemoveAt(i);
|
||||
}
|
||||
}
|
||||
else if (g == 2)
|
||||
{
|
||||
fileCollections = (from l in fileCollections orderby l.Length descending select l).ToList();
|
||||
for (int i = fileCollections.Count - 1; i > -1; i--)
|
||||
{
|
||||
if (fileCollections[i].Length > maxImagesInDirectoryForTopLevelFirstPass * g)
|
||||
break;
|
||||
parentDirectory = Path.GetDirectoryName(fileCollections[i][0]);
|
||||
if (string.IsNullOrEmpty(parentDirectory))
|
||||
continue;
|
||||
results.Add(new(g, parentDirectory, fileCollections[i], results.Count));
|
||||
fileCollections.RemoveAt(i);
|
||||
}
|
||||
}
|
||||
else if (g == 3)
|
||||
{
|
||||
subDirectories = Directory.GetDirectories(rootDirectory, "*", SearchOption.AllDirectories);
|
||||
if (reverse)
|
||||
subDirectories = subDirectories.Reverse().ToArray();
|
||||
foreach (string subDirectory in subDirectories)
|
||||
{
|
||||
sourceDirectoryFiles = Directory.GetFiles(subDirectory, "*", SearchOption.TopDirectoryOnly);
|
||||
if (!topDirectories.Contains(subDirectory))
|
||||
results.Add(new(g, subDirectory, sourceDirectoryFiles, results.Count));
|
||||
}
|
||||
}
|
||||
else if (g == 1)
|
||||
{
|
||||
sourceDirectoryFiles = Directory.GetFiles(rootDirectory, searchPattern, SearchOption.TopDirectoryOnly);
|
||||
if (sourceDirectoryFiles.Length > maxImagesInDirectoryForTopLevelFirstPass)
|
||||
fileCollections.Add(sourceDirectoryFiles);
|
||||
else
|
||||
results.Add(new(g, rootDirectory, sourceDirectoryFiles, results.Count));
|
||||
if (reverse)
|
||||
topDirectories.Reverse();
|
||||
subDirectories = topDirectories.ToArray();
|
||||
foreach (string subDirectory in subDirectories)
|
||||
{
|
||||
sourceDirectoryFiles = Directory.GetFiles(subDirectory, searchPattern, SearchOption.TopDirectoryOnly);
|
||||
if (sourceDirectoryFiles.Length > maxImagesInDirectoryForTopLevelFirstPass)
|
||||
fileCollections.Add(sourceDirectoryFiles);
|
||||
else
|
||||
{
|
||||
if (sourceDirectoryFiles.Any() || Directory.GetDirectories(subDirectory, "*", SearchOption.TopDirectoryOnly).Any())
|
||||
results.Add(new(g, subDirectory, sourceDirectoryFiles, results.Count));
|
||||
else if (searchPattern == "*")
|
||||
{
|
||||
sourceDirectoryFiles = Directory.GetFiles(subDirectory, searchPattern, SearchOption.TopDirectoryOnly);
|
||||
foreach (string subFile in sourceDirectoryFiles)
|
||||
File.Delete(subFile);
|
||||
Directory.Delete(subDirectory);
|
||||
}
|
||||
}
|
||||
}
|
||||
fileCollections.Reverse();
|
||||
}
|
||||
else
|
||||
throw new Exception();
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
public static List<(int g, string sourceDirectory, string[] sourceDirectoryFiles, int r)> GetJsonGroupCollection(string rootDirectory)
|
||||
{
|
||||
List<(int g, string sourceDirectory, string[] sourceDirectoryFiles, int r)> results;
|
||||
bool reverse = false;
|
||||
string searchPattern = "*.json";
|
||||
List<string> topDirectories = new();
|
||||
int maxImagesInDirectoryForTopLevelFirstPass = 50;
|
||||
results = GetGroupCollection(rootDirectory, searchPattern, topDirectories, maxImagesInDirectoryForTopLevelFirstPass, reverse);
|
||||
return results;
|
||||
}
|
||||
|
||||
public static List<(int g, string sourceDirectory, FileHolder[] sourceDirectoryFiles, int r)> GetFileHolderGroupCollection(Models.Configuration configuration, bool reverse, string searchPattern, List<string> topDirectories)
|
||||
{
|
||||
if (configuration.MaxImagesInDirectoryForTopLevelFirstPass is null)
|
||||
throw new ArgumentNullException(nameof(configuration.MaxImagesInDirectoryForTopLevelFirstPass));
|
||||
List<(int g, string sourceDirectory, FileHolder[] sourceDirectoryFiles, int r)> results = new();
|
||||
List<(int g, string sourceDirectory, string[] sourceDirectoryFiles, int r)>? collection = GetGroupCollection(configuration.RootDirectory, searchPattern, topDirectories, configuration.MaxImagesInDirectoryForTopLevelFirstPass.Value, reverse);
|
||||
foreach ((int g, string sourceDirectory, string[] sourceDirectoryFiles, int r) in collection)
|
||||
results.Add(new(g, sourceDirectory, (from l in sourceDirectoryFiles select new FileHolder(l)).ToArray(), r));
|
||||
return results;
|
||||
}
|
||||
|
||||
private static List<(int g, string sourceDirectory, List<(string sourceDirectoryFile, Models.A_Property? property)> collection, int r)> GetCollection(string rootDirectory, List<(int g, string sourceDirectory, string[] SourceDirectoryFiles, int r)> jsonCollection)
|
||||
{
|
||||
List<(int, string, List<(string, Models.A_Property?)>, int)> results = new();
|
||||
int length = rootDirectory.Length;
|
||||
ParallelOptions parallelOptions = new() { MaxDegreeOfParallelism = Environment.ProcessorCount };
|
||||
_ = Parallel.For(0, jsonCollection.Count, parallelOptions, i => ParallelFor(jsonCollection, i, length, results));
|
||||
return results;
|
||||
}
|
||||
|
||||
private static List<PropertyHolder[]> Populate(Models.Configuration configuration, string aPropertySingletonDirectory, List<(int, string, FileHolder[], int)> fileHolderGroupCollection, List<(int, string, List<(string, Models.A_Property?)>, int)> collectionFromJson)
|
||||
{
|
||||
List<PropertyHolder[]> results = new();
|
||||
if (configuration.PropertiesChangedForProperty is null)
|
||||
throw new Exception($"{configuration.PropertiesChangedForProperty} is null");
|
||||
int length;
|
||||
string inferred;
|
||||
string relativePath;
|
||||
FileHolder keyFileHolder;
|
||||
string keySourceDirectory;
|
||||
List<PropertyHolder> propertyHolderCollection;
|
||||
Dictionary<string, (string SourceDirectory, FileHolder FileHolder)> fileHolderKeyValuePairs = new();
|
||||
length = configuration.RootDirectory.Length;
|
||||
foreach ((int g, string sourceDirectory, FileHolder[] sourceDirectoryFileHolderCollection, int r) in fileHolderGroupCollection)
|
||||
{
|
||||
foreach (FileHolder sourceDirectoryFileHolder in sourceDirectoryFileHolderCollection)
|
||||
{
|
||||
relativePath = $"{XPath.GetRelativePath(sourceDirectoryFileHolder.FullName, length)}.json";
|
||||
fileHolderKeyValuePairs.Add(relativePath, new(sourceDirectory, sourceDirectoryFileHolder));
|
||||
}
|
||||
}
|
||||
length = aPropertySingletonDirectory.Length;
|
||||
foreach ((int g, string _, List<(string, Models.A_Property?)> collection, int r) in collectionFromJson)
|
||||
{
|
||||
if (!collection.Any())
|
||||
continue;
|
||||
propertyHolderCollection = new();
|
||||
foreach ((string sourceDirectoryFile, Models.A_Property? property) in collection)
|
||||
{
|
||||
relativePath = XPath.GetRelativePath(sourceDirectoryFile, length);
|
||||
if (!fileHolderKeyValuePairs.ContainsKey(relativePath))
|
||||
{
|
||||
inferred = string.Concat(configuration.RootDirectory, relativePath);
|
||||
keyFileHolder = new(inferred[..^5]);
|
||||
if (keyFileHolder.Extension is ".json")
|
||||
continue;
|
||||
keySourceDirectory = string.Concat(keyFileHolder.DirectoryName);
|
||||
propertyHolderCollection.Add(new(g, keySourceDirectory, sourceDirectoryFile, relativePath, r, keyFileHolder, property, true, null, null, null));
|
||||
}
|
||||
else
|
||||
{
|
||||
keyFileHolder = fileHolderKeyValuePairs[relativePath].FileHolder;
|
||||
keySourceDirectory = fileHolderKeyValuePairs[relativePath].SourceDirectory;
|
||||
if (!fileHolderKeyValuePairs.Remove(relativePath))
|
||||
throw new Exception();
|
||||
if (keyFileHolder.Extension is ".json")
|
||||
continue;
|
||||
if (property?.Id is null || property?.Width is null || property?.Height is null)
|
||||
propertyHolderCollection.Add(new(g, keySourceDirectory, sourceDirectoryFile, relativePath, r, keyFileHolder, property, false, null, null, null));
|
||||
else if (configuration.PropertiesChangedForProperty.Value || property.LastWriteTime != keyFileHolder.LastWriteTime || property.FileSize != keyFileHolder.Length)
|
||||
propertyHolderCollection.Add(new(g, keySourceDirectory, sourceDirectoryFile, relativePath, r, keyFileHolder, property, false, true, null, null));
|
||||
else
|
||||
propertyHolderCollection.Add(new(g, keySourceDirectory, sourceDirectoryFile, relativePath, r, keyFileHolder, property, false, false, null, null));
|
||||
}
|
||||
}
|
||||
if (propertyHolderCollection.Any())
|
||||
results.Add(propertyHolderCollection.ToArray());
|
||||
}
|
||||
length = configuration.RootDirectory.Length;
|
||||
foreach ((int g, string sourceDirectory, FileHolder[] sourceDirectoryFileHolderCollection, int r) in fileHolderGroupCollection)
|
||||
{
|
||||
propertyHolderCollection = new();
|
||||
foreach (FileHolder sourceDirectoryFileHolder in sourceDirectoryFileHolderCollection)
|
||||
{
|
||||
relativePath = $"{XPath.GetRelativePath(sourceDirectoryFileHolder.FullName, length)}.json";
|
||||
if (!fileHolderKeyValuePairs.ContainsKey(relativePath))
|
||||
continue;
|
||||
if (!fileHolderKeyValuePairs.Remove(relativePath))
|
||||
throw new Exception();
|
||||
if (sourceDirectoryFileHolder.Extension is ".json")
|
||||
continue;
|
||||
propertyHolderCollection.Add(new(g, sourceDirectory, relativePath, sourceDirectoryFileHolder.FullName, r, sourceDirectoryFileHolder, null, null, null, null, null));
|
||||
}
|
||||
if (propertyHolderCollection.Any())
|
||||
results.Add(propertyHolderCollection.ToArray());
|
||||
}
|
||||
if (fileHolderKeyValuePairs.Any())
|
||||
throw new Exception();
|
||||
results = (from l in results orderby l[0].G, l[0].R select l).ToList();
|
||||
return results;
|
||||
}
|
||||
|
||||
private static void ParallelFor(List<(int, string, string[], int)> jsonCollection, int i, int length, List<(int, string, List<(string, Models.A_Property?)>, int)> results)
|
||||
{
|
||||
string key;
|
||||
string json;
|
||||
Models.A_Property? property;
|
||||
(int g, string sourceDirectory, string[] sourceDirectoryFiles, int r) = jsonCollection[i];
|
||||
List<(string, Models.A_Property?)> collection = new();
|
||||
foreach (string sourceDirectoryFile in sourceDirectoryFiles)
|
||||
{
|
||||
json = File.ReadAllText(sourceDirectoryFile);
|
||||
key = XPath.GetRelativePath(sourceDirectoryFile, length);
|
||||
property = JsonSerializer.Deserialize<Models.A_Property>(json);
|
||||
collection.Add(new(sourceDirectoryFile, property));
|
||||
}
|
||||
lock (results)
|
||||
results.Add(new(g, sourceDirectory, collection, r));
|
||||
}
|
||||
|
||||
public static List<PropertyHolder[]> Get(Models.Configuration configuration, bool reverse, Model? model, PredictorModel? predictorModel, PropertyLogic propertyLogic)
|
||||
{
|
||||
List<PropertyHolder[]> results;
|
||||
string searchPattern = "*";
|
||||
List<Models.Container> results;
|
||||
long ticks = DateTime.Now.Ticks;
|
||||
List<string> topDirectories = new();
|
||||
List<(int g, string sourceDirectory, string[] sourceDirectoryFiles, int r)> jsonCollection;
|
||||
List<(int g, string sourceDirectory, FileHolder[] sourceDirectoryFiles, int r)> fileHolderGroupCollection;
|
||||
string aPropertySingletonDirectory = IResult.GetResultsDateGroupDirectory(configuration, nameof(A_Property), "{}");
|
||||
List<(int g, string sourceDirectory, List<(string sourceDirectoryFile, Models.A_Property? property)> collection, int r)> collectionFromJson;
|
||||
jsonCollection = GetJsonGroupCollection(aPropertySingletonDirectory);
|
||||
fileHolderGroupCollection = GetFileHolderGroupCollection(configuration, reverse, searchPattern, topDirectories);
|
||||
collectionFromJson = GetCollection(aPropertySingletonDirectory, jsonCollection);
|
||||
results = Populate(configuration, aPropertySingletonDirectory, fileHolderGroupCollection, collectionFromJson);
|
||||
propertyLogic.ParallelWork(configuration, model, predictorModel, ticks, results, firstPass: false);
|
||||
if (propertyLogic.ExceptionsDirectories.Any())
|
||||
List<string> exceptionsDirectories = new();
|
||||
results = Container.GetContainers(configuration, propertyLogic);
|
||||
propertyLogic.ParallelWork(ticks, results, firstPass: false);
|
||||
if (exceptionsDirectories.Any())
|
||||
throw new Exception();
|
||||
return results;
|
||||
}
|
||||
@ -413,15 +187,19 @@ public static class A_Property
|
||||
return result;
|
||||
}
|
||||
|
||||
public static TimeSpan GetThreeStandardDeviationHigh(int minimum, PropertyHolder[] propertyHolderCollection)
|
||||
public static TimeSpan GetThreeStandardDeviationHigh(int minimum, Models.Container container)
|
||||
{
|
||||
TimeSpan result;
|
||||
DateTime? minimumDateTime;
|
||||
List<long> ticksCollection = new();
|
||||
foreach (PropertyHolder propertyHolder in propertyHolderCollection)
|
||||
foreach (Item item in container.Items)
|
||||
{
|
||||
if (propertyHolder.Property is null || propertyHolder.MinimumDateTime is null)
|
||||
if (item.Property is null)
|
||||
continue;
|
||||
ticksCollection.Add(propertyHolder.MinimumDateTime.Value.Ticks);
|
||||
minimumDateTime = GetMinimumDateTime(item.Property);
|
||||
if (minimumDateTime is null)
|
||||
continue;
|
||||
ticksCollection.Add(minimumDateTime.Value.Ticks);
|
||||
}
|
||||
long threeStandardDeviationHigh;
|
||||
long min;
|
||||
@ -443,35 +221,42 @@ public static class A_Property
|
||||
return result;
|
||||
}
|
||||
|
||||
public static (int, List<DateTime>, List<PropertyHolder>) Get(PropertyHolder[] propertyHolderCollection, TimeSpan threeStandardDeviationHigh, int i)
|
||||
public static (int, List<DateTime>, List<Item>) Get(Models.Container container, TimeSpan threeStandardDeviationHigh, int i)
|
||||
{
|
||||
List<PropertyHolder> results = new();
|
||||
List<Item> results = new();
|
||||
int j = i;
|
||||
Item item;
|
||||
long? ticks;
|
||||
Item nextItem;
|
||||
TimeSpan timeSpan;
|
||||
PropertyHolder propertyHolder;
|
||||
DateTime? minimumDateTime;
|
||||
DateTime? nextMinimumDateTime;
|
||||
List<DateTime> dateTimes = new();
|
||||
PropertyHolder nextPropertyHolder;
|
||||
for (; j < propertyHolderCollection.Length; j++)
|
||||
for (; j < container.Items.Count; j++)
|
||||
{
|
||||
ticks = null;
|
||||
propertyHolder = propertyHolderCollection[j];
|
||||
if (propertyHolder.Property is null || propertyHolder.MinimumDateTime is null)
|
||||
item = container.Items[j];
|
||||
if (item.Property is null)
|
||||
continue;
|
||||
for (int k = j + 1; k < propertyHolderCollection.Length; k++)
|
||||
minimumDateTime = GetMinimumDateTime(item.Property);
|
||||
if (minimumDateTime is null)
|
||||
continue;
|
||||
for (int k = j + 1; k < container.Items.Count; k++)
|
||||
{
|
||||
nextPropertyHolder = propertyHolderCollection[k];
|
||||
if (nextPropertyHolder.Property is not null && nextPropertyHolder.MinimumDateTime is not null)
|
||||
{
|
||||
ticks = nextPropertyHolder.MinimumDateTime.Value.Ticks;
|
||||
break;
|
||||
}
|
||||
nextItem = container.Items[k];
|
||||
if (nextItem.Property is null)
|
||||
continue;
|
||||
nextMinimumDateTime = GetMinimumDateTime(nextItem.Property);
|
||||
if (nextMinimumDateTime is null)
|
||||
continue;
|
||||
ticks = nextMinimumDateTime.Value.Ticks;
|
||||
break;
|
||||
}
|
||||
results.Add(propertyHolder);
|
||||
dateTimes.Add(propertyHolder.MinimumDateTime.Value);
|
||||
results.Add(item);
|
||||
dateTimes.Add(minimumDateTime.Value);
|
||||
if (ticks.HasValue)
|
||||
{
|
||||
timeSpan = new(ticks.Value - propertyHolder.MinimumDateTime.Value.Ticks);
|
||||
timeSpan = new(ticks.Value - minimumDateTime.Value.Ticks);
|
||||
if (timeSpan > threeStandardDeviationHigh)
|
||||
break;
|
||||
}
|
||||
@ -479,14 +264,14 @@ public static class A_Property
|
||||
return new(j, dateTimes, results);
|
||||
}
|
||||
|
||||
public static bool Any(List<PropertyHolder[]> propertyHolderCollections)
|
||||
public static bool Any(List<Models.Container> propertyHolderCollections)
|
||||
{
|
||||
bool result = false;
|
||||
foreach (PropertyHolder[] propertyHolderCollection in propertyHolderCollections)
|
||||
foreach (Models.Container container in propertyHolderCollections)
|
||||
{
|
||||
if (!propertyHolderCollection.Any())
|
||||
if (!container.Items.Any())
|
||||
continue;
|
||||
if ((from l in propertyHolderCollection where l.Any() select true).Any())
|
||||
if ((from l in container.Items where l.Any() select true).Any())
|
||||
{
|
||||
result = true;
|
||||
break;
|
||||
|
267
Property/Models/Stateless/Container.cs
Normal file
267
Property/Models/Stateless/Container.cs
Normal file
@ -0,0 +1,267 @@
|
||||
using System.Text.Json;
|
||||
|
||||
namespace View_by_Distance.Property.Models.Stateless;
|
||||
|
||||
public class Container
|
||||
{
|
||||
|
||||
public static List<(int g, string sourceDirectory, string[] sourceDirectoryFiles, int r)> GetGroupCollection(string rootDirectory, int maxImagesInDirectoryForTopLevelFirstPass, bool reverse, string searchPattern, List<string> topDirectories)
|
||||
{
|
||||
List<(int g, string sourceDirectory, string[] sourceDirectoryFiles, int r)> results = new();
|
||||
string? parentDirectory;
|
||||
string[] subDirectories;
|
||||
string[] sourceDirectoryFiles;
|
||||
List<string[]> fileCollections = new();
|
||||
if (!topDirectories.Any())
|
||||
topDirectories.AddRange(from l in Directory.GetDirectories(rootDirectory, "*", SearchOption.TopDirectoryOnly) select Path.GetFullPath(l));
|
||||
for (int g = 1; g < 5; g++)
|
||||
{
|
||||
if (g == 4)
|
||||
{
|
||||
for (int i = fileCollections.Count - 1; i > -1; i--)
|
||||
{
|
||||
parentDirectory = Path.GetDirectoryName(fileCollections[i][0]);
|
||||
if (string.IsNullOrEmpty(parentDirectory))
|
||||
continue;
|
||||
results.Add(new(g, parentDirectory, fileCollections[i], results.Count));
|
||||
fileCollections.RemoveAt(i);
|
||||
}
|
||||
}
|
||||
else if (g == 2)
|
||||
{
|
||||
fileCollections = (from l in fileCollections orderby l.Length descending select l).ToList();
|
||||
for (int i = fileCollections.Count - 1; i > -1; i--)
|
||||
{
|
||||
if (fileCollections[i].Length > maxImagesInDirectoryForTopLevelFirstPass * g)
|
||||
break;
|
||||
parentDirectory = Path.GetDirectoryName(fileCollections[i][0]);
|
||||
if (string.IsNullOrEmpty(parentDirectory))
|
||||
continue;
|
||||
results.Add(new(g, parentDirectory, fileCollections[i], results.Count));
|
||||
fileCollections.RemoveAt(i);
|
||||
}
|
||||
}
|
||||
else if (g == 3)
|
||||
{
|
||||
subDirectories = Directory.GetDirectories(rootDirectory, "*", SearchOption.AllDirectories);
|
||||
if (reverse)
|
||||
subDirectories = subDirectories.Reverse().ToArray();
|
||||
foreach (string subDirectory in subDirectories)
|
||||
{
|
||||
sourceDirectoryFiles = Directory.GetFiles(subDirectory, "*", SearchOption.TopDirectoryOnly);
|
||||
if (!topDirectories.Contains(subDirectory))
|
||||
results.Add(new(g, subDirectory, sourceDirectoryFiles, results.Count));
|
||||
}
|
||||
}
|
||||
else if (g == 1)
|
||||
{
|
||||
sourceDirectoryFiles = Directory.GetFiles(rootDirectory, searchPattern, SearchOption.TopDirectoryOnly);
|
||||
if (sourceDirectoryFiles.Length > maxImagesInDirectoryForTopLevelFirstPass)
|
||||
fileCollections.Add(sourceDirectoryFiles);
|
||||
else
|
||||
results.Add(new(g, rootDirectory, sourceDirectoryFiles, results.Count));
|
||||
if (reverse)
|
||||
topDirectories.Reverse();
|
||||
subDirectories = topDirectories.ToArray();
|
||||
foreach (string subDirectory in subDirectories)
|
||||
{
|
||||
sourceDirectoryFiles = Directory.GetFiles(subDirectory, searchPattern, SearchOption.TopDirectoryOnly);
|
||||
if (sourceDirectoryFiles.Length > maxImagesInDirectoryForTopLevelFirstPass)
|
||||
fileCollections.Add(sourceDirectoryFiles);
|
||||
else
|
||||
{
|
||||
if (sourceDirectoryFiles.Any() || Directory.GetDirectories(subDirectory, "*", SearchOption.TopDirectoryOnly).Any())
|
||||
results.Add(new(g, subDirectory, sourceDirectoryFiles, results.Count));
|
||||
else if (searchPattern == "*")
|
||||
{
|
||||
sourceDirectoryFiles = Directory.GetFiles(subDirectory, searchPattern, SearchOption.TopDirectoryOnly);
|
||||
foreach (string subFile in sourceDirectoryFiles)
|
||||
File.Delete(subFile);
|
||||
Directory.Delete(subDirectory);
|
||||
}
|
||||
}
|
||||
}
|
||||
fileCollections.Reverse();
|
||||
}
|
||||
else
|
||||
throw new Exception();
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
public static List<(int g, string sourceDirectory, string[] sourceDirectoryFiles, int r)> GetGroupCollection(string rootDirectory, string searchPattern, List<string> topDirectories)
|
||||
{
|
||||
List<(int g, string sourceDirectory, string[] sourceDirectoryFiles, int r)> results;
|
||||
int maxImagesInDirectoryForTopLevelFirstPass = 50;
|
||||
bool reverse = false;
|
||||
results = GetGroupCollection(rootDirectory, maxImagesInDirectoryForTopLevelFirstPass, reverse, searchPattern, topDirectories);
|
||||
return results;
|
||||
}
|
||||
|
||||
private static List<(int g, string sourceDirectory, string[] sourceDirectoryFiles, int r)> GetJsonGroupCollection(Models.Configuration configuration, PropertyLogic propertyLogic, string rootDirectory)
|
||||
{
|
||||
List<(int g, string sourceDirectory, string[] sourceDirectoryFiles, int r)> results;
|
||||
if (configuration.MaxImagesInDirectoryForTopLevelFirstPass is null)
|
||||
throw new NullReferenceException(nameof(configuration.MaxImagesInDirectoryForTopLevelFirstPass));
|
||||
string searchPattern = "*.json";
|
||||
List<string> topDirectories = new();
|
||||
results = GetGroupCollection(rootDirectory, configuration.MaxImagesInDirectoryForTopLevelFirstPass.Value, propertyLogic.Reverse, searchPattern, topDirectories);
|
||||
return results;
|
||||
}
|
||||
|
||||
private static List<(int g, string sourceDirectory, FileHolder[] sourceDirectoryFiles, int r)> GetFileHolderGroupCollection(Models.Configuration configuration, PropertyLogic propertyLogic, string searchPattern, List<string> topDirectories)
|
||||
{
|
||||
List<(int g, string sourceDirectory, FileHolder[] sourceDirectoryFiles, int r)> results = new();
|
||||
if (configuration.MaxImagesInDirectoryForTopLevelFirstPass is null)
|
||||
throw new NullReferenceException(nameof(configuration.MaxImagesInDirectoryForTopLevelFirstPass));
|
||||
List<(int g, string sourceDirectory, string[] sourceDirectoryFiles, int r)>? collection = GetGroupCollection(configuration.RootDirectory, configuration.MaxImagesInDirectoryForTopLevelFirstPass.Value, propertyLogic.Reverse, searchPattern, topDirectories);
|
||||
foreach ((int g, string sourceDirectory, string[] sourceDirectoryFiles, int r) in collection)
|
||||
results.Add(new(g, sourceDirectory, (from l in sourceDirectoryFiles select new FileHolder(l)).ToArray(), r));
|
||||
return results;
|
||||
}
|
||||
|
||||
private static void ParallelFor(List<(int, string, string[], int)> jsonCollection, int i, int length, List<(int, string, List<(string, Models.A_Property?)>, int)> results)
|
||||
{
|
||||
string key;
|
||||
string json;
|
||||
Models.A_Property? property;
|
||||
(int g, string sourceDirectory, string[] sourceDirectoryFiles, int r) = jsonCollection[i];
|
||||
List<(string, Models.A_Property?)> collection = new();
|
||||
foreach (string sourceDirectoryFile in sourceDirectoryFiles)
|
||||
{
|
||||
json = File.ReadAllText(sourceDirectoryFile);
|
||||
key = XPath.GetRelativePath(sourceDirectoryFile, length);
|
||||
property = JsonSerializer.Deserialize<Models.A_Property>(json);
|
||||
collection.Add(new(sourceDirectoryFile, property));
|
||||
}
|
||||
lock (results)
|
||||
results.Add(new(g, sourceDirectory, collection, r));
|
||||
}
|
||||
|
||||
private static List<(int g, string sourceDirectory, List<(string sourceDirectoryFile, Models.A_Property? property)> collection, int r)> GetCollection(string rootDirectory, List<(int g, string sourceDirectory, string[] SourceDirectoryFiles, int r)> jsonCollection)
|
||||
{
|
||||
List<(int, string, List<(string, Models.A_Property?)>, int)> results = new();
|
||||
int length = rootDirectory.Length;
|
||||
ParallelOptions parallelOptions = new() { MaxDegreeOfParallelism = Environment.ProcessorCount };
|
||||
_ = Parallel.For(0, jsonCollection.Count, parallelOptions, i => ParallelFor(jsonCollection, i, length, results));
|
||||
return results;
|
||||
}
|
||||
|
||||
private static List<Models.Container> GetContainers(Models.Configuration configuration, string aPropertySingletonDirectory, List<(int, string, FileHolder[], int)> fileHolderGroupCollection, List<(int, string, List<(string, Models.A_Property?)>, int)> collectionFromJson)
|
||||
{
|
||||
List<Models.Container> results = new();
|
||||
if (configuration.PropertiesChangedForProperty is null)
|
||||
throw new Exception($"{configuration.PropertiesChangedForProperty} is null");
|
||||
int length;
|
||||
string key;
|
||||
string inferred;
|
||||
List<Item> items;
|
||||
string relativePath;
|
||||
FileHolder keyFileHolder;
|
||||
Models.Container container;
|
||||
bool isValidImageFormatExtension;
|
||||
List<string> keySourceDirectories;
|
||||
Dictionary<string, (string SourceDirectory, FileHolder FileHolder)> fileHolderKeyValuePairs = new();
|
||||
length = configuration.RootDirectory.Length;
|
||||
foreach ((int g, string sourceDirectory, FileHolder[] sourceDirectoryFileHolderCollection, int r) in fileHolderGroupCollection)
|
||||
{
|
||||
foreach (FileHolder sourceDirectoryFileHolder in sourceDirectoryFileHolderCollection)
|
||||
{
|
||||
relativePath = XPath.GetRelativePath(sourceDirectoryFileHolder.FullName, length);
|
||||
key = string.Concat(relativePath, ".json");
|
||||
fileHolderKeyValuePairs.Add(key, new(sourceDirectory, sourceDirectoryFileHolder));
|
||||
}
|
||||
}
|
||||
length = aPropertySingletonDirectory.Length;
|
||||
foreach ((int g, string _, List<(string, Models.A_Property?)> collection, int r) in collectionFromJson)
|
||||
{
|
||||
if (!collection.Any())
|
||||
continue;
|
||||
items = new();
|
||||
keySourceDirectories = new();
|
||||
foreach ((string sourceDirectoryFile, Models.A_Property? property) in collection)
|
||||
{
|
||||
key = XPath.GetRelativePath(sourceDirectoryFile, length);
|
||||
relativePath = key[..^5];
|
||||
if (!fileHolderKeyValuePairs.ContainsKey(key))
|
||||
{
|
||||
inferred = string.Concat(configuration.RootDirectory, relativePath);
|
||||
keyFileHolder = new(inferred);
|
||||
if (keyFileHolder.ExtensionLowered is ".json")
|
||||
continue;
|
||||
keySourceDirectories.Add(string.Concat(keyFileHolder.DirectoryName));
|
||||
isValidImageFormatExtension = configuration.ValidImageFormatExtensions.Contains(keyFileHolder.ExtensionLowered);
|
||||
items.Add(new(sourceDirectoryFile, relativePath, keyFileHolder, isValidImageFormatExtension, property, true, null));
|
||||
}
|
||||
else
|
||||
{
|
||||
keyFileHolder = fileHolderKeyValuePairs[key].FileHolder;
|
||||
keySourceDirectories.Add(fileHolderKeyValuePairs[key].SourceDirectory);
|
||||
if (!fileHolderKeyValuePairs.Remove(key))
|
||||
throw new Exception();
|
||||
if (keyFileHolder.ExtensionLowered is ".json")
|
||||
continue;
|
||||
isValidImageFormatExtension = configuration.ValidImageFormatExtensions.Contains(keyFileHolder.ExtensionLowered);
|
||||
if (property?.Id is null || property?.Width is null || property?.Height is null)
|
||||
items.Add(new(sourceDirectoryFile, relativePath, keyFileHolder, isValidImageFormatExtension, property, false, null));
|
||||
else if (configuration.PropertiesChangedForProperty.Value || property.LastWriteTime != keyFileHolder.LastWriteTime || property.FileSize != keyFileHolder.Length)
|
||||
items.Add(new(sourceDirectoryFile, relativePath, keyFileHolder, isValidImageFormatExtension, property, false, true));
|
||||
else
|
||||
items.Add(new(sourceDirectoryFile, relativePath, keyFileHolder, isValidImageFormatExtension, property, false, false));
|
||||
}
|
||||
}
|
||||
if (items.Any())
|
||||
{
|
||||
if (keySourceDirectories.Distinct().Count() != 1)
|
||||
continue;
|
||||
container = new(g, r, items, keySourceDirectories[0]);
|
||||
results.Add(container);
|
||||
}
|
||||
}
|
||||
length = configuration.RootDirectory.Length;
|
||||
foreach ((int g, string sourceDirectory, FileHolder[] sourceDirectoryFileHolderCollection, int r) in fileHolderGroupCollection)
|
||||
{
|
||||
items = new();
|
||||
foreach (FileHolder sourceDirectoryFileHolder in sourceDirectoryFileHolderCollection)
|
||||
{
|
||||
relativePath = XPath.GetRelativePath(sourceDirectoryFileHolder.FullName, length);
|
||||
key = string.Concat(relativePath, ".json");
|
||||
if (!fileHolderKeyValuePairs.ContainsKey(key))
|
||||
continue;
|
||||
if (!fileHolderKeyValuePairs.Remove(key))
|
||||
throw new Exception();
|
||||
if (sourceDirectoryFileHolder.ExtensionLowered is ".json")
|
||||
continue;
|
||||
isValidImageFormatExtension = configuration.ValidImageFormatExtensions.Contains(sourceDirectoryFileHolder.ExtensionLowered);
|
||||
items.Add(new(relativePath, sourceDirectoryFileHolder.FullName, sourceDirectoryFileHolder, isValidImageFormatExtension, null, null, null));
|
||||
}
|
||||
if (items.Any())
|
||||
{
|
||||
container = new(g, r, items, sourceDirectory);
|
||||
results.Add(container);
|
||||
}
|
||||
}
|
||||
if (fileHolderKeyValuePairs.Any())
|
||||
throw new Exception();
|
||||
results = (from l in results orderby l.G, l.R select l).ToList();
|
||||
return results;
|
||||
}
|
||||
|
||||
public static List<Models.Container> GetContainers(Models.Configuration configuration, PropertyLogic propertyLogic)
|
||||
{
|
||||
List<Models.Container> results;
|
||||
string searchPattern = "*";
|
||||
long ticks = DateTime.Now.Ticks;
|
||||
List<string> topDirectories = new();
|
||||
List<(int g, string sourceDirectory, string[] sourceDirectoryFiles, int r)> jsonCollection;
|
||||
List<(int g, string sourceDirectory, FileHolder[] sourceDirectoryFiles, int r)> fileHolderGroupCollection;
|
||||
string aPropertySingletonDirectory = IResult.GetResultsDateGroupDirectory(configuration, nameof(A_Property), "{}");
|
||||
List<(int g, string sourceDirectory, List<(string sourceDirectoryFile, Models.A_Property? property)> collection, int r)> collectionFromJson;
|
||||
jsonCollection = GetJsonGroupCollection(configuration, propertyLogic, aPropertySingletonDirectory);
|
||||
fileHolderGroupCollection = GetFileHolderGroupCollection(configuration, propertyLogic, searchPattern, topDirectories);
|
||||
collectionFromJson = GetCollection(aPropertySingletonDirectory, jsonCollection);
|
||||
results = GetContainers(configuration, aPropertySingletonDirectory, fileHolderGroupCollection, collectionFromJson);
|
||||
return results;
|
||||
}
|
||||
|
||||
}
|
@ -92,7 +92,7 @@ internal class XPath
|
||||
string? pathRoot = Path.GetPathRoot(directory);
|
||||
string extension = Path.GetExtension(directory);
|
||||
if (string.IsNullOrEmpty(pathRoot))
|
||||
throw new ArgumentNullException(nameof(pathRoot));
|
||||
throw new NullReferenceException(nameof(pathRoot));
|
||||
if (Directory.Exists(directory))
|
||||
results.Add(Path.GetFileName(directory));
|
||||
else if ((string.IsNullOrEmpty(extension) || extension.Length > 3) && !File.Exists(directory))
|
||||
|
Reference in New Issue
Block a user