Remove Person Require People File,
PersonContainer and bug fix for GetRightPadded
This commit is contained in:
@ -55,6 +55,10 @@ public class Face : Properties.IFace
|
||||
_DateTime = (from l in dateTimes where l.HasValue select l.Value).Min();
|
||||
}
|
||||
|
||||
public Face(Face face, Location location, int locationDigits, int locationFactor, int zCount) :
|
||||
this(face.DateTime, face.FaceDistance, face.FaceEncoding, face.FaceParts, new(location, locationDigits, locationFactor, zCount), face.LocationIndex, face.Mapping, face.OutputResolution, face.RelativePath)
|
||||
{ }
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
string result = JsonSerializer.Serialize(this, new JsonSerializerOptions() { WriteIndented = true });
|
||||
|
@ -39,6 +39,10 @@ public class Location : Properties.ILocation, IEquatable<Location>
|
||||
this(bottom, confidence, left, Stateless.Methods.Location.GetNormalizedPixelPercentage(bottom, height, left, locationDigits, locationFactor, right, top, width, zCount), right, top) =>
|
||||
Stateless.Methods.Location.Check(_Bottom, height, _Left, _NormalizedPixelPercentage, _Right, _Top, width, zCount);
|
||||
|
||||
public Location(Location location, int locationDigits, int locationFactor, int zCount) :
|
||||
this(location.Bottom, location.Confidence, location.Left, Stateless.Methods.Location.GetNormalizedPixelPercentage(location.Bottom, height: location.Bottom - location.Top, location.Left, locationDigits, locationFactor, location.Right, location.Top, width: location.Right - location.Left, zCount), location.Right, location.Top) =>
|
||||
Stateless.Methods.Location.Check(_Bottom, _Left, _NormalizedPixelPercentage, _Right, _Top, zCount);
|
||||
|
||||
public Location(double confidence, int factor, int height, Location location, int locationDigits, int locationFactor, int width, int zCount)
|
||||
{
|
||||
int x = (location.Right - location.Left) / factor;
|
||||
|
41
Shared/Models/PersonContainer.cs
Normal file
41
Shared/Models/PersonContainer.cs
Normal file
@ -0,0 +1,41 @@
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace View_by_Distance.Shared.Models;
|
||||
|
||||
public class PersonContainer : Properties.IPersonContainer
|
||||
{
|
||||
|
||||
public int? ApproximateYears { init; get; }
|
||||
public Person? Person { init; get; }
|
||||
public PersonBirthday[]? PersonBirthdays { init; get; }
|
||||
public string[] PersonDisplayDirectoryAllFiles { init; get; }
|
||||
public string PersonDisplayDirectoryName { init; get; }
|
||||
public long? PersonKey { init; get; }
|
||||
|
||||
[JsonConstructor]
|
||||
public PersonContainer(int? approximateYears, Person? person, PersonBirthday[]? personBirthdays, string[] personDisplayDirectoryAllFiles, string personDisplayDirectoryName, long? personKey)
|
||||
{
|
||||
ApproximateYears = approximateYears;
|
||||
Person = person;
|
||||
PersonBirthdays = personBirthdays;
|
||||
PersonDisplayDirectoryAllFiles = personDisplayDirectoryAllFiles;
|
||||
PersonDisplayDirectoryName = personDisplayDirectoryName;
|
||||
PersonKey = personKey;
|
||||
}
|
||||
|
||||
public PersonContainer(int? approximateYears, string[] personDisplayDirectoryAllFiles, string personDisplayDirectoryName) :
|
||||
this(approximateYears, null, null, personDisplayDirectoryAllFiles, personDisplayDirectoryName, null)
|
||||
{ }
|
||||
|
||||
public PersonContainer(int? approximateYears, PersonBirthday personBirthday, string personDisplayDirectoryName, long personKey) :
|
||||
this(approximateYears, null, new PersonBirthday[] { personBirthday }, Array.Empty<string>(), personDisplayDirectoryName, personKey)
|
||||
{ }
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
string result = JsonSerializer.Serialize(this, new JsonSerializerOptions() { WriteIndented = true });
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
13
Shared/Models/Properties/IPersonContainer.cs
Normal file
13
Shared/Models/Properties/IPersonContainer.cs
Normal file
@ -0,0 +1,13 @@
|
||||
namespace View_by_Distance.Shared.Models.Properties;
|
||||
|
||||
public interface IPersonContainer
|
||||
{
|
||||
|
||||
public int? ApproximateYears { init; get; }
|
||||
public Person? Person { init; get; }
|
||||
public PersonBirthday[]? PersonBirthdays { init; get; }
|
||||
public string[] PersonDisplayDirectoryAllFiles { init; get; }
|
||||
public string PersonDisplayDirectoryName { init; get; }
|
||||
public long? PersonKey { init; get; }
|
||||
|
||||
}
|
@ -31,4 +31,16 @@ internal abstract class Age
|
||||
return (years, result);
|
||||
}
|
||||
|
||||
internal static int? GetApproximateYears(string personDisplayDirectoryName, char[] chars)
|
||||
{
|
||||
int? result;
|
||||
const int zero = 0;
|
||||
string[] segments = personDisplayDirectoryName.Split(chars);
|
||||
if (segments.Length == 1 || !int.TryParse(segments[1].Split('-')[zero], out int years))
|
||||
result = null;
|
||||
else
|
||||
result = years;
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
@ -28,6 +28,21 @@ internal abstract class Face
|
||||
return result;
|
||||
}
|
||||
|
||||
internal static List<Models.Face> GetVerifiedFaces(int locationDigits, int locationFactor, List<Models.Face> faces)
|
||||
{
|
||||
List<Models.Face> results = new();
|
||||
foreach (Models.Face face in faces)
|
||||
{
|
||||
if (face.Location?.NormalizedPixelPercentage is null)
|
||||
results.Add(face);
|
||||
else if (face.Location.NormalizedPixelPercentage.ToString() == ILocation.GetRightPadded(locationDigits, face.Location.NormalizedPixelPercentage.Value))
|
||||
results.Add(face);
|
||||
else
|
||||
results.Add(new(face, face.Location, locationDigits, locationFactor, faces.Count));
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
private static JsonElement[] GetJsonElements(string jsonFileFullName)
|
||||
{
|
||||
string json = GetJson(jsonFileFullName);
|
||||
|
@ -3,22 +3,38 @@ namespace View_by_Distance.Shared.Models.Stateless.Methods;
|
||||
public interface IFace
|
||||
{ // ...
|
||||
|
||||
string TestStatic_GetJson(string jsonFileFullName);
|
||||
static string GetJson(string jsonFileFullName) => Face.GetJson(jsonFileFullName);
|
||||
string TestStatic_GetJson(string jsonFileFullName) =>
|
||||
GetJson(jsonFileFullName);
|
||||
static string GetJson(string jsonFileFullName) =>
|
||||
Face.GetJson(jsonFileFullName);
|
||||
|
||||
double TestStatic_Getα(int x1, int x2, int y1, int y2);
|
||||
static double Getα(int x1, int x2, int y1, int y2) => Face.Getα(x1, x2, y1, y2);
|
||||
double TestStatic_Getα(int x1, int x2, int y1, int y2) =>
|
||||
Getα(x1, x2, y1, y2);
|
||||
static double Getα(int x1, int x2, int y1, int y2) =>
|
||||
Face.Getα(x1, x2, y1, y2);
|
||||
|
||||
Models.Face TestStatic_GetFace(string jsonFileFullName);
|
||||
static Models.Face GetFace(string jsonFileFullName) => Face.GetFace(jsonFileFullName);
|
||||
Models.Face TestStatic_GetFace(string jsonFileFullName) =>
|
||||
GetFace(jsonFileFullName);
|
||||
static Models.Face GetFace(string jsonFileFullName) =>
|
||||
Face.GetFace(jsonFileFullName);
|
||||
|
||||
Models.Face[] TestStatic_GetFaces(string jsonFileFullName);
|
||||
static Models.Face[] GetFaces(string jsonFileFullName) => Face.GetFaces(jsonFileFullName);
|
||||
List<Models.Face> TestStatic_GetVerifiedFaces(int locationDigits, int locationFactor, List<Models.Face> faces) =>
|
||||
GetVerifiedFaces(locationDigits, locationFactor, faces);
|
||||
static List<Models.Face> GetVerifiedFaces(int locationDigits, int locationFactor, List<Models.Face> faces) =>
|
||||
Face.GetVerifiedFaces(locationDigits, locationFactor, faces);
|
||||
|
||||
Models.Face[] TestStatic_Getα(Dictionary<FacePart, Models.FacePoint[]> faceParts);
|
||||
static double? Getα(Dictionary<FacePart, Models.FacePoint[]> faceParts) => Face.Getα(faceParts);
|
||||
Models.Face[] TestStatic_GetFaces(string jsonFileFullName) =>
|
||||
GetFaces(jsonFileFullName);
|
||||
static Models.Face[] GetFaces(string jsonFileFullName) =>
|
||||
Face.GetFaces(jsonFileFullName);
|
||||
|
||||
int?[] TestStatic_GetInts(List<Models.Face> faces);
|
||||
double? TestStatic_Getα(Dictionary<FacePart, Models.FacePoint[]> faceParts) =>
|
||||
Getα(faceParts);
|
||||
static double? Getα(Dictionary<FacePart, Models.FacePoint[]> faceParts) =>
|
||||
Face.Getα(faceParts);
|
||||
|
||||
int?[] TestStatic_GetInts(List<Models.Face> faces) =>
|
||||
GetInts(faces);
|
||||
static int?[] GetInts(List<Models.Face> faces) =>
|
||||
(from l in faces where l.FaceEncoding is not null && l.Location?.NormalizedPixelPercentage is not null select l.Location?.NormalizedPixelPercentage).ToArray();
|
||||
|
||||
|
@ -3,6 +3,16 @@ namespace View_by_Distance.Shared.Models.Stateless.Methods;
|
||||
public interface ILocation
|
||||
{ // ...
|
||||
|
||||
string TestStatic_GetRightPadded(int locationDigits, string value) =>
|
||||
GetRightPadded(locationDigits, value);
|
||||
static string GetRightPadded(int locationDigits, string value) =>
|
||||
value.PadRight(locationDigits, '0');
|
||||
|
||||
string TestStatic_GetRightPadded(int locationDigits, int value) =>
|
||||
GetRightPadded(locationDigits, value);
|
||||
static string GetRightPadded(int locationDigits, int value) =>
|
||||
GetRightPadded(locationDigits, value.ToString());
|
||||
|
||||
Models.Location? TestStatic_GetLocation(Models.Location? location, int locationDigits, int locationFactor, int height, int width, int zCount) =>
|
||||
GetLocation(location, locationDigits, locationFactor, height, width, zCount);
|
||||
static Models.Location? GetLocation(Models.Location? location, int locationDigits, int locationFactor, int height, int width, int zCount) =>
|
||||
|
@ -6,6 +6,11 @@ public interface IMapping
|
||||
static string GetDeterministicHashCodeKey(int id, int normalizedPixelPercentage)
|
||||
=> $"{id}.{normalizedPixelPercentage}";
|
||||
|
||||
(int?, int?, List<Models.Face>?) TestStatic_GetReversedDeterministicHashCodeKey(int locationDigits, string file) =>
|
||||
GetReversedDeterministicHashCodeKey(locationDigits, file);
|
||||
static (int?, int?, List<Models.Face>?) GetReversedDeterministicHashCodeKey(int locationDigits, string file) =>
|
||||
Mapping.GetReversedDeterministicHashCodeKey(locationDigits, false, new(), file);
|
||||
|
||||
(int?, int?, List<Models.Face>?) TestStatic_GetReversedDeterministicHashCodeKey(int locationDigits, bool keyValuePairsAny, Dictionary<int, List<Models.Face>> keyValuePairs, string file) =>
|
||||
GetReversedDeterministicHashCodeKey(locationDigits, keyValuePairsAny, keyValuePairs, file);
|
||||
static (int?, int?, List<Models.Face>?) GetReversedDeterministicHashCodeKey(int locationDigits, bool keyValuePairsAny, Dictionary<int, List<Models.Face>> keyValuePairs, string file) =>
|
||||
|
@ -5,29 +5,19 @@ public interface IPerson
|
||||
|
||||
// ...
|
||||
|
||||
Dictionary<DateTime, string[]> TestStatic_Split(int personBirthdayFirstYear, string personKeyFormat, string knownPeopleFile) =>
|
||||
Split(personBirthdayFirstYear, personKeyFormat, knownPeopleFile);
|
||||
static Dictionary<DateTime, string[]> Split(int personBirthdayFirstYear, string personKeyFormat, string knownPeopleFile) =>
|
||||
Person.Split(personBirthdayFirstYear, personKeyFormat, knownPeopleFile);
|
||||
|
||||
Models.Person[] TestStatic_GetPeople(Properties.IStorage storage, int personBirthdayFirstYear, string personBirthdayFormat, string personKeyFormat, bool personRequirePeopleFile) =>
|
||||
GetPeople(storage, personBirthdayFirstYear, personBirthdayFormat, personKeyFormat, personRequirePeopleFile);
|
||||
static Models.Person[] GetPeople(Properties.IStorage storage, int personBirthdayFirstYear, string personBirthdayFormat, string personKeyFormat, bool personRequirePeopleFile) =>
|
||||
Person.GetPeople(storage, personBirthdayFirstYear, personBirthdayFormat, personKeyFormat, personRequirePeopleFile);
|
||||
|
||||
void TestStatic_SavePerson(Properties.IStorage storage, string personBirthdayFormat, Models.Person person) =>
|
||||
SavePerson(storage, personBirthdayFormat, person);
|
||||
static void SavePerson(Properties.IStorage storage, string personBirthdayFormat, Models.Person person) =>
|
||||
Person.SavePerson(storage, personBirthdayFormat, person);
|
||||
|
||||
string TestStatic_GetFileFullName(Properties.IStorage storage, string personBirthdayFormat, Models.Person person) =>
|
||||
GetFileFullName(storage, personBirthdayFormat, person);
|
||||
static string GetFileFullName(Properties.IStorage storage, string personBirthdayFormat, Models.Person person) =>
|
||||
PersonBirthday.GetFileFullName(storage, personBirthdayFormat, person.Birthday);
|
||||
|
||||
Models.Person TestStatic_CreatePerson(Properties.IStorage storage, string personBirthdayFormat, Models.PersonBirthday birthday, Models.PersonName name, List<Models.PersonComment> comments, List<Models.PersonURL> urls, List<Models.PersonNumber> numbers, List<Models.PersonEmail> emails, List<Models.PersonAddress> addresses) =>
|
||||
CreatePerson(storage, personBirthdayFormat, birthday, name, comments, urls, numbers, emails, addresses);
|
||||
static Models.Person CreatePerson(Properties.IStorage storage, string personBirthdayFormat, Models.PersonBirthday birthday, Models.PersonName name, List<Models.PersonComment> comments, List<Models.PersonURL> urls, List<Models.PersonNumber> numbers, List<Models.PersonEmail> emails, List<Models.PersonAddress> addresses) =>
|
||||
Person.CreatePerson(storage, personBirthdayFormat, birthday, name, comments, urls, numbers, emails, addresses);
|
||||
Models.Person TestStatic_GetPerson(string resultAllInOne, long personKey, Models.PersonBirthday personBirthday) =>
|
||||
GetPerson(resultAllInOne, personKey, personBirthday);
|
||||
static Models.Person GetPerson(string resultAllInOne, long personKey, Models.PersonBirthday personBirthday) =>
|
||||
Person.GetPerson(personKey, personBirthday, new string[] { resultAllInOne });
|
||||
|
||||
Models.Person TestStatic_GetPerson(long personKey, string[] segments) =>
|
||||
GetPerson(personKey, segments);
|
||||
static Models.Person GetPerson(long personKey, string[] segments) =>
|
||||
Person.GetPerson(personKey, IPersonBirthday.GetPersonBirthday(personKey), segments);
|
||||
|
||||
}
|
@ -41,37 +41,43 @@ public interface IPersonBirthday
|
||||
static (int, TimeSpan) GetAge(long dateTimeTicks, Models.PersonBirthday birthday) =>
|
||||
PersonBirthday.GetAge(dateTimeTicks, birthday);
|
||||
|
||||
string TestStatic_GetFormatted(string personBirthdayFormat, long personKey) =>
|
||||
GetFormatted(personBirthdayFormat, personKey);
|
||||
static string GetFormatted(string personBirthdayFormat, long personKey) =>
|
||||
PersonBirthday.GetFormatted(personBirthdayFormat, GetPersonBirthday(personKey));
|
||||
|
||||
string TestStatic_GetFormatted(string personBirthdayFormat, Models.PersonBirthday personBirthday) =>
|
||||
PersonBirthday.GetFormatted(personBirthdayFormat, personBirthday);
|
||||
GetFormatted(personBirthdayFormat, personBirthday);
|
||||
static string GetFormatted(string personBirthdayFormat, Models.PersonBirthday personBirthday) =>
|
||||
PersonBirthday.GetFormatted(personBirthdayFormat, personBirthday);
|
||||
|
||||
Models.PersonBirthday? TestStatic_GetPersonBirthday(string personBirthdayFormat, string personKey) =>
|
||||
PersonBirthday.GetPersonBirthday(personBirthdayFormat, personKey);
|
||||
GetPersonBirthday(personBirthdayFormat, personKey);
|
||||
static Models.PersonBirthday? GetPersonBirthday(string personBirthdayFormat, string personKey) =>
|
||||
PersonBirthday.GetPersonBirthday(personBirthdayFormat, personKey);
|
||||
|
||||
bool TestStatic_IsCounterPersonBirthday(Models.PersonBirthday personBirthday);
|
||||
bool TestStatic_IsCounterPersonBirthday(Models.PersonBirthday personBirthday) =>
|
||||
IsCounterPersonBirthday(personBirthday);
|
||||
static bool IsCounterPersonBirthday(Models.PersonBirthday personBirthday) =>
|
||||
PersonBirthday.IsCounterPersonBirthday(personBirthday);
|
||||
|
||||
Models.PersonBirthday TestStatic_GetNextBirthDate(Properties.IStorage storage) =>
|
||||
PersonBirthday.GetNextBirthDate(storage);
|
||||
GetNextBirthDate(storage);
|
||||
static Models.PersonBirthday GetNextBirthDate(Properties.IStorage storage) =>
|
||||
PersonBirthday.GetNextBirthDate(storage);
|
||||
|
||||
TimeSpan? TestStatic_Get(DateTime minimumDateTime, Models.PersonBirthday personBirthday) =>
|
||||
PersonBirthday.GetTimeSpan(minimumDateTime, isWrongYear: false, personBirthday);
|
||||
GetTimeSpan(minimumDateTime, isWrongYear: false, personBirthday);
|
||||
static TimeSpan? GetTimeSpan(DateTime minimumDateTime, Models.PersonBirthday personBirthday) =>
|
||||
PersonBirthday.GetTimeSpan(minimumDateTime, isWrongYear: false, personBirthday);
|
||||
|
||||
TimeSpan? TestStatic_Get(long minimumDateTimeTicks, bool? isWrongYear, Models.PersonBirthday personBirthday) =>
|
||||
PersonBirthday.GetTimeSpan(minimumDateTimeTicks, isWrongYear, personBirthday);
|
||||
GetTimeSpan(minimumDateTimeTicks, isWrongYear, personBirthday);
|
||||
static TimeSpan? GetTimeSpan(long minimumDateTimeTicks, bool? isWrongYear, Models.PersonBirthday personBirthday) =>
|
||||
PersonBirthday.GetTimeSpan(minimumDateTimeTicks, isWrongYear, personBirthday);
|
||||
|
||||
string TestStatic_GetFileFullName(Properties.IStorage storage, string personBirthdayFormat, Models.PersonBirthday personBirthday) =>
|
||||
PersonBirthday.GetFileFullName(storage, personBirthdayFormat, personBirthday);
|
||||
GetFileFullName(storage, personBirthdayFormat, personBirthday);
|
||||
static string GetFileFullName(Properties.IStorage storage, string personBirthdayFormat, Models.PersonBirthday personBirthday) =>
|
||||
PersonBirthday.GetFileFullName(storage, personBirthdayFormat, personBirthday);
|
||||
|
||||
@ -81,11 +87,12 @@ public interface IPersonBirthday
|
||||
DoesBirthDateExits(storage, personBirthday);
|
||||
|
||||
TimeSpan? TestStatic_Get(DateTime minimumDateTime, bool? isWrongYear, Models.PersonBirthday personBirthday) =>
|
||||
PersonBirthday.GetTimeSpan(minimumDateTime, isWrongYear, personBirthday);
|
||||
GetTimeSpan(minimumDateTime, isWrongYear, personBirthday);
|
||||
static TimeSpan? GetTimeSpan(DateTime minimumDateTime, bool? isWrongYear, Models.PersonBirthday personBirthday) =>
|
||||
PersonBirthday.GetTimeSpan(minimumDateTime, isWrongYear, personBirthday);
|
||||
|
||||
bool TestStatic_IsWrongYearFilterOrCounterPersonBirthday(bool? isWrongYear, Models.PersonBirthday personBirthday);
|
||||
bool TestStatic_IsWrongYearFilterOrCounterPersonBirthday(bool? isWrongYear, Models.PersonBirthday personBirthday) =>
|
||||
IsWrongYearFilterOrCounterPersonBirthday(isWrongYear, personBirthday);
|
||||
static bool IsWrongYearFilterOrCounterPersonBirthday(bool? isWrongYear, Models.PersonBirthday personBirthday) =>
|
||||
PersonBirthday.IsWrongYearFilterOrCounterPersonBirthday(isWrongYear, personBirthday);
|
||||
|
||||
|
13
Shared/Models/Stateless/Methods/IPersonContainer.cs
Normal file
13
Shared/Models/Stateless/Methods/IPersonContainer.cs
Normal file
@ -0,0 +1,13 @@
|
||||
namespace View_by_Distance.Shared.Models.Stateless.Methods;
|
||||
|
||||
public interface IPersonContainer
|
||||
{
|
||||
|
||||
// ...
|
||||
|
||||
List<Models.PersonContainer> TestStatic_GetPersonContainers(Properties.IStorage storage, string personBirthdayFormat) =>
|
||||
GetPersonContainers(storage, personBirthdayFormat);
|
||||
static List<Models.PersonContainer> GetPersonContainers(Properties.IStorage storage, string personBirthdayFormat) =>
|
||||
PersonContainer.GetPersonContainers(storage, personBirthdayFormat);
|
||||
|
||||
}
|
@ -16,6 +16,9 @@ internal abstract class Location
|
||||
if (value < 0)
|
||||
value = 3;
|
||||
result = (int)(Math.Round(value, locationDigits) * locationFactor);
|
||||
string rightPadded = ILocation.GetRightPadded(locationDigits, result);
|
||||
if (result.ToString() != rightPadded)
|
||||
result = int.Parse(rightPadded);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -24,7 +24,7 @@ internal abstract class Mapping
|
||||
faces = null;
|
||||
normalizedPixelPercentage = null;
|
||||
}
|
||||
else if (!int.TryParse(segments[0], out int idValue) || !int.TryParse(segments[1].PadRight(locationDigits, '0'), out int normalizedPixelPercentageValue))
|
||||
else if (!int.TryParse(segments[0], out int idValue) || !int.TryParse(ILocation.GetRightPadded(locationDigits, segments[1]), out int normalizedPixelPercentageValue))
|
||||
{
|
||||
id = null;
|
||||
faces = null;
|
||||
|
@ -1,6 +1,3 @@
|
||||
using System.Text.Json;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace View_by_Distance.Shared.Models.Stateless.Methods;
|
||||
|
||||
internal abstract class Person
|
||||
@ -8,288 +5,29 @@ internal abstract class Person
|
||||
|
||||
// ...
|
||||
|
||||
private static List<string> ValidatePerson(Properties.IStorage storage, string personBirthdayFormat, Models.PersonId id, Models.PersonBirthday birthday, Models.PersonName name)
|
||||
internal static (Models.PersonBirthday?, string) Get(string personBirthdayFormat, string personDisplayDirectory, string personKeyDirectory, DateTime birthday)
|
||||
{
|
||||
List<string> results = new();
|
||||
if (birthday is null)
|
||||
throw new Exception("Birthday must be supplied!");
|
||||
if (birthday.Value > DateTime.Now)
|
||||
results.Add("Birthday must be in the past!");
|
||||
if (id is null)
|
||||
throw new Exception("Birthday must be supplied!");
|
||||
if (id.Value != birthday.Value.Ticks)
|
||||
results.Add("Id must be Birthday ticks!");
|
||||
if (name.First is null || string.IsNullOrEmpty(name.First.Value))
|
||||
results.Add("Fist Name must be supplied!");
|
||||
if (PersonBirthday.DoesBirthDateExits(storage, personBirthdayFormat, birthday))
|
||||
results.Add("BirthDate already exits!");
|
||||
return results;
|
||||
Models.PersonBirthday? personBirthday = new(birthday);
|
||||
string personKeyFormatted = IPersonBirthday.GetFormatted(personBirthdayFormat, personBirthday);
|
||||
string convertedPersonKeyDirectory = Path.Combine(personDisplayDirectory, personKeyFormatted);
|
||||
if (!Directory.Exists(convertedPersonKeyDirectory))
|
||||
Directory.Move(personKeyDirectory, convertedPersonKeyDirectory);
|
||||
return new(personBirthday, personKeyFormatted);
|
||||
}
|
||||
|
||||
internal static Models.Person CreatePerson(Properties.IStorage storage, string personBirthdayFormat, Models.PersonBirthday birthday, Models.PersonName name, List<Models.PersonComment> comments, List<Models.PersonURL> urls, List<Models.PersonNumber> numbers, List<Models.PersonEmail> emails, List<Models.PersonAddress> addresses)
|
||||
internal static Models.Person GetPerson(long personKey, Models.PersonBirthday personBirthday, string[] segments)
|
||||
{
|
||||
Models.Person result;
|
||||
Models.PersonId id = new(birthday.Value.Ticks);
|
||||
if (birthday.Value == DateTime.MinValue)
|
||||
birthday = PersonBirthday.GetNextBirthDate(storage);
|
||||
List<string> results = ValidatePerson(storage, personBirthdayFormat, id, birthday, name);
|
||||
if (results.Any())
|
||||
throw new Exception(string.Join(Environment.NewLine, results));
|
||||
if (comments is null)
|
||||
comments = new();
|
||||
if (urls is null)
|
||||
urls = new();
|
||||
if (numbers is null)
|
||||
numbers = new();
|
||||
if (emails is null)
|
||||
emails = new();
|
||||
if (addresses is null)
|
||||
addresses = new();
|
||||
result = new(id, birthday, name, comments, urls, numbers, emails, addresses);
|
||||
return result;
|
||||
}
|
||||
|
||||
private static void SetSegments(ref string[] segments, string KeyFormat, ref DateTime incrementDate)
|
||||
{
|
||||
if (segments[0].Length != KeyFormat.Length || !segments[0].Contains('-') || !segments[0].Contains('_'))
|
||||
{
|
||||
List<string> temporarySegments;
|
||||
temporarySegments = segments.ToList();
|
||||
temporarySegments.Insert(0, incrementDate.ToString(KeyFormat));
|
||||
segments = temporarySegments.ToArray();
|
||||
incrementDate = incrementDate.AddDays(1);
|
||||
}
|
||||
}
|
||||
|
||||
internal static Dictionary<DateTime, string[]> Split(int personBirthdayFirstYear, string personKeyFormat, string knownPeopleFile)
|
||||
{
|
||||
Dictionary<DateTime, string[]> results = new();
|
||||
string[] segments;
|
||||
DateTime personKey;
|
||||
DateTime incrementDate = new(personBirthdayFirstYear, 1, 1);
|
||||
string[] lines = File.ReadAllLines(knownPeopleFile);
|
||||
_ = incrementDate.AddDays(lines.Length);
|
||||
System.Globalization.CultureInfo cultureInfo = System.Globalization.CultureInfo.InvariantCulture;
|
||||
foreach (string line in lines)
|
||||
{
|
||||
if (string.IsNullOrEmpty(line))
|
||||
continue;
|
||||
segments = line.Replace(" //", "\t//").Split('\t');
|
||||
if (segments.Length < 1)
|
||||
continue;
|
||||
SetSegments(ref segments, personKeyFormat, ref incrementDate);
|
||||
personKey = DateTime.ParseExact(segments[0], personKeyFormat, cultureInfo);
|
||||
if (results.ContainsKey(personKey))
|
||||
continue;
|
||||
results.Add(personKey, segments);
|
||||
}
|
||||
if (results.Any())
|
||||
{
|
||||
int countBefore = results.Count;
|
||||
DateTime minimumDateTime = results.Keys.Min();
|
||||
for (int i = 1; i < (1000 - countBefore); i++)
|
||||
{
|
||||
personKey = minimumDateTime.AddDays(i * -1);
|
||||
results.Add(personKey, new string[] { personKey.ToString(personKeyFormat) });
|
||||
}
|
||||
}
|
||||
return results.OrderBy(l => l.Key).ToDictionary(l => l.Key, l => l.Value);
|
||||
}
|
||||
|
||||
private static void SetValues(ref string name, ref string comment, ref string mergeName, KeyValuePair<DateTime, string[]> splitLine)
|
||||
{
|
||||
foreach (string segment in splitLine.Value)
|
||||
{
|
||||
if (!segment.Contains('*'))
|
||||
continue;
|
||||
mergeName = segment.Split('*')[1].Split('\t')[0];
|
||||
}
|
||||
if (splitLine.Value[1].StartsWith("//"))
|
||||
comment = splitLine.Value[1];
|
||||
else
|
||||
name = splitLine.Value[1].Split('\t')[0];
|
||||
if (splitLine.Value.Length > 2)
|
||||
comment = splitLine.Value[2];
|
||||
}
|
||||
|
||||
private static void CheckSplitLineAndSetValues(ref string name, ref string comment, ref string mergeName, KeyValuePair<DateTime, string[]> splitLine)
|
||||
{
|
||||
if (splitLine.Value.Length > 1)
|
||||
SetValues(ref name, ref comment, ref mergeName, splitLine);
|
||||
}
|
||||
|
||||
private static Dictionary<DateTime, PersonImport> GetPersonCollection(int personBirthdayFirstYear, string personKeyFormat, string knownPeopleFile)
|
||||
{
|
||||
Dictionary<DateTime, PersonImport> results = new();
|
||||
string name;
|
||||
DateTime key;
|
||||
string comment;
|
||||
string oldName;
|
||||
string mergeName;
|
||||
PersonImport person;
|
||||
Dictionary<DateTime, string[]> splitLines = Split(personBirthdayFirstYear, personKeyFormat, knownPeopleFile);
|
||||
foreach (KeyValuePair<DateTime, string[]> splitLine in splitLines)
|
||||
{
|
||||
name = string.Empty;
|
||||
key = splitLine.Key;
|
||||
comment = string.Empty;
|
||||
oldName = string.Empty;
|
||||
mergeName = string.Empty;
|
||||
CheckSplitLineAndSetValues(ref name, ref comment, ref mergeName, splitLine);
|
||||
person = new(key, name, mergeName, oldName, comment);
|
||||
results.Add(splitLine.Key, person);
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
internal static void SavePerson(Properties.IStorage storage, string personBirthdayFormat, Models.Person person)
|
||||
{
|
||||
string fileName = IPerson.GetFileFullName(storage, personBirthdayFormat, person);
|
||||
string json = JsonSerializer.Serialize(person, new JsonSerializerOptions { WriteIndented = true });
|
||||
_ = IStorage.WriteAllText(fileName, json, updateDateWhenMatches: true, compareBeforeWrite: true);
|
||||
}
|
||||
|
||||
private static string GetComment(List<Models.PersonURL> urls, List<Models.PersonComment> comments, KeyValuePair<DateTime, PersonImport> keyValuePair)
|
||||
{
|
||||
string result = keyValuePair.Value.Comment[2..];
|
||||
if (!string.IsNullOrEmpty(result))
|
||||
{
|
||||
if (result.StartsWith("http://") || result.StartsWith("https://"))
|
||||
urls.Add(new(new(result)));
|
||||
else
|
||||
comments.Add(new(new(result)));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private static List<Models.Person> GetPeopleFromText(Properties.IStorage storage, int personBirthdayFirstYear, string personBirthdayFormat, string personKeyFormat, string localKnownPeopleFile)
|
||||
{
|
||||
List<Models.Person> results = new();
|
||||
string comment;
|
||||
Models.Person person;
|
||||
Models.PersonName name;
|
||||
List<Models.PersonURL> urls;
|
||||
Models.PersonBirthday birthday;
|
||||
List<Models.PersonComment> comments;
|
||||
const int zero = 0;
|
||||
List<Models.PersonURL> urls = new();
|
||||
Models.PersonId id = new(personKey);
|
||||
List<Models.PersonEmail> emails = new();
|
||||
List<Models.PersonNumber> numbers = new();
|
||||
List<Models.PersonComment> comments = new();
|
||||
List<Models.PersonAddress> addresses = new();
|
||||
Dictionary<DateTime, PersonImport> keyValuePairs = GetPersonCollection(personBirthdayFirstYear, personKeyFormat, localKnownPeopleFile);
|
||||
foreach (KeyValuePair<DateTime, PersonImport> keyValuePair in keyValuePairs)
|
||||
{
|
||||
if (string.IsNullOrEmpty(keyValuePair.Value.Name))
|
||||
continue;
|
||||
urls = new();
|
||||
comments = new();
|
||||
birthday = new(keyValuePair.Key);
|
||||
name = PersonName.Create(keyValuePair.Value.Name);
|
||||
if (name.First is null || string.IsNullOrEmpty(name.First.Value))
|
||||
continue;
|
||||
if (!string.IsNullOrEmpty(keyValuePair.Value.Comment))
|
||||
comment = GetComment(urls, comments, keyValuePair);
|
||||
if (!string.IsNullOrEmpty(keyValuePair.Value.OldName))
|
||||
comments.Add(new(new(keyValuePair.Value.OldName)));
|
||||
person = IPerson.CreatePerson(storage, personBirthdayFormat, birthday, name, comments, urls, numbers, emails, addresses);
|
||||
SavePerson(storage, personBirthdayFormat, person);
|
||||
results.Add(person);
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
internal static Models.Person[] GetPeople(Properties.IStorage storage, int personBirthdayFirstYear, string personBirthdayFormat, string personKeyFormat, bool personRequirePeopleFile)
|
||||
{
|
||||
List<Models.Person> results = new();
|
||||
string json;
|
||||
string[] files;
|
||||
FileInfo fileInfo;
|
||||
Models.Person? person;
|
||||
string localKnownPeopleFile;
|
||||
DateTime dateTime = DateTime.MinValue;
|
||||
string peopleContentDirectory = Path.Combine(storage.PeopleRootDirectory, "()");
|
||||
string peopleSingletonDirectory = Path.Combine(storage.PeopleRootDirectory, "{}");
|
||||
if (!Directory.Exists(peopleSingletonDirectory))
|
||||
_ = Directory.CreateDirectory(peopleSingletonDirectory);
|
||||
if (!Directory.Exists(peopleContentDirectory))
|
||||
_ = Directory.CreateDirectory(peopleContentDirectory);
|
||||
files = Directory.GetFiles(peopleContentDirectory, "*People*.txt", SearchOption.TopDirectoryOnly);
|
||||
if (!files.Any() && personRequirePeopleFile)
|
||||
throw new Exception("Copy \"KnownPeople.txt\" file from server!");
|
||||
if (files.Any())
|
||||
localKnownPeopleFile = files[0];
|
||||
else
|
||||
localKnownPeopleFile = string.Empty;
|
||||
files = Directory.GetFiles(peopleSingletonDirectory, "*.json", SearchOption.TopDirectoryOnly);
|
||||
foreach (string file in files)
|
||||
{
|
||||
fileInfo = new(file);
|
||||
if (dateTime < fileInfo.LastWriteTime)
|
||||
dateTime = fileInfo.LastWriteTime;
|
||||
json = File.ReadAllText(file);
|
||||
person = JsonSerializer.Deserialize<Models.Person>(json);
|
||||
if (person is null)
|
||||
continue;
|
||||
results.Add(person);
|
||||
}
|
||||
if (!results.Any())
|
||||
results = GetPeopleFromText(storage, personBirthdayFirstYear, personBirthdayFormat, personKeyFormat, localKnownPeopleFile);
|
||||
else if (!string.IsNullOrEmpty(localKnownPeopleFile))
|
||||
{
|
||||
fileInfo = new FileInfo(localKnownPeopleFile);
|
||||
if (fileInfo.LastWriteTime > dateTime)
|
||||
{
|
||||
foreach (string file in files)
|
||||
File.Delete(file);
|
||||
results = GetPeopleFromText(storage, personBirthdayFirstYear, personBirthdayFormat, personKeyFormat, localKnownPeopleFile);
|
||||
}
|
||||
}
|
||||
SaveToDirectory(storage, personBirthdayFormat, results);
|
||||
return results.ToArray();
|
||||
}
|
||||
|
||||
private static void SaveToDirectory(Properties.IStorage storage, string personBirthdayFormat, List<Models.Person> people)
|
||||
{
|
||||
int years;
|
||||
TimeSpan? timeSpan;
|
||||
string personDirectory;
|
||||
string? personFullName;
|
||||
DateTime createdDateTime;
|
||||
string birthdayDirectory;
|
||||
string personJsonFileName;
|
||||
string personDirectoryName;
|
||||
string? peopleDirectory = null;
|
||||
DateTime dateTime = DateTime.Now;
|
||||
string? personJsonFileNameWithoutExtension;
|
||||
const string pattern = @"[\\,\/,\:,\*,\?,\"",\<,\>,\|]";
|
||||
foreach (Models.Person person in people)
|
||||
{
|
||||
personJsonFileName = IPerson.GetFileFullName(storage, personBirthdayFormat, person);
|
||||
if (string.IsNullOrEmpty(peopleDirectory))
|
||||
peopleDirectory = Path.GetDirectoryName(personJsonFileName);
|
||||
if (string.IsNullOrEmpty(peopleDirectory))
|
||||
break;
|
||||
personJsonFileNameWithoutExtension = Path.GetFileNameWithoutExtension(personJsonFileName);
|
||||
if (string.IsNullOrEmpty(personJsonFileNameWithoutExtension))
|
||||
break;
|
||||
personFullName = Regex.Replace(person.GetFullName(), pattern, string.Empty);
|
||||
timeSpan = IPersonBirthday.GetTimeSpan(dateTime, person.Birthday);
|
||||
if (timeSpan is null || timeSpan.Value.Ticks < 0)
|
||||
personDirectoryName = $"{personFullName}~";
|
||||
else
|
||||
{
|
||||
createdDateTime = new FileInfo(personJsonFileName).CreationTime;
|
||||
(years, timeSpan) = IPersonBirthday.GetAge(createdDateTime, person.Birthday);
|
||||
personDirectoryName = $"{personFullName}^{years}-{Math.Floor(timeSpan.Value.TotalDays):000}";
|
||||
}
|
||||
personDirectory = Path.Combine(peopleDirectory, personDirectoryName);
|
||||
if (!Directory.Exists(personDirectory))
|
||||
_ = Directory.CreateDirectory(personDirectory);
|
||||
birthdayDirectory = Path.Combine(personDirectory, personJsonFileNameWithoutExtension);
|
||||
if (!Directory.Exists(birthdayDirectory))
|
||||
{
|
||||
_ = Directory.CreateDirectory(birthdayDirectory);
|
||||
File.Copy(personJsonFileName, Path.Combine(birthdayDirectory, $"{personJsonFileNameWithoutExtension}.json"));
|
||||
}
|
||||
}
|
||||
Models.PersonName name = PersonName.Create(segments[zero]);
|
||||
result = new(id, personBirthday, name, comments, urls, numbers, emails, addresses);
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
@ -109,4 +109,23 @@ internal abstract class PersonBirthday
|
||||
return result;
|
||||
}
|
||||
|
||||
internal static List<Models.PersonBirthday> GetPersonBirthdays(string personBirthdayFormat, string[] personKeyDirectories, string personDisplayDirectory)
|
||||
{
|
||||
List<Models.PersonBirthday> results = new();
|
||||
string personKeyFormatted;
|
||||
Models.PersonBirthday? personBirthday;
|
||||
foreach (string personKeyDirectory in personKeyDirectories)
|
||||
{
|
||||
personKeyFormatted = Path.GetFileName(personKeyDirectory);
|
||||
if (!DateTime.TryParseExact(personKeyFormatted, "MM.dd.yyyy", CultureInfo.InvariantCulture, DateTimeStyles.None, out DateTime birthday))
|
||||
personBirthday = IPersonBirthday.GetPersonBirthday(personBirthdayFormat, personKeyFormatted);
|
||||
else
|
||||
(personBirthday, personKeyFormatted) = Person.Get(personBirthdayFormat, personDisplayDirectory, personKeyDirectory, birthday);
|
||||
if (personBirthday is null)
|
||||
continue;
|
||||
results.Add(personBirthday);
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
}
|
105
Shared/Models/Stateless/Methods/PersonContainer.cs
Normal file
105
Shared/Models/Stateless/Methods/PersonContainer.cs
Normal file
@ -0,0 +1,105 @@
|
||||
namespace View_by_Distance.Shared.Models.Stateless.Methods;
|
||||
|
||||
internal abstract class PersonContainer
|
||||
{
|
||||
|
||||
private static List<Models.PersonContainer> GetPersonContainersCollections(string personBirthdayFormat, char[] chars, string personDisplayDirectory, string personDisplayDirectoryName, string[] personKeyDirectories, int? approximateYears, List<Models.PersonBirthday> collections)
|
||||
{
|
||||
List<Models.PersonContainer> results = new();
|
||||
long personKey;
|
||||
string[] segments;
|
||||
const int zero = 0;
|
||||
Models.Person person;
|
||||
string personKeyFormatted;
|
||||
Models.PersonBirthday? personBirthday;
|
||||
Models.PersonContainer personContainer;
|
||||
Models.PersonBirthday[] personBirthdays = collections.OrderByDescending(l => l.Value).ToArray();
|
||||
string[] personDisplayDirectoryAllFiles = Directory.GetFiles(personDisplayDirectory, "*", SearchOption.AllDirectories);
|
||||
foreach (string personKeyDirectory in personKeyDirectories)
|
||||
{
|
||||
personKeyFormatted = Path.GetFileName(personKeyDirectory);
|
||||
personBirthday = IPersonBirthday.GetPersonBirthday(personBirthdayFormat, personKeyFormatted);
|
||||
if (personBirthday is null)
|
||||
continue;
|
||||
personKey = personBirthdays[zero].Value.Ticks;
|
||||
segments = personDisplayDirectoryName.Split(chars);
|
||||
person = IPerson.GetPerson(personKey, segments);
|
||||
personContainer = new(approximateYears, person, personBirthdays, personDisplayDirectoryAllFiles, personDisplayDirectoryName, personKey);
|
||||
results.Add(personContainer);
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
private static Models.PersonContainer GetPersonContainer(string personDisplayDirectory, string personDisplayDirectoryName, int? approximateYears)
|
||||
{
|
||||
Models.PersonContainer result;
|
||||
string[] personDisplayDirectoryAllFiles = Directory.GetFiles(personDisplayDirectory, "*", SearchOption.AllDirectories);
|
||||
result = new(approximateYears, personDisplayDirectoryAllFiles, personDisplayDirectoryName);
|
||||
return result;
|
||||
}
|
||||
|
||||
private static List<Models.PersonContainer> GetPersonContainersGroup(string personBirthdayFormat, char[] chars, string[] personDisplayDirectories)
|
||||
{
|
||||
List<Models.PersonContainer> results = new();
|
||||
int? approximateYears;
|
||||
string[] personKeyDirectories;
|
||||
string? personDisplayDirectoryName;
|
||||
List<Models.PersonBirthday> collections;
|
||||
foreach (string personDisplayDirectory in personDisplayDirectories)
|
||||
{
|
||||
personDisplayDirectoryName = Path.GetFileName(personDisplayDirectory);
|
||||
if (string.IsNullOrEmpty(personDisplayDirectoryName))
|
||||
continue;
|
||||
approximateYears = Age.GetApproximateYears(personDisplayDirectoryName, chars);
|
||||
personKeyDirectories = Directory.GetDirectories(personDisplayDirectory, "*", SearchOption.TopDirectoryOnly);
|
||||
collections = PersonBirthday.GetPersonBirthdays(personBirthdayFormat, personKeyDirectories, personDisplayDirectory);
|
||||
if (!collections.Any())
|
||||
results.Add(GetPersonContainer(personDisplayDirectory, personDisplayDirectoryName, approximateYears));
|
||||
else
|
||||
results.AddRange(GetPersonContainersCollections(personBirthdayFormat, chars, personDisplayDirectory, personDisplayDirectoryName, personKeyDirectories, approximateYears, collections));
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
private static List<Models.PersonContainer> GetPersonContainersGroups(string personBirthdayFormat, char[] chars, string[] groupDirectories)
|
||||
{
|
||||
List<Models.PersonContainer> results = new();
|
||||
const int zero = 0;
|
||||
string groupDirectoryName;
|
||||
string[] personDisplayDirectories;
|
||||
List<Models.PersonContainer> personContainers;
|
||||
foreach (string groupDirectory in groupDirectories)
|
||||
{
|
||||
groupDirectoryName = Path.GetFileName(groupDirectory);
|
||||
if (!chars.Contains(groupDirectoryName[zero]))
|
||||
continue;
|
||||
personDisplayDirectories = Directory.GetDirectories(groupDirectory, "*", SearchOption.TopDirectoryOnly);
|
||||
personContainers = GetPersonContainersGroup(personBirthdayFormat, chars, personDisplayDirectories);
|
||||
results.AddRange(personContainers);
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
internal static List<Models.PersonContainer> GetPersonContainers(Properties.IStorage storage, string personBirthdayFormat)
|
||||
{
|
||||
List<Models.PersonContainer> results;
|
||||
char[] chars = new char[] { '!', '^', '_', '~' };
|
||||
string a2PeopleSingletonDirectory = Path.Combine(storage.PeopleRootDirectory, "{}");
|
||||
if (!Directory.Exists(a2PeopleSingletonDirectory))
|
||||
_ = Directory.CreateDirectory(a2PeopleSingletonDirectory);
|
||||
string a2PeopleSingletonDirectoryChar;
|
||||
foreach (char @char in chars)
|
||||
{
|
||||
a2PeopleSingletonDirectoryChar = Path.Combine(a2PeopleSingletonDirectory, @char.ToString());
|
||||
if (!Directory.Exists(a2PeopleSingletonDirectoryChar))
|
||||
_ = Directory.CreateDirectory(a2PeopleSingletonDirectoryChar);
|
||||
}
|
||||
string[] groupDirectories = Directory.GetDirectories(a2PeopleSingletonDirectory, "*", SearchOption.TopDirectoryOnly);
|
||||
if (!groupDirectories.Any())
|
||||
results = new();
|
||||
else
|
||||
results = GetPersonContainersGroups(personBirthdayFormat, chars, groupDirectories);
|
||||
return results;
|
||||
}
|
||||
|
||||
}
|
Reference in New Issue
Block a user