Ready to test

This commit is contained in:
2022-07-24 12:35:00 -07:00
parent 4a3e24236f
commit 36592ea319
58 changed files with 1743 additions and 995 deletions

View File

@ -103,8 +103,8 @@ public class A_Property : Shared.Models.Properties.IProperty, IProperty
year = minimumDateTime.Value.ToString("yyyy");
else
{
List<DateTime> datetimes = GetDateTimes();
year = datetimes.Min().ToString("yyyy");
List<DateTime> dateTimes = GetDateTimes();
year = dateTimes.Min().ToString("yyyy");
}
for (int i = 0; i < int.MaxValue; i++)
{

View File

@ -98,4 +98,6 @@ public class Configuration
throw new Exception($"{nameof(propertyConfiguration.RootDirectory)} must have a value and exits!");
}
public void ChangeRootDirectory(string rootDirectory) => _RootDirectory = rootDirectory;
}

View File

@ -0,0 +1,46 @@
namespace View_by_Distance.Property.Models;
public class DirectoryInfo
{
protected readonly FileInfo[] _SourceDirectoryFileInfoCollection;
protected readonly string[] _FilteredSourceDirectoryFiles;
protected readonly int _G;
protected readonly bool[] _Moved;
protected readonly bool?[] _Changed;
protected readonly A_Property?[] _PropertyCollection;
protected readonly FileInfo?[] _PropertyFileInfoCollection;
protected readonly int _R;
protected readonly string _SourceDirectory;
protected readonly bool[] _ValidImageFormatExtensionCollection;
protected readonly bool[] _WrongYear;
public FileInfo[] SourceDirectoryFileInfoCollection => _SourceDirectoryFileInfoCollection;
[Obsolete($"Use {nameof(SourceDirectoryFileInfoCollection)}")]
public string[] FilteredSourceDirectoryFiles => _FilteredSourceDirectoryFiles;
public int G => _G;
public bool[] Moved => _Moved;
public bool?[] Changed => _Changed;
public A_Property?[] PropertyCollection => _PropertyCollection;
public FileInfo?[] PropertyFileInfoCollection => _PropertyFileInfoCollection;
public int R => _R;
public string SourceDirectory => _SourceDirectory;
public bool[] ValidImageFormatExtensionCollection => _ValidImageFormatExtensionCollection;
public bool[] WrongYear => _WrongYear;
public DirectoryInfo(int g, string sourceDirectory, string[] filteredSourceDirectoryFiles, int r)
{
int length = filteredSourceDirectoryFiles.Length;
_G = g;
_R = r;
_Changed = Array.Empty<bool?>();
_SourceDirectory = sourceDirectory;
_Moved = Enumerable.Repeat(false, length).ToArray();
_WrongYear = Enumerable.Repeat(false, length).ToArray();
_FilteredSourceDirectoryFiles = filteredSourceDirectoryFiles;
_PropertyCollection = Enumerable.Repeat<A_Property?>(null, length).ToArray();
_ValidImageFormatExtensionCollection = Enumerable.Repeat(false, length).ToArray();
_PropertyFileInfoCollection = Enumerable.Repeat<FileInfo?>(null, length).ToArray();
_SourceDirectoryFileInfoCollection = (from l in filteredSourceDirectoryFiles select new FileInfo(l)).ToArray();
}
}

View File

@ -1,32 +0,0 @@
namespace View_by_Distance.Property.Models;
public class Group
{
protected readonly int _G;
protected readonly string _SourceDirectory;
protected readonly string[] _FilteredSourceDirectoryFiles;
protected readonly int _R;
protected readonly bool[] _ValidImageFormatExtentionCollection;
protected readonly FileInfo?[] _PropertyFileInfoCollection;
protected readonly A_Property?[] _PropertyCollection;
public int G => _G;
public string SourceDirectory => _SourceDirectory;
public string[] FilteredSourceDirectoryFiles => _FilteredSourceDirectoryFiles;
public int R => _R;
public bool[] ValidImageFormatExtentionCollection => _ValidImageFormatExtentionCollection;
public FileInfo?[] PropertyFileInfoCollection => _PropertyFileInfoCollection;
public A_Property?[] PropertyCollection => _PropertyCollection;
public Group(int g, string sourceDirectory, string[] filteredSourceDirectoryFiles, int r)
{
_G = g;
_SourceDirectory = sourceDirectory;
_FilteredSourceDirectoryFiles = filteredSourceDirectoryFiles;
_R = r;
_ValidImageFormatExtentionCollection = Enumerable.Repeat(false, filteredSourceDirectoryFiles.Length).ToArray();
_PropertyFileInfoCollection = Enumerable.Repeat<FileInfo?>(null, filteredSourceDirectoryFiles.Length).ToArray();
_PropertyCollection = Enumerable.Repeat<A_Property?>(null, filteredSourceDirectoryFiles.Length).ToArray();
}
}

View File

@ -0,0 +1,83 @@
using System.Text.Json.Serialization;
namespace View_by_Distance.Property.Models;
public class PropertyHolder
{
protected readonly bool? _Abandoned;
protected readonly bool? _Changed;
protected FileInfo? _FileInfo;
protected readonly int _G;
protected DateTime? _MinimumDateTime;
protected bool? _Moved;
protected readonly bool? _NoJson;
protected A_Property? _Property;
protected readonly int _R;
protected readonly string _RelativePath;
protected FileInfo? _ResizedFileInfo;
protected readonly string _SourceDirectory;
protected readonly string _SourceDirectoryFile;
protected bool? _ValidImageFormatExtension;
protected bool? _WrongYear;
public bool? Abandoned => _Abandoned;
public bool? Changed => _Changed;
public FileInfo? FileInfo => _FileInfo;
public int G => _G;
public DateTime? MinimumDateTime => _MinimumDateTime;
public bool? Moved => _Moved;
public bool? NoJson => _NoJson;
public A_Property? Property => _Property;
public int R => _R;
public string RelativePath => _RelativePath;
public FileInfo? ResizedFileInfo => _ResizedFileInfo;
public string SourceDirectory => _SourceDirectory;
public string SourceDirectoryFile => _SourceDirectoryFile;
public bool? ValidImageFormatExtension => _ValidImageFormatExtension;
public bool? WrongYear => _WrongYear;
public PropertyHolder()
{
_G = -1;
_SourceDirectory = string.Empty;
_SourceDirectoryFile = string.Empty;
_RelativePath = string.Empty;
_R = -1;
}
[JsonConstructor]
public PropertyHolder(int g, string sourceDirectory, string sourceDirectoryFile, string relativePath, int r, FileInfo? fileInfo, A_Property? property, bool? abandoned, bool? changed, bool? moved, bool? validImageFormatExtension, bool? wrongYear)
{
_Abandoned = abandoned;
_Changed = changed;
_FileInfo = fileInfo;
_G = g;
_Moved = moved;
_NoJson = abandoned is null;
_Property = property;
_R = r;
_RelativePath = relativePath;
_SourceDirectory = sourceDirectory;
_SourceDirectoryFile = sourceDirectoryFile;
_ValidImageFormatExtension = validImageFormatExtension;
_WrongYear = wrongYear;
_MinimumDateTime = Stateless.A_Property.GetMinimumDateTime(property);
}
internal void SetValidImageFormatExtension(bool isValidImageFormatExtension) => _ValidImageFormatExtension = isValidImageFormatExtension;
internal void SetWrongYear(bool wrongYear) => _WrongYear = wrongYear;
internal void SetMoved(bool moved) => _Moved = moved;
public void SetResizedFileInfo(FileInfo fileInfo) => _ResizedFileInfo = fileInfo;
internal void Update(FileInfo fileInfo, A_Property property)
{
_Property = property;
_FileInfo = fileInfo;
}
public bool Any() => (_Abandoned.HasValue && _Abandoned.Value) || (_Changed.HasValue && _Changed.Value) || (_Moved.HasValue && _Moved.Value) || (_NoJson.HasValue && _NoJson.Value);
}

View File

@ -14,47 +14,62 @@ namespace View_by_Distance.Property.Models;
public class PropertyLogic
{
protected readonly List<string> _ExceptionsDirectories;
protected readonly Dictionary<int, int[]> _IndicesFromNew;
protected readonly Dictionary<int, int[]> _IndicesFromOld;
protected readonly Dictionary<int, string[]> _NamedFaceInfo;
public List<string> AngleBracketCollection { get; }
public Dictionary<int, int[]> IndicesFromNew => _IndicesFromNew;
public Dictionary<int, int[]> IndicesFromOld => _IndicesFromOld;
public Dictionary<int, string[]> NamedFaceInfo => _NamedFaceInfo;
public List<string> ExceptionsDirectories => _ExceptionsDirectories;
private readonly Serilog.ILogger? _Log;
private readonly string[] _VerifyToSeason;
private readonly int _MaxDegreeOfParallelism;
private readonly ASCIIEncoding _ASCIIEncoding;
private readonly Configuration _Configuration;
private readonly List<string> _ExceptionsDirectories;
private readonly JsonSerializerOptions _WriteIndentedJsonSerializerOptions;
public PropertyLogic(int maxDegreeOfParallelism, Configuration configuration, string[] verifyToSeason)
public PropertyLogic(int maxDegreeOfParallelism, Configuration configuration)
{
_Configuration = configuration;
_ExceptionsDirectories = new();
_VerifyToSeason = verifyToSeason;
_ASCIIEncoding = new ASCIIEncoding();
AngleBracketCollection = new List<string>();
_Log = Serilog.Log.ForContext<A_Property>();
_MaxDegreeOfParallelism = maxDegreeOfParallelism;
_WriteIndentedJsonSerializerOptions = new JsonSerializerOptions { WriteIndented = true };
if (verifyToSeason is null)
if (configuration.VerifyToSeason is null || !configuration.VerifyToSeason.Any())
throw new Exception();
_VerifyToSeason = configuration.VerifyToSeason.Select(l => Path.Combine(configuration.RootDirectory, l)).ToArray();
string json;
string[] files;
string fullPath;
Dictionary<int, int[]>? indicesFromOld;
Dictionary<int, string[]>? namedFaceInfo;
List<KeyValuePair<int, int[]>>? collection;
Dictionary<int, int[]> indicesFromNew = new();
string? rootDirectoryParent = Path.GetDirectoryName(configuration.RootDirectory);
if (string.IsNullOrEmpty(rootDirectoryParent))
throw new Exception($"{nameof(rootDirectoryParent)} is null!");
string keyValuePairsJsonFile = Path.Combine(rootDirectoryParent, "keyValuePairs-637864726339738801.json");
if (!File.Exists(keyValuePairsJsonFile))
files = Directory.GetFiles(rootDirectoryParent, "*Named*.json", SearchOption.TopDirectoryOnly);
if (files.Length != 1)
namedFaceInfo = new();
else
{
json = File.ReadAllText(files[0]);
namedFaceInfo = JsonSerializer.Deserialize<Dictionary<int, string[]>>(json);
if (namedFaceInfo is null)
throw new Exception($"{nameof(namedFaceInfo)} is null!");
}
files = Directory.GetFiles(rootDirectoryParent, "*keyValuePairs*.json", SearchOption.TopDirectoryOnly);
if (files.Length != 1)
indicesFromOld = new();
else
{
json = File.ReadAllText(keyValuePairsJsonFile);
json = File.ReadAllText(files[0]);
indicesFromOld = JsonSerializer.Deserialize<Dictionary<int, int[]>>(json);
if (indicesFromOld is null)
throw new Exception($"{nameof(indicesFromOld)} is null!");
@ -77,6 +92,7 @@ public class PropertyLogic
indicesFromNew.Add(keyValuePair.Key, keyValuePair.Value);
}
}
_NamedFaceInfo = namedFaceInfo;
_IndicesFromNew = indicesFromNew;
_IndicesFromOld = indicesFromOld;
}
@ -124,9 +140,15 @@ public class PropertyLogic
return results;
}
public static List<DateTime> GetMetadataDateTimesByPattern(string dateTimeFormat, FileInfo filteredSourceDirectoryFileInfo)
{
List<DateTime> results = GetMetadataDateTimesByPattern(dateTimeFormat, filteredSourceDirectoryFileInfo.FullName);
return results;
}
#pragma warning disable CA1416
private A_Property GetImageProperty(string angleBracket, string filteredSourceDirectoryFile, bool populateId, bool isIgnoreExtension, bool isValidImageFormatExtension, bool isValidMetadataExtensions, int? id, List<int> indices)
private A_Property GetImageProperty(string angleBracket, string filteredSourceDirectoryFile, bool populateId, bool isIgnoreExtension, bool isValidImageFormatExtension, bool isValidMetadataExtensions, int? id, List<int> indices, long fileInfoLength, DateTime creationTime, DateTime lastWriteTime)
{
A_Property result;
if (_Log is null)
@ -149,11 +171,7 @@ public class PropertyLogic
DateTime? dateTimeOriginal = null;
string orientation = string.Empty;
DateTime? dateTimeDigitized = null;
FileInfo fileInfo = new(filteredSourceDirectoryFile);
long fileInfoLength = fileInfo.Length;
DateTime creationTime = fileInfo.CreationTime;
DateTime lastWriteTime = fileInfo.LastWriteTime;
if (isValidMetadataExtensions)
if (!isValidImageFormatExtension && isValidMetadataExtensions)
{
dateTimeFormat = "ddd MMM dd HH:mm:ss yyyy";
List<DateTime> dateTimes = GetMetadataDateTimesByPattern(dateTimeFormat, filteredSourceDirectoryFile);
@ -294,9 +312,173 @@ public class PropertyLogic
return result;
}
private A_Property GetImagePropertyB(string angleBracket, FileInfo filteredSourceDirectoryFileInfo, bool populateId, bool isIgnoreExtension, bool isValidImageFormatExtension, bool isValidMetadataExtensions, int? id, List<int> indices)
{
A_Property result;
if (_Log is null)
throw new Exception($"{nameof(_Log)} is null!");
if (_Configuration.WriteBitmapDataBytes is null)
throw new Exception($"{nameof(_Configuration.WriteBitmapDataBytes)} is null!");
long ticks;
byte[] bytes;
string value;
int encodingHash;
int? width = null;
int? height = null;
string dateTimeFormat;
DateTime checkDateTime;
DateTime? dateTime = null;
PropertyItem? propertyItem;
string make = string.Empty;
string model = string.Empty;
DateTime? gpsDateStamp = null;
DateTime? dateTimeOriginal = null;
string orientation = string.Empty;
DateTime? dateTimeDigitized = null;
if (!isValidImageFormatExtension && isValidMetadataExtensions)
{
dateTimeFormat = "ddd MMM dd HH:mm:ss yyyy";
List<DateTime> dateTimes = GetMetadataDateTimesByPattern(dateTimeFormat, filteredSourceDirectoryFileInfo);
if (dateTimes.Any())
dateTimeOriginal = dateTimes.Min();
}
else if (!isIgnoreExtension && isValidImageFormatExtension)
{
try
{
using Image image = Image.FromFile(filteredSourceDirectoryFileInfo.FullName);
if (populateId && (id is null || !indices.Any()))
{
using Bitmap bitmap = new(image);
Rectangle rectangle = new(0, 0, image.Width, image.Height);
BitmapData bitmapData = bitmap.LockBits(rectangle, ImageLockMode.ReadOnly, bitmap.PixelFormat);
IntPtr intPtr = bitmapData.Scan0;
int length = bitmapData.Stride * bitmap.Height;
bytes = new byte[length];
Marshal.Copy(intPtr, bytes, 0, length);
bitmap.UnlockBits(bitmapData);
if (id is null)
{
ticks = DateTime.Now.Ticks;
id = Stateless.A_Property.GetDeterministicHashCode(bytes);
if (_MaxDegreeOfParallelism < 2)
ticks = LogDelta(ticks, nameof(Stateless.A_Property.GetDeterministicHashCode));
}
if (_Configuration.WriteBitmapDataBytes.Value)
{
FileInfo contentFileInfo = new(Path.Combine(angleBracket.Replace("<>", "()"), filteredSourceDirectoryFileInfo.Name));
File.WriteAllBytes(Path.ChangeExtension(contentFileInfo.FullName, string.Empty), bytes);
}
if (_IndicesFromNew.ContainsKey(id.Value) && _IndicesFromNew[id.Value].Any())
indices.AddRange(_IndicesFromNew[id.Value]);
else
{
ticks = DateTime.Now.Ticks;
string encoding = Encoding.Default.GetString(bytes);
if (_MaxDegreeOfParallelism < 2)
ticks = LogDelta(ticks, nameof(Encoding.Default.GetString));
encodingHash = Stateless.A_Property.GetDeterministicHashCode(encoding);
if (_MaxDegreeOfParallelism < 2)
ticks = LogDelta(ticks, nameof(Stateless.A_Property.GetDeterministicHashCode));
if (!_IndicesFromOld.ContainsKey(encodingHash))
indices.Add(encodingHash);
else
indices.AddRange(_IndicesFromOld[encodingHash]);
}
}
width = image.Width;
height = image.Height;
dateTimeFormat = Stateless.A_Property.DateTimeFormat();
if (image.PropertyIdList.Contains((int)IExif.Tags.DateTime))
{
propertyItem = image.GetPropertyItem((int)IExif.Tags.DateTime);
if (propertyItem?.Value is not null)
{
value = _ASCIIEncoding.GetString(propertyItem.Value, 0, propertyItem.Len - 1);
if (value.Length > dateTimeFormat.Length)
value = value[..dateTimeFormat.Length];
if (value.Length == dateTimeFormat.Length && DateTime.TryParseExact(value, dateTimeFormat, CultureInfo.InvariantCulture, DateTimeStyles.None, out checkDateTime))
dateTime = checkDateTime;
}
}
if (image.PropertyIdList.Contains((int)IExif.Tags.DateTimeDigitized))
{
propertyItem = image.GetPropertyItem((int)IExif.Tags.DateTimeDigitized);
if (propertyItem?.Value is not null)
{
value = _ASCIIEncoding.GetString(propertyItem.Value, 0, propertyItem.Len - 1);
if (value.Length > dateTimeFormat.Length)
value = value[..dateTimeFormat.Length];
if (value.Length == dateTimeFormat.Length && DateTime.TryParseExact(value, dateTimeFormat, CultureInfo.InvariantCulture, DateTimeStyles.None, out checkDateTime))
dateTimeDigitized = checkDateTime;
}
}
if (image.PropertyIdList.Contains((int)IExif.Tags.DateTimeOriginal))
{
propertyItem = image.GetPropertyItem((int)IExif.Tags.DateTimeOriginal);
if (propertyItem?.Value is not null)
{
value = _ASCIIEncoding.GetString(propertyItem.Value, 0, propertyItem.Len - 1);
if (value.Length > dateTimeFormat.Length)
value = value[..dateTimeFormat.Length];
if (value.Length == dateTimeFormat.Length && DateTime.TryParseExact(value, dateTimeFormat, CultureInfo.InvariantCulture, DateTimeStyles.None, out checkDateTime))
dateTimeOriginal = checkDateTime;
}
}
if (image.PropertyIdList.Contains((int)IExif.Tags.GPSDateStamp))
{
propertyItem = image.GetPropertyItem((int)IExif.Tags.GPSDateStamp);
if (propertyItem?.Value is not null)
{
value = _ASCIIEncoding.GetString(propertyItem.Value, 0, propertyItem.Len - 1);
if (value.Length > dateTimeFormat.Length)
value = value[..dateTimeFormat.Length];
if (value.Length == dateTimeFormat.Length && DateTime.TryParseExact(value, dateTimeFormat, CultureInfo.InvariantCulture, DateTimeStyles.None, out checkDateTime))
gpsDateStamp = checkDateTime;
}
}
if (image.PropertyIdList.Contains((int)IExif.Tags.Make))
{
propertyItem = image.GetPropertyItem((int)IExif.Tags.Make);
if (propertyItem?.Value is not null)
{
value = _ASCIIEncoding.GetString(propertyItem.Value, 0, propertyItem.Len - 1);
make = value;
}
}
if (image.PropertyIdList.Contains((int)IExif.Tags.Model))
{
propertyItem = image.GetPropertyItem((int)IExif.Tags.Model);
if (propertyItem?.Value is not null)
{
value = _ASCIIEncoding.GetString(propertyItem.Value, 0, propertyItem.Len - 1);
model = value;
}
}
if (image.PropertyIdList.Contains((int)IExif.Tags.Orientation))
{
propertyItem = image.GetPropertyItem((int)IExif.Tags.Orientation);
if (propertyItem?.Value is not null)
{
value = BitConverter.ToInt16(propertyItem.Value, 0).ToString();
orientation = value;
}
}
}
catch (Exception)
{
_Log.Info(string.Concat(new StackFrame().GetMethod()?.Name, " <", filteredSourceDirectoryFileInfo.Name, ">"));
}
}
else
dateTimeOriginal = null;
result = new(filteredSourceDirectoryFileInfo.CreationTime, dateTime, dateTimeDigitized, dateTimeOriginal, filteredSourceDirectoryFileInfo.Length, gpsDateStamp, height, id, indices.ToArray(), filteredSourceDirectoryFileInfo.LastWriteTime, make, model, orientation, width);
return result;
}
#pragma warning restore CA1416
private A_Property GetProperty(List<Tuple<string, DateTime>> filteredSourceDirectoryFileTuples, List<string> parseExceptions, bool firstPass, string angleBracket, string filteredSourceDirectoryFile, FileInfo fileInfo, bool isIgnoreExtension, bool isValidImageFormatExtension, bool isValidMetadataExtensions)
private A_Property GetPropertyA(List<Tuple<string, DateTime>> filteredSourceDirectoryFileTuples, List<string> parseExceptions, bool firstPass, string angleBracket, FileInfo filteredSourceDirectoryFileInfo, FileInfo fileInfo, bool isIgnoreExtension, bool isValidImageFormatExtension, bool isValidMetadataExtensions)
{
A_Property? result;
if (_Configuration.ForcePropertyLastWriteTimeToCreationTime is null)
@ -309,7 +491,7 @@ public class PropertyLogic
int? id = null;
List<int> indices = new();
bool hasWrongYearProperty = false;
string[] changesFrom = new string[] { "B_Metadata" };
string[] changesFrom = Array.Empty<string>();
bool populateId = !firstPass && _Configuration.PopulatePropertyId.Value;
List<DateTime> dateTimes = (from l in filteredSourceDirectoryFileTuples where changesFrom.Contains(l.Item1) select l.Item2).ToList();
if (!fileInfo.Exists)
@ -352,7 +534,7 @@ public class PropertyLogic
id = property?.Id;
if (property is not null && property.Indices.Any())
indices = property.Indices.ToList();
property = GetImageProperty(angleBracket, filteredSourceDirectoryFile, populateId, isIgnoreExtension, isValidImageFormatExtension, isValidMetadataExtensions, id, indices);
property = GetImagePropertyB(angleBracket, filteredSourceDirectoryFileInfo, populateId, isIgnoreExtension, isValidImageFormatExtension, isValidMetadataExtensions, id, indices);
}
if (!isIgnoreExtension && isValidImageFormatExtension && populateId && property is not null && !property.Indices.Any())
{
@ -360,25 +542,32 @@ public class PropertyLogic
id = property?.Id;
if (property is not null && property.Indices.Any())
indices = property.Indices.ToList();
property = GetImageProperty(angleBracket, filteredSourceDirectoryFile, populateId, isIgnoreExtension, isValidImageFormatExtension, isValidMetadataExtensions, id, indices);
property = GetImagePropertyB(angleBracket, filteredSourceDirectoryFileInfo, populateId, isIgnoreExtension, isValidImageFormatExtension, isValidMetadataExtensions, id, indices);
}
if (!isIgnoreExtension && isValidImageFormatExtension && populateId && property is not null && property.LastWriteTime != new FileInfo(filteredSourceDirectoryFile).LastWriteTime)
if (!isIgnoreExtension && isValidImageFormatExtension && populateId && property is not null && property.LastWriteTime != filteredSourceDirectoryFileInfo.LastWriteTime)
{
check = false;
id = null;
indices.Clear();
property = GetImageProperty(angleBracket, filteredSourceDirectoryFile, populateId, isIgnoreExtension, isValidImageFormatExtension, isValidMetadataExtensions, id, indices);
property = GetImagePropertyB(angleBracket, filteredSourceDirectoryFileInfo, populateId, isIgnoreExtension, isValidImageFormatExtension, isValidMetadataExtensions, id, indices);
}
if (!isIgnoreExtension && isValidImageFormatExtension && property?.Width is not null && property?.Height is not null && property.Width.Value == property.Height.Value && File.Exists(filteredSourceDirectoryFile))
if (!isIgnoreExtension && isValidImageFormatExtension && property?.Width is not null && property?.Height is not null && property.Width.Value == property.Height.Value && filteredSourceDirectoryFileInfo.Exists)
{
check = false;
id = property?.Id;
if (property is not null && property.Indices.Any())
indices = property.Indices.ToList();
property = GetImageProperty(angleBracket, filteredSourceDirectoryFile, populateId, isIgnoreExtension, isValidImageFormatExtension, isValidMetadataExtensions, id, indices);
property = GetImagePropertyB(angleBracket, filteredSourceDirectoryFileInfo, populateId, isIgnoreExtension, isValidImageFormatExtension, 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!");
}
// if (filteredSourceDirectoryFileFileInfo.CreationTime != property?.CreationTime || filteredSourceDirectoryFileFileInfo.LastWriteTime != property?.LastWriteTime)
// {
// check = false;
// id = null;
// indices.Clear();
// property = GetImagePropertyB(angleBracket, filteredSourceDirectoryFile, populateId, isIgnoreExtension, isValidImageFormatExtension, isValidMetadataExtensions, id, indices);
// }
if (json.Contains("WrongYear"))
{
id = property?.Id;
@ -402,7 +591,7 @@ public class PropertyLogic
}
if (result is null)
{
result = GetImageProperty(angleBracket, filteredSourceDirectoryFile, populateId, isIgnoreExtension, isValidImageFormatExtension, isValidMetadataExtensions, id, indices);
result = GetImagePropertyB(angleBracket, filteredSourceDirectoryFileInfo, populateId, isIgnoreExtension, isValidImageFormatExtension, isValidMetadataExtensions, id, indices);
json = JsonSerializer.Serialize(result, _WriteIndentedJsonSerializerOptions);
if (populateId && IPath.WriteAllText(fileInfo.FullName, json, compareBeforeWrite: true))
{
@ -429,7 +618,145 @@ public class PropertyLogic
return result;
}
private bool AnyFilesMoved(Group group)
private A_Property GetPropertyB(List<Tuple<string, DateTime>> filteredSourceDirectoryFileTuples, List<string> parseExceptions, bool firstPass, string angleBracket, FileInfo filteredSourceDirectoryFileInfo, A_Property? property, FileInfo fileInfo, bool isIgnoreExtension, bool isValidImageFormatExtension, bool isValidMetadataExtensions)
{
A_Property? result;
if (_Configuration.ForcePropertyLastWriteTimeToCreationTime is null)
throw new Exception($"{nameof(_Configuration.ForcePropertyLastWriteTimeToCreationTime)} is null!");
if (_Configuration.PopulatePropertyId is null)
throw new Exception($"{nameof(_Configuration.PopulatePropertyId)} is null!");
if (_Configuration.PropertiesChangedForProperty is null)
throw new Exception($"{nameof(_Configuration.PropertiesChangedForProperty)} is null!");
string json;
int? id = null;
List<int> indices = new();
bool hasWrongYearProperty = false;
string[] changesFrom = Array.Empty<string>();
bool populateId = !firstPass && _Configuration.PopulatePropertyId.Value;
List<DateTime> dateTimes = (from l in filteredSourceDirectoryFileTuples where changesFrom.Contains(l.Item1) select l.Item2).ToList();
if (!fileInfo.Exists)
{
if (fileInfo.Directory?.Parent is null)
throw new Exception();
string parentCheck = Path.Combine(fileInfo.Directory.Parent.FullName, fileInfo.Name);
if (File.Exists(parentCheck))
{
File.Move(parentCheck, fileInfo.FullName);
fileInfo.Refresh();
}
}
if (_Configuration.ForcePropertyLastWriteTimeToCreationTime.Value && !fileInfo.Exists && File.Exists(Path.ChangeExtension(fileInfo.FullName, ".delete")))
{
File.Move(Path.ChangeExtension(fileInfo.FullName, ".delete"), fileInfo.FullName);
fileInfo.Refresh();
}
if (_Configuration.ForcePropertyLastWriteTimeToCreationTime.Value && fileInfo.Exists && fileInfo.LastWriteTime != fileInfo.CreationTime)
{
File.SetLastWriteTime(fileInfo.FullName, fileInfo.CreationTime);
fileInfo.Refresh();
}
if (_Configuration.PropertiesChangedForProperty.Value)
result = null;
else if (!fileInfo.Exists)
result = null;
else
{
json = File.ReadAllText(fileInfo.FullName);
try
{
bool check = true;
property = JsonSerializer.Deserialize<A_Property>(json);
if (!isIgnoreExtension && isValidImageFormatExtension && ((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 = GetImagePropertyB(angleBracket, filteredSourceDirectoryFileInfo, populateId, isIgnoreExtension, isValidImageFormatExtension, isValidMetadataExtensions, id, indices);
}
if (!isIgnoreExtension && isValidImageFormatExtension && 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 = GetImagePropertyB(angleBracket, filteredSourceDirectoryFileInfo, populateId, isIgnoreExtension, isValidImageFormatExtension, isValidMetadataExtensions, id, indices);
}
if (!isIgnoreExtension && isValidImageFormatExtension && populateId && property is not null && property.LastWriteTime != filteredSourceDirectoryFileInfo.LastWriteTime)
{
check = false;
id = null;
indices.Clear();
property = GetImagePropertyB(angleBracket, filteredSourceDirectoryFileInfo, populateId, isIgnoreExtension, isValidImageFormatExtension, isValidMetadataExtensions, id, indices);
}
if (!isIgnoreExtension && isValidImageFormatExtension && property?.Width is not null && property?.Height is not null && property.Width.Value == property.Height.Value && filteredSourceDirectoryFileInfo.Exists)
{
check = false;
id = property?.Id;
if (property is not null && property.Indices.Any())
indices = property.Indices.ToList();
property = GetImagePropertyB(angleBracket, filteredSourceDirectoryFileInfo, populateId, isIgnoreExtension, isValidImageFormatExtension, 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!");
}
// if (filteredSourceDirectoryFileFileInfo.CreationTime != property?.CreationTime || filteredSourceDirectoryFileFileInfo.LastWriteTime != property?.LastWriteTime)
// {
// check = false;
// id = null;
// indices.Clear();
// property = GetImagePropertyB(angleBracket, filteredSourceDirectoryFile, populateId, isIgnoreExtension, isValidImageFormatExtension, isValidMetadataExtensions, id, indices);
// }
if (json.Contains("WrongYear"))
{
id = property?.Id;
hasWrongYearProperty = true;
}
if (property is null)
throw new Exception();
if (!check)
result = null;
else
{
result = property;
filteredSourceDirectoryFileTuples.Add(new Tuple<string, DateTime>(nameof(A_Property), fileInfo.LastWriteTime));
}
}
catch (Exception)
{
result = null;
parseExceptions.Add(nameof(A_Property));
}
}
if (result is null)
{
result = GetImagePropertyB(angleBracket, filteredSourceDirectoryFileInfo, populateId, isIgnoreExtension, isValidImageFormatExtension, isValidMetadataExtensions, id, indices);
json = JsonSerializer.Serialize(result, _WriteIndentedJsonSerializerOptions);
if (populateId && IPath.WriteAllText(fileInfo.FullName, json, compareBeforeWrite: true))
{
if (!_Configuration.ForcePropertyLastWriteTimeToCreationTime.Value && (!fileInfo.Exists || fileInfo.LastWriteTime == fileInfo.CreationTime))
filteredSourceDirectoryFileTuples.Add(new Tuple<string, DateTime>(nameof(A_Property), DateTime.Now));
else
{
File.SetLastWriteTime(fileInfo.FullName, fileInfo.CreationTime);
fileInfo.Refresh();
filteredSourceDirectoryFileTuples.Add(new Tuple<string, DateTime>(nameof(A_Property), fileInfo.CreationTime));
}
}
}
else if (hasWrongYearProperty)
{
json = JsonSerializer.Serialize(result, _WriteIndentedJsonSerializerOptions);
if (IPath.WriteAllText(fileInfo.FullName, json, compareBeforeWrite: true))
{
File.SetLastWriteTime(fileInfo.FullName, fileInfo.CreationTime);
fileInfo.Refresh();
filteredSourceDirectoryFileTuples.Add(new Tuple<string, DateTime>(nameof(A_Property), fileInfo.CreationTime));
}
}
return result;
}
private bool AnyFilesMoved(string sourceDirectory, PropertyHolder[] filteredPropertyHolderCollection)
{
bool result = false;
if (_Log is null)
@ -440,52 +767,58 @@ public class PropertyLogic
bool? isWrongYear;
string seasonName;
DateTime dateTime;
A_Property? property;
string destinationFile;
DateTime minimumDateTime;
FileInfo? propertyFileInfo;
string destinationDirectory;
string[] sourceDirectorySegments;
string filteredSourceDirectoryFile;
FileInfo filteredSourceDirectoryFileInfo;
DateTime directoryMaximumOfMinimumDateTime = DateTime.MinValue;
for (int i = 0; i < group.FilteredSourceDirectoryFiles.Length; i++)
foreach (PropertyHolder propertyHolder in filteredPropertyHolderCollection)
{
if (!group.ValidImageFormatExtentionCollection[i])
if (propertyHolder.ValidImageFormatExtension is null || !propertyHolder.ValidImageFormatExtension.Value)
continue;
property = group.PropertyCollection[i];
if (property is null)
if (propertyHolder.Property is null)
continue;
minimumDateTime = Stateless.A_Property.GetMinimumDateTime(property);
if (propertyHolder.FileInfo is null)
continue;
minimumDateTime = Stateless.A_Property.GetMinimumDateTime(propertyHolder.Property);
if (minimumDateTime > directoryMaximumOfMinimumDateTime)
directoryMaximumOfMinimumDateTime = minimumDateTime;
filteredSourceDirectoryFile = group.FilteredSourceDirectoryFiles[i];
filteredSourceDirectoryFileInfo = new(filteredSourceDirectoryFile);
if (minimumDateTime != filteredSourceDirectoryFileInfo.CreationTime)
if (minimumDateTime != propertyHolder.FileInfo.CreationTime)
{
(isWrongYear, matches) = property.IsWrongYear(filteredSourceDirectoryFile, minimumDateTime);
(isWrongYear, matches) = propertyHolder.Property.IsWrongYear(propertyHolder.FileInfo.FullName, minimumDateTime);
if (isWrongYear is null || !isWrongYear.Value)
dateTime = minimumDateTime;
else
{
if (isWrongYear.HasValue && isWrongYear.Value)
_Log.Information($"Wrong Year? <{filteredSourceDirectoryFile}>");
{
lock (propertyHolder)
propertyHolder.SetWrongYear(true);
}
if (!matches.Any())
continue;
if (!DateTime.TryParseExact(matches[0], "yyyy", CultureInfo.InvariantCulture, DateTimeStyles.None, out dateTime))
continue;
}
try
{ File.SetCreationTime(filteredSourceDirectoryFile, dateTime); }
{ File.SetCreationTime(propertyHolder.FileInfo.FullName, dateTime); }
catch (Exception)
{ }
}
if (!_VerifyToSeason.Contains(group.SourceDirectory))
if (!_VerifyToSeason.Contains(sourceDirectory))
continue;
propertyFileInfo = group.PropertyFileInfoCollection[i];
if (propertyFileInfo is null)
continue;
sourceDirectorySegments = Path.GetFileName(group.SourceDirectory).Split(' ');
if (!propertyHolder.FileInfo.FullName.Contains("zzz ") && !propertyHolder.FileInfo.FullName.Contains("Camera ") && propertyHolder.Property.DateTimeOriginal.HasValue)
{
TimeSpan timeSpan = new(propertyHolder.Property.DateTimeOriginal.Value.Ticks - propertyHolder.Property.LastWriteTime.Ticks);
if (timeSpan.TotalHours > 6)
{
_Log.Warning($"*** propertyHolder.FileInfo.FullName <{propertyHolder.FileInfo.FullName}>");
_Log.Warning($"*** DateTimeOriginal <{propertyHolder.Property.DateTimeOriginal.Value}>");
_Log.Warning($"*** LastWriteTime <{propertyHolder.Property.LastWriteTime}>");
_Log.Warning($"*** TotalHours <{timeSpan.TotalHours}>");
}
}
sourceDirectorySegments = Path.GetFileName(sourceDirectory).Split(' ');
(season, seasonName) = Stateless.A_Property.GetSeason(minimumDateTime.DayOfYear);
if (sourceDirectorySegments[0] == "zzz")
destinationDirectory = Path.Combine(_Configuration.RootDirectory, $"zzz ={minimumDateTime:yyyy}.{season} {seasonName} {string.Join(' ', sourceDirectorySegments.Skip(3))}");
@ -493,74 +826,75 @@ public class PropertyLogic
destinationDirectory = Path.Combine(_Configuration.RootDirectory, $"={minimumDateTime:yyyy}.{season} {seasonName} {string.Join(' ', sourceDirectorySegments.Skip(2))}");
else
destinationDirectory = Path.Combine(_Configuration.RootDirectory, $"={minimumDateTime:yyyy}.{season} {seasonName}");
if (destinationDirectory == group.SourceDirectory)
if (destinationDirectory == sourceDirectory)
continue;
lock (propertyHolder)
propertyHolder.SetMoved(true);
if (!result)
result = true;
if (!Directory.Exists(destinationDirectory))
_ = Directory.CreateDirectory(destinationDirectory);
destinationFile = Path.Combine(destinationDirectory, filteredSourceDirectoryFileInfo.Name);
destinationFile = Path.Combine(destinationDirectory, propertyHolder.FileInfo.Name);
if (File.Exists(destinationFile))
{
if (destinationFile.EndsWith(".jpg", ignoreCase: true, CultureInfo.CurrentCulture))
destinationFile = Path.Combine(destinationDirectory, Path.ChangeExtension(filteredSourceDirectoryFileInfo.Name, ".jpeg"));
destinationFile = Path.Combine(destinationDirectory, Path.ChangeExtension(propertyHolder.FileInfo.Name, ".jpeg"));
else if (destinationFile.EndsWith(".jpeg", ignoreCase: true, CultureInfo.CurrentCulture))
destinationFile = Path.Combine(destinationDirectory, Path.ChangeExtension(filteredSourceDirectoryFileInfo.Name, ".jpg"));
destinationFile = Path.Combine(destinationDirectory, Path.ChangeExtension(propertyHolder.FileInfo.Name, ".jpg"));
}
if (File.Exists(destinationFile))
{
_Log.Information($"*** source <{filteredSourceDirectoryFile}>");
_Log.Information($"*** source <{propertyHolder.FileInfo.FullName}>");
_Log.Information($"*** destination <{destinationFile}>");
if (propertyFileInfo.Exists)
if (propertyHolder.FileInfo.Exists)
{
deleteFile = Path.ChangeExtension(propertyFileInfo.FullName, ".delete");
deleteFile = Path.ChangeExtension(propertyHolder.FileInfo.FullName, ".delete");
if (File.Exists(deleteFile))
File.Delete(deleteFile);
File.Move(propertyFileInfo.FullName, deleteFile);
File.Move(propertyHolder.FileInfo.FullName, deleteFile);
}
}
else
{
File.Move(filteredSourceDirectoryFile, destinationFile);
if (propertyFileInfo.Exists)
File.Move(propertyHolder.FileInfo.FullName, destinationFile);
if (propertyHolder.FileInfo.Exists)
{
deleteFile = Path.ChangeExtension(propertyFileInfo.FullName, ".delete");
deleteFile = Path.ChangeExtension(propertyHolder.FileInfo.FullName, ".delete");
if (File.Exists(deleteFile))
File.Delete(deleteFile);
File.Move(propertyFileInfo.FullName, deleteFile);
File.Move(propertyHolder.FileInfo.FullName, deleteFile);
}
}
}
if (directoryMaximumOfMinimumDateTime != DateTime.MinValue)
{
DirectoryInfo directoryInfo = new(group.SourceDirectory);
System.IO.DirectoryInfo directoryInfo = new(sourceDirectory);
if (directoryInfo.LastWriteTime != directoryMaximumOfMinimumDateTime)
Directory.SetLastWriteTime(group.SourceDirectory, directoryMaximumOfMinimumDateTime);
Directory.SetLastWriteTime(sourceDirectory, directoryMaximumOfMinimumDateTime);
}
return result;
}
private void WriteGroup(Group group, string angleBracket)
private void WriteGroup(int sourceDirectoryLength, PropertyHolder[] filteredPropertyHolderCollection, string angleBracket)
{
if (!(from l in @group.PropertyCollection where l?.Width is null select true).Any())
if (!(from l in filteredPropertyHolderCollection where l?.Property?.Width is null select true).Any())
{
string key;
string json;
string checkFile;
A_Property? property;
string checkDirectory;
int sourceDirectoryLength = group.SourceDirectory.Length;
List<KeyValuePair<string, A_Property>> propertyCollectionKeyValuePairs = new();
JsonSerializerOptions writeIndentedJsonSerializerOptions = new() { WriteIndented = false };
(int level, List<string> directories) = IPath.Get(_Configuration.RootDirectory, group.SourceDirectory);
(int level, List<string> directories) = IPath.Get(_Configuration.RootDirectory, filteredPropertyHolderCollection[0].SourceDirectory);
string fileName = string.Concat(string.Join(_Configuration.FileNameDirectorySeparator, directories), ".json");
for (int i = 0; i < group.FilteredSourceDirectoryFiles.Length; i++)
foreach (PropertyHolder propertyHolder in filteredPropertyHolderCollection)
{
property = group.PropertyCollection[i];
if (property is null)
if (propertyHolder.Property is null)
continue;
key = IPath.GetRelativePath(group.FilteredSourceDirectoryFiles[i], sourceDirectoryLength);
propertyCollectionKeyValuePairs.Add(new KeyValuePair<string, A_Property>(key, property));
if (propertyHolder.FileInfo is null)
continue;
key = IPath.GetRelativePath(propertyHolder.FileInfo.FullName, sourceDirectoryLength);
propertyCollectionKeyValuePairs.Add(new KeyValuePair<string, A_Property>(key, propertyHolder.Property));
}
checkDirectory = IPath.GetDirectory(angleBracket, level, "[{}]");
checkFile = Path.Combine(checkDirectory, fileName);
@ -572,130 +906,132 @@ public class PropertyLogic
}
}
private (List<Tuple<string, DateTime>> filteredSourceDirectoryFileTuples, bool isValidImageFormatExtension, FileInfo propertyFileInfo, A_Property property) ParallelForWork(bool firstPass, string angleBracket, string sourceDirectory, string filteredSourceDirectoryFile)
private void ParallelForWork(bool firstPass, string angleBracket, string sourceDirectory, List<Tuple<string, DateTime>> filteredSourceDirectoryFileTuples, PropertyHolder propertyHolder)
{
if (propertyHolder.FileInfo is null)
throw new Exception($"{nameof(propertyHolder.FileInfo)} is null!");
A_Property property;
List<string> parseExceptions = new();
List<Tuple<string, DateTime>> filteredSourceDirectoryFileTuples = new();
string extensionLowered = Path.GetExtension(filteredSourceDirectoryFile).ToLower();
string extensionLowered = propertyHolder.FileInfo.Extension.ToLower();
bool isValidMetadataExtensions = _Configuration.ValidMetadataExtensions.Contains(extensionLowered);
string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(propertyHolder.FileInfo.FullName);
bool isValidImageFormatExtension = _Configuration.ValidImageFormatExtensions.Contains(extensionLowered);
lock (propertyHolder)
propertyHolder.SetValidImageFormatExtension(isValidImageFormatExtension);
bool isIgnoreExtension = isValidImageFormatExtension && _Configuration.IgnoreExtensions.Contains(extensionLowered);
string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(filteredSourceDirectoryFile);
string filteredSourceDirectoryFileExtensionLowered = Path.Combine(sourceDirectory, $"{fileNameWithoutExtension}{extensionLowered}");
if (isValidImageFormatExtension && filteredSourceDirectoryFile.Length == filteredSourceDirectoryFileExtensionLowered.Length && filteredSourceDirectoryFile != filteredSourceDirectoryFileExtensionLowered)
File.Move(filteredSourceDirectoryFile, filteredSourceDirectoryFileExtensionLowered);
string without = Path.Combine(angleBracket.Replace("<>", "{}"), $"{fileNameWithoutExtension}.json");
FileInfo propertyFileInfo = new(Path.Combine(angleBracket.Replace("<>", "{}"), $"{fileNameWithoutExtension}{extensionLowered}.json"));
if (isValidImageFormatExtension && File.Exists(without))
if (isValidImageFormatExtension && propertyHolder.FileInfo.FullName.Length == filteredSourceDirectoryFileExtensionLowered.Length && propertyHolder.FileInfo.FullName != filteredSourceDirectoryFileExtensionLowered)
File.Move(propertyHolder.FileInfo.FullName, filteredSourceDirectoryFileExtensionLowered);
if (propertyHolder.Changed is null || propertyHolder.Changed.Value || propertyHolder.Property is null)
{
File.Move(without, propertyFileInfo.FullName);
propertyFileInfo.Refresh();
string without = Path.Combine(angleBracket.Replace("<>", "{}"), $"{fileNameWithoutExtension}.json");
FileInfo fileInfo = new(Path.Combine(angleBracket.Replace("<>", "{}"), $"{fileNameWithoutExtension}{extensionLowered}.json"));
if (isValidImageFormatExtension && File.Exists(without))
{
File.Move(without, fileInfo.FullName);
fileInfo.Refresh();
}
property = GetPropertyB(filteredSourceDirectoryFileTuples, parseExceptions, firstPass, angleBracket, propertyHolder.FileInfo, propertyHolder.Property, fileInfo, isIgnoreExtension, isValidImageFormatExtension, isValidMetadataExtensions);
lock (propertyHolder)
propertyHolder.Update(fileInfo, property);
}
A_Property property = GetProperty(filteredSourceDirectoryFileTuples, parseExceptions, firstPass, angleBracket, filteredSourceDirectoryFile, propertyFileInfo, isIgnoreExtension, isValidImageFormatExtension, isValidMetadataExtensions);
return new(filteredSourceDirectoryFileTuples, isValidImageFormatExtension, propertyFileInfo, property);
}
private int ParallelWork(bool firstPass, object @lock, long ticks, List<Tuple<string, DateTime>> sourceDirectoryChanges, int count, Group group, string angleBracket)
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)
{
int result = 0;
if (_Log is null)
throw new Exception($"{nameof(_Log)} is null!");
List<Tuple<string, DateTime>> filteredSourceDirectoryFileTuples = new();
ParallelOptions parallelOptions = new() { MaxDegreeOfParallelism = _MaxDegreeOfParallelism };
int totalSeconds = (int)Math.Truncate(new TimeSpan(DateTime.Now.Ticks - ticks).TotalSeconds);
ProgressBarOptions options = new() { ProgressCharacter = '─', ProgressBarOnBottom = true, DisableBottomPercentage = true };
using (ProgressBar progressBar = new(group.FilteredSourceDirectoryFiles.Length, $"{group.G}) {group.R + 1:000} / {count:000} - {group.SourceDirectory} - {group.FilteredSourceDirectoryFiles.Length} file(s) - {totalSeconds} total second(s)", options))
{
_ = Parallel.For(0, group.FilteredSourceDirectoryFiles.Length, parallelOptions, i =>
using ProgressBar progressBar = new(filteredPropertyHolderCollection.Length, $"{r + 1:000}.{g} / {propertyHolderCollectionsCount:000}) {filteredPropertyHolderCollection.Length:000} file(s) - {totalSeconds} total second(s) - {sourceDirectory}", options);
_ = Parallel.For(0, filteredPropertyHolderCollection.Length, parallelOptions, i =>
{
try
{
try
{
long ticks = DateTime.Now.Ticks;
DateTime dateTime = DateTime.Now;
(List<Tuple<string, DateTime>> filteredSourceDirectoryFileTuples, bool isValidImageFormatExtension, FileInfo propertyFileInfo, A_Property property) = ParallelForWork(firstPass, angleBracket, group.SourceDirectory, group.FilteredSourceDirectoryFiles[i]);
progressBar.Tick();
if (_MaxDegreeOfParallelism < 2)
ticks = LogDelta(ticks, nameof(PropertyLogic.ParallelForWork));
lock (@lock)
{
group.PropertyCollection[i] = property;
group.PropertyFileInfoCollection[i] = propertyFileInfo;
if (isValidImageFormatExtension)
group.ValidImageFormatExtentionCollection[i] = isValidImageFormatExtension;
sourceDirectoryChanges.AddRange(from l in filteredSourceDirectoryFileTuples where l.Item2 > dateTime select l);
}
}
catch (Exception ex)
{
result += 1;
_Log.Error(string.Concat(group.SourceDirectory, Environment.NewLine, ex.Message, Environment.NewLine, ex.StackTrace), ex);
if (result == group.FilteredSourceDirectoryFiles.Length)
throw new Exception(string.Concat("All in [", group.SourceDirectory, "]failed!"));
}
});
}
return result;
long ticks = DateTime.Now.Ticks;
DateTime dateTime = DateTime.Now;
List<Tuple<string, DateTime>> collection;
ParallelForWork(firstPass, angleBracket, sourceDirectory, filteredSourceDirectoryFileTuples, filteredPropertyHolderCollection[i]);
progressBar.Tick();
lock (filteredSourceDirectoryFileTuples)
collection = (from l in filteredSourceDirectoryFileTuples where l.Item2 > dateTime select l).ToList();
lock (sourceDirectoryChanges)
sourceDirectoryChanges.AddRange(collection);
}
catch (Exception ex)
{
lock (exceptions)
exceptions.Add(ex);
}
});
}
private string SetAngleBracketCollectionAndGetZero(Configuration configuration, string sourceDirectory)
private string SetAngleBracketCollectionAndGetZero(Configuration configuration, string modelName, string predictorModelName, string sourceDirectory)
{
string result;
AngleBracketCollection.Clear();
AngleBracketCollection.AddRange(IResult.GetDirectoryInfoCollection(configuration,
sourceDirectory,
nameof(A_Property),
string.Empty,
includeResizeGroup: false,
includeModel: false,
includePredictorModel: false,
contentDescription: string.Empty,
singletonDescription: "Properties for each image",
collectionDescription: string.Empty));
modelName,
predictorModelName,
sourceDirectory,
nameof(A_Property),
string.Empty,
includeResizeGroup: false,
includeModel: false,
includePredictorModel: false,
contentDescription: string.Empty,
singletonDescription: "Properties for each image",
collectionDescription: string.Empty));
result = AngleBracketCollection[0];
return result;
}
public List<Group> GetParallelWork(Configuration configuration, List<string> topDirectories, List<(int g, string sourceDirectory, string[] sourceDirectoryFiles, int r)> groupCollection, bool firstPass, bool filterOnFirstPass)
public void ParallelWork(Configuration configuration, string modelName, string predictorModelName, long ticks, List<PropertyHolder[]> propertyHolderCollections, bool firstPass)
{
List<Group> results = new();
if (_Log is null)
throw new Exception($"{nameof(_Log)} is null!");
if (_Configuration.PopulatePropertyId is null)
throw new Exception($"{nameof(_Configuration.PopulatePropertyId)} is null!");
Group group;
int exceptionCount;
int g;
int r;
int totalSeconds;
string angleBracket;
object @lock = new();
long ticks = DateTime.Now.Ticks;
string[] filteredSourceDirectoryFiles;
string sourceDirectory;
List<Exception> exceptions = new();
PropertyHolder[] filteredPropertyHolderCollection;
List<Tuple<string, DateTime>> sourceDirectoryChanges = new();
int sourceDirectoryLength = configuration.RootDirectory.Length;
int propertyHolderCollectionsCount = propertyHolderCollections.Count;
string propertyRoot = IResult.GetResultsGroupDirectory(configuration, nameof(A_Property));
foreach ((int g, string sourceDirectory, string[] sourceDirectoryFiles, int r) in groupCollection)
foreach (PropertyHolder[] propertyHolderCollection in propertyHolderCollections)
{
if (!topDirectories.Any())
if (!propertyHolderCollection.Any())
continue;
sourceDirectoryChanges.Clear();
if (firstPass && !filterOnFirstPass)
filteredSourceDirectoryFiles = sourceDirectoryFiles;
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();
else
filteredSourceDirectoryFiles = (from l in sourceDirectoryFiles where !_Configuration.IgnoreExtensions.Contains(Path.GetExtension(l)) select l).ToArray();
if (!filteredSourceDirectoryFiles.Any())
filteredPropertyHolderCollection = (from l in propertyHolderCollection where l.FileInfo is not null && !_Configuration.IgnoreExtensions.Contains(l.FileInfo.Extension) select l).ToArray();
if (!filteredPropertyHolderCollection.Any())
continue;
group = new(g, sourceDirectory, filteredSourceDirectoryFiles, r);
angleBracket = SetAngleBracketCollectionAndGetZero(configuration, sourceDirectory);
exceptionCount = ParallelWork(firstPass, @lock, ticks, sourceDirectoryChanges, groupCollection.Count, group, angleBracket);
if (exceptionCount != 0)
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, modelName, predictorModelName, sourceDirectory);
ParallelWork(firstPass, exceptions, sourceDirectoryChanges, propertyHolderCollectionsCount, g, sourceDirectory, r, filteredPropertyHolderCollection, totalSeconds, angleBracket);
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!"));
if (exceptions.Count != 0)
_ExceptionsDirectories.Add(sourceDirectory);
else
results.Add(group);
bool? anyFilesMoved;
if (!firstPass || exceptionCount != 0)
if (!firstPass || exceptions.Count != 0)
anyFilesMoved = null;
else
anyFilesMoved = AnyFilesMoved(group);
if (exceptionCount != 0 || (anyFilesMoved is not null && anyFilesMoved.Value))
results.Clear();
if (exceptionCount == 0 && !firstPass && _Configuration.PopulatePropertyId.Value && (anyFilesMoved is null || !anyFilesMoved.Value))
WriteGroup(group, angleBracket);
anyFilesMoved = AnyFilesMoved(sourceDirectory, filteredPropertyHolderCollection);
if (exceptions.Count == 0 && !firstPass && _Configuration.PopulatePropertyId.Value && (anyFilesMoved is null || !anyFilesMoved.Value))
WriteGroup(sourceDirectoryLength, filteredPropertyHolderCollection, angleBracket);
if (Directory.GetFiles(propertyRoot, "*.txt", SearchOption.TopDirectoryOnly).Any())
{
for (int y = 0; y < int.MaxValue; y++)
@ -707,27 +1043,18 @@ public class PropertyLogic
_Log.Information(". . .");
}
}
return results;
}
public List<string> DoWork(Configuration configuration, List<string> topDirectories, List<(int g, string sourceDirectory, string[] sourceDirectoryFiles, int r)> groupCollection, bool firstPass)
{
List<string> results = new();
_ExceptionsDirectories.Clear();
_ = GetParallelWork(configuration, topDirectories, groupCollection, firstPass, filterOnFirstPass: false);
results.AddRange(_ExceptionsDirectories);
return results;
}
public A_Property GetProperty(string angleBracket, string sourceDirectory, string filteredSourceDirectoryFile, List<Tuple<string, DateTime>> filteredSourceDirectoryFileTuples, List<string> parseExceptions, FileInfo fileInfo)
{
A_Property result;
bool firstPass = false;
string extensionLowered = Path.GetExtension(filteredSourceDirectoryFile).ToLower();
FileInfo filteredSourceDirectoryFileInfo = new(filteredSourceDirectoryFile);
string extensionLowered = filteredSourceDirectoryFileInfo.Extension.ToLower();
bool isValidMetadataExtensions = _Configuration.ValidMetadataExtensions.Contains(extensionLowered);
bool isValidImageFormatExtension = _Configuration.ValidImageFormatExtensions.Contains(extensionLowered);
string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(filteredSourceDirectoryFileInfo.FullName);
bool isIgnoreExtension = isValidImageFormatExtension && _Configuration.IgnoreExtensions.Contains(extensionLowered);
string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(filteredSourceDirectoryFile);
string filteredSourceDirectoryFileExtensionLowered = Path.Combine(sourceDirectory, $"{fileNameWithoutExtension}{extensionLowered}");
if (isValidImageFormatExtension && filteredSourceDirectoryFile.Length == filteredSourceDirectoryFileExtensionLowered.Length && filteredSourceDirectoryFile != filteredSourceDirectoryFileExtensionLowered)
File.Move(filteredSourceDirectoryFile, filteredSourceDirectoryFileExtensionLowered);
@ -738,11 +1065,11 @@ public class PropertyLogic
File.Move(without, propertyFileInfo.FullName);
propertyFileInfo.Refresh();
}
result = GetProperty(filteredSourceDirectoryFileTuples, parseExceptions, firstPass, angleBracket, filteredSourceDirectoryFile, fileInfo, isIgnoreExtension, isValidImageFormatExtension, isValidMetadataExtensions);
result = GetPropertyA(filteredSourceDirectoryFileTuples, parseExceptions, firstPass, angleBracket, filteredSourceDirectoryFileInfo, fileInfo, isIgnoreExtension, isValidImageFormatExtension, isValidMetadataExtensions);
return result;
}
public (long Ticks, string FilteredSourceDirectoryFile, string PropertyDirectory, int PropertyId)[] GetPropertyIds(Configuration configuration, List<Group> groupCollection, bool saveToCollection)
public (long Ticks, string FilteredSourceDirectoryFile, string PropertyDirectory, int PropertyId)[] GetPropertyIds(Configuration configuration, string modelName, string predictorModelName, List<DirectoryInfo> groupCollection, bool saveToCollection)
{
List<(long Ticks, string FilteredSourceDirectoryFile, string PropertyDirectory, int PropertyId)> results = new();
int level;
@ -751,9 +1078,9 @@ public class PropertyLogic
string checkDirectory;
List<string> directories;
string propertyDirectory;
foreach (Group group in groupCollection)
foreach (DirectoryInfo group in groupCollection)
{
angleBracket = SetAngleBracketCollectionAndGetZero(configuration, group.SourceDirectory);
angleBracket = SetAngleBracketCollectionAndGetZero(configuration, modelName, predictorModelName, group.SourceDirectory);
if (string.IsNullOrEmpty(group.SourceDirectory))
throw new Exception();
if (!saveToCollection)
@ -766,7 +1093,7 @@ public class PropertyLogic
}
if (!Directory.Exists(propertyDirectory))
_ = Directory.CreateDirectory(propertyDirectory);
for (int i = 0; i < group.FilteredSourceDirectoryFiles.Length; i++)
for (int i = 0; i < group.SourceDirectoryFileInfoCollection.Length; i++)
{
property = group.PropertyCollection[i];
if (property?.Id is null)

View File

@ -1,3 +1,5 @@
using System.Text.Json;
namespace View_by_Distance.Property.Models.Stateless;
public static class A_Property
@ -26,10 +28,7 @@ public static class A_Property
string[] sourceDirectoryFiles;
List<string[]> fileCollections = new();
if (!topDirectories.Any())
{
topDirectories.Add(rootDirectory);
topDirectories.AddRange(from l in Directory.GetDirectories(rootDirectory, "*", SearchOption.TopDirectoryOnly) select Path.GetFullPath(l));
}
for (int g = 1; g < 5; g++)
{
if (g == 4)
@ -105,6 +104,151 @@ public static class A_Property
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, FileInfo[] sourceDirectoryFiles, int r)> GetFileInfoGroupCollection(Models.Configuration configuration, bool reverse, string searchPattern, List<string> topDirectories)
{
if (configuration.MaxImagesInDirectoryForTopLevelFirstPass is null)
throw new Exception($"{nameof(configuration.MaxImagesInDirectoryForTopLevelFirstPass)} is null!");
List<(int g, string sourceDirectory, FileInfo[] 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 FileInfo(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, FileInfo[], int)> fileInfoGroupCollection, 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;
FileInfo keyFileInfo;
string keySourceDirectory;
List<PropertyHolder> propertyHolderCollection;
Dictionary<string, (string SourceDirectory, FileInfo FileInfo)> fileInfoKeyValuePairs = new();
length = configuration.RootDirectory.Length;
foreach ((int g, string sourceDirectory, FileInfo[] sourceDirectoryFileInfoCollection, int r) in fileInfoGroupCollection)
{
foreach (FileInfo sourceDirectoryFileInfo in sourceDirectoryFileInfoCollection)
{
relativePath = $"{XPath.GetRelativePath(sourceDirectoryFileInfo.FullName, length)}.json";
fileInfoKeyValuePairs.Add(relativePath, new(sourceDirectory, sourceDirectoryFileInfo));
}
}
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 (!fileInfoKeyValuePairs.ContainsKey(relativePath))
{
inferred = string.Concat(configuration.RootDirectory, relativePath);
keyFileInfo = new(inferred[..^5]);
keySourceDirectory = string.Concat(keyFileInfo.DirectoryName);
propertyHolderCollection.Add(new(g, keySourceDirectory, sourceDirectoryFile, relativePath, r, keyFileInfo, property, true, null, null, null, null));
}
else
{
keyFileInfo = fileInfoKeyValuePairs[relativePath].FileInfo;
keySourceDirectory = fileInfoKeyValuePairs[relativePath].SourceDirectory;
if (!fileInfoKeyValuePairs.Remove(relativePath))
throw new Exception();
if (property?.Id is null || property?.Width is null || property?.Height is null)
propertyHolderCollection.Add(new(g, keySourceDirectory, sourceDirectoryFile, relativePath, r, keyFileInfo, property, false, null, null, null, null));
else if (configuration.PropertiesChangedForProperty.Value || property.LastWriteTime != keyFileInfo.LastWriteTime || property.FileSize != keyFileInfo.Length)
propertyHolderCollection.Add(new(g, keySourceDirectory, sourceDirectoryFile, relativePath, r, keyFileInfo, property, false, true, null, null, null));
else
propertyHolderCollection.Add(new(g, keySourceDirectory, sourceDirectoryFile, relativePath, r, keyFileInfo, property, false, false, null, null, null));
}
}
if (propertyHolderCollection.Any())
results.Add(propertyHolderCollection.ToArray());
}
length = configuration.RootDirectory.Length;
foreach ((int g, string sourceDirectory, FileInfo[] sourceDirectoryFileInfoCollection, int r) in fileInfoGroupCollection)
{
propertyHolderCollection = new();
foreach (FileInfo sourceDirectoryFileInfo in sourceDirectoryFileInfoCollection)
{
relativePath = $"{XPath.GetRelativePath(sourceDirectoryFileInfo.FullName, length)}.json";
if (!fileInfoKeyValuePairs.ContainsKey(relativePath))
continue;
if (!fileInfoKeyValuePairs.Remove(relativePath))
throw new Exception();
propertyHolderCollection.Add(new(g, sourceDirectory, relativePath, sourceDirectoryFileInfo.FullName, r, sourceDirectoryFileInfo, null, null, null, null, null, null));
}
if (propertyHolderCollection.Any())
results.Add(propertyHolderCollection.ToArray());
}
if (fileInfoKeyValuePairs.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, string modelName, string predictorModelName, PropertyLogic propertyLogic)
{
List<PropertyHolder[]> 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, FileInfo[] sourceDirectoryFiles, int r)> fileInfoGroupCollection;
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);
fileInfoGroupCollection = GetFileInfoGroupCollection(configuration, reverse, searchPattern, topDirectories);
collectionFromJson = GetCollection(aPropertySingletonDirectory, jsonCollection);
results = Populate(configuration, aPropertySingletonDirectory, fileInfoGroupCollection, collectionFromJson);
propertyLogic.ParallelWork(configuration, modelName, predictorModelName, ticks, results, firstPass: false);
if (propertyLogic.ExceptionsDirectories.Any())
throw new Exception();
return results;
}
public static int GetDeterministicHashCode(byte[] value)
{
int result;
@ -199,20 +343,20 @@ public static class A_Property
result = DateTime.MinValue;
else
{
List<DateTime> datetimes = new()
List<DateTime> dateTimes = new()
{
property.CreationTime,
property.LastWriteTime
};
if (property.DateTime.HasValue)
datetimes.Add(property.DateTime.Value);
dateTimes.Add(property.DateTime.Value);
if (property.DateTimeDigitized.HasValue)
datetimes.Add(property.DateTimeDigitized.Value);
dateTimes.Add(property.DateTimeDigitized.Value);
if (property.DateTimeOriginal.HasValue)
datetimes.Add(property.DateTimeOriginal.Value);
dateTimes.Add(property.DateTimeOriginal.Value);
if (property.GPSDateStamp.HasValue)
datetimes.Add(property.GPSDateStamp.Value);
result = datetimes.Min();
dateTimes.Add(property.GPSDateStamp.Value);
result = dateTimes.Min();
}
return result;
}
@ -222,139 +366,17 @@ public static class A_Property
public static DateTime GetMinimumDateTime(Models.A_Property? property)
{
DateTime result;
List<DateTime> datetimes;
List<DateTime> dateTimes;
if (property is null)
result = DateTime.MinValue;
else
{
datetimes = GetDateTimes(property);
result = datetimes.Min();
dateTimes = GetDateTimes(property);
result = dateTimes.Min();
}
return result;
}
public static string[] GetDirectoryRenameCollection(Models.Configuration configuration, string outputResolution, string bMetadata, string cResizeName)
{
List<string> results = new();
string cResizeContentDirectory;
string cResizeSingletonDirectory;
string bMetadataSingletonDirectory;
string aPropertySingletonDirectory;
bMetadataSingletonDirectory = IResult.GetResultsDateGroupDirectory(configuration, bMetadata, "{}");
if (Directory.Exists(bMetadataSingletonDirectory))
results.Add(bMetadataSingletonDirectory);
aPropertySingletonDirectory = IResult.GetResultsDateGroupDirectory(configuration, nameof(A_Property), "{}");
if (Directory.Exists(aPropertySingletonDirectory))
results.Add(aPropertySingletonDirectory);
cResizeContentDirectory = Path.Combine(IResult.GetResultsFullGroupDirectory(configuration, cResizeName, outputResolution, includeResizeGroup: true, includeModel: false, includePredictorModel: false), "()");
if (Directory.Exists(cResizeContentDirectory))
results.Add(cResizeContentDirectory);
cResizeSingletonDirectory = Path.Combine(IResult.GetResultsFullGroupDirectory(configuration, cResizeName, outputResolution, includeResizeGroup: true, includeModel: false, includePredictorModel: false), "{}");
if (Directory.Exists(cResizeSingletonDirectory))
results.Add(cResizeSingletonDirectory);
return results.ToArray();
}
public static void SearchForAbandonedFilesFull(string argZero, string rootDirectory, bool onlyJson)
{
bool check;
string[] files;
string moveFile;
string extension;
string? directory;
const int last = 6;
string searchPattern;
string searchDirectory;
int lessThan = last + 1;
string? parentDirectory;
DirectoryInfo directoryInfo;
string fileNameWithoutExtension;
IEnumerator<FileInfo> enumerator;
List<string[]> fileMovePaths = new();
List<string> toReviewFiles = new();
int rootDirectoryLength = rootDirectory.Length;
for (int i = 1; i < lessThan; i++)
{
files = i switch
{
1 => Directory.GetFiles(rootDirectory, "*.json", SearchOption.AllDirectories),
2 => Directory.GetFiles(rootDirectory, "*.nosj", SearchOption.AllDirectories),
3 => Directory.GetFiles(rootDirectory, "*.jpeg", SearchOption.AllDirectories),
4 => Directory.GetFiles(rootDirectory, "*.tvs", SearchOption.AllDirectories),
5 => Directory.GetFiles(rootDirectory, "*.png", SearchOption.AllDirectories),
last => Directory.GetFiles(rootDirectory, "*", SearchOption.AllDirectories),
_ => Array.Empty<string>()
};
foreach (string file in files)
{
extension = Path.GetExtension(file);
if (extension == ".delete")
continue;
directory = Path.GetDirectoryName(file);
if (string.IsNullOrEmpty(directory))
continue;
fileNameWithoutExtension = Path.GetFileNameWithoutExtension(file);
if (file.EndsWith(" - R.png"))
continue;
if (fileNameWithoutExtension.Length < 1)
continue;
if (fileNameWithoutExtension[1..] != string.Concat(" - ", Path.GetFileNameWithoutExtension(directory)))
{
searchPattern = string.Concat(fileNameWithoutExtension, '*');
searchDirectory = string.Concat(argZero, directory[rootDirectoryLength..]);
}
else
{
if (fileNameWithoutExtension.Length < 4)
continue;
searchPattern = string.Concat(fileNameWithoutExtension[4..], '*');
parentDirectory = Path.GetDirectoryName(directory);
if (string.IsNullOrEmpty(parentDirectory))
continue;
searchDirectory = string.Concat(argZero, parentDirectory[rootDirectoryLength..]);
}
directoryInfo = new(searchDirectory);
if (!directoryInfo.Exists)
check = false;
else
{
enumerator = directoryInfo.EnumerateFiles(searchPattern, SearchOption.TopDirectoryOnly).GetEnumerator();
check = enumerator.MoveNext();
}
if (check)
continue;
toReviewFiles.Add(file);
}
if (toReviewFiles.Any())
throw new Exception("Need to fix property having the extension before .json extension!");
foreach (string toReviewFile in toReviewFiles)
{
extension = Path.GetExtension(toReviewFile);
if (extension == ".delete")
continue;
directory = Path.GetDirectoryName(toReviewFile);
if (string.IsNullOrEmpty(directory))
continue;
moveFile = Path.Combine(directory, Path.ChangeExtension(toReviewFile, ".delete"));
if (i == last)
fileMovePaths.Add(new string[] { toReviewFile, moveFile });
else if (extension is ".nosj")
File.Delete(toReviewFile);
else
{
if (File.Exists(moveFile))
File.Delete(moveFile);
File.Move(toReviewFile, moveFile);
}
}
toReviewFiles.Clear();
if (onlyJson)
break;
}
if (fileMovePaths.Any())
throw new Exception(string.Join(',', (from l in fileMovePaths select l[0]).ToArray()));
}
public static string GetDiffRootDirectory(string diffPropertyDirectory)
{
string result = string.Empty;
@ -374,4 +396,96 @@ public static class A_Property
return result;
}
public static double GetStandardDeviation(IEnumerable<long> values, double average)
{
double result = 0;
if (!values.Any())
throw new Exception("Collection must have at least one value!");
double sum = values.Sum(l => (l - average) * (l - average));
result = Math.Sqrt(sum / values.Count());
return result;
}
public static TimeSpan GetThreeStandardDeviationHigh(int minimum, PropertyHolder[] propertyHolderCollection)
{
TimeSpan result;
List<long> ticksCollection = new();
foreach (PropertyHolder propertyHolder in propertyHolderCollection)
{
if (propertyHolder.Property is null || propertyHolder.MinimumDateTime is null)
continue;
ticksCollection.Add(propertyHolder.MinimumDateTime.Value.Ticks);
}
long threeStandardDeviationHigh;
long min;
if (!ticksCollection.Any())
min = 0;
else
min = ticksCollection.Min();
if (ticksCollection.Count < minimum)
threeStandardDeviationHigh = long.MaxValue;
else
{
ticksCollection = (from l in ticksCollection select l - min).ToList();
double sum = ticksCollection.Sum();
double average = sum / ticksCollection.Count;
double standardDeviation = GetStandardDeviation(ticksCollection, average);
threeStandardDeviationHigh = (long)Math.Ceiling(average + min + (standardDeviation * 3));
}
result = new TimeSpan(threeStandardDeviationHigh - min);
return result;
}
public static (int, List<DateTime>, List<PropertyHolder>) Get(PropertyHolder[] propertyHolderCollection, TimeSpan threeStandardDeviationHigh, int i)
{
List<PropertyHolder> results = new();
int j = i;
long? ticks;
TimeSpan timeSpan;
PropertyHolder propertyHolder;
List<DateTime> dateTimes = new();
PropertyHolder nextPropertyHolder;
for (; j < propertyHolderCollection.Length; j++)
{
ticks = null;
propertyHolder = propertyHolderCollection[j];
if (propertyHolder.Property is null || propertyHolder.MinimumDateTime is null)
continue;
for (int k = j + 1; k < propertyHolderCollection.Length; k++)
{
nextPropertyHolder = propertyHolderCollection[k];
if (nextPropertyHolder.Property is not null && nextPropertyHolder.MinimumDateTime is not null)
{
ticks = nextPropertyHolder.MinimumDateTime.Value.Ticks;
break;
}
}
results.Add(propertyHolder);
dateTimes.Add(propertyHolder.MinimumDateTime.Value);
if (ticks.HasValue)
{
timeSpan = new(ticks.Value - propertyHolder.MinimumDateTime.Value.Ticks);
if (timeSpan > threeStandardDeviationHigh)
break;
}
}
return new(j, dateTimes, results);
}
public static bool Any(List<PropertyHolder[]> propertyHolderCollections)
{
bool result = false;
foreach (PropertyHolder[] propertyHolderCollection in propertyHolderCollections)
{
if (!propertyHolderCollection.Any())
continue;
if ((from l in propertyHolderCollection where l.Any() select true).Any())
{
result = true;
break;
}
}
return result;
}
}

View File

@ -15,10 +15,10 @@ public interface IResult
string TestStatic_GetResultsDateGroupDirectory(Models.Configuration configuration, string description, string jsonGroup);
static string GetResultsDateGroupDirectory(Models.Configuration configuration, string description, string jsonGroup) => Result.GetResultsDateGroupDirectory(configuration, description, jsonGroup);
string TestStatic_GetResultsFullGroupDirectory(Models.Configuration configuration, string description, string outputResolution, bool includeResizeGroup, bool includeModel, bool includePredictorModel);
static string GetResultsFullGroupDirectory(Models.Configuration configuration, string description, string outputResolution, bool includeResizeGroup, bool includeModel, bool includePredictorModel) => Result.GetResultsFullGroupDirectory(configuration, description, outputResolution, includeResizeGroup, includeModel, includePredictorModel);
string TestStatic_GetResultsFullGroupDirectory(Models.Configuration configuration, string modelName, string predictorModelName, string description, string outputResolution, bool includeResizeGroup, bool includeModel, bool includePredictorModel);
static string GetResultsFullGroupDirectory(Models.Configuration configuration, string modelName, string predictorModelName, string description, string outputResolution, bool includeResizeGroup, bool includeModel, bool includePredictorModel) => Result.GetResultsFullGroupDirectory(configuration, modelName, predictorModelName, description, outputResolution, includeResizeGroup, includeModel, includePredictorModel);
List<string> TestStatic_GetDirectoryInfoCollection(Models.Configuration configuration, string sourceDirectory, string description, string outputResolution, bool includeResizeGroup, bool includeModel, bool includePredictorModel, string contentDescription, string singletonDescription, string collectionDescription);
static List<string> GetDirectoryInfoCollection(Models.Configuration configuration, string sourceDirectory, string description, string outputResolution, bool includeResizeGroup, bool includeModel, bool includePredictorModel, string contentDescription, string singletonDescription, string collectionDescription) => Result.GetDirectoryInfoCollection(configuration, sourceDirectory, description, outputResolution, includeResizeGroup, includeModel, includePredictorModel, contentDescription, singletonDescription, collectionDescription);
static List<string> GetDirectoryInfoCollection(Models.Configuration configuration, string modelName, string predictorModelName, string sourceDirectory, string description, string outputResolution, bool includeResizeGroup, bool includeModel, bool includePredictorModel, string contentDescription, string singletonDescription, string collectionDescription) => Result.GetDirectoryInfoCollection(configuration, modelName, predictorModelName, sourceDirectory, description, outputResolution, includeResizeGroup, includeModel, includePredictorModel, contentDescription, singletonDescription, collectionDescription);
}

View File

@ -33,14 +33,14 @@ internal class Result
return result;
}
internal static string GetResultsFullGroupDirectory(Models.Configuration configuration, string description, string outputResolution, bool includeResizeGroup, bool includeModel, bool includePredictorModel)
internal static string GetResultsFullGroupDirectory(Models.Configuration configuration, string modelName, string predictorModelName, string description, string outputResolution, bool includeResizeGroup, bool includeModel, bool includePredictorModel)
{
string result = GetResultsDateGroupDirectory(configuration, description);
if (includeResizeGroup)
result = Path.Combine(result, outputResolution);
if (includeModel && includePredictorModel)
{
string dateGroupDirectory = string.Concat(outputResolution.Replace(" ", string.Empty), " - ", "_Configuration.ModelName", " - ", "_Configuration.PredictorModelName");
string dateGroupDirectory = string.Concat(outputResolution.Replace(" ", string.Empty), " - ", modelName, " - ", predictorModelName);
result = Path.Combine(result, dateGroupDirectory);
}
else if (includeModel)
@ -52,17 +52,17 @@ internal class Result
return result;
}
internal static List<string> GetDirectoryInfoCollection(Models.Configuration configuration, string sourceDirectory, string description, string outputResolution, bool includeResizeGroup, bool includeModel, bool includePredictorModel, string contentDescription, string singletonDescription, string collectionDescription)
internal static List<string> GetDirectoryInfoCollection(Models.Configuration configuration, string modelName, string predictorModelName, string sourceDirectory, string description, string outputResolution, bool includeResizeGroup, bool includeModel, bool includePredictorModel, string contentDescription, string singletonDescription, string collectionDescription)
{
List<string> results = new();
string result = string.Empty;
string checkDirectory;
string sourceDirectorySegment = GetRelativePath(configuration, sourceDirectory);
string dateGroupDirectory = IResult.GetResultsFullGroupDirectory(configuration, description, outputResolution, includeResizeGroup, includeModel, includePredictorModel);
string dateGroupDirectory = IResult.GetResultsFullGroupDirectory(configuration, modelName, predictorModelName, description, outputResolution, includeResizeGroup, includeModel, includePredictorModel);
if (!string.IsNullOrEmpty(contentDescription))
{
result = string.Concat(Path.Combine(dateGroupDirectory, "<>"), sourceDirectorySegment);
DirectoryInfo contentDirectoryInfo = new(result.Replace("<>", "()"));
System.IO.DirectoryInfo contentDirectoryInfo = new(result.Replace("<>", "()"));
if (!contentDirectoryInfo.Exists)
contentDirectoryInfo.Create();
checkDirectory = Path.Combine(dateGroupDirectory, string.Concat("() - ", contentDescription));
@ -72,7 +72,7 @@ internal class Result
if (!string.IsNullOrEmpty(singletonDescription))
{
result = string.Concat(Path.Combine(dateGroupDirectory, "<>"), sourceDirectorySegment);
DirectoryInfo singletonDirectoryInfo = new(result.Replace("<>", "{}"));
System.IO.DirectoryInfo singletonDirectoryInfo = new(result.Replace("<>", "{}"));
if (!singletonDirectoryInfo.Exists)
singletonDirectoryInfo.Create();
checkDirectory = Path.Combine(dateGroupDirectory, string.Concat("{} - ", singletonDescription));
@ -82,7 +82,7 @@ internal class Result
if (!string.IsNullOrEmpty(collectionDescription))
{
result = string.Concat(Path.Combine(dateGroupDirectory, "<>"), sourceDirectorySegment);
DirectoryInfo collectionDirectoryInfo = new(result.Replace("<>", "[]"));
System.IO.DirectoryInfo collectionDirectoryInfo = new(result.Replace("<>", "[]"));
if (!collectionDirectoryInfo.Exists)
collectionDirectoryInfo.Create();
checkDirectory = Path.Combine(dateGroupDirectory, string.Concat("[] - ", collectionDescription));