Remove Person Require People File,

PersonContainer and bug fix for GetRightPadded
This commit is contained in:
2022-09-18 23:43:37 -07:00
parent 9ec5da1e7a
commit 8b2cbf7e16
40 changed files with 1235 additions and 1111 deletions

View File

@ -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 });

View File

@ -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;

View 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;
}
}

View 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; }
}

View File

@ -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;
}
}

View File

@ -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);

View File

@ -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();

View File

@ -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) =>

View File

@ -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) =>

View 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);
}

View File

@ -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);

View 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);
}

View File

@ -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;
}

View File

@ -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;

View File

@ -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;
}
}

View File

@ -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;
}
}

View 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;
}
}