LocationContainerDistanceGroupMinimum

This commit is contained in:
2023-09-21 20:43:28 -07:00
parent 5633430bfb
commit f540cac462
11 changed files with 190 additions and 104 deletions

View File

@ -8,46 +8,86 @@ namespace View_by_Distance.Map.Models.Stateless;
internal abstract class RelationLogic
{
internal record RelationCollection(ReadOnlyCollection<RelationContainer> RelationContainers,
ReadOnlyCollection<string> Linked1,
ReadOnlyCollection<string> Linked2,
ReadOnlyCollection<string> Linked3,
ReadOnlyCollection<string> Linked4,
ReadOnlyCollection<string> Linked5,
ReadOnlyCollection<string> Linked6,
ReadOnlyCollection<string> Linked7,
ReadOnlyCollection<string> Linked8,
ReadOnlyCollection<string> Linked9,
ReadOnlyDictionary<string, string> MovedFiles);
internal record Group(string Key, long PersonKey, ReadOnlyCollection<LocationContainer<MetadataExtractor.Directory>> RelationContainersCollection);
private static ReadOnlyCollection<ReadOnlyCollection<LocationContainer<MetadataExtractor.Directory>>> GetCollections(Configuration configuration, List<LocationContainer<MetadataExtractor.Directory>> locationContainers)
private static Dictionary<long, Dictionary<int, List<LocationContainer<MetadataExtractor.Directory>>>> GetPersonKeyTo(Configuration configuration, List<LocationContainer<MetadataExtractor.Directory>> locationContainers)
{
List<ReadOnlyCollection<LocationContainer<MetadataExtractor.Directory>>> results = new();
List<LocationContainer<MetadataExtractor.Directory>>? collection;
Dictionary<long, List<LocationContainer<MetadataExtractor.Directory>>> keyValuePairs = new();
Dictionary<int, List<LocationContainer<MetadataExtractor.Directory>>>? yearTo;
Dictionary<long, Dictionary<int, List<LocationContainer<MetadataExtractor.Directory>>>> personKeyTo = new();
foreach (LocationContainer<MetadataExtractor.Directory> locationContainer in locationContainers)
{
if (!locationContainer.FromDistanceContent)
continue;
if (!locationContainer.File.Contains(configuration.LocationContainerDirectoryPattern))
continue;
if (!keyValuePairs.TryGetValue(locationContainer.PersonKey, out collection))
if (!personKeyTo.TryGetValue(locationContainer.PersonKey, out yearTo))
{
keyValuePairs.Add(locationContainer.PersonKey, new());
if (!keyValuePairs.TryGetValue(locationContainer.PersonKey, out collection))
personKeyTo.Add(locationContainer.PersonKey, new());
if (!personKeyTo.TryGetValue(locationContainer.PersonKey, out yearTo))
throw new Exception();
}
if (!yearTo.TryGetValue(locationContainer.CreationDateOnly.Year, out collection))
{
yearTo.Add(locationContainer.CreationDateOnly.Year, new());
if (!yearTo.TryGetValue(locationContainer.CreationDateOnly.Year, out collection))
throw new Exception();
}
collection.Add(locationContainer);
}
foreach (KeyValuePair<long, List<LocationContainer<MetadataExtractor.Directory>>> keyValuePair in keyValuePairs)
results.Add(new(keyValuePair.Value));
return personKeyTo;
}
private static ReadOnlyCollection<Group> GetGroups(Configuration configuration, List<LocationContainer<MetadataExtractor.Directory>> locationContainers)
{
List<Group> results = new();
string key;
int lastIndex;
List<int> years = new();
List<int> indices = new();
List<(int Index, int Year)> sort = new();
List<LocationContainer<MetadataExtractor.Directory>> collection = new();
KeyValuePair<int, List<LocationContainer<MetadataExtractor.Directory>>> keyValue;
Dictionary<long, Dictionary<int, List<LocationContainer<MetadataExtractor.Directory>>>> personKeyTo = GetPersonKeyTo(configuration, locationContainers);
foreach (KeyValuePair<long, Dictionary<int, List<LocationContainer<MetadataExtractor.Directory>>>> keyValuePair in personKeyTo)
{
sort.Clear();
years.Clear();
indices.Clear();
for (int i = 0; i < keyValuePair.Value.Count; i++)
sort.Add(new(i, keyValuePair.Value.ElementAt(i).Key));
if (sort.Count == 0)
continue;
foreach ((int index, int _) in sort.OrderBy(l => l.Year))
indices.Add(index);
lastIndex = indices[^1];
foreach (int index in indices)
{
keyValue = keyValuePair.Value.ElementAt(index);
if (keyValue.Value.Count == 0)
continue;
years.Add(keyValue.Key);
collection.AddRange(keyValue.Value);
if (index != lastIndex && years.Count < 6 && years.Sum() > configuration.LocationContainerDistanceGroupMinimum)
continue;
if (years.Count == 1)
key = keyValue.Key.ToString();
else
key = $"{years.Min()}-{keyValue.Key}";
if (collection.Count == 0)
continue;
results.Add(new(key, collection[0].PersonKey, new(collection)));
collection = new();
years.Clear();
}
}
return new(results);
}
private static ReadOnlyDictionary<string, string> MoveFiles(Configuration configuration, bool isCounterPersonYear, string? displayDirectoryName, List<string> linked1, List<string> linked2, List<string> linked3, List<string> linked4, List<string> linked5, List<string> linked6, List<string> linked7, List<string> linked8, List<string> linked9)
private static ReadOnlyDictionary<string, string> MoveFiles(Configuration configuration, string key, bool isCounterPersonYear, string? displayDirectoryName, ReadOnlyCollection<RelationContainer> relationContainers, List<string> linked1, List<string> linked2, List<string> linked3, List<string> linked4, List<string> linked5, List<string> linked6, List<string> linked7, List<string> linked8, List<string> linked9)
{
Dictionary<string, string> results = new();
char c;
string value;
string checkFile;
string debugFile;
string checkDirectory;
@ -56,44 +96,42 @@ internal abstract class RelationLogic
string? maybeTicksDirectoryName;
string? personNameDirectoryName;
string? personKeyFormattedDirectory;
Dictionary<string, int> fullNameToCount = new();
foreach (string file in linked1)
fullNameToCount.Add(file, 1);
foreach (string file in linked2)
fullNameToCount[file] += 1;
foreach (string file in linked3)
fullNameToCount[file] += 1;
foreach (string file in linked4)
fullNameToCount[file] += 1;
foreach (string file in linked5)
fullNameToCount[file] += 1;
foreach (string file in linked6)
fullNameToCount[file] += 1;
foreach (string file in linked7)
fullNameToCount[file] += 1;
foreach (string file in linked8)
fullNameToCount[file] += 1;
foreach (string file in linked9)
fullNameToCount[file] += 1;
foreach (KeyValuePair<string, int> keyValuePair in fullNameToCount)
foreach ((FileHolder fileHolder, _) in relationContainers)
{
personNameDirectory = Path.GetDirectoryName(keyValuePair.Key);
personNameDirectory = fileHolder.DirectoryName;
yearDirectory = Path.GetDirectoryName(personNameDirectory);
personNameDirectoryName = Path.GetFileName(personNameDirectory);
personKeyFormattedDirectory = Path.GetDirectoryName(yearDirectory);
maybeTicksDirectoryName = Path.GetFileName(personKeyFormattedDirectory);
if (string.IsNullOrEmpty(personNameDirectory) || string.IsNullOrEmpty(yearDirectory) || string.IsNullOrEmpty(personKeyFormattedDirectory) || string.IsNullOrEmpty(personNameDirectoryName))
continue;
c = Convert.ToChar(48 + keyValuePair.Value);
if (c is ':' or ';' or '<' or '=' or '>' or '?')
c = '_';
if (linked9.Contains(fileHolder.FullName))
value = "JJJ";
else if (linked8.Contains(fileHolder.FullName))
value = "III";
else if (linked7.Contains(fileHolder.FullName))
value = "HHH";
else if (linked6.Contains(fileHolder.FullName))
value = "GGG";
else if (linked5.Contains(fileHolder.FullName))
value = "FFF";
else if (linked4.Contains(fileHolder.FullName))
value = "EEE";
else if (linked3.Contains(fileHolder.FullName))
value = "DDD";
else if (linked2.Contains(fileHolder.FullName))
value = "CCC";
else if (linked1.Contains(fileHolder.FullName))
value = "BBB";
else
value = "AAA";
if (maybeTicksDirectoryName == configuration.LocationContainerDebugDirectory)
checkDirectory = Path.Combine(yearDirectory, $"{keyValuePair.Value}{new string(c, 7)}");
checkDirectory = Path.Combine(yearDirectory, $"{key}-{value}");
else
{
if (!string.IsNullOrEmpty(configuration.LocationContainerDebugDirectory))
continue;
checkDirectory = Path.Combine(personKeyFormattedDirectory, $"{keyValuePair.Value}{new string(c, 7)}");
checkDirectory = Path.Combine(personKeyFormattedDirectory, $"{key}-{value}");
}
if (maybeTicksDirectoryName != configuration.LocationContainerDebugDirectory)
{
@ -106,15 +144,15 @@ internal abstract class RelationLogic
continue;
if (!Directory.Exists(checkDirectory))
_ = Directory.CreateDirectory(checkDirectory);
checkFile = Path.Combine(checkDirectory, Path.GetFileName(keyValuePair.Key));
checkFile = Path.Combine(checkDirectory, fileHolder.Name);
if (File.Exists(checkFile))
continue;
results.Add(keyValuePair.Key, checkFile);
File.Move(keyValuePair.Key, checkFile);
debugFile = $"{keyValuePair.Key[..^4]}.gif";
results.Add(fileHolder.FullName, checkFile);
File.Move(fileHolder.FullName, checkFile);
debugFile = $"{fileHolder.FullName[..^4]}.gif";
if (File.Exists(debugFile))
{
checkFile = Path.Combine(checkDirectory, $"{Path.GetFileName(keyValuePair.Key)[..^4]}.gif");
checkFile = Path.Combine(checkDirectory, $"{Path.GetFileName(fileHolder.FullName)[..^4]}.gif");
if (File.Exists(checkFile))
continue;
File.Move(debugFile, checkFile);
@ -190,9 +228,9 @@ internal abstract class RelationLogic
_ = IPath.WriteAllText(Path.Combine(vsCodeDirectory, "tasks.json"), json, updateDateWhenMatches: false, compareBeforeWrite: true, updateToWhenMatches: null);
}
private static RelationCollection GetMappedRelationCollection(Configuration configuration, int take, bool isCounterPersonYear, string? displayDirectoryName, ReadOnlyCollection<RelationContainer> relationContainers)
private static ReadOnlyDictionary<string, string> GetMoveFiles(Configuration configuration, string key, int take, bool isCounterPersonYear, string? displayDirectoryName, ReadOnlyCollection<RelationContainer> relationContainers)
{
RelationCollection result;
ReadOnlyDictionary<string, string> results;
List<string> linked1 = new();
List<string> linked2 = new();
List<string> linked3 = new();
@ -253,12 +291,11 @@ internal abstract class RelationLogic
}
}
}
ReadOnlyDictionary<string, string> movedFiles = MoveFiles(configuration, isCounterPersonYear, displayDirectoryName, linked1, linked2, linked3, linked4, linked5, linked6, linked7, linked8, linked9);
result = new(relationContainers, new(linked1), new(linked2), new(linked3), new(linked4), new(linked5), new(linked6), new(linked7), new(linked8), new(linked9), movedFiles);
return result;
results = MoveFiles(configuration, key, isCounterPersonYear, displayDirectoryName, relationContainers, linked1, linked2, linked3, linked4, linked5, linked6, linked7, linked8, linked9);
return results;
}
private static void WriteFile(int take, long personKey, bool isCounterPersonYear, string personKeyFormatted, string? displayDirectoryName, string directory, long ticks, Uri uri, RelationCollection relationCollection)
private static void WriteFile(int take, long personKey, bool isCounterPersonYear, string personKeyFormatted, string? displayDirectoryName, string directory, long ticks, Uri uri, ReadOnlyCollection<RelationContainer> relationContainers, ReadOnlyDictionary<string, string> movedFiles)
{
string a;
string b;
@ -271,10 +308,10 @@ internal abstract class RelationLogic
string originalString;
List<string> lines = new();
string fileNameWithoutExtension;
foreach ((FileHolder relationFileHolder, ReadOnlyCollection<Relation> relations) in relationCollection.RelationContainers)
foreach ((FileHolder relationFileHolder, ReadOnlyCollection<Relation> relations) in relationContainers)
{
lines.Clear();
if (relationCollection.MovedFiles.TryGetValue(relationFileHolder.FullName, out file))
if (movedFiles.TryGetValue(relationFileHolder.FullName, out file))
fileHolder = new(file);
else
fileHolder = new(relationFileHolder.FullName);
@ -295,18 +332,18 @@ internal abstract class RelationLogic
else
lines.Add($"## {displayDirectoryName}");
lines.Add(string.Empty);
lines.Add($"![0]({uri.MakeRelativeUri(new(relationFileHolder.FullName)).OriginalString})");
lines.Add($"__{fileNameWithoutExtension}__");
lines.Add($"![0]({uri.MakeRelativeUri(new(fileHolder.FullName)).OriginalString})");
lines.Add($"- __{fileNameWithoutExtension}__");
if (isCounterPersonYear)
lines.Add($"#{years}yrs-ago");
lines.Add($"- #{years}yrs-ago");
else
lines.Add($"#{years}yrs-old");
lines.Add($"~~{relations.Count}~~");
lines.Add($"- #{years}yrs-old");
lines.Add($"- ~~{relations.Count}~~");
lines.Add(string.Empty);
for (int i = 0; i < relations.Count; i++)
{
relation = relations[i];
if (relationCollection.MovedFiles.TryGetValue(relation.File, out file))
if (movedFiles.TryGetValue(relation.File, out file))
fileHolder = new(file);
else
fileHolder = new(relation.File);
@ -321,30 +358,37 @@ internal abstract class RelationLogic
lines.Add($"![{relation.DistancePermyriad}]({originalString}){Environment.NewLine}{a}{fileNameWithoutExtension}{b}");
lines.Add(string.Empty);
}
lines.Add("<style>");
lines.Add("img {");
lines.Add("min-width: 75px;");
lines.Add("max-width: 75px;");
lines.Add("display: block;");
lines.Add("}");
lines.Add("</style>");
text = string.Join(Environment.NewLine, lines);
File.WriteAllText(Path.Combine(directory, markDownFile), text);
}
}
private static void AddDisplayDirectoryNames(Configuration configuration, string eDistanceContentDirectory, ReadOnlyDictionary<string, PersonContainer> readOnlyPersonKeyFormattedToPersonContainer, ReadOnlyDictionary<long, List<PersonContainer>> readOnlyPersonKeyToPersonContainerCollection, ReadOnlyCollection<ReadOnlyCollection<LocationContainer<MetadataExtractor.Directory>>> collections)
private static void AddDisplayDirectoryNames(Configuration configuration, string eDistanceContentDirectory, ReadOnlyDictionary<string, PersonContainer> readOnlyPersonKeyFormattedToPersonContainer, ReadOnlyDictionary<long, List<PersonContainer>> readOnlyPersonKeyToPersonContainerCollection, ReadOnlyCollection<Group> groups)
{
bool isCounterPersonYear;
string personKeyFormatted;
string? displayDirectoryName;
string? checkDirectory = Path.Combine(eDistanceContentDirectory, configuration.LocationContainerDebugDirectory);
_ = IPath.DeleteEmptyDirectories(checkDirectory);
foreach (ReadOnlyCollection<LocationContainer<MetadataExtractor.Directory>> collection in collections)
foreach (Group group in groups)
{
if (configuration.LocationContainerDistanceTolerance is null)
break;
isCounterPersonYear = IPersonBirthday.IsCounterPersonYear(new DateTime(collection[0].PersonKey).Year);
isCounterPersonYear = IPersonBirthday.IsCounterPersonYear(new DateTime(group.PersonKey).Year);
if (isCounterPersonYear)
continue;
personKeyFormatted = IPersonBirthday.GetFormatted(configuration.PersonBirthdayFormat, collection[0].PersonKey);
personKeyFormatted = IPersonBirthday.GetFormatted(configuration.PersonBirthdayFormat, group.PersonKey);
checkDirectory = Path.Combine(eDistanceContentDirectory, configuration.LocationContainerDebugDirectory, personKeyFormatted);
if (!Directory.Exists(checkDirectory))
continue;
displayDirectoryName = GetDisplayDirectoryName(readOnlyPersonKeyToPersonContainerCollection, readOnlyPersonKeyFormattedToPersonContainer, collection[0].PersonKey, personKeyFormatted);
displayDirectoryName = GetDisplayDirectoryName(readOnlyPersonKeyToPersonContainerCollection, readOnlyPersonKeyFormattedToPersonContainer, group.PersonKey, personKeyFormatted);
if (string.IsNullOrEmpty(displayDirectoryName))
continue;
foreach (string yearDirectory in Directory.GetDirectories(checkDirectory, "*", SearchOption.TopDirectoryOnly))
@ -367,36 +411,36 @@ internal abstract class RelationLogic
string personKeyFormatted;
string? displayDirectoryName;
Uri uri = new(eDistanceContentDirectory);
RelationCollection relationCollection;
ReadOnlyDictionary<string, string> movedFiles;
ReadOnlyCollection<RelationContainer> relationContainers;
ReadOnlyCollection<Group> groups = GetGroups(configuration, locationContainers);
int totalSeconds = (int)Math.Floor(new TimeSpan(DateTime.Now.Ticks - ticks).TotalSeconds);
string message = $") Save Mapped Relations - {totalSeconds} total second(s)";
ProgressBarOptions options = new() { ProgressCharacter = '─', ProgressBarOnBottom = true, DisableBottomPercentage = true };
ReadOnlyCollection<ReadOnlyCollection<LocationContainer<MetadataExtractor.Directory>>> collections = GetCollections(configuration, locationContainers);
using ProgressBar progressBar = new(collections.Count, message, options);
foreach (ReadOnlyCollection<LocationContainer<MetadataExtractor.Directory>> collection in collections)
using ProgressBar progressBar = new(groups.Count, message, options);
foreach (Group group in groups)
{
if (configuration.LocationContainerDistanceTolerance is null)
break;
progressBar.Tick();
if (collection.Count == 0)
if (group.RelationContainersCollection.Count == 0)
continue;
take = GetTake(configuration.LocationContainerDistanceTake, collection.Count);
isCounterPersonYear = IPersonBirthday.IsCounterPersonYear(new DateTime(collection[0].PersonKey).Year);
personKeyFormatted = IPersonBirthday.GetFormatted(configuration.PersonBirthdayFormat, collection[0].PersonKey);
displayDirectoryName = GetDisplayDirectoryName(readOnlyPersonKeyToPersonContainerCollection, readOnlyPersonKeyFormattedToPersonContainer, collection[0].PersonKey, personKeyFormatted);
directory = Path.Combine(a2PeopleContentDirectory, $"{ticks}-{configuration.LocationContainerDistanceTolerance.Value}", personKeyFormatted);
take = GetTake(configuration.LocationContainerDistanceTake, group.RelationContainersCollection.Count);
isCounterPersonYear = IPersonBirthday.IsCounterPersonYear(new DateTime(group.PersonKey).Year);
personKeyFormatted = IPersonBirthday.GetFormatted(configuration.PersonBirthdayFormat, group.PersonKey);
displayDirectoryName = GetDisplayDirectoryName(readOnlyPersonKeyToPersonContainerCollection, readOnlyPersonKeyFormattedToPersonContainer, group.PersonKey, personKeyFormatted);
directory = Path.Combine(a2PeopleContentDirectory, $"{ticks}-{configuration.LocationContainerDistanceTolerance.Value}", personKeyFormatted, group.Key);
if (!Directory.Exists(directory))
_ = Directory.CreateDirectory(directory);
WriteVsCodeFiles(eDistanceContentDirectory, displayDirectoryName, directory);
relationContainers = distance.GetRelationContainers(configuration.FaceDistancePermyriad, configuration.LocationContainerDistanceTake, configuration.LocationContainerDistanceTolerance.Value, collection);
relationCollection = GetMappedRelationCollection(configuration, take, isCounterPersonYear, displayDirectoryName, relationContainers);
WriteFile(take, collection[0].PersonKey, isCounterPersonYear, personKeyFormatted, displayDirectoryName, directory, ticks, uri, relationCollection);
relationContainers = distance.GetRelationContainers(configuration.FaceDistancePermyriad, configuration.LocationContainerDistanceTake, configuration.LocationContainerDistanceTolerance.Value, group.RelationContainersCollection);
movedFiles = GetMoveFiles(configuration, group.Key, take, isCounterPersonYear, displayDirectoryName, relationContainers);
WriteFile(take, group.PersonKey, isCounterPersonYear, personKeyFormatted, displayDirectoryName, directory, ticks, uri, relationContainers, movedFiles);
}
if (string.IsNullOrEmpty(configuration.LocationContainerDebugDirectory))
_ = IPath.DeleteEmptyDirectories(eDistanceContentDirectory);
else
AddDisplayDirectoryNames(configuration, eDistanceContentDirectory, readOnlyPersonKeyFormattedToPersonContainer, readOnlyPersonKeyToPersonContainerCollection, collections);
AddDisplayDirectoryNames(configuration, eDistanceContentDirectory, readOnlyPersonKeyFormattedToPersonContainer, readOnlyPersonKeyToPersonContainerCollection, groups);
}
}