diff --git a/.gitignore b/.gitignore index ba9b4a6..d46572d 100644 --- a/.gitignore +++ b/.gitignore @@ -454,6 +454,7 @@ $RECYCLE.BIN/ !.vscode/extensions.json !Instance/.vscode/appsettings.example.json !Rename/.vscode/appsettings.example.json +Shared/.vscode/ged #VSCode Settings => mklink /J "VSCode Settings" "C:\Users\phares\AppData\Roaming\Code\User" globalStorage/ diff --git a/Instance/DlibDotNet.cs b/Instance/DlibDotNet.cs index 422c9d6..13e04ee 100644 --- a/Instance/DlibDotNet.cs +++ b/Instance/DlibDotNet.cs @@ -843,6 +843,7 @@ public partial class DlibDotNet configuration.FaceConfidencePercent, configuration.FaceDistancePermyriad, configuration.LocationContainerDebugDirectory, + configuration.LocationContainerDirectoryPattern, configuration.LocationContainerDistanceTake, configuration.LocationContainerDistanceTolerance, configuration.LocationDigits, diff --git a/Instance/Models/Binder/Configuration.cs b/Instance/Models/Binder/Configuration.cs index d8a87b9..ba36a42 100644 --- a/Instance/Models/Binder/Configuration.cs +++ b/Instance/Models/Binder/Configuration.cs @@ -33,6 +33,7 @@ public class Configuration public string[]? LoadOrCreateThenSaveImageFacesResultsForOutputResolutions { get; set; } public bool? LoadPhotoPrismLocations { get; set; } public string? LocationContainerDebugDirectory { get; set; } + public string? LocationContainerDirectoryPattern { get; set; } public int? LocationContainerDistanceTake { get; set; } public float? LocationContainerDistanceTolerance { get; set; } public int? LocationDigits { get; set; } @@ -133,6 +134,7 @@ public class Configuration // if (configuration?.LoadOrCreateThenSaveImageFacesResultsForOutputResolutions is null) throw new NullReferenceException(nameof(configuration.LoadOrCreateThenSaveImageFacesResultsForOutputResolutions)); if (configuration?.LoadPhotoPrismLocations is null) throw new NullReferenceException(nameof(configuration.LoadPhotoPrismLocations)); if (configuration?.LocationContainerDebugDirectory is null) throw new NullReferenceException(nameof(configuration.LocationContainerDebugDirectory)); + if (configuration?.LocationContainerDirectoryPattern is null) throw new NullReferenceException(nameof(configuration.LocationContainerDirectoryPattern)); if (configuration?.LocationContainerDistanceTake is null) throw new NullReferenceException(nameof(configuration.LocationContainerDistanceTake)); // if (configuration?.LocationContainerDistanceTolerance is null) throw new NullReferenceException(nameof(configuration.LocationContainerDistanceTolerance)); if (configuration?.LocationDigits is null) throw new NullReferenceException(nameof(configuration.LocationDigits)); @@ -220,6 +222,7 @@ public class Configuration configuration.LoadOrCreateThenSaveImageFacesResultsForOutputResolutions ?? Array.Empty(), configuration.LoadPhotoPrismLocations.Value, configuration.LocationContainerDebugDirectory, + configuration.LocationContainerDirectoryPattern, configuration.LocationContainerDistanceTake.Value, configuration.LocationContainerDistanceTolerance, configuration.LocationDigits.Value, diff --git a/Instance/Models/Configuration.cs b/Instance/Models/Configuration.cs index 7e31b4a..2303204 100644 --- a/Instance/Models/Configuration.cs +++ b/Instance/Models/Configuration.cs @@ -27,6 +27,7 @@ public record Configuration(Property.Models.Configuration PropertyConfiguration, string[] LoadOrCreateThenSaveImageFacesResultsForOutputResolutions, bool LoadPhotoPrismLocations, string LocationContainerDebugDirectory, + string LocationContainerDirectoryPattern, int LocationContainerDistanceTake, float? LocationContainerDistanceTolerance, int LocationDigits, diff --git a/Map/Models/Configuration.cs b/Map/Models/Configuration.cs index 4a78e01..550da0a 100644 --- a/Map/Models/Configuration.cs +++ b/Map/Models/Configuration.cs @@ -6,6 +6,7 @@ public record Configuration(bool DeletePossibleDuplicates, int FaceConfidencePercent, int FaceDistancePermyriad, string LocationContainerDebugDirectory, + string LocationContainerDirectoryPattern, int LocationContainerDistanceTake, float? LocationContainerDistanceTolerance, int LocationDigits, diff --git a/Map/Models/MapLogic.cs b/Map/Models/MapLogic.cs index 9545c01..3d549ff 100644 --- a/Map/Models/MapLogic.cs +++ b/Map/Models/MapLogic.cs @@ -21,7 +21,7 @@ public partial class MapLogic : Shared.Models.Methods.IMapLogic internal record Record(string? DebugDirectory, string? Directory, long? Ticks, - string PersonDirectory); + string? PersonDirectory); public void SaveContainers(int? updated, List saveContainers) { @@ -263,7 +263,7 @@ public partial class MapLogic : Shared.Models.Methods.IMapLogic readOnlyPersonKeyFormattedCollection = new(personKeyFormattedCollection); readOnlyPersonKeyFormattedToNewestPersonKeyFormatted = new(personKeyFormattedToNewestPersonKeyFormatted); } - List records = Stateless.MapLogic.DeleteEmptyDirectoriesAndGetCollection(configuration, ticks, eDistanceContentDirectory, readOnlyPersonKeyFormattedToNewestPersonKeyFormatted, readOnlyPersonKeyFormattedCollection); + List records = Stateless.DistanceLogic.DeleteEmptyDirectoriesAndGetCollection(configuration, ticks, eDistanceContentDirectory, readOnlyPersonKeyFormattedToNewestPersonKeyFormatted, readOnlyPersonKeyFormattedCollection); ReadOnlyCollection<(Stateless.MapLogic.PersonKeyFormattedIdThenWholePercentages, PersonContainer)> readOnlyPossiblyNewPersonDisplayDirectoryNamesAndPersonContainer; ReadOnlyCollection personKeyFormattedIdThenWholePercentagesCollection = Stateless.MapLogic.GetPersonKeyFormattedIdThenWholePercentages(configuration, ticks, records); // @@ -509,12 +509,12 @@ public partial class MapLogic : Shared.Models.Methods.IMapLogic long? ticks; string? directory; string? debugDirectory; - string personDirectory; + string? personDirectory; if (question.MappingFromPerson is null) { debugDirectory = null; (ticks, directory) = GetDirectory(configuration, saveIndividually, padLeft, question.SegmentC, by, question.MappingFromItem); - personDirectory = directory is null ? string.Empty : Path.Combine(directory, $"X+{ticks}"); + personDirectory = directory is null ? null : Path.Combine(directory, $"X+{ticks}"); } else { @@ -551,6 +551,7 @@ public partial class MapLogic : Shared.Models.Methods.IMapLogic FileHolder faceFileHolder; string facePartsDirectory; SaveContainer? saveContainer; + int? distancePermyriad = null; FileHolder facePartsFileHolder; FileHolder hiddenFaceFileHolder; ReadOnlyDictionary? wholePercentagesToMapping; @@ -570,7 +571,7 @@ public partial class MapLogic : Shared.Models.Methods.IMapLogic continue; if (mapping.MappingFromFilterPost.IsFocusPerson is not null && !mapping.MappingFromFilterPost.IsFocusPerson.Value) continue; - (by, isByMapping, isBySorting) = Stateless.MapLogic.Get(useFiltersCounter, saveIndividually, sortingContainersAny, forceSingleImageHumanized, mapping); + (by, isByMapping, isBySorting) = Stateless.MapLogic.Get(useFiltersCounter, saveIndividually, sortingContainersAny, forceSingleImageHumanized, distancePermyriad, mapping); if (isByMapping && !saveMapped) continue; if (!isBySorting || mapping.SortingContainer is null) @@ -586,8 +587,8 @@ public partial class MapLogic : Shared.Models.Methods.IMapLogic continue; } record = Get(_Configuration, saveIndividually, by, mapping, padLeft); - if (string.IsNullOrEmpty(record.Directory)) - throw new NotSupportedException(); + if (string.IsNullOrEmpty(record.Directory) || string.IsNullOrEmpty(record.PersonDirectory)) + continue; directory = record.Directory; if (mapping.MappingFromPerson is not null) { @@ -736,7 +737,7 @@ public partial class MapLogic : Shared.Models.Methods.IMapLogic foreach (SortingContainer sortingContainer in sortingContainers) { if (sortingContainer.Question is null) - throw new NotSupportedException(); + continue; if (sortingContainer.Source.MappingFromPerson is null) { sortingContainer.Question.UpdateMappingFromUnknownPerson(_Configuration.SaveIndividually, sortingContainer); @@ -788,6 +789,7 @@ public partial class MapLogic : Shared.Models.Methods.IMapLogic SaveContainer? saveContainer; FileHolder? facePartsFileHolder; FileHolder? hiddenFaceFileHolder; + bool sortingContainersAny = sortingContainers.Count > 0; int padLeft = _Configuration.FaceDistancePermyriad.ToString().Length; string forceSingleImageHumanized = nameof(Shared.Models.Stateless.IMapLogic.ForceSingleImage).Humanize(LetterCasing.Title); foreach (SortingContainer sortingContainer in sortingContainers) @@ -795,15 +797,15 @@ public partial class MapLogic : Shared.Models.Methods.IMapLogic if (sortingContainer.Question is null) throw new NotSupportedException(); isCounterPersonYear = sortingContainer.Source.MappingFromPerson is not null && IPersonBirthday.IsCounterPersonYear(sortingContainer.Source.MappingFromPerson.PersonKey); - (by, _, isBySorting) = Stateless.MapLogic.Get(useFiltersCounter, _Configuration.SaveIndividually, sortingContainers.Count > 0, forceSingleImageHumanized, sortingContainer.Question); + (by, _, isBySorting) = Stateless.MapLogic.Get(useFiltersCounter, _Configuration.SaveIndividually, sortingContainersAny, forceSingleImageHumanized, sortingContainer.Sorting.DistancePermyriad, sortingContainer.Question); question = sortingContainer.Question.MappingFromPerson is null ? sortingContainer.Source : sortingContainer.Question; if (question is null) throw new NotSupportedException(); if (question.MappingFromLocation is null) continue; record = Get(_Configuration, _Configuration.SaveIndividually, by, question, padLeft); - if (string.IsNullOrEmpty(record.Directory)) - throw new NotSupportedException(); + if (string.IsNullOrEmpty(record.Directory) || string.IsNullOrEmpty(record.PersonDirectory)) + continue; directory = record.Directory; if (!string.IsNullOrEmpty(record.DebugDirectory)) results.Add(new(record.DebugDirectory)); diff --git a/Map/Models/Stateless/DistanceLogic.cs b/Map/Models/Stateless/DistanceLogic.cs new file mode 100644 index 0000000..b99c739 --- /dev/null +++ b/Map/Models/Stateless/DistanceLogic.cs @@ -0,0 +1,452 @@ +using Humanizer; +using ShellProgressBar; +using System.Collections.ObjectModel; +using System.Diagnostics; +using System.Globalization; +using View_by_Distance.Shared.Models.Stateless.Methods; + +namespace View_by_Distance.Map.Models.Stateless; + +internal record Record(string PersonKeyFormatted, + int DirectoryNumber, + string? PersonDisplayDirectoryName, + bool? IsDefault, + string MappedFaceFile); + +internal abstract class DistanceLogic +{ + + internal record TicksDirectory(string Directory, + string DirectoryName, + DateTime DirectoryDateTime, + DateTime AlternateDirectoryDateTime, + float? TotalDays); + + private static void MoveTo(string actionDirectory, TicksDirectory ticksDirectory, string directory, string personKeyFormatted, string yearDirectoryName, string alphaDirectoryName, string[] files, string[] facesFileNames) + { + string checkFile; + string actionDirectoryName = Path.GetFileName(actionDirectory); + string checkDirectory = actionDirectoryName.StartsWith("y", StringComparison.CurrentCultureIgnoreCase) ? Path.Combine(ticksDirectory.Directory, personKeyFormatted, yearDirectoryName, alphaDirectoryName) : Path.Combine(directory, actionDirectoryName); + if (!Directory.Exists(checkDirectory)) + _ = Directory.CreateDirectory(checkDirectory); + foreach (string file in files) + { + if (facesFileNames.Contains(file)) + { + checkFile = Path.Combine(checkDirectory, Path.GetFileName(file)); + if (File.Exists(checkFile)) + continue; + File.Move(file, checkFile); + continue; + } + File.Delete(file); + } + } + + private static void MoveFiles(string personKeyFormatted, string personKeyDirectory, string newestPersonKeyFormatted, string newestPersonKeyDirectory) + { + 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); + } + } + } + _ = IPath.DeleteEmptyDirectories(personKeyDirectory); + } + + private static List UpdateDateVerifyAndGetTicksDirectories(Configuration configuration, string eDistanceContentDirectory) + { + List results = new(); + float? totalDays; + long? next = null; + string? checkDirectory; + string ticksDirectoryName; + DateTime directoryDateTime; + DirectoryInfo directoryInfo; + long? lastDirectoryTicks = null; + DateTime dateTime = DateTime.Now; + long month = dateTime.AddMonths(1).Ticks - dateTime.Ticks; + for (int i = 1; i < 5; i++) + _ = IPath.DeleteEmptyDirectories(eDistanceContentDirectory); + if (!Directory.Exists(eDistanceContentDirectory)) + _ = Directory.CreateDirectory(eDistanceContentDirectory); + string[] ticksDirectories = Directory.GetDirectories(eDistanceContentDirectory, "*", SearchOption.TopDirectoryOnly); + foreach (string ticksDirectory in ticksDirectories) + { + ticksDirectoryName = Path.GetFileName(ticksDirectory); + if (ticksDirectoryName.Length < 3) + continue; + if (!long.TryParse(ticksDirectoryName, out long directoryTicks)) + throw new NotSupportedException(); + if (next is null) + next = new DateTime(directoryTicks).Ticks; + else + { + next += month; + checkDirectory = Path.GetDirectoryName(ticksDirectory); + if (string.IsNullOrEmpty(checkDirectory)) + { + if (string.IsNullOrEmpty(checkDirectory)) + continue; + checkDirectory = Path.Combine(checkDirectory, next.Value.ToString()); + if (ticksDirectory == checkDirectory || !checkDirectory.EndsWith(configuration.LocationContainerDirectoryPattern)) + continue; + Directory.Move(ticksDirectory, checkDirectory); + continue; + } + } + directoryInfo = new(ticksDirectory); + directoryDateTime = new DateTime(directoryTicks); + if (directoryInfo.CreationTime.Ticks != directoryTicks) + Directory.SetCreationTime(ticksDirectory, new DateTime(directoryTicks)); + if (directoryInfo.LastWriteTime.Ticks != directoryTicks) + Directory.SetLastWriteTime(ticksDirectory, new DateTime(directoryTicks)); + totalDays = lastDirectoryTicks is null || new TimeSpan(dateTime.Ticks - directoryTicks).TotalDays < 1 ? null : (float)new TimeSpan(directoryTicks - lastDirectoryTicks.Value).TotalDays; + results.Add(new(ticksDirectory, ticksDirectoryName, new(directoryTicks), new DateTime(directoryDateTime.Year, directoryDateTime.Month, directoryDateTime.Day).AddMonths(1), totalDays)); + if (directoryDateTime.Hour == 0 && directoryDateTime.Minute == 0 && directoryDateTime.Second == 0) + continue; + lastDirectoryTicks = directoryTicks; + } + string[] compare = (from l in results where l.TotalDays is not null and < 9.95f select l.Directory).ToArray(); + if (compare.Length > 0 && configuration.ReMap) + throw new Exception($"Please Consolidate <{string.Join(Environment.NewLine, compare)}>"); + return results; + } + + private static void Individually(Configuration configuration, TicksDirectory ticksDirectory, string directory) + { + bool isDefault; + string[] files; + FileInfo[] collection; + string[] facesFileNames; + string yearDirectoryName; + string[] yearDirectories; + string alphaDirectoryName; + string matchDirectoryName; + string personKeyFormatted; + string[] alphaDirectories; + string[] matchDirectories; + string[] actionDirectories; + string personDisplayDirectory; + string[] personKeyDirectories; + string[] segmentCDirectories = Directory.GetDirectories(directory, "*", SearchOption.TopDirectoryOnly); + foreach (string segmentCDirectory in segmentCDirectories) + { + personKeyDirectories = Directory.GetDirectories(segmentCDirectory, "*", SearchOption.TopDirectoryOnly); + foreach (string personKeyDirectory in personKeyDirectories) + { + personKeyFormatted = Path.GetFileName(personKeyDirectory); + yearDirectories = Directory.GetDirectories(personKeyDirectory, "*", SearchOption.TopDirectoryOnly); + foreach (string yearDirectory in yearDirectories) + { + yearDirectoryName = Path.GetFileName(yearDirectory); + if (yearDirectoryName.StartsWith('=')) + Directory.Move(yearDirectory, yearDirectory.Replace('=', '~')); + } + yearDirectories = Directory.GetDirectories(personKeyDirectory, "*", SearchOption.TopDirectoryOnly); + foreach (string yearDirectory in yearDirectories) + { + yearDirectoryName = Path.GetFileName(yearDirectory); + matchDirectories = Directory.GetDirectories(yearDirectory, "*", SearchOption.TopDirectoryOnly); + alphaDirectories = matchDirectories.Where(l => !long.TryParse(Path.GetFileName(l), out long a)).ToArray(); + if (alphaDirectories.Length == 0) + continue; + alphaDirectoryName = Path.GetFileName(alphaDirectories[0]); + foreach (string matchDirectory in matchDirectories) + { + matchDirectoryName = Path.GetFileName(matchDirectory); + files = Directory.GetFiles(matchDirectory, "*", SearchOption.TopDirectoryOnly); + if (files.Length != 4) + continue; + collection = files.Select(l => new FileInfo(l)).ToArray(); + isDefault = IPerson.IsDefaultName(alphaDirectoryName) && IPersonBirthday.IsCounterPersonYear(personKeyFormatted[..4]); + if (isDefault) + facesFileNames = (from l in collection where l.Extension == configuration.FacesFileNameExtension select l.FullName).ToArray(); + else + facesFileNames = (from l in collection where l.Extension == configuration.FacesFileNameExtension && l.Name.Contains(matchDirectoryName) select l.FullName).ToArray(); + if (facesFileNames.Length == 0) + continue; + personDisplayDirectory = Path.Combine(matchDirectory, alphaDirectoryName); + if (!Directory.Exists(personDisplayDirectory) || !Directory.Exists(matchDirectory)) + continue; + _ = Process.Start("explorer", matchDirectory); + for (int i = 0; i < int.MaxValue; i++) + { + Thread.Sleep(500); + actionDirectories = Directory.GetDirectories(matchDirectory, "*", SearchOption.TopDirectoryOnly).Where(l => l != personDisplayDirectory && !l.EndsWith("Maybe")).ToArray(); + if (actionDirectories.Length > 0) + { + MoveTo(actionDirectories[0], ticksDirectory, directory, personKeyFormatted, yearDirectoryName, alphaDirectoryName, files, facesFileNames); + break; + } + } + } + } + } + } + } + + private static List GetRecords(Configuration configuration, bool? isDefault, string[] files, int directoryNumber, string personKeyFormatted, List distinct, string? personDisplayDirectoryName) + { + List results = new(); + int? id; + string fileName; + string checkFile; + int? wholePercentages; + foreach (string mappedFaceFile in files) + { + if (mappedFaceFile.EndsWith(".lnk")) + continue; + (id, wholePercentages) = IMapping.GetConverted(configuration.FacesFileNameExtension, mappedFaceFile); + if (id is null || wholePercentages is null) + continue; + fileName = Path.GetFileName(mappedFaceFile); + if (distinct.Contains(fileName)) + { + checkFile = $"{mappedFaceFile}.dup"; + if (File.Exists(checkFile)) + continue; + File.Move(mappedFaceFile, checkFile); + continue; + } + distinct.Add(fileName); + results.Add(new(personKeyFormatted, directoryNumber, personDisplayDirectoryName, isDefault, mappedFaceFile)); + } + return results; + } + + private static void RenameUnknown(string[] files) + { + foreach (string file in files) + { + if (file.EndsWith(".unk")) + continue; + File.Move(file, $"{file}.unk"); + } + } + + private static void MovedToNewestPersonKeyFormatted(string personKeyFormatted, string newestPersonKeyFormatted, TicksDirectory ticksDirectory, string personKeyDirectory) + { + string newestPersonKeyDirectory = Path.Combine(ticksDirectory.Directory, newestPersonKeyFormatted); + if (Directory.Exists(newestPersonKeyDirectory)) + MoveFiles(personKeyFormatted, personKeyDirectory, newestPersonKeyFormatted, newestPersonKeyDirectory); + else + Directory.Move(personKeyDirectory, newestPersonKeyDirectory); + } + + internal static List DeleteEmptyDirectoriesAndGetCollection(Configuration configuration, long ticks, string eDistanceContentDirectory, ReadOnlyDictionary personKeyFormattedToNewestPersonKeyFormatted, ReadOnlyCollection personKeyFormattedCollection) + { + List results = new(); + bool check; + string message; + string[] files; + bool? isDefault; + int totalSeconds; + DateTime dateTime; + TimeSpan timeSpan; + int directoryNumber; + string? checkDirectory; + ProgressBar progressBar; + string[] yearDirectories; + string personKeyFormatted; + string? personFirstInitial; + bool isReservedDirectoryName; + List distinct = new(); + string[] personNameDirectories; + string? newestPersonKeyFormatted; + string? personDisplayDirectoryName; + string[] personNameLinkDirectories; + string? personFirstInitialDirectory; + List ticksDirectories; + string[] personKeyFormattedDirectories; + string manualCopyHumanized = nameof(Shared.Models.Stateless.IMapLogic.ManualCopy).Humanize(LetterCasing.Title); + string forceSingleImageHumanized = nameof(Shared.Models.Stateless.IMapLogic.ForceSingleImage).Humanize(LetterCasing.Title); + ProgressBarOptions options = new() { ProgressCharacter = '─', ProgressBarOnBottom = true, DisableBottomPercentage = true }; + for (int i = 1; i < 6; i++) + { + check = false; + results.Clear(); + distinct.Clear(); + directoryNumber = 0; + ticksDirectories = UpdateDateVerifyAndGetTicksDirectories(configuration, eDistanceContentDirectory); + totalSeconds = (int)Math.Floor(new TimeSpan(DateTime.Now.Ticks - ticks).TotalSeconds); + message = $"{i}) {ticksDirectories.Count:000} compile from and clean ticks Director(ies) - B - {totalSeconds} total second(s)"; + progressBar = new(ticksDirectories.Count, message, options); + foreach (TicksDirectory ticksDirectory in ticksDirectories) + { + if (i == 1) + progressBar.Tick(); + personKeyFormattedDirectories = Directory.GetDirectories(ticksDirectory.Directory, "*", SearchOption.TopDirectoryOnly); + foreach (string personKeyFormattedDirectory in personKeyFormattedDirectories) + { + personKeyFormatted = Path.GetFileName(personKeyFormattedDirectory); + isReservedDirectoryName = personKeyFormatted.StartsWith(nameof(Shared.Models.Stateless.IMapLogic.Sorting)) || personKeyFormatted.StartsWith(nameof(Shared.Models.Stateless.IMapLogic.Mapping)) || personKeyFormatted.StartsWith(nameof(Shared.Models.Stateless.IMapLogic.ManualCopy)); + if (!isReservedDirectoryName && personKeyFormatted.StartsWith(nameof(Shared.Models.Stateless.IMapLogic.Individually))) + { + Individually(configuration, ticksDirectory, personKeyFormattedDirectory); + 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!"); + } + _ = personKeyFormattedToNewestPersonKeyFormatted.TryGetValue(personKeyFormatted, out newestPersonKeyFormatted); + if (personKeyFormattedToNewestPersonKeyFormatted.Count > 0 && newestPersonKeyFormatted is null) + { + timeSpan = new TimeSpan(DateTime.Now.Ticks - ticksDirectory.DirectoryDateTime.Ticks); + if (timeSpan.TotalDays > 6) + throw new Exception($"{configuration.MappingDefaultName} <{ticksDirectory.DirectoryDateTime}> are only allowed within x days!"); + } + yearDirectories = Directory.GetDirectories(personKeyFormattedDirectory, "*", SearchOption.TopDirectoryOnly); + foreach (string yearDirectory in yearDirectories) + { + if (check && !Directory.Exists(yearDirectory)) + continue; + if (ticksDirectory.DirectoryName != configuration.LocationContainerDebugDirectory) + { + files = Directory.GetFiles(yearDirectory, "*", SearchOption.TopDirectoryOnly); + foreach (string file in files) + File.Delete(file); + } + if (ticksDirectory.DirectoryName == configuration.LocationContainerDebugDirectory) + { + isDefault = null; + personDisplayDirectoryName = null; + files = Directory.GetFiles(yearDirectory, "*", SearchOption.TopDirectoryOnly); + results.AddRange(GetRecords(configuration, isDefault, files, directoryNumber, personKeyFormatted, distinct, personDisplayDirectoryName)); + files = Directory.GetFiles(yearDirectory, "*.lnk", SearchOption.AllDirectories); + foreach (string file in files) + File.Delete(file); + continue; + } + personNameDirectories = Directory.GetDirectories(yearDirectory, "*", SearchOption.TopDirectoryOnly); + if (personNameDirectories.Length > 1) + throw new NotSupportedException(); + foreach (string personNameDirectory in personNameDirectories) + { + directoryNumber++; + personDisplayDirectoryName = Path.GetFileName(personNameDirectory); + isDefault = IPerson.IsDefaultName(personDisplayDirectoryName) && IPersonBirthday.IsCounterPersonYear(personKeyFormatted[..4]); + if (isDefault.Value && personDisplayDirectoryName.Length == 1) + { + if (personKeyFormatted.Length != configuration.PersonBirthdayFormat.Length || !DateTime.TryParseExact(personKeyFormatted, configuration.PersonBirthdayFormat, CultureInfo.InvariantCulture, DateTimeStyles.None, out dateTime)) + continue; + checkDirectory = Path.Combine(yearDirectory, $"X+{dateTime.Ticks}"); + if (Directory.Exists(checkDirectory)) + { + Directory.Delete(yearDirectory, recursive: true); + continue; + } + Directory.Move(personNameDirectory, checkDirectory); + if (!check) + check = true; + continue; + } + if (isDefault.Value && (ticksDirectory.DirectoryDateTime.Hour != 0 || ticksDirectory.DirectoryDateTime.Minute != 0 || ticksDirectory.DirectoryDateTime.Second != 0)) + { + checkDirectory = Path.GetDirectoryName(ticksDirectory.Directory); + if (checkDirectory is null) + continue; + checkDirectory = Path.Combine(checkDirectory, ticksDirectory.AlternateDirectoryDateTime.Ticks.ToString()); + if (!Directory.Exists(checkDirectory)) + _ = Directory.CreateDirectory(checkDirectory); + checkDirectory = Path.Combine(checkDirectory, personKeyFormatted); + if (!Directory.Exists(checkDirectory)) + { + Directory.Move(personKeyFormattedDirectory, checkDirectory); + if (!check) + check = true; + break; + } + } + files = Directory.GetFiles(personNameDirectory, "*", SearchOption.TopDirectoryOnly); + if (isReservedDirectoryName && files.Length > 0) + throw new Exception($"Move personKey directories up one from {nameof(Shared.Models.Stateless.IMapLogic.Sorting)} and delete {nameof(Shared.Models.Stateless.IMapLogic.Sorting)} directory!"); + if (personKeyFormatted == manualCopyHumanized && files.Length > 0) + throw new Exception($"Move personKey directories up one from {manualCopyHumanized} and delete {manualCopyHumanized} directory!"); + if (personKeyFormatted == forceSingleImageHumanized && files.Length > 0) + throw new Exception($"Move personKey directories up one from {forceSingleImageHumanized} and delete {forceSingleImageHumanized} directory!"); + if (!isDefault.Value) + { + if (personKeyFormattedToNewestPersonKeyFormatted.Count > 0 && newestPersonKeyFormatted is null) + RenameUnknown(files); + else if (newestPersonKeyFormatted is not null && personKeyFormatted != newestPersonKeyFormatted) + { + if (!check) + check = true; + MovedToNewestPersonKeyFormatted(personKeyFormatted, newestPersonKeyFormatted, ticksDirectory, personKeyFormattedDirectory); + continue; + } + } + if (personKeyFormatted.Length != configuration.PersonBirthdayFormat.Length) + continue; + if (personDisplayDirectoryName.Length == 1 || isDefault.Value || !personKeyFormattedCollection.Contains(personKeyFormatted)) + personFirstInitialDirectory = personNameDirectory; + else + { + personFirstInitial = personDisplayDirectoryName[..1]; + if (personFirstInitial.All(l => char.IsDigit(l))) + { + foreach (string file in files) + File.Delete(file); + files = Directory.GetFiles(personNameDirectory, "*", SearchOption.AllDirectories); + foreach (string file in files) + File.Delete(file); + _ = IPath.DeleteEmptyDirectories(personNameDirectory); + continue; + } + personFirstInitialDirectory = Path.Combine(yearDirectory, personFirstInitial.ToString()); + if (Directory.Exists(personFirstInitialDirectory)) + throw new Exception("Forgot to ..."); + Directory.Move(personNameDirectory, personFirstInitialDirectory); + files = Directory.GetFiles(personFirstInitialDirectory, "*", SearchOption.TopDirectoryOnly); + } + results.AddRange(GetRecords(configuration, isDefault, files, directoryNumber, personKeyFormatted, distinct, personDisplayDirectoryName)); + personNameLinkDirectories = Directory.GetDirectories(personFirstInitialDirectory, "*", SearchOption.TopDirectoryOnly); + foreach (string personNameLinkDirectory in personNameLinkDirectories) + { + files = Directory.GetFiles(personNameLinkDirectory, "*", SearchOption.TopDirectoryOnly); + foreach (string file in files) + { + if (!file.EndsWith(".lnk")) + continue; + File.Delete(file); + } + _ = IPath.DeleteEmptyDirectories(personNameLinkDirectory); + } + _ = IPath.DeleteEmptyDirectories(personFirstInitialDirectory); + } + _ = IPath.DeleteEmptyDirectories(yearDirectory); + } + _ = IPath.DeleteEmptyDirectories(personKeyFormattedDirectory); + } + _ = IPath.DeleteEmptyDirectories(ticksDirectory.Directory); + _ = IPath.DeleteEmptyDirectories(ticksDirectory.Directory); + } + progressBar.Dispose(); + if (check) + continue; + break; + } + return results; + } + +} \ No newline at end of file diff --git a/Map/Models/Stateless/MapLogic.cs b/Map/Models/Stateless/MapLogic.cs index f400452..aba8235 100644 --- a/Map/Models/Stateless/MapLogic.cs +++ b/Map/Models/Stateless/MapLogic.cs @@ -1,4 +1,3 @@ -using Humanizer; using ShellProgressBar; using System.Collections.ObjectModel; using System.Diagnostics; @@ -14,12 +13,6 @@ namespace View_by_Distance.Map.Models.Stateless; internal abstract class MapLogic { - internal record Record(string PersonKeyFormatted, - int DirectoryNumber, - string? PersonDisplayDirectoryName, - bool? IsDefault, - string MappedFaceFile); - internal record MappedFile(long PersonKey, string PersonKeyFormatted, string? PersonDisplayDirectoryName, @@ -31,12 +24,6 @@ internal abstract class MapLogic string File, float? Percent); - internal record TicksDirectory(string Directory, - string DirectoryName, - DateTime DirectoryDateTime, - DateTime AlternateDirectoryDateTime, - float? TotalDays); - internal record PersonKeyFormattedIdThenWholePercentages(string PersonKeyFormatted, string? PersonDisplayDirectoryName, bool? IsDefault, @@ -188,58 +175,10 @@ internal abstract class MapLogic return new(results); } - private static void MoveTo(string actionDirectory, TicksDirectory ticksDirectory, string directory, string personKeyFormatted, string yearDirectoryName, string alphaDirectoryName, string[] files, string[] facesFileNames) + internal static string GetMappingSegmentB(long ticks, PersonBirthday personBirthday, int? approximateYears, MappingFromItem mappingFromItem) { - string checkFile; - string actionDirectoryName = Path.GetFileName(actionDirectory); - string checkDirectory = actionDirectoryName.StartsWith("y", StringComparison.CurrentCultureIgnoreCase) ? Path.Combine(ticksDirectory.Directory, personKeyFormatted, yearDirectoryName, alphaDirectoryName) : Path.Combine(directory, actionDirectoryName); - if (!Directory.Exists(checkDirectory)) - _ = Directory.CreateDirectory(checkDirectory); - foreach (string file in files) - { - if (facesFileNames.Contains(file)) - { - checkFile = Path.Combine(checkDirectory, Path.GetFileName(file)); - if (File.Exists(checkFile)) - continue; - File.Move(file, checkFile); - continue; - } - File.Delete(file); - } - } - - private static void MoveFiles(string personKeyFormatted, string personKeyDirectory, string newestPersonKeyFormatted, string newestPersonKeyDirectory) - { - 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); - } - } - } - _ = IPath.DeleteEmptyDirectories(personKeyDirectory); + string result = GetMappingSegmentB(ticks, personBirthday, approximateYears, mappingFromItem.GetDateTimeOriginalThenMinimumDateTime(), mappingFromItem.IsWrongYear); + return result; } private static List GetDisplayDirectoryAllFiles(string fileNameExtension, string personBirthdayFormat, ReadOnlyCollection personContainers) @@ -293,149 +232,43 @@ internal abstract class MapLogic } } - private static List UpdateDateVerifyAndGetTicksDirectories(Configuration configuration, string eDistanceContentDirectory) + internal static string GetFacesDirectory(Shared.Models.Properties.IPropertyConfiguration propertyConfiguration, string dFacesContentDirectory, MappingFromItem mappingFromItem) { - List results = new(); - float? totalDays; - long? next = null; - string? checkDirectory; - string ticksDirectoryName; - DateTime directoryDateTime; - DirectoryInfo directoryInfo; - long? lastDirectoryTicks = null; - DateTime dateTime = DateTime.Now; - long month = dateTime.AddMonths(1).Ticks - dateTime.Ticks; - for (int i = 1; i < 5; i++) - _ = IPath.DeleteEmptyDirectories(eDistanceContentDirectory); - if (!Directory.Exists(eDistanceContentDirectory)) - _ = Directory.CreateDirectory(eDistanceContentDirectory); - string[] ticksDirectories = Directory.GetDirectories(eDistanceContentDirectory, "*", SearchOption.TopDirectoryOnly); - foreach (string ticksDirectory in ticksDirectories) - { - ticksDirectoryName = Path.GetFileName(ticksDirectory); - if (!long.TryParse(ticksDirectoryName, out long directoryTicks)) - throw new NotSupportedException(); - if (next is null) - next = new DateTime(directoryTicks).Ticks; - else - { - next += month; - checkDirectory = Path.GetDirectoryName(ticksDirectory); - if (string.IsNullOrEmpty(checkDirectory)) - { - if (!string.IsNullOrEmpty(checkDirectory)) - Directory.Move(ticksDirectory, Path.Combine(checkDirectory, next.Value.ToString())); - continue; - } - } - directoryInfo = new(ticksDirectory); - directoryDateTime = new DateTime(directoryTicks); - if (directoryInfo.CreationTime.Ticks != directoryTicks) - Directory.SetCreationTime(ticksDirectory, new DateTime(directoryTicks)); - if (directoryInfo.LastWriteTime.Ticks != directoryTicks) - Directory.SetLastWriteTime(ticksDirectory, new DateTime(directoryTicks)); - totalDays = lastDirectoryTicks is null || new TimeSpan(dateTime.Ticks - directoryTicks).TotalDays < 1 ? null : (float)new TimeSpan(directoryTicks - lastDirectoryTicks.Value).TotalDays; - results.Add(new(ticksDirectory, ticksDirectoryName, new(directoryTicks), new DateTime(directoryDateTime.Year, directoryDateTime.Month, directoryDateTime.Day).AddMonths(1), totalDays)); - if (directoryDateTime.Hour == 0 && directoryDateTime.Minute == 0 && directoryDateTime.Second == 0) - continue; - lastDirectoryTicks = directoryTicks; - } - string[] compare = (from l in results where l.TotalDays is not null and < 9.95f select l.Directory).ToArray(); - if (compare.Length > 0 && configuration.ReMap) - throw new Exception($"Please Consolidate <{string.Join(Environment.NewLine, compare)}>"); - return results; + string result; + (string directoryName, _) = IPath.GetDirectoryNameAndIndex(propertyConfiguration.ResultAllInOneSubdirectoryLength, mappingFromItem.ImageFileHolder.NameWithoutExtension); + result = Path.Combine(dFacesContentDirectory, propertyConfiguration.ResultAllInOne, directoryName, mappingFromItem.ImageFileHolder.NameWithoutExtension); + return result; } - private static void Individually(Configuration configuration, TicksDirectory ticksDirectory, string directory) + private static List<(string, long)> GetDirectoryAndTicksCollection(string[] jLinks, string personBirthdayFormat, string? rootDirectory) { - bool isDefault; - string[] files; - FileInfo[] collection; - string[] facesFileNames; - string yearDirectoryName; - string[] yearDirectories; - string alphaDirectoryName; - string matchDirectoryName; - string personKeyFormatted; - string[] alphaDirectories; - string[] matchDirectories; - string[] actionDirectories; - string personDisplayDirectory; + List<(string, long)> results = new(); + string directory; + DateTime dateTime; string[] personKeyDirectories; - string[] segmentCDirectories = Directory.GetDirectories(directory, "*", SearchOption.TopDirectoryOnly); - foreach (string segmentCDirectory in segmentCDirectories) + string[] personDisplayDirectoryNames; + string personKeyFormattedDirectoryName; + foreach (string jLink in jLinks) { - personKeyDirectories = Directory.GetDirectories(segmentCDirectory, "*", SearchOption.TopDirectoryOnly); - foreach (string personKeyDirectory in personKeyDirectories) + if (rootDirectory is null) + continue; + directory = Path.Combine(rootDirectory, jLink); + if (!Directory.Exists(directory)) + continue; + personDisplayDirectoryNames = Directory.GetDirectories(directory, "*", SearchOption.TopDirectoryOnly); + foreach (string personDisplayDirectoryName in personDisplayDirectoryNames) { - personKeyFormatted = Path.GetFileName(personKeyDirectory); - yearDirectories = Directory.GetDirectories(personKeyDirectory, "*", SearchOption.TopDirectoryOnly); - foreach (string yearDirectory in yearDirectories) + personKeyDirectories = Directory.GetDirectories(personDisplayDirectoryName, "*", SearchOption.TopDirectoryOnly); + foreach (string personKeyFormattedDirectory in personKeyDirectories) { - yearDirectoryName = Path.GetFileName(yearDirectory); - if (yearDirectoryName.StartsWith('=')) - Directory.Move(yearDirectory, yearDirectory.Replace('=', '~')); - } - yearDirectories = Directory.GetDirectories(personKeyDirectory, "*", SearchOption.TopDirectoryOnly); - foreach (string yearDirectory in yearDirectories) - { - yearDirectoryName = Path.GetFileName(yearDirectory); - matchDirectories = Directory.GetDirectories(yearDirectory, "*", SearchOption.TopDirectoryOnly); - alphaDirectories = matchDirectories.Where(l => !long.TryParse(Path.GetFileName(l), out long a)).ToArray(); - if (alphaDirectories.Length == 0) + personKeyFormattedDirectoryName = Path.GetFileName(personKeyFormattedDirectory); + if (personKeyFormattedDirectoryName.Length != personBirthdayFormat.Length || !DateTime.TryParseExact(personKeyFormattedDirectoryName, personBirthdayFormat, CultureInfo.InvariantCulture, DateTimeStyles.None, out dateTime)) continue; - alphaDirectoryName = Path.GetFileName(alphaDirectories[0]); - foreach (string matchDirectory in matchDirectories) - { - matchDirectoryName = Path.GetFileName(matchDirectory); - files = Directory.GetFiles(matchDirectory, "*", SearchOption.TopDirectoryOnly); - if (files.Length != 4) - continue; - collection = files.Select(l => new FileInfo(l)).ToArray(); - isDefault = IPerson.IsDefaultName(alphaDirectoryName) && IPersonBirthday.IsCounterPersonYear(personKeyFormatted[..4]); - if (isDefault) - facesFileNames = (from l in collection where l.Extension == configuration.FacesFileNameExtension select l.FullName).ToArray(); - else - facesFileNames = (from l in collection where l.Extension == configuration.FacesFileNameExtension && l.Name.Contains(matchDirectoryName) select l.FullName).ToArray(); - if (facesFileNames.Length == 0) - continue; - personDisplayDirectory = Path.Combine(matchDirectory, alphaDirectoryName); - if (!Directory.Exists(personDisplayDirectory) || !Directory.Exists(matchDirectory)) - continue; - _ = Process.Start("explorer", matchDirectory); - for (int i = 0; i < int.MaxValue; i++) - { - Thread.Sleep(500); - actionDirectories = Directory.GetDirectories(matchDirectory, "*", SearchOption.TopDirectoryOnly).Where(l => l != personDisplayDirectory && !l.EndsWith("Maybe")).ToArray(); - if (actionDirectories.Length > 0) - { - MoveTo(actionDirectories[0], ticksDirectory, directory, personKeyFormatted, yearDirectoryName, alphaDirectoryName, files, facesFileNames); - break; - } - } - } + results.Add((directory, dateTime.Ticks)); } } } - } - - private static void RenameUnknown(string[] files) - { - foreach (string file in files) - { - if (file.EndsWith(".unk")) - continue; - File.Move(file, $"{file}.unk"); - } - } - - private static void MovedToNewestPersonKeyFormatted(string personKeyFormatted, string newestPersonKeyFormatted, TicksDirectory ticksDirectory, string personKeyDirectory) - { - string newestPersonKeyDirectory = Path.Combine(ticksDirectory.Directory, newestPersonKeyFormatted); - if (Directory.Exists(newestPersonKeyDirectory)) - MoveFiles(personKeyFormatted, personKeyDirectory, newestPersonKeyFormatted, newestPersonKeyDirectory); - else - Directory.Move(personKeyDirectory, newestPersonKeyDirectory); + return results; } private static (long, PersonContainer)[] GetDistinctCollection(Configuration configuration, IEnumerable personContainers, Dictionary> personKeyToPersonContainerCollection, Dictionary personKeyFormattedToPersonContainer) @@ -602,6 +435,7 @@ internal abstract class MapLogic string file; long personKey; string fileName; + string checkFile; List distinct = new(); PersonBirthday? personBirthday; results.AddRange(GetDisplayDirectoryAllFiles(configuration.FacesFileNameExtension, configuration.PersonBirthdayFormat, personContainers)); @@ -629,7 +463,10 @@ internal abstract class MapLogic continue; if (!File.Exists(file)) continue; - File.Move(file, file[..^4]); + checkFile = file[..^4]; + if (File.Exists(checkFile)) + continue; + File.Move(file, checkFile); results[i] = new(results[i].PersonKey, results[i].PersonKeyFormatted, results[i].PersonDisplayDirectoryName, results[i].DirectoryNumber, file[..^4]); } return results; @@ -721,12 +558,33 @@ internal abstract class MapLogic } } - internal static string GetFacesDirectory(Shared.Models.Properties.IPropertyConfiguration propertyConfiguration, string dFacesContentDirectory, MappingFromItem mappingFromItem) + internal static (SaveContainer?, SaveContainer?) GetContainers(string facesFileNameExtension, string facePartsFileNameExtension, Shared.Models.Properties.IPropertyConfiguration propertyConfiguration, string dFacesContentDirectory, string d2FacePartsContentCollectionDirectory, string directory, Mapping keyMapping) { - string result; - (string directoryName, _) = IPath.GetDirectoryNameAndIndex(propertyConfiguration.ResultAllInOneSubdirectoryLength, mappingFromItem.ImageFileHolder.NameWithoutExtension); - result = Path.Combine(dFacesContentDirectory, propertyConfiguration.ResultAllInOne, directoryName, mappingFromItem.ImageFileHolder.NameWithoutExtension); - return result; + SaveContainer? result; + SaveContainer? saveContainer; + if (keyMapping.MappingFromLocation is null) + (result, saveContainer) = (null, null); + else + { + string? facePartsContentCollectionFile = GetFacePartsContentCollectionFile(facePartsFileNameExtension, d2FacePartsContentCollectionDirectory, keyMapping.MappingFromItem); + if (facePartsContentCollectionFile is null || !File.Exists(facePartsContentCollectionFile)) + result = null; + else + { + string checkFile = Path.Combine(directory, $"{keyMapping.MappingFromItem.ImageFileHolder.Name}{facePartsFileNameExtension}"); + result = new(checkFile, directory, new(facePartsContentCollectionFile)); + } + string facesDirectory = GetFacesDirectory(propertyConfiguration, dFacesContentDirectory, keyMapping.MappingFromItem); + FileHolder faceFileHolder = new(Path.Combine(facesDirectory, $"{keyMapping.MappingFromLocation.DeterministicHashCodeKey}{keyMapping.MappingFromItem.ImageFileHolder.ExtensionLowered}{facesFileNameExtension}")); + if (!faceFileHolder.Exists) + saveContainer = null; + else + { + string checkFile = Path.Combine(directory, $"{keyMapping.MappingFromLocation.DeterministicHashCodeKey}{keyMapping.MappingFromItem.ImageFileHolder.ExtensionLowered}{facesFileNameExtension}"); + saveContainer = new(checkFile, directory, faceFileHolder); + } + } + return (result, saveContainer); } private static IEnumerable<(string, string)> GetCollection(string[] yearDirectories) @@ -735,37 +593,6 @@ internal abstract class MapLogic yield return new(l, Path.GetFileName(l)); } - private static List<(string, long)> GetDirectoryAndTicksCollection(string[] jLinks, string personBirthdayFormat, string? rootDirectory) - { - List<(string, long)> results = new(); - string directory; - DateTime dateTime; - string[] personKeyDirectories; - string[] personDisplayDirectoryNames; - string personKeyFormattedDirectoryName; - foreach (string jLink in jLinks) - { - if (rootDirectory is null) - continue; - directory = Path.Combine(rootDirectory, jLink); - if (!Directory.Exists(directory)) - continue; - personDisplayDirectoryNames = Directory.GetDirectories(directory, "*", SearchOption.TopDirectoryOnly); - foreach (string personDisplayDirectoryName in personDisplayDirectoryNames) - { - personKeyDirectories = Directory.GetDirectories(personDisplayDirectoryName, "*", SearchOption.TopDirectoryOnly); - foreach (string personKeyFormattedDirectory in personKeyDirectories) - { - personKeyFormattedDirectoryName = Path.GetFileName(personKeyFormattedDirectory); - if (personKeyFormattedDirectoryName.Length != personBirthdayFormat.Length || !DateTime.TryParseExact(personKeyFormattedDirectoryName, personBirthdayFormat, CultureInfo.InvariantCulture, DateTimeStyles.None, out dateTime)) - continue; - results.Add((directory, dateTime.Ticks)); - } - } - } - return results; - } - private static List<(string, long)> GetGenealogicalDataCommunicationDirectories(string genealogicalDataCommunicationFile, string[] jLinks, string personBirthdayFormat) { List<(string, long)> results; @@ -841,228 +668,6 @@ internal abstract class MapLogic return results; } - private static List GetRecords(Configuration configuration, bool? isDefault, string[] files, int directoryNumber, string personKeyFormatted, List distinct, string? personDisplayDirectoryName) - { - List results = new(); - int? id; - string fileName; - string checkFile; - int? wholePercentages; - foreach (string mappedFaceFile in files) - { - if (mappedFaceFile.EndsWith(".lnk")) - continue; - (id, wholePercentages) = IMapping.GetConverted(configuration.FacesFileNameExtension, mappedFaceFile); - if (id is null || wholePercentages is null) - continue; - fileName = Path.GetFileName(mappedFaceFile); - if (distinct.Contains(fileName)) - { - checkFile = $"{mappedFaceFile}.dup"; - if (File.Exists(checkFile)) - continue; - File.Move(mappedFaceFile, checkFile); - continue; - } - distinct.Add(fileName); - results.Add(new(personKeyFormatted, directoryNumber, personDisplayDirectoryName, isDefault, mappedFaceFile)); - } - return results; - } - - internal static List DeleteEmptyDirectoriesAndGetCollection(Configuration configuration, long ticks, string eDistanceContentDirectory, ReadOnlyDictionary personKeyFormattedToNewestPersonKeyFormatted, ReadOnlyCollection personKeyFormattedCollection) - { - List results = new(); - bool check; - string message; - string[] files; - bool? isDefault; - int totalSeconds; - DateTime dateTime; - TimeSpan timeSpan; - int directoryNumber; - string? checkDirectory; - ProgressBar progressBar; - string[] yearDirectories; - string personKeyFormatted; - string? personFirstInitial; - bool isReservedDirectoryName; - List distinct = new(); - string[] personNameDirectories; - string? newestPersonKeyFormatted; - string? personDisplayDirectoryName; - string[] personNameLinkDirectories; - string? personFirstInitialDirectory; - List ticksDirectories; - string[] personKeyFormattedDirectories; - string manualCopyHumanized = nameof(Shared.Models.Stateless.IMapLogic.ManualCopy).Humanize(LetterCasing.Title); - string forceSingleImageHumanized = nameof(Shared.Models.Stateless.IMapLogic.ForceSingleImage).Humanize(LetterCasing.Title); - ProgressBarOptions options = new() { ProgressCharacter = '─', ProgressBarOnBottom = true, DisableBottomPercentage = true }; - for (int i = 1; i < 6; i++) - { - check = false; - results.Clear(); - distinct.Clear(); - directoryNumber = 0; - ticksDirectories = UpdateDateVerifyAndGetTicksDirectories(configuration, eDistanceContentDirectory); - totalSeconds = (int)Math.Floor(new TimeSpan(DateTime.Now.Ticks - ticks).TotalSeconds); - message = $"{i}) {ticksDirectories.Count:000} compile from and clean ticks Director(ies) - B - {totalSeconds} total second(s)"; - progressBar = new(ticksDirectories.Count, message, options); - foreach (TicksDirectory ticksDirectory in ticksDirectories) - { - if (i == 1) - progressBar.Tick(); - personKeyFormattedDirectories = Directory.GetDirectories(ticksDirectory.Directory, "*", SearchOption.TopDirectoryOnly); - foreach (string personKeyFormattedDirectory in personKeyFormattedDirectories) - { - personKeyFormatted = Path.GetFileName(personKeyFormattedDirectory); - isReservedDirectoryName = personKeyFormatted.StartsWith(nameof(Shared.Models.Stateless.IMapLogic.Sorting)) || personKeyFormatted.StartsWith(nameof(Shared.Models.Stateless.IMapLogic.Mapping)) || personKeyFormatted.StartsWith(nameof(Shared.Models.Stateless.IMapLogic.ManualCopy)); - if (!isReservedDirectoryName && personKeyFormatted.StartsWith(nameof(Shared.Models.Stateless.IMapLogic.Individually))) - { - Individually(configuration, ticksDirectory, personKeyFormattedDirectory); - 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!"); - } - _ = personKeyFormattedToNewestPersonKeyFormatted.TryGetValue(personKeyFormatted, out newestPersonKeyFormatted); - if (personKeyFormattedToNewestPersonKeyFormatted.Count > 0 && newestPersonKeyFormatted is null) - { - timeSpan = new TimeSpan(DateTime.Now.Ticks - ticksDirectory.DirectoryDateTime.Ticks); - if (timeSpan.TotalDays > 6) - throw new Exception($"{configuration.MappingDefaultName} <{ticksDirectory.DirectoryDateTime}> are only allowed within x days!"); - } - yearDirectories = Directory.GetDirectories(personKeyFormattedDirectory, "*", SearchOption.TopDirectoryOnly); - foreach (string yearDirectory in yearDirectories) - { - if (check && !Directory.Exists(yearDirectory)) - continue; - if (ticksDirectory.DirectoryName != configuration.LocationContainerDebugDirectory) - { - files = Directory.GetFiles(yearDirectory, "*", SearchOption.TopDirectoryOnly); - foreach (string file in files) - File.Delete(file); - } - if (ticksDirectory.DirectoryName == configuration.LocationContainerDebugDirectory) - { - isDefault = null; - personDisplayDirectoryName = null; - files = Directory.GetFiles(yearDirectory, "*", SearchOption.TopDirectoryOnly); - results.AddRange(GetRecords(configuration, isDefault, files, directoryNumber, personKeyFormatted, distinct, personDisplayDirectoryName)); - files = Directory.GetFiles(yearDirectory, "*.lnk", SearchOption.AllDirectories); - foreach (string file in files) - File.Delete(file); - continue; - } - personNameDirectories = Directory.GetDirectories(yearDirectory, "*", SearchOption.TopDirectoryOnly); - if (personNameDirectories.Length > 1) - throw new NotSupportedException(); - foreach (string personNameDirectory in personNameDirectories) - { - directoryNumber++; - personDisplayDirectoryName = Path.GetFileName(personNameDirectory); - isDefault = IPerson.IsDefaultName(personDisplayDirectoryName) && IPersonBirthday.IsCounterPersonYear(personKeyFormatted[..4]); - if (isDefault.Value && personDisplayDirectoryName.Length == 1) - { - if (personKeyFormatted.Length != configuration.PersonBirthdayFormat.Length || !DateTime.TryParseExact(personKeyFormatted, configuration.PersonBirthdayFormat, CultureInfo.InvariantCulture, DateTimeStyles.None, out dateTime)) - continue; - checkDirectory = Path.Combine(yearDirectory, $"X+{dateTime.Ticks}"); - if (Directory.Exists(checkDirectory)) - { - Directory.Delete(yearDirectory, recursive: true); - continue; - } - Directory.Move(personNameDirectory, checkDirectory); - if (!check) - check = true; - continue; - } - if (isDefault.Value && (ticksDirectory.DirectoryDateTime.Hour != 0 || ticksDirectory.DirectoryDateTime.Minute != 0 || ticksDirectory.DirectoryDateTime.Second != 0)) - { - checkDirectory = Path.GetDirectoryName(ticksDirectory.Directory); - if (checkDirectory is null) - continue; - checkDirectory = Path.Combine(checkDirectory, ticksDirectory.AlternateDirectoryDateTime.Ticks.ToString()); - if (!Directory.Exists(checkDirectory)) - _ = Directory.CreateDirectory(checkDirectory); - checkDirectory = Path.Combine(checkDirectory, personKeyFormatted); - if (!Directory.Exists(checkDirectory)) - { - Directory.Move(personKeyFormattedDirectory, checkDirectory); - if (!check) - check = true; - break; - } - } - files = Directory.GetFiles(personNameDirectory, "*", SearchOption.TopDirectoryOnly); - if (isReservedDirectoryName && files.Length > 0) - throw new Exception($"Move personKey directories up one from {nameof(Shared.Models.Stateless.IMapLogic.Sorting)} and delete {nameof(Shared.Models.Stateless.IMapLogic.Sorting)} directory!"); - if (personKeyFormatted == manualCopyHumanized && files.Length > 0) - throw new Exception($"Move personKey directories up one from {manualCopyHumanized} and delete {manualCopyHumanized} directory!"); - if (personKeyFormatted == forceSingleImageHumanized && files.Length > 0) - throw new Exception($"Move personKey directories up one from {forceSingleImageHumanized} and delete {forceSingleImageHumanized} directory!"); - if (!isDefault.Value) - { - if (personKeyFormattedToNewestPersonKeyFormatted.Count > 0 && newestPersonKeyFormatted is null) - RenameUnknown(files); - else if (newestPersonKeyFormatted is not null && personKeyFormatted != newestPersonKeyFormatted) - { - if (!check) - check = true; - MovedToNewestPersonKeyFormatted(personKeyFormatted, newestPersonKeyFormatted, ticksDirectory, personKeyFormattedDirectory); - continue; - } - } - if (personKeyFormatted.Length != configuration.PersonBirthdayFormat.Length) - continue; - if (personDisplayDirectoryName.Length == 1 || isDefault.Value || !personKeyFormattedCollection.Contains(personKeyFormatted)) - personFirstInitialDirectory = personNameDirectory; - else - { - personFirstInitial = personDisplayDirectoryName[..1]; - if (personFirstInitial.All(l => char.IsDigit(l))) - { - foreach (string file in files) - File.Delete(file); - files = Directory.GetFiles(personNameDirectory, "*", SearchOption.AllDirectories); - foreach (string file in files) - File.Delete(file); - _ = IPath.DeleteEmptyDirectories(personNameDirectory); - continue; - } - personFirstInitialDirectory = Path.Combine(yearDirectory, personFirstInitial.ToString()); - if (Directory.Exists(personFirstInitialDirectory)) - throw new Exception("Forgot to ..."); - Directory.Move(personNameDirectory, personFirstInitialDirectory); - files = Directory.GetFiles(personFirstInitialDirectory, "*", SearchOption.TopDirectoryOnly); - } - results.AddRange(GetRecords(configuration, isDefault, files, directoryNumber, personKeyFormatted, distinct, personDisplayDirectoryName)); - personNameLinkDirectories = Directory.GetDirectories(personFirstInitialDirectory, "*", SearchOption.TopDirectoryOnly); - foreach (string personNameLinkDirectory in personNameLinkDirectories) - { - files = Directory.GetFiles(personNameLinkDirectory, "*", SearchOption.TopDirectoryOnly); - foreach (string file in files) - { - if (!file.EndsWith(".lnk")) - continue; - File.Delete(file); - } - _ = IPath.DeleteEmptyDirectories(personNameLinkDirectory); - } - _ = IPath.DeleteEmptyDirectories(personFirstInitialDirectory); - } - _ = IPath.DeleteEmptyDirectories(yearDirectory); - } - _ = IPath.DeleteEmptyDirectories(personKeyFormattedDirectory); - } - _ = IPath.DeleteEmptyDirectories(ticksDirectory.Directory); - _ = IPath.DeleteEmptyDirectories(ticksDirectory.Directory); - } - progressBar.Dispose(); - if (check) - continue; - break; - } - return results; - } - internal static void SetKeyValuePairsAndAddToCollections(Configuration configuration, ReadOnlyCollection personContainers, Dictionary personKeyToPersonContainer, ReadOnlyCollection personKeyFormattedIdThenWholePercentagesCollection, Dictionary personKeyToCount, Dictionary personKeyFormattedToPersonContainer, Dictionary> personKeyToPersonContainerCollection, List<(PersonKeyFormattedIdThenWholePercentages, PersonContainer)> possiblyNewPersonDisplayDirectoryNamesAndPersonContainer) { PersonBirthday? personBirthday; @@ -1333,12 +938,6 @@ internal abstract class MapLogic return result; } - internal static string GetMappingSegmentB(long ticks, PersonBirthday personBirthday, int? approximateYears, MappingFromItem mappingFromItem) - { - string result = GetMappingSegmentB(ticks, personBirthday, approximateYears, mappingFromItem.GetDateTimeOriginalThenMinimumDateTime(), mappingFromItem.IsWrongYear); - return result; - } - internal static string? GetFacePartsContentCollectionFile(string extension, string d2FacePartsContentCollectionDirectory, MappingFromItem mappingFromItem) { string? result; @@ -1373,35 +972,6 @@ internal abstract class MapLogic return result; } - internal static (SaveContainer?, SaveContainer?) GetContainers(string facesFileNameExtension, string facePartsFileNameExtension, Shared.Models.Properties.IPropertyConfiguration propertyConfiguration, string dFacesContentDirectory, string d2FacePartsContentCollectionDirectory, string directory, Mapping keyMapping) - { - SaveContainer? result; - SaveContainer? saveContainer; - if (keyMapping.MappingFromLocation is null) - (result, saveContainer) = (null, null); - else - { - string? facePartsContentCollectionFile = GetFacePartsContentCollectionFile(facePartsFileNameExtension, d2FacePartsContentCollectionDirectory, keyMapping.MappingFromItem); - if (facePartsContentCollectionFile is null || !File.Exists(facePartsContentCollectionFile)) - result = null; - else - { - string checkFile = Path.Combine(directory, $"{keyMapping.MappingFromItem.ImageFileHolder.Name}{facePartsFileNameExtension}"); - result = new(checkFile, directory, new(facePartsContentCollectionFile)); - } - string facesDirectory = GetFacesDirectory(propertyConfiguration, dFacesContentDirectory, keyMapping.MappingFromItem); - FileHolder faceFileHolder = new(Path.Combine(facesDirectory, $"{keyMapping.MappingFromLocation.DeterministicHashCodeKey}{keyMapping.MappingFromItem.ImageFileHolder.ExtensionLowered}{facesFileNameExtension}")); - if (!faceFileHolder.Exists) - saveContainer = null; - else - { - string checkFile = Path.Combine(directory, $"{keyMapping.MappingFromLocation.DeterministicHashCodeKey}{keyMapping.MappingFromItem.ImageFileHolder.ExtensionLowered}{facesFileNameExtension}"); - saveContainer = new(checkFile, directory, faceFileHolder); - } - } - return (result, saveContainer); - } - internal static (SaveContainer, SaveContainer?) GetContainers(string facesFileNameExtension, string facePartsFileNameExtension, string directory, FileHolder faceFileHolder, FileHolder facePartsFileHolder, Mapping mapping) { string checkFile; @@ -1568,7 +1138,7 @@ internal abstract class MapLogic return results; } - internal static (string, bool, bool) Get(int? useFiltersCounter, bool saveIndividually, bool sortingContainersAny, string forceSingleImageHumanized, Mapping mapping) + internal static (string, bool, bool) Get(int? useFiltersCounter, bool saveIndividually, bool sortingContainersAny, string forceSingleImageHumanized, int? distancePermyriad, Mapping mapping) { string by; bool isByMapping; @@ -1585,7 +1155,7 @@ internal abstract class MapLogic isBySorting = mapping.By == Shared.Models.Stateless.IMapLogic.Sorting; bool isDefaultName = mapping.MappingFromPerson is not null && IPerson.IsDefaultName(mapping.MappingFromPerson.DisplayDirectoryName); if (isBySorting && mapping.MappingFromPerson is null) - by = saveIndividually ? nameof(Shared.Models.Stateless.IMapLogic.Individually) : $"{nameof(Shared.Models.Stateless.IMapLogic.Sorting)} Without Person"; + by = saveIndividually ? nameof(Shared.Models.Stateless.IMapLogic.Individually) : $"{nameof(Shared.Models.Stateless.IMapLogic.Sorting)} Without Person{(distancePermyriad < 2000 ? "-A" : "-Z")}"; else if (isBySorting && useFiltersCounter.HasValue) by = $"{nameof(Shared.Models.Stateless.IMapLogic.Sorting)}{(!isDefaultName ? "-A" : "-Z")} Modified Filters - {useFiltersCounter.Value}"; else diff --git a/Map/Models/Stateless/RelationLogic.cs b/Map/Models/Stateless/RelationLogic.cs index 428fc69..491eadf 100644 --- a/Map/Models/Stateless/RelationLogic.cs +++ b/Map/Models/Stateless/RelationLogic.cs @@ -20,7 +20,7 @@ internal abstract class RelationLogic ReadOnlyCollection Linked9, ReadOnlyDictionary MovedFiles); - private static ReadOnlyCollection>> GetCollections(List> locationContainers) + private static ReadOnlyCollection>> GetCollections(Configuration configuration, List> locationContainers) { List>> results = new(); List>? collection; @@ -29,6 +29,8 @@ internal abstract class RelationLogic { if (!locationContainer.FromDistanceContent) continue; + if (!locationContainer.File.Contains(configuration.LocationContainerDirectoryPattern)) + continue; if (!keyValuePairs.TryGetValue(locationContainer.PersonKey, out collection)) { keyValuePairs.Add(locationContainer.PersonKey, new()); @@ -42,72 +44,7 @@ internal abstract class RelationLogic return new(results); } - private static string? GetDisplayDirectoryName(ReadOnlyDictionary> readOnlyPersonKeyToPersonContainerCollection, ReadOnlyDictionary readOnlyPersonKeyFormattedToPersonContainer, long personKey, string personKeyFormatted) - { - string? result; - PersonContainer? personContainer; - List? collection; - _ = readOnlyPersonKeyToPersonContainerCollection.TryGetValue(personKey, out collection); - if (collection is not null) - result = collection[0].DisplayDirectoryName; - else - { - if (!readOnlyPersonKeyFormattedToPersonContainer.TryGetValue(personKeyFormatted, out personContainer)) - result = null; - else - result = personContainer.DisplayDirectoryName; - } - return result; - } - - private static void AddDisplayDirectoryNames(Configuration configuration, string eDistanceContentDirectory, ReadOnlyDictionary readOnlyPersonKeyFormattedToPersonContainer, ReadOnlyDictionary> readOnlyPersonKeyToPersonContainerCollection, ReadOnlyCollection>> collections) - { - bool isCounterPersonYear; - string personKeyFormatted; - string? displayDirectoryName; - string? checkDirectory = Path.Combine(eDistanceContentDirectory, configuration.LocationContainerDebugDirectory); - _ = IPath.DeleteEmptyDirectories(checkDirectory); - foreach (ReadOnlyCollection> collection in collections) - { - if (configuration.LocationContainerDistanceTolerance is null) - break; - isCounterPersonYear = IPersonBirthday.IsCounterPersonYear(new DateTime(collection[0].PersonKey).Year); - if (isCounterPersonYear) - continue; - personKeyFormatted = IPersonBirthday.GetFormatted(configuration.PersonBirthdayFormat, collection[0].PersonKey); - checkDirectory = Path.Combine(eDistanceContentDirectory, configuration.LocationContainerDebugDirectory, personKeyFormatted); - if (!Directory.Exists(checkDirectory)) - continue; - displayDirectoryName = GetDisplayDirectoryName(readOnlyPersonKeyToPersonContainerCollection, readOnlyPersonKeyFormattedToPersonContainer, collection[0].PersonKey, personKeyFormatted); - if (string.IsNullOrEmpty(displayDirectoryName)) - continue; - foreach (string yearDirectory in Directory.GetDirectories(checkDirectory, "*", SearchOption.TopDirectoryOnly)) - { - checkDirectory = Path.Combine(yearDirectory, displayDirectoryName); - if (!Directory.Exists(checkDirectory)) - _ = Directory.CreateDirectory(checkDirectory); - } - checkDirectory = Path.Combine(eDistanceContentDirectory, configuration.LocationContainerDebugDirectory, personKeyFormatted, displayDirectoryName); - if (!Directory.Exists(checkDirectory)) - _ = Directory.CreateDirectory(checkDirectory); - } - } - - private static void WriteVsCodeFiles(string eDistanceContentDirectory, string? displayDirectoryName, string directory) - { - string json; - string vsCodeDirectory = Path.Combine(directory, ".vscode"); - if (!Directory.Exists(vsCodeDirectory)) - _ = Directory.CreateDirectory(vsCodeDirectory); - if (displayDirectoryName is not null) - File.WriteAllText(Path.Combine(directory, $"_ {displayDirectoryName}.txt"), string.Empty); - json = "{ \"[markdown]\": { \"editor.wordWrap\": \"off\" }, \"foam.links.hover.enable\": false, \"foam.graph.style\": { \"background\": \"#202020\", \"node\": { \"note\": \"#f2cb1d\", \"distance\": \"green\", \"image\": \"orange\", \"placeholder\": \"white\", } } }"; - _ = IPath.WriteAllText(Path.Combine(vsCodeDirectory, "settings.json"), json, updateDateWhenMatches: false, compareBeforeWrite: true, updateToWhenMatches: null); - json = string.Concat("{ \"version\": \"2.0.0\", \"tasks\": [ { \"label\": \"MKLink\", \"type\": \"shell\", \"command\": \"New-Item\", \"args\": [ \"-ItemType\", \"Junction\", \"-Path\", \"'", directory.Replace('\\', '/'), "/()'\", \"-Target\", \"'", eDistanceContentDirectory.Replace('\\', '/'), "'\" ], \"problemMatcher\": [] } ] }"); - _ = IPath.WriteAllText(Path.Combine(vsCodeDirectory, "tasks.json"), json, updateDateWhenMatches: false, compareBeforeWrite: true, updateToWhenMatches: null); - } - - private static ReadOnlyDictionary MoveFiles(string locationContainerDebugDirectory, bool isCounterPersonYear, string? displayDirectoryName, List linked1, List linked2, List linked3, List linked4, List linked5, List linked6, List linked7, List linked8, List linked9) + private static ReadOnlyDictionary MoveFiles(Configuration configuration, bool isCounterPersonYear, string? displayDirectoryName, List linked1, List linked2, List linked3, List linked4, List linked5, List linked6, List linked7, List linked8, List linked9) { Dictionary results = new(); char c; @@ -150,15 +87,15 @@ internal abstract class RelationLogic c = Convert.ToChar(48 + keyValuePair.Value); if (c is ':' or ';' or '<' or '=' or '>' or '?') c = '_'; - if (maybeTicksDirectoryName == locationContainerDebugDirectory) + if (maybeTicksDirectoryName == configuration.LocationContainerDebugDirectory) checkDirectory = Path.Combine(yearDirectory, $"{keyValuePair.Value}{new string(c, 7)}"); else { - if (!string.IsNullOrEmpty(locationContainerDebugDirectory)) + if (!string.IsNullOrEmpty(configuration.LocationContainerDebugDirectory)) continue; checkDirectory = Path.Combine(personKeyFormattedDirectory, $"{keyValuePair.Value}{new string(c, 7)}"); } - if (maybeTicksDirectoryName != locationContainerDebugDirectory) + if (maybeTicksDirectoryName != configuration.LocationContainerDebugDirectory) { if (isCounterPersonYear || string.IsNullOrEmpty(displayDirectoryName)) checkDirectory = Path.Combine(checkDirectory, personNameDirectoryName); @@ -182,7 +119,7 @@ internal abstract class RelationLogic continue; File.Move(debugFile, checkFile); } - if (maybeTicksDirectoryName == locationContainerDebugDirectory && !string.IsNullOrEmpty(displayDirectoryName)) + if (maybeTicksDirectoryName == configuration.LocationContainerDebugDirectory && !string.IsNullOrEmpty(displayDirectoryName)) { checkDirectory = Path.Combine(checkDirectory, displayDirectoryName); if (!Directory.Exists(checkDirectory)) @@ -192,7 +129,68 @@ internal abstract class RelationLogic return new(results); } - private static RelationCollection GetMappedRelationCollection(string locationContainerDebugDirectory, int take, bool isCounterPersonYear, string? displayDirectoryName, ReadOnlyCollection relationContainers) + private static string? GetDisplayDirectoryName(ReadOnlyDictionary> readOnlyPersonKeyToPersonContainerCollection, ReadOnlyDictionary readOnlyPersonKeyFormattedToPersonContainer, long personKey, string personKeyFormatted) + { + string? result; + PersonContainer? personContainer; + List? collection; + _ = readOnlyPersonKeyToPersonContainerCollection.TryGetValue(personKey, out collection); + if (collection is not null) + result = collection[0].DisplayDirectoryName; + else + { + if (!readOnlyPersonKeyFormattedToPersonContainer.TryGetValue(personKeyFormatted, out personContainer)) + result = null; + else + result = personContainer.DisplayDirectoryName; + } + return result; + } + + private static int GetTake(int locationContainerDistanceTake, int count) + { + int result = locationContainerDistanceTake; + int subtract = (int)(locationContainerDistanceTake * .05); + if (subtract < 1) + subtract = 1; + if (count > 9000) + result -= subtract; + if (count > 8000) + result -= subtract; + if (count > 7000) + result -= subtract; + if (count > 6000) + result -= subtract; + if (count > 5000) + result -= subtract; + if (count > 4000) + result -= subtract; + if (count > 3000) + result -= subtract; + if (count > 2000) + result -= subtract; + if (count > 1000) + result -= subtract; + if (result < 3) + result = 3; + return result; + } + + private static void WriteVsCodeFiles(string eDistanceContentDirectory, string? displayDirectoryName, string directory) + { + string json; + string vsCodeDirectory = Path.Combine(directory, ".vscode"); + if (!Directory.Exists(vsCodeDirectory)) + _ = Directory.CreateDirectory(vsCodeDirectory); + if (displayDirectoryName is not null) + File.WriteAllText(Path.Combine(directory, $"_ {displayDirectoryName}.txt"), string.Empty); + json = "{ \"[markdown]\": { \"editor.wordWrap\": \"off\" }, \"foam.links.hover.enable\": false, \"foam.graph.style\": { \"background\": \"#202020\", \"node\": { \"note\": \"#f2cb1d\", \"distance\": \"green\", \"image\": \"orange\", \"placeholder\": \"white\", } } }"; + _ = IPath.WriteAllText(Path.Combine(vsCodeDirectory, "settings.json"), json, updateDateWhenMatches: false, compareBeforeWrite: true, updateToWhenMatches: null); + json = string.Concat("{ \"version\": \"2.0.0\", \"tasks\": [ { \"label\": \"MKLink\", \"type\": \"shell\", \"command\": \"New-Item\", \"args\": [ \"-ItemType\", \"Junction\", \"-Path\", \"'", directory.Replace('\\', '/'), "/()'\", \"-Target\", \"'", eDistanceContentDirectory.Replace('\\', '/'), "'\" ], \"problemMatcher\": [] } ] }"); + _ = 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 relationContainers) { RelationCollection result; List linked1 = new(); @@ -255,7 +253,7 @@ internal abstract class RelationLogic } } } - ReadOnlyDictionary movedFiles = MoveFiles(locationContainerDebugDirectory, isCounterPersonYear, displayDirectoryName, linked1, linked2, linked3, linked4, linked5, linked6, linked7, linked8, linked9); + ReadOnlyDictionary 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; } @@ -328,33 +326,37 @@ internal abstract class RelationLogic } } - private static int GetTake(int locationContainerDistanceTake, int count) + private static void AddDisplayDirectoryNames(Configuration configuration, string eDistanceContentDirectory, ReadOnlyDictionary readOnlyPersonKeyFormattedToPersonContainer, ReadOnlyDictionary> readOnlyPersonKeyToPersonContainerCollection, ReadOnlyCollection>> collections) { - int result = locationContainerDistanceTake; - int subtract = (int)(locationContainerDistanceTake * .05); - if (subtract < 1) - subtract = 1; - if (count > 9000) - result -= subtract; - if (count > 8000) - result -= subtract; - if (count > 7000) - result -= subtract; - if (count > 6000) - result -= subtract; - if (count > 5000) - result -= subtract; - if (count > 4000) - result -= subtract; - if (count > 3000) - result -= subtract; - if (count > 2000) - result -= subtract; - if (count > 1000) - result -= subtract; - if (result < 3) - result = 3; - return result; + bool isCounterPersonYear; + string personKeyFormatted; + string? displayDirectoryName; + string? checkDirectory = Path.Combine(eDistanceContentDirectory, configuration.LocationContainerDebugDirectory); + _ = IPath.DeleteEmptyDirectories(checkDirectory); + foreach (ReadOnlyCollection> collection in collections) + { + if (configuration.LocationContainerDistanceTolerance is null) + break; + isCounterPersonYear = IPersonBirthday.IsCounterPersonYear(new DateTime(collection[0].PersonKey).Year); + if (isCounterPersonYear) + continue; + personKeyFormatted = IPersonBirthday.GetFormatted(configuration.PersonBirthdayFormat, collection[0].PersonKey); + checkDirectory = Path.Combine(eDistanceContentDirectory, configuration.LocationContainerDebugDirectory, personKeyFormatted); + if (!Directory.Exists(checkDirectory)) + continue; + displayDirectoryName = GetDisplayDirectoryName(readOnlyPersonKeyToPersonContainerCollection, readOnlyPersonKeyFormattedToPersonContainer, collection[0].PersonKey, personKeyFormatted); + if (string.IsNullOrEmpty(displayDirectoryName)) + continue; + foreach (string yearDirectory in Directory.GetDirectories(checkDirectory, "*", SearchOption.TopDirectoryOnly)) + { + checkDirectory = Path.Combine(yearDirectory, displayDirectoryName); + if (!Directory.Exists(checkDirectory)) + _ = Directory.CreateDirectory(checkDirectory); + } + checkDirectory = Path.Combine(eDistanceContentDirectory, configuration.LocationContainerDebugDirectory, personKeyFormatted, displayDirectoryName); + if (!Directory.Exists(checkDirectory)) + _ = Directory.CreateDirectory(checkDirectory); + } } internal static void SaveMappedRelations(Configuration configuration, Shared.Models.Methods.IDistance distance, string a2PeopleContentDirectory, string eDistanceContentDirectory, long ticks, List> locationContainers, ReadOnlyDictionary readOnlyPersonKeyFormattedToPersonContainer, ReadOnlyDictionary> readOnlyPersonKeyToPersonContainerCollection) @@ -370,7 +372,7 @@ internal abstract class RelationLogic 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>> collections = GetCollections(locationContainers); + ReadOnlyCollection>> collections = GetCollections(configuration, locationContainers); using ProgressBar progressBar = new(collections.Count, message, options); foreach (ReadOnlyCollection> collection in collections) { @@ -388,7 +390,7 @@ internal abstract class RelationLogic _ = Directory.CreateDirectory(directory); WriteVsCodeFiles(eDistanceContentDirectory, displayDirectoryName, directory); relationContainers = distance.GetRelationContainers(configuration.FaceDistancePermyriad, configuration.LocationContainerDistanceTake, configuration.LocationContainerDistanceTolerance.Value, collection); - relationCollection = GetMappedRelationCollection(configuration.LocationContainerDebugDirectory, take, isCounterPersonYear, displayDirectoryName, relationContainers); + relationCollection = GetMappedRelationCollection(configuration, take, isCounterPersonYear, displayDirectoryName, relationContainers); WriteFile(take, collection[0].PersonKey, isCounterPersonYear, personKeyFormatted, displayDirectoryName, directory, ticks, uri, relationCollection); } if (string.IsNullOrEmpty(configuration.LocationContainerDebugDirectory)) diff --git a/Shared/.kanbn/index.md b/Shared/.kanbn/index.md index d55e124..e7f4a3e 100644 --- a/Shared/.kanbn/index.md +++ b/Shared/.kanbn/index.md @@ -26,8 +26,6 @@ taskTemplate: '^+^_${overdue ? ''^R'' : ''''}${name}^: ${relations ? (''\n^-^/^g ## Todo -- [verify-camera-model-still-works](tasks/verify-camera-model-still-works.md) -- [run-limiting-on-days](tasks/run-limiting-on-days.md) - [update-drag-and-drop-to-work-with-new-resize-location](tasks/update-drag-and-drop-to-work-with-new-resize-location.md) - [triangle-over-person-in-full-image-for-some](tasks/triangle-over-person-in-full-image-for-some.md) - [use-eyes-to-find-orientation](tasks/use-eyes-to-find-orientation.md) @@ -39,7 +37,10 @@ taskTemplate: '^+^_${overdue ? ''^R'' : ''''}${name}^: ${relations ? (''\n^-^/^g ## In Progress +- [verify-ignore-get-set-to-dup-if-they-are-set](tasks/verify-ignore-get-set-to-dup-if-they-are-set.md) - [name-some-from-638324064000000000-verify-manual-still-works](tasks/name-some-from-638324064000000000-verify-manual-still-works.md) +- [verify-camera-model-still-works](tasks/verify-camera-model-still-works.md) +- [run-limiting-on-days](tasks/run-limiting-on-days.md) - [merge-kristy-files](tasks/merge-kristy-files.md) ## Done diff --git a/Shared/.kanbn/tasks/run-limiting-on-days.md b/Shared/.kanbn/tasks/run-limiting-on-days.md index 011c2bc..cde3bab 100644 --- a/Shared/.kanbn/tasks/run-limiting-on-days.md +++ b/Shared/.kanbn/tasks/run-limiting-on-days.md @@ -1,6 +1,6 @@ --- created: 2023-09-09T15:01:12.800Z -updated: 2023-09-09T21:51:53.090Z +updated: 2023-09-10T01:10:32.967Z assigned: "" progress: 0 tags: [] diff --git a/Shared/.kanbn/tasks/verify-camera-model-still-works.md b/Shared/.kanbn/tasks/verify-camera-model-still-works.md index 4dd9546..17b5a03 100644 --- a/Shared/.kanbn/tasks/verify-camera-model-still-works.md +++ b/Shared/.kanbn/tasks/verify-camera-model-still-works.md @@ -1,6 +1,6 @@ --- created: 2023-09-09T15:01:28.239Z -updated: 2023-09-09T21:51:54.599Z +updated: 2023-09-10T01:10:31.283Z assigned: "" progress: 0 tags: [] diff --git a/Shared/.kanbn/tasks/verify-ignore-get-set-to-dup-if-they-are-set.md b/Shared/.kanbn/tasks/verify-ignore-get-set-to-dup-if-they-are-set.md new file mode 100644 index 0000000..cf3acfc --- /dev/null +++ b/Shared/.kanbn/tasks/verify-ignore-get-set-to-dup-if-they-are-set.md @@ -0,0 +1,10 @@ +--- +created: 2023-09-10T02:21:51.169Z +updated: 2023-09-10T02:21:59.136Z +assigned: "" +progress: 0 +tags: [] +started: 2023-09-10T02:21:51.169Z +--- + +# Verify ignore get set to dup if they are set diff --git a/Shared/.vscode/tasks.json b/Shared/.vscode/tasks.json index c4433af..45e4a9a 100644 --- a/Shared/.vscode/tasks.json +++ b/Shared/.vscode/tasks.json @@ -28,14 +28,20 @@ { "label": "File-Folder-Helper AOT s G File System to Genealogical Data Communication", "type": "shell", - "command": "& L:/DevOps/Mesa_FI/File-Folder-Helper/bin/Release/net7.0/win-x64/publish/File-Folder-Helper.exe s G 'D:/1-Images-A/Images-dd514b88-Results/A2)People/dd514b88/([])/File-Folder-Helper/638280519245151237' -d 'D:/1-Images-A/Images-dd514b88-Results/A2)People/dd514b88/{2}'", + "command": "& L:/DevOps/Mesa_FI/File-Folder-Helper/bin/Release/net7.0/win-x64/publish/File-Folder-Helper.exe s G 'D:/1-Images-A/Images-dd514b88-Results/A2)People/dd514b88/([])/File-Folder-Helper/638298094252901621' -d 'D:/1-Images-A/Images-dd514b88-Results/A2)People/dd514b88/{2}'", "problemMatcher": [] }, { - "label": "File-Folder-Helper AOT s VSCode Possible", + "label": "File-Folder-Helper AOT s VSCode Possible - Instance", "type": "shell", "command": "& L:/DevOps/Mesa_FI/File-Folder-Helper/bin/Release/net7.0/win-x64/publish/File-Folder-Helper.exe s V 'L:/Git/View-by-Distance-MKLink-Console/Instance'", "problemMatcher": [] + }, + { + "label": "File-Folder-Helper AOT s VSCode Possible - Map", + "type": "shell", + "command": "& L:/DevOps/Mesa_FI/File-Folder-Helper/bin/Release/net7.0/win-x64/publish/File-Folder-Helper.exe s V L:/Git/View-by-Distance-MKLink-Console/Map/Models/Stateless", + "problemMatcher": [] } ] } \ No newline at end of file