Family Tree as Markdown Files

This commit is contained in:
2023-07-16 23:06:08 -07:00
parent 240c1ef6f9
commit b2fe53275f
15 changed files with 594 additions and 202 deletions

View File

@ -13,6 +13,10 @@ namespace View_by_Distance.Map.Models.Stateless;
internal abstract class MapLogic
{
private record Record(string PersonKeyFormatted,
string[] PersonDisplayDirectoryNames,
string MappedFaceFile);
private static void SetPersonCollections(Configuration configuration, ReadOnlyCollection<PersonContainer> personContainers, string? a2PeopleSingletonDirectory, Dictionary<string, string> personKeyFormattedToNewestPersonKeyFormatted, List<string> personKeyFormattedCollection, Dictionary<int, List<int>> skipCollection, Dictionary<int, List<int>> skipNotSkipCollection)
{
int? id;
@ -150,12 +154,45 @@ internal abstract class MapLogic
}
}
internal static List<(string, string[], string)> DeleteEmptyDirectoriesAndGetCollection(Configuration configuration, List<string> personKeyFormattedCollection, string[] ticksDirectories, string message)
private static void MoveFiles(string personKeyFormatted, string personKeyDirectory, string newestPersonKeyFormatted, string newestPersonKeyDirectory)
{
List<(string, string[], string)> results = new();
string[] files;
string checkFile;
string? checkDirectory;
string[] directories = Directory.GetDirectories(personKeyDirectory, "*", SearchOption.TopDirectoryOnly);
foreach (string directory in directories)
{
checkDirectory = Path.Combine(newestPersonKeyDirectory, Path.GetFileName(directory));
if (!Directory.Exists(checkDirectory))
Directory.Move(directory, checkDirectory);
else
{
files = Directory.GetFiles(directory, "*", SearchOption.AllDirectories);
foreach (string file in files)
{
if (file.Split(personKeyFormatted).Length != 2 || file.Contains(newestPersonKeyFormatted))
continue;
checkFile = file.Replace(personKeyFormatted, newestPersonKeyFormatted);
checkDirectory = Path.GetDirectoryName(checkFile);
if (checkDirectory is null)
continue;
if (File.Exists(checkFile))
continue;
if (!Directory.Exists(checkDirectory))
_ = Directory.CreateDirectory(checkDirectory);
File.Move(file, checkFile);
}
}
}
}
private static List<Record> DeleteEmptyDirectoriesAndGetCollection(Configuration configuration, Dictionary<string, string> personKeyFormattedToNewestPersonKeyFormatted, List<string> personKeyFormattedCollection, string[] ticksDirectories, string message)
{
List<Record> results = new();
int? id;
string[] files;
string fileName;
bool check = false;
const int zero = 0;
int? wholePercentages;
string[] yearDirectories;
@ -166,6 +203,8 @@ internal abstract class MapLogic
List<string> distinct = new();
string[] personKeyDirectories;
string[] personNameDirectories;
string newestPersonKeyDirectory;
string? newestPersonKeyFormatted;
string[] personNameLinkDirectories;
string? personFirstInitialDirectory;
string[] personDisplayDirectoryNames;
@ -189,6 +228,17 @@ internal abstract class MapLogic
Individually(configuration, ticksDirectory, personKeyDirectory);
throw new Exception($"B) Move personKey directories up one from {nameof(Shared.Models.Stateless.IMapLogic.Sorting)} and delete {nameof(Shared.Models.Stateless.IMapLogic.Sorting)} directory!");
}
if (personKeyFormattedToNewestPersonKeyFormatted.TryGetValue(personKeyFormatted, out newestPersonKeyFormatted) && personKeyFormatted != newestPersonKeyFormatted)
{
if (!check)
check = true;
newestPersonKeyDirectory = Path.Combine(ticksDirectory, newestPersonKeyFormatted);
if (Directory.Exists(newestPersonKeyDirectory))
MoveFiles(personKeyFormatted, personKeyDirectory, newestPersonKeyFormatted, newestPersonKeyDirectory);
else
Directory.Move(personKeyDirectory, newestPersonKeyDirectory);
continue;
}
yearDirectories = Directory.GetDirectories(personKeyDirectory, "*", SearchOption.TopDirectoryOnly);
foreach (string yearDirectory in yearDirectories)
{
@ -201,6 +251,11 @@ internal abstract class MapLogic
personDisplayDirectoryNames = IPath.GetDirectoryNames(personNameDirectory);
if (!personDisplayDirectoryNames.Any())
continue;
if (newestPersonKeyFormatted is null)
{
if (!IPerson.IsDefaultName(configuration.MappingDefaultName, personDisplayDirectoryNames[^1]))
throw new NotImplementedException("Should this happen?");
}
files = Directory.GetFiles(personNameDirectory, "*", SearchOption.TopDirectoryOnly);
if (isReservedDirectoryName && files.Any())
throw new Exception($"Move personKey directories up one from {nameof(Shared.Models.Stateless.IMapLogic.Sorting)} and delete {nameof(Shared.Models.Stateless.IMapLogic.Sorting)} directory!");
@ -231,22 +286,22 @@ internal abstract class MapLogic
Directory.Move(personNameDirectory, personFirstInitialDirectory);
files = Directory.GetFiles(personFirstInitialDirectory, "*", SearchOption.TopDirectoryOnly);
}
foreach (string file in files)
foreach (string mappedFaceFile in files)
{
if (file.EndsWith(".lnk"))
if (mappedFaceFile.EndsWith(".lnk"))
continue;
(id, wholePercentages) = IMapping.GetConverted(configuration.FacesFileNameExtension, file);
(id, wholePercentages) = IMapping.GetConverted(configuration.FacesFileNameExtension, mappedFaceFile);
if (id is null || wholePercentages is null)
continue;
fileName = Path.GetFileName(file);
fileName = Path.GetFileName(mappedFaceFile);
if (distinct.Contains(fileName))
{
if (!File.Exists($"{file}.dup"))
File.Move(file, $"{file}.dup");
if (!File.Exists($"{mappedFaceFile}.dup"))
File.Move(mappedFaceFile, $"{mappedFaceFile}.dup");
continue;
}
distinct.Add(fileName);
results.Add(new(personKeyFormatted, personDisplayDirectoryNames, file));
results.Add(new(personKeyFormatted, personDisplayDirectoryNames, mappedFaceFile));
}
personNameLinkDirectories = Directory.GetDirectories(personFirstInitialDirectory, "*", SearchOption.TopDirectoryOnly);
foreach (string personNameLinkDirectory in personNameLinkDirectories)
@ -269,6 +324,8 @@ internal abstract class MapLogic
_ = IPath.DeleteEmptyDirectories(ticksDirectory);
_ = IPath.DeleteEmptyDirectories(ticksDirectory);
}
if (check)
throw new Exception("PersonKey director(ies) where renamed. Please restart!");
return results;
}
@ -363,12 +420,11 @@ internal abstract class MapLogic
return results;
}
private static int SetCollectionsAndGetUnableToConvertCount(Configuration configuration, long ticks, Dictionary<string, string> personKeyFormattedToNewestPersonKeyFormatted, List<(string, string[], int, int)> personKeyFormattedIdThenWholePercentagesCollection, List<(string, string[], string)> collection)
private static int SetCollectionsAndGetUnableToConvertCount(Configuration configuration, long ticks, List<(string, string[], int, int)> personKeyFormattedIdThenWholePercentagesCollection, List<Record> collection)
{
int result = 0;
int? id;
int? wholePercentages;
string? newestPersonKeyFormatted;
string personDisplayDirectoryName;
List<int> wholePercentagesCollection;
Dictionary<int, List<int>> idToWholePercentagesCollection = new();
@ -379,12 +435,6 @@ internal abstract class MapLogic
foreach ((string personKeyFormatted, string[] personDisplayDirectoryNames, string mappedFaceFile) in collection)
{
progressBar.Tick();
if (!personKeyFormattedToNewestPersonKeyFormatted.TryGetValue(personKeyFormatted, out newestPersonKeyFormatted))
{
if (personDisplayDirectoryNames.Any() && !IPerson.IsDefaultName(configuration.MappingDefaultName, personDisplayDirectoryNames[^1]))
continue;
newestPersonKeyFormatted = personKeyFormatted;
}
(id, wholePercentages) = IMapping.GetConverted(configuration.FacesFileNameExtension, mappedFaceFile);
if (id is null || wholePercentages is null)
{
@ -399,7 +449,7 @@ internal abstract class MapLogic
personDisplayDirectoryName = personDisplayDirectoryNames[^1];
if (string.IsNullOrEmpty(personDisplayDirectoryName))
continue;
personKeyFormattedIdThenWholePercentagesCollection.Add(new(newestPersonKeyFormatted, personDisplayDirectoryNames, id.Value, wholePercentages.Value));
personKeyFormattedIdThenWholePercentagesCollection.Add(new(personKeyFormatted, personDisplayDirectoryNames, id.Value, wholePercentages.Value));
}
return result;
}
@ -543,7 +593,7 @@ internal abstract class MapLogic
collection.Add((ticksDirectory, new TimeSpan(directoryTicks - lastDirectoryTicks.Value)));
lastDirectoryTicks = directoryTicks;
}
string[] compare = (from l in collection where l.TimeSpan.TotalDays < 4 select l.Directory).ToArray();
string[] compare = (from l in collection where l.TimeSpan.TotalDays < 3.95 select l.Directory).ToArray();
if (compare.Any())
throw new Exception($"Please Consolidate <{string.Join(Environment.NewLine, compare)}>");
return results;
@ -552,6 +602,7 @@ internal abstract class MapLogic
private static List<(long, string)> GetDisplayDirectoryAllFiles(string fileNameExtension, ReadOnlyCollection<PersonContainer> personContainers)
{
List<(long, string)> results = new();
string fileName;
List<string> distinct = new();
foreach (PersonContainer personContainer in personContainers)
{
@ -559,35 +610,38 @@ internal abstract class MapLogic
continue;
foreach (string displayDirectoryAllFile in personContainer.DisplayDirectoryAllFiles)
{
if (!displayDirectoryAllFile.EndsWith(fileNameExtension))
fileName = Path.GetFileName(displayDirectoryAllFile);
if (!fileName.EndsWith(fileNameExtension))
continue;
if (distinct.Contains(displayDirectoryAllFile))
if (distinct.Contains(fileName))
continue;
distinct.Add(displayDirectoryAllFile);
distinct.Add(fileName);
results.Add(new(personContainer.Key.Value, displayDirectoryAllFile));
}
}
return results;
}
private static List<(long PersonKey, string File)> GetCollection(Configuration configuration, ReadOnlyCollection<PersonContainer> personContainers, List<(string, string[], string)> collection)
private static List<(long PersonKey, string File)> GetCollection(Configuration configuration, ReadOnlyCollection<PersonContainer> personContainers, List<Record> records)
{
List<(long PersonKey, string File)> results = new();
string file;
long personKey;
string fileName;
List<string> distinct = new();
PersonBirthday? personBirthday;
results.AddRange(GetDisplayDirectoryAllFiles(configuration.FacesFileNameExtension, personContainers));
foreach ((string personKeyFormatted, _, string mappedFaceFile) in collection)
foreach (Record record in records)
{
personBirthday = IPersonBirthday.GetPersonBirthday(configuration.PersonBirthdayFormat, personKeyFormatted);
personBirthday = IPersonBirthday.GetPersonBirthday(configuration.PersonBirthdayFormat, record.PersonKeyFormatted);
if (personBirthday is null)
continue;
if (distinct.Contains(mappedFaceFile))
fileName = Path.GetFileName(record.MappedFaceFile);
if (distinct.Contains(fileName))
continue;
distinct.Add(mappedFaceFile);
distinct.Add(fileName);
personKey = personBirthday.Value.Ticks;
results.Add(new(personKey, mappedFaceFile));
results.Add(new(personKey, record.MappedFaceFile));
}
for (int i = results.Count - 1; i > -1; i--)
{
@ -700,10 +754,10 @@ internal abstract class MapLogic
}
}
private static List<LocationContainer<MetadataExtractor.Directory>> GetLocationContainers(int maxDegreeOfParallelism, Configuration configuration, long ticks, ReadOnlyCollection<PersonContainer> personContainers, string eDistanceContentDirectory, List<(string, string[], string)> sourceCollection)
private static List<LocationContainer<MetadataExtractor.Directory>> GetLocationContainers(int maxDegreeOfParallelism, Configuration configuration, long ticks, ReadOnlyCollection<PersonContainer> personContainers, string eDistanceContentDirectory, List<Record> records)
{
List<LocationContainer<MetadataExtractor.Directory>> results = new();
List<(long PersonKey, string File)> collection = GetCollection(configuration, personContainers, sourceCollection);
List<(long PersonKey, string File)> collection = GetCollection(configuration, personContainers, records);
if (collection.Any() && (configuration.DistanceMoveUnableToMatch || configuration.DistanceRenameToMatch))
{
int totalSeconds = (int)Math.Floor(new TimeSpan(DateTime.Now.Ticks - ticks).TotalSeconds);
@ -734,17 +788,16 @@ internal abstract class MapLogic
List<(string, string[], int, int)> personKeyFormattedIdThenWholePercentagesCollection = new();
List<(string[], PersonContainer)> possiblyNewPersonDisplayDirectoryNamesAndPersonContainer = new();
SetPersonCollections(configuration, personContainers, a2PeopleSingletonDirectory, personKeyFormattedToNewestPersonKeyFormatted, personKeyFormattedCollection, skipCollection, skipNotSkipCollection);
// personContainers.AddRange(GetNonSpecificPeopleCollection(configuration, ticks, personKeys));
totalSeconds = (int)Math.Floor(new TimeSpan(DateTime.Now.Ticks - ticks).TotalSeconds);
message = $") {ticksDirectories.Length:000} compile from and clean ticks Director(ies) - B - {totalSeconds} total second(s)";
List<(string, string[], string)> collection = DeleteEmptyDirectoriesAndGetCollection(configuration, personKeyFormattedCollection, ticksDirectories, message);
locationContainers.AddRange(GetLocationContainers(maxDegreeOfParallelism, configuration, ticks, personContainers, eDistanceContentDirectory, collection));
int unableToMatchCount = SetCollectionsAndGetUnableToConvertCount(configuration, ticks, personKeyFormattedToNewestPersonKeyFormatted, personKeyFormattedIdThenWholePercentagesCollection, collection);
List<Record> records = DeleteEmptyDirectoriesAndGetCollection(configuration, personKeyFormattedToNewestPersonKeyFormatted, personKeyFormattedCollection, ticksDirectories, message);
locationContainers.AddRange(GetLocationContainers(maxDegreeOfParallelism, configuration, ticks, personContainers, eDistanceContentDirectory, records));
int unableToMatchCount = SetCollectionsAndGetUnableToConvertCount(configuration, ticks, personKeyFormattedIdThenWholePercentagesCollection, records);
SetKeyValuePairs(configuration, personContainers, personKeyToPersonContainerCollection, personKeyFormattedToPersonContainer, personKeyFormattedIdThenWholePercentagesCollection, personKeyToPersonContainer, idThenWholePercentagesToPersonContainers, possiblyNewPersonDisplayDirectoryNamesAndPersonContainer);
totalSeconds = (int)Math.Floor(new TimeSpan(DateTime.Now.Ticks - ticks).TotalSeconds);
message = $") {collection.Count:000} message from ticks Director(ies) - D - {unableToMatchCount} Unable To Match Count / {collection.Count} Collection - {totalSeconds} total second(s)";
message = $") {records.Count:000} message from ticks Director(ies) - D - {unableToMatchCount} Unable To Match Count / {records.Count} Collection - {totalSeconds} total second(s)";
ProgressBarOptions options = new() { ProgressCharacter = '─', ProgressBarOnBottom = true, DisableBottomPercentage = true };
using (ProgressBar progressBar = new(collection.Count, message, options))
using (ProgressBar progressBar = new(records.Count, message, options))
{
foreach (KeyValuePair<int, Dictionary<int, PersonContainer[]>> keyValuePair in idThenWholePercentagesToPersonContainers)
{