305 lines
15 KiB
C#
305 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 PropertyHolder
|
|
{
|
|
|
|
protected readonly bool? _Abandoned;
|
|
protected readonly bool? _Changed;
|
|
protected List<IFace> _Faces;
|
|
protected readonly FileInfo? _ImageFileInfo;
|
|
protected readonly string _ImageFileNameWithoutExtension;
|
|
protected readonly int _G;
|
|
protected DateTime? _MinimumDateTime;
|
|
protected bool? _Moved;
|
|
protected List<(bool?, DateTime, PersonBirthday, double?)> _Named;
|
|
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;
|
|
public bool? Abandoned => _Abandoned;
|
|
public bool? Changed => _Changed;
|
|
public List<IFace> Faces => _Faces;
|
|
public FileInfo? ImageFileInfo => _ImageFileInfo;
|
|
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 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 PropertyHolder()
|
|
{
|
|
_G = -1;
|
|
_R = -1;
|
|
_Faces = new();
|
|
_Named = new();
|
|
_RelativePath = string.Empty;
|
|
_SourceDirectory = string.Empty;
|
|
_SourceDirectoryFile = string.Empty;
|
|
_ImageFileNameWithoutExtension = string.Empty;
|
|
}
|
|
|
|
[JsonConstructor]
|
|
public PropertyHolder(int g, string sourceDirectory, string sourceDirectoryFile, string relativePath, int r, FileInfo? imageFileInfo, A_Property? property, bool? abandoned, bool? changed, bool? moved, bool? validImageFormatExtension)
|
|
{
|
|
_G = g;
|
|
_R = r;
|
|
_Faces = new();
|
|
_Moved = moved;
|
|
_Named = new();
|
|
_Changed = changed;
|
|
_Property = property;
|
|
_Abandoned = abandoned;
|
|
_NoJson = abandoned is null;
|
|
_RelativePath = relativePath;
|
|
_ImageFileInfo = 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")
|
|
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 ? "~" : "=";
|
|
|
|
public void SetResizedFileInfo(FileInfo fileInfo) => _ResizedFileInfo = fileInfo;
|
|
|
|
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 static void AddToNamed(PropertyLogic propertyLogic, PropertyHolder[] filteredPropertyHolderCollection)
|
|
{
|
|
bool? isWrongYear;
|
|
string[] segments;
|
|
string[] personKeys;
|
|
double? pixelPercentage;
|
|
DateTime minimumDateTime;
|
|
PropertyHolder propertyHolder;
|
|
PersonBirthday? personBirthday;
|
|
for (int i = 0; i < filteredPropertyHolderCollection.Length; i++)
|
|
{
|
|
propertyHolder = filteredPropertyHolderCollection[i];
|
|
if (propertyHolder.ImageFileInfo is null)
|
|
continue;
|
|
if (propertyHolder.Property?.Id is null || propertyHolder.MinimumDateTime is null || propertyHolder.ResizedFileInfo is null)
|
|
continue;
|
|
if (!propertyLogic.NamedFaceInfoDeterministicHashCodeIndices.ContainsKey(propertyHolder.Property.Id.Value))
|
|
continue;
|
|
minimumDateTime = Stateless.A_Property.GetMinimumDateTime(propertyHolder.Property);
|
|
personKeys = propertyLogic.NamedFaceInfoDeterministicHashCodeIndices[propertyHolder.Property.Id.Value];
|
|
(isWrongYear, _) = propertyHolder.Property.IsWrongYear(propertyHolder.ImageFileInfo.FullName, minimumDateTime);
|
|
for (int j = 0; j < personKeys.Length; j++)
|
|
{
|
|
segments = Shared.Models.Stateless.Methods.IPersonBirthday.GetSegments(personKeys[j]);
|
|
personBirthday = Shared.Models.Stateless.Methods.IPersonBirthday.GetPersonBirthday(personKeys[j]);
|
|
if (personBirthday is null)
|
|
continue;
|
|
if (segments.Length <= 1 || !double.TryParse(segments[1], out double value))
|
|
pixelPercentage = null;
|
|
else
|
|
pixelPercentage = value;
|
|
propertyHolder.Named.Add(new(isWrongYear, minimumDateTime, personBirthday, pixelPercentage));
|
|
}
|
|
}
|
|
}
|
|
|
|
public static List<(PropertyHolder, (string, IFace?, (string, string, string, string))[])> GetCollection(PropertyLogic propertyLogic, PropertyHolder[] filteredPropertyHolderCollection, string dFacesContentDirectory)
|
|
{
|
|
List<(PropertyHolder, (string, IFace?, (string, string, string, string))[])> results = new();
|
|
string[] keys;
|
|
string directory;
|
|
string personKey;
|
|
bool? isWrongYear;
|
|
string[] segments;
|
|
const int zero = 0;
|
|
TimeSpan? timeSpan;
|
|
string copyFileName;
|
|
string copyDirectory;
|
|
string? relativePath;
|
|
string isWrongYearFlag;
|
|
string shortcutFileName;
|
|
string subDirectoryName;
|
|
List<int> indices = new();
|
|
List<IFace> faceCollection;
|
|
PropertyHolder propertyHolder;
|
|
PersonBirthday? personBirthday;
|
|
List<(string, IFace?, (string, string, string, string))> collection;
|
|
for (int i = 0; i < filteredPropertyHolderCollection.Length; i++)
|
|
{
|
|
indices.Clear();
|
|
personKey = string.Empty;
|
|
copyFileName = string.Empty;
|
|
copyDirectory = string.Empty;
|
|
propertyHolder = filteredPropertyHolderCollection[i];
|
|
if (propertyHolder.ImageFileInfo is null)
|
|
continue;
|
|
relativePath = Path.GetDirectoryName($"C:{propertyHolder.RelativePath}");
|
|
if (string.IsNullOrEmpty(relativePath) || relativePath.Length < 3)
|
|
continue;
|
|
if (propertyHolder.Property?.Id is null || propertyHolder.MinimumDateTime is null || propertyHolder.ResizedFileInfo is null)
|
|
continue;
|
|
collection = new();
|
|
if (!propertyLogic.NamedFaceInfoDeterministicHashCodeIndices.ContainsKey(propertyHolder.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.ImageFileInfo.FullName, propertyHolder.MinimumDateTime.Value);
|
|
isWrongYearFlag = GetWrongYearFlag(isWrongYear);
|
|
subDirectoryName = $"{isWrongYearFlag}{propertyHolder.MinimumDateTime.Value:yyyy}";
|
|
if (!faceCollection.Any())
|
|
directory = Path.Combine(dFacesContentDirectory, $"None{relativePath[2..]}", subDirectoryName);
|
|
else if (keys.Length != 1)
|
|
directory = Path.Combine(dFacesContentDirectory, $"Not Supported{relativePath[2..]}", subDirectoryName);
|
|
else if (faceCollection.Count != 1)
|
|
directory = Path.Combine(dFacesContentDirectory, $"Many{relativePath[2..]}", subDirectoryName);
|
|
else
|
|
{
|
|
indices.Add(zero);
|
|
segments = Shared.Models.Stateless.Methods.IPersonBirthday.GetSegments(keys[zero]);
|
|
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);
|
|
if (timeSpan.HasValue)
|
|
{
|
|
if (timeSpan.Value.Ticks < 0)
|
|
subDirectoryName = "!---";
|
|
else
|
|
subDirectoryName = $"^{Math.Floor(timeSpan.Value.TotalDays / 365):000}";
|
|
}
|
|
personKey = segments[zero];
|
|
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, $"{propertyHolder.Property.Id.Value}{propertyHolder.ResizedFileInfo.Extension}");
|
|
}
|
|
}
|
|
shortcutFileName = Path.Combine(directory, $"{propertyHolder.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(propertyHolder, collection.ToArray()));
|
|
}
|
|
return results;
|
|
}
|
|
|
|
private static Dictionary<string, List<(string[], PersonBirthday, IFace)>> GetKeyValuePairs(string argZero, List<PropertyHolder[]> propertyHolderCollections, string eDistanceCollectionDirectory)
|
|
{
|
|
Dictionary<string, List<(string[], PersonBirthday, IFace)>> results = new();
|
|
string key;
|
|
string personKey;
|
|
TimeSpan? timeSpan;
|
|
string[] directories;
|
|
string isWrongYearFlag;
|
|
string facePopulatedKey;
|
|
foreach (PropertyHolder[] propertyHolderCollection in propertyHolderCollections)
|
|
{
|
|
if (!propertyHolderCollection.Any())
|
|
continue;
|
|
if (!propertyHolderCollection[0].SourceDirectory.StartsWith(argZero))
|
|
continue;
|
|
foreach (PropertyHolder propertyHolder in propertyHolderCollection)
|
|
{
|
|
if (propertyHolder.ImageFileInfo is null || propertyHolder.Property is null || !propertyHolder.Named.Any())
|
|
continue;
|
|
foreach ((bool? isWrongYear, DateTime minimumDateTime, PersonBirthday personBirthday, double? pixelPercentage) in propertyHolder.Named)
|
|
{
|
|
if (propertyHolder.MinimumDateTime is null)
|
|
continue;
|
|
if (pixelPercentage is null && (propertyHolder.Named.Count != 1 || propertyHolder.Faces.Count != 1))
|
|
continue;
|
|
foreach (IFace face in propertyHolder.Faces)
|
|
{
|
|
if (pixelPercentage.HasValue && pixelPercentage.Value != face.Location.PixelPercentage)
|
|
continue;
|
|
personKey = Shared.Models.Stateless.Methods.IPersonBirthday.GetFormatted(personBirthday);
|
|
timeSpan = Shared.Models.Stateless.Methods.IPersonBirthday.GetTimeSpan(minimumDateTime, isWrongYear, personBirthday);
|
|
if (face.Populated)
|
|
facePopulatedKey = "Images";
|
|
else
|
|
facePopulatedKey = "ImagesBut";
|
|
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}{propertyHolder.MinimumDateTime.Value:yyyy}" };
|
|
}
|
|
key = string.Join('\t', directories);
|
|
if (!results.ContainsKey(key))
|
|
results.Add(key, new());
|
|
directories[0] = eDistanceCollectionDirectory;
|
|
results[key].Add(new(directories, personBirthday, face));
|
|
if (pixelPercentage is null)
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return results;
|
|
}
|
|
|
|
public static List<(string, PersonBirthday, IFace)[]> GetCollection(string argZero, List<PropertyHolder[]> propertyHolderCollections, string eDistanceCollectionDirectory)
|
|
{
|
|
List<(string, PersonBirthday, IFace)[]> results = new();
|
|
string directory;
|
|
List<(string, PersonBirthday, IFace)> group;
|
|
Dictionary<string, List<(string[], PersonBirthday, IFace)>> keyValuePairs = GetKeyValuePairs(argZero, propertyHolderCollections, eDistanceCollectionDirectory);
|
|
foreach (KeyValuePair<string, List<(string[], PersonBirthday, IFace)>> keyValuePair in keyValuePairs)
|
|
{
|
|
group = new();
|
|
foreach ((string[] directories, PersonBirthday personBirthday, IFace face) in keyValuePair.Value)
|
|
{
|
|
directory = Path.Combine(directories);
|
|
group.Add(new(directory, personBirthday, face));
|
|
}
|
|
results.Add(group.ToArray());
|
|
}
|
|
return results;
|
|
}
|
|
|
|
} |