318 lines
15 KiB
C#
318 lines
15 KiB
C#
using System.Text.Json.Serialization;
|
|
using View_by_Distance.Shared.Models;
|
|
using View_by_Distance.Shared.Models.Properties;
|
|
|
|
namespace View_by_Distance.Property.Models;
|
|
|
|
public class Item
|
|
{
|
|
|
|
protected readonly bool? _Abandoned;
|
|
protected readonly bool? _Changed;
|
|
protected List<Closest> _Closest;
|
|
protected List<IFace> _Faces;
|
|
protected readonly FileHolder? _ImageFileHolder;
|
|
protected bool? _Moved;
|
|
protected List<Named> _Named;
|
|
protected readonly bool? _NoJson;
|
|
protected A_Property? _Property;
|
|
protected readonly string _RelativePath;
|
|
protected FileHolder? _ResizedFileHolder;
|
|
protected readonly string _SourceDirectoryFile;
|
|
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 bool? Moved => _Moved;
|
|
public bool? NoJson => _NoJson;
|
|
public List<Named> Named => _Named;
|
|
public A_Property? Property => _Property;
|
|
public string RelativePath => _RelativePath;
|
|
public FileHolder? ResizedFileHolder => _ResizedFileHolder;
|
|
public string SourceDirectoryFile => _SourceDirectoryFile;
|
|
public bool ValidImageFormatExtension => _ValidImageFormatExtension;
|
|
|
|
[JsonConstructor]
|
|
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)
|
|
{
|
|
_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;
|
|
_Property = property;
|
|
_Abandoned = abandoned;
|
|
_NoJson = abandoned is null;
|
|
_RelativePath = relativePath;
|
|
_ImageFileHolder = imageFileInfo;
|
|
_SourceDirectoryFile = sourceDirectoryFile;
|
|
_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!");
|
|
}
|
|
|
|
internal void SetMoved(bool moved) => _Moved = moved;
|
|
|
|
public static string GetWrongYearFlag(bool? isWrongYear) => isWrongYear is null ? "#" : isWrongYear.Value ? "~" : "=";
|
|
|
|
public void SetResizedFileHolder(FileHolder fileHolder) => _ResizedFileHolder = fileHolder;
|
|
|
|
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;
|
|
|
|
public (bool?, string[]) IsWrongYear()
|
|
{
|
|
(bool?, string[]) result;
|
|
if (_Property is null || _ImageFileHolder is null)
|
|
throw new NullReferenceException();
|
|
DateTime? minimumDateTime = Stateless.A_Property.GetMinimumDateTime(_Property);
|
|
result = _Property.IsWrongYear(_ImageFileHolder.FullName, minimumDateTime);
|
|
return result;
|
|
}
|
|
|
|
public static void AddToNamed(PropertyLogic propertyLogic, List<Item> items)
|
|
{
|
|
bool? isWrongYear;
|
|
DateTime minimumDateTime;
|
|
PersonBirthday? personBirthday;
|
|
float deterministicHashCodeKey;
|
|
List<string> personKeys = new();
|
|
foreach (Item item in items)
|
|
{
|
|
if (item.ImageFileHolder is null)
|
|
continue;
|
|
if (item.Property?.Id is null || item.ResizedFileHolder is null)
|
|
continue;
|
|
foreach (IFace face in item.Faces)
|
|
{
|
|
personKeys.Clear();
|
|
if (face.LocationIndex is null)
|
|
continue;
|
|
deterministicHashCodeKey = Models.Named.GetDeterministicHashCodeKey(item, face);
|
|
if (!propertyLogic.NamedDeterministicHashCodeKeyValuePairs.ContainsKey(deterministicHashCodeKey))
|
|
continue;
|
|
minimumDateTime = Stateless.A_Property.GetMinimumDateTime(item.Property);
|
|
personKeys.AddRange(propertyLogic.NamedDeterministicHashCodeKeyValuePairs[deterministicHashCodeKey]);
|
|
(isWrongYear, _) = item.Property.IsWrongYear(item.ImageFileHolder.FullName, minimumDateTime);
|
|
for (int i = 0; i < personKeys.Count; i++)
|
|
{
|
|
personBirthday = Shared.Models.Stateless.Methods.IPersonBirthday.GetPersonBirthday(personKeys[i]);
|
|
if (personBirthday is null)
|
|
continue;
|
|
item.Named.Add(new(isWrongYear, minimumDateTime, face.Location.NormalizedPixelPercentage, personBirthday));
|
|
}
|
|
}
|
|
if (!personKeys.Any())
|
|
{
|
|
if (!propertyLogic.NamedFaceInfoDeterministicHashCodeKeyValuePairs.ContainsKey(item.Property.Id.Value))
|
|
continue;
|
|
minimumDateTime = Stateless.A_Property.GetMinimumDateTime(item.Property);
|
|
personKeys.AddRange(propertyLogic.NamedFaceInfoDeterministicHashCodeKeyValuePairs[item.Property.Id.Value]);
|
|
(isWrongYear, _) = item.Property.IsWrongYear(item.ImageFileHolder.FullName, minimumDateTime);
|
|
for (int i = 0; i < personKeys.Count; i++)
|
|
{
|
|
personBirthday = Shared.Models.Stateless.Methods.IPersonBirthday.GetPersonBirthday(personKeys[i]);
|
|
if (personBirthday is null)
|
|
continue;
|
|
item.Named.Add(new(isWrongYear, minimumDateTime, personBirthday));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
public static List<(Item, (string, IFace?, (string, string, string, string))[])> GetCollection(PropertyLogic propertyLogic, List<Item> items, string dFacesContentDirectory)
|
|
{
|
|
List<(Item, (string, IFace?, (string, string, string, string))[])> results = new();
|
|
Item item;
|
|
string[] keys;
|
|
string directory;
|
|
string personKey;
|
|
bool? isWrongYear;
|
|
const int zero = 0;
|
|
TimeSpan? timeSpan;
|
|
string copyFileName;
|
|
string copyDirectory;
|
|
string? relativePath;
|
|
string isWrongYearFlag;
|
|
string shortcutFileName;
|
|
string subDirectoryName;
|
|
List<int> indices = new();
|
|
DateTime? minimumDateTime;
|
|
List<IFace> faceCollection;
|
|
PersonBirthday? personBirthday;
|
|
List<(string, IFace?, (string, string, string, string))> collection;
|
|
for (int i = 0; i < items.Count; i++)
|
|
{
|
|
indices.Clear();
|
|
copyFileName = string.Empty;
|
|
copyDirectory = string.Empty;
|
|
item = items[i];
|
|
if (item.ImageFileHolder is null)
|
|
continue;
|
|
relativePath = Path.GetDirectoryName($"C:{item.RelativePath}");
|
|
if (string.IsNullOrEmpty(relativePath) || relativePath.Length < 3)
|
|
continue;
|
|
if (item.Property?.Id is null || item.ResizedFileHolder is null)
|
|
continue;
|
|
collection = new();
|
|
if (!propertyLogic.NamedFaceInfoDeterministicHashCodeKeyValuePairs.ContainsKey(item.Property.Id.Value))
|
|
{
|
|
faceCollection = new();
|
|
personKey = string.Empty;
|
|
directory = Path.Combine(dFacesContentDirectory, $"Unnamed{relativePath[2..]}");
|
|
}
|
|
else
|
|
{
|
|
faceCollection = item.Faces;
|
|
keys = propertyLogic.NamedFaceInfoDeterministicHashCodeKeyValuePairs[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}{minimumDateTime.Value:yyyy}";
|
|
if (!faceCollection.Any())
|
|
{
|
|
personKey = string.Empty;
|
|
directory = Path.Combine(dFacesContentDirectory, $"None{relativePath[2..]}", subDirectoryName);
|
|
}
|
|
else if (keys.Length != 1)
|
|
{
|
|
personKey = string.Empty;
|
|
directory = Path.Combine(dFacesContentDirectory, $"Not Supported{relativePath[2..]}", subDirectoryName);
|
|
}
|
|
else if (faceCollection.Count != 1)
|
|
{
|
|
personKey = string.Empty;
|
|
directory = Path.Combine(dFacesContentDirectory, $"Many{relativePath[2..]}", subDirectoryName);
|
|
}
|
|
else
|
|
{
|
|
indices.Add(zero);
|
|
personKey = keys[zero];
|
|
personBirthday = Shared.Models.Stateless.Methods.IPersonBirthday.GetPersonBirthday(personKey);
|
|
if (personBirthday is null)
|
|
continue;
|
|
timeSpan = Shared.Models.Stateless.Methods.IPersonBirthday.GetTimeSpan(minimumDateTime.Value, isWrongYear, personBirthday);
|
|
if (timeSpan.HasValue)
|
|
{
|
|
if (timeSpan.Value.Ticks < 0)
|
|
subDirectoryName = "!---";
|
|
else
|
|
subDirectoryName = $"^{Math.Floor(timeSpan.Value.TotalDays / 365):000}";
|
|
}
|
|
directory = Path.Combine(dFacesContentDirectory, "Shortcuts", personKey, subDirectoryName);
|
|
if (faceCollection[zero].Populated)
|
|
copyDirectory = Path.Combine(dFacesContentDirectory, "Images", personKey, subDirectoryName);
|
|
else
|
|
copyDirectory = Path.Combine(dFacesContentDirectory, "ImagesBut", personKey, subDirectoryName);
|
|
copyFileName = Path.Combine(copyDirectory, $"{item.Property.Id.Value}{item.ResizedFileHolder.ExtensionLowered}");
|
|
}
|
|
}
|
|
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
|
|
{
|
|
foreach (int index in indices)
|
|
collection.Add(new(personKey, faceCollection[index], (directory, copyDirectory, copyFileName, shortcutFileName)));
|
|
}
|
|
results.Add(new(item, collection.ToArray()));
|
|
}
|
|
return results;
|
|
}
|
|
|
|
public static string GetKey(DateTime minimumDateTime, bool? isWrongYear, PersonBirthday personBirthday)
|
|
{
|
|
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
|
|
{
|
|
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 (!container.SourceDirectory.StartsWith(argZero))
|
|
continue;
|
|
foreach (Item item in container.Items)
|
|
{
|
|
if (item.ImageFileHolder is null || item.Property is null || !item.Named.Any())
|
|
continue;
|
|
foreach (Named named in item.Named)
|
|
{
|
|
if (named.NormalizedPixelPercentage is null && (item.Named.Count != 1 || item.Faces.Count != 1))
|
|
continue;
|
|
foreach (IFace face in item.Faces)
|
|
{
|
|
if (!face.Populated)
|
|
continue;
|
|
if (named.PersonBirthday is null)
|
|
continue;
|
|
if (named.NormalizedPixelPercentage.HasValue && named.NormalizedPixelPercentage.Value != face.Location.NormalizedPixelPercentage)
|
|
continue;
|
|
key = GetKey(named.MinimumDateTime, named.IsWrongYear, named.PersonBirthday);
|
|
if (!results.ContainsKey(key))
|
|
results.Add(key, new());
|
|
results[key].Add(new(named.MinimumDateTime, named.IsWrongYear, named.PersonBirthday, face));
|
|
if (named.NormalizedPixelPercentage is null)
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return results;
|
|
}
|
|
|
|
} |