LookForAbandoned

This commit is contained in:
Mike Phares 2023-04-25 20:29:26 -07:00
parent 931f33606d
commit 272ed90c56
14 changed files with 321 additions and 138 deletions

View File

@ -1,6 +1,7 @@
using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Configuration;
using Phares.Shared; using Phares.Shared;
using ShellProgressBar; using ShellProgressBar;
using System.Collections.ObjectModel;
using System.Drawing.Imaging; using System.Drawing.Imaging;
using View_by_Distance.Distance.Models; using View_by_Distance.Distance.Models;
using View_by_Distance.Face.Models; using View_by_Distance.Face.Models;
@ -30,8 +31,8 @@ public partial class DlibDotNet
private readonly List<string> _Exceptions; private readonly List<string> _Exceptions;
private readonly IsEnvironment _IsEnvironment; private readonly IsEnvironment _IsEnvironment;
private readonly bool _PropertyRootExistedBefore; private readonly bool _PropertyRootExistedBefore;
private readonly PersonContainer[] _PersonContainers;
private readonly Models.Configuration _Configuration; private readonly Models.Configuration _Configuration;
private readonly List<PersonContainer> _PersonContainers;
private readonly bool _ArgZeroIsConfigurationRootDirectory; private readonly bool _ArgZeroIsConfigurationRootDirectory;
private readonly Map.Models.Configuration _MapConfiguration; private readonly Map.Models.Configuration _MapConfiguration;
private readonly string[]? _GenealogicalDataCommunicationFooterLines; private readonly string[]? _GenealogicalDataCommunicationFooterLines;
@ -104,7 +105,7 @@ public partial class DlibDotNet
{ {
_GenealogicalDataCommunicationFooterLines = null; _GenealogicalDataCommunicationFooterLines = null;
_GenealogicalDataCommunicationHeaderLines = null; _GenealogicalDataCommunicationHeaderLines = null;
_PersonContainers = Array.Empty<PersonContainer>(); _PersonContainers = new();
} }
else else
{ {
@ -270,7 +271,7 @@ public partial class DlibDotNet
return result; return result;
} }
private void SetMapping(Dictionary<int, List<LocationContainer<MetadataExtractor.Directory>>> idToLocationContainers, MapLogic mapLogic, Item item, bool? isFocusRelativePath, bool? isIgnoreRelativePath, MappingFromItem mappingFromItem, List<MappingFromPhotoPrism>? mappingFromPhotoPrismCollection, List<Shared.Models.Face> faces) private void SetMapping(ReadOnlyDictionary<int, List<LocationContainer<MetadataExtractor.Directory>>> idToLocationContainers, MapLogic mapLogic, Item item, bool? isFocusRelativePath, bool? isIgnoreRelativePath, MappingFromItem mappingFromItem, List<MappingFromPhotoPrism>? mappingFromPhotoPrismCollection, List<Shared.Models.Face> faces)
{ {
string? model; string? model;
Mapping mapping; Mapping mapping;
@ -328,7 +329,7 @@ public partial class DlibDotNet
private void FullParallelForWork(A_Property propertyLogic, private void FullParallelForWork(A_Property propertyLogic,
B_Metadata metadata, B_Metadata metadata,
Dictionary<int, List<LocationContainer<MetadataExtractor.Directory>>> idToLocationContainers, ReadOnlyDictionary<int, List<LocationContainer<MetadataExtractor.Directory>>> idToLocationContainers,
MapLogic mapLogic, MapLogic mapLogic,
string outputResolution, string outputResolution,
string cResultsFullGroupDirectory, string cResultsFullGroupDirectory,
@ -457,7 +458,7 @@ public partial class DlibDotNet
private int FullParallelWork(int maxDegreeOfParallelism, private int FullParallelWork(int maxDegreeOfParallelism,
A_Property propertyLogic, A_Property propertyLogic,
B_Metadata metadata, B_Metadata metadata,
Dictionary<int, List<LocationContainer<MetadataExtractor.Directory>>> idToLocationContainers, ReadOnlyDictionary<int, List<LocationContainer<MetadataExtractor.Directory>>> idToLocationContainers,
MapLogic mapLogic, MapLogic mapLogic,
string outputResolution, string outputResolution,
string cResultsFullGroupDirectory, string cResultsFullGroupDirectory,
@ -598,7 +599,7 @@ public partial class DlibDotNet
return new(cResultsFullGroupDirectory, dResultsFullGroupDirectory, d2ResultsFullGroupDirectory); return new(cResultsFullGroupDirectory, dResultsFullGroupDirectory, d2ResultsFullGroupDirectory);
} }
private void FullDoWork(string argZero, string propertyRoot, long ticks, string aResultsFullGroupDirectory, string bResultsFullGroupDirectory, int t, Container[] containers, A_Property propertyLogic, B_Metadata metadata, string eDistanceContentDirectory, Dictionary<string, List<MappingFromPhotoPrism>> fileNameToCollection, Dictionary<int, List<LocationContainer<MetadataExtractor.Directory>>> idToLocationContainers, MapLogic mapLogic) private void FullDoWork(string argZero, string propertyRoot, long ticks, string aResultsFullGroupDirectory, string bResultsFullGroupDirectory, int t, Container[] containers, A_Property propertyLogic, B_Metadata metadata, string eDistanceContentDirectory, Dictionary<string, List<MappingFromPhotoPrism>> fileNameToCollection, ReadOnlyDictionary<int, List<LocationContainer<MetadataExtractor.Directory>>> idToLocationContainers, MapLogic mapLogic)
{ {
if (_Log is null) if (_Log is null)
throw new NullReferenceException(nameof(_Log)); throw new NullReferenceException(nameof(_Log));
@ -676,11 +677,11 @@ public partial class DlibDotNet
} }
} }
private (List<int>, List<Shared.Models.Face>) GetFilteredDistinct(string argZero, Container[] containers) private List<Shared.Models.Face> GetFilteredDistinct(string argZero, Container[] containers)
{ {
List<int> resultIds = new(); List<Shared.Models.Face> results = new();
List<Shared.Models.Face> resultFaces = new();
Item[] filteredItems; Item[] filteredItems;
List<int> distinct = new();
foreach (Container container in containers) foreach (Container container in containers)
{ {
if (!container.Items.Any()) if (!container.Items.Any())
@ -694,18 +695,18 @@ public partial class DlibDotNet
{ {
if (item.Property?.Id is null || item.ResizedFileHolder is null) if (item.Property?.Id is null || item.ResizedFileHolder is null)
continue; continue;
if (resultIds.Contains(item.Property.Id.Value)) if (distinct.Contains(item.Property.Id.Value))
continue; continue;
resultIds.Add(item.Property.Id.Value); distinct.Add(item.Property.Id.Value);
foreach (Shared.Models.Face face in item.Faces) foreach (Shared.Models.Face face in item.Faces)
{ {
if (face.FaceEncoding is null || face.Location is null || face.OutputResolution is null) if (face.FaceEncoding is null || face.Location is null || face.OutputResolution is null)
continue; continue;
resultFaces.Add(face); results.Add(face);
} }
} }
} }
return new(resultIds, resultFaces); return results;
} }
private List<Item> GetItems(string argZero, Container[] containers) private List<Item> GetItems(string argZero, Container[] containers)
@ -859,7 +860,7 @@ public partial class DlibDotNet
return result; return result;
} }
private static void LookForAbandoned(Dictionary<int, List<LocationContainer<MetadataExtractor.Directory>>> idToLocationContainers, List<int> distinctFilteredIds) private static void LookForAbandoned(ReadOnlyDictionary<int, List<LocationContainer<MetadataExtractor.Directory>>> idToLocationContainers, List<int> distinctFilteredIds)
{ {
List<string> renameCollection = new(); List<string> renameCollection = new();
foreach (KeyValuePair<int, List<LocationContainer<MetadataExtractor.Directory>>> idToCollection in idToLocationContainers) foreach (KeyValuePair<int, List<LocationContainer<MetadataExtractor.Directory>>> idToCollection in idToLocationContainers)
@ -874,18 +875,71 @@ public partial class DlibDotNet
} }
} }
if (renameCollection.Any()) if (renameCollection.Any())
{ Shared.Models.Stateless.Methods.IDirectory.MoveFiles(renameCollection, "()", "(abd)");
string checkFile; }
foreach (string file in renameCollection)
{ private static void LookForAbandoned(List<int> distinctFilteredIds, string directory, string directoryName)
if (!File.Exists(file)) {
continue; string fileNameWithoutExtension;
checkFile = $"{file}.abd"; List<string> renameCollection = new();
if (File.Exists(checkFile)) string[] distinctFilteredIdsValues = distinctFilteredIds.Select(l => l.ToString()).ToArray();
continue; string[] files = Directory.GetFiles(directory, "*", SearchOption.AllDirectories);
File.Move(file, checkFile); foreach (string file in files)
{
fileNameWithoutExtension = Path.GetFileNameWithoutExtension(Path.GetFileNameWithoutExtension(Path.GetFileNameWithoutExtension(file)));
if (distinctFilteredIdsValues.Contains(fileNameWithoutExtension))
continue;
if (!Shared.Models.Stateless.Methods.IProperty.NameWithoutExtensionIsIdFormat(fileNameWithoutExtension))
continue;
renameCollection.Add(file);
}
if (renameCollection.Any())
{
if (directoryName.Length == 2)
Shared.Models.Stateless.Methods.IDirectory.MoveFiles(renameCollection, directoryName, $"{directoryName[0]}abd{directoryName[^1]}");
else if (directoryName.Length == 4)
Shared.Models.Stateless.Methods.IDirectory.MoveFiles(renameCollection, directoryName, $"{directoryName[..2]}abd{directoryName[^2]}");
else
throw new NotSupportedException();
}
}
private void LookForAbandoned(Container[] containers, ReadOnlyDictionary<int, List<LocationContainer<MetadataExtractor.Directory>>> idToLocationContainers)
{
string[] directories;
string? directoryName;
string cResultsFullGroupDirectory;
string dResultsFullGroupDirectory;
string d2ResultsFullGroupDirectory;
List<int> distinctFilteredIds = Shared.Models.Stateless.Methods.IContainer.GetFilteredDistinct(_Configuration.PropertyConfiguration, containers);
LookForAbandoned(idToLocationContainers, distinctFilteredIds);
foreach (string outputResolution in _Configuration.OutputResolutions)
{
(cResultsFullGroupDirectory, dResultsFullGroupDirectory, d2ResultsFullGroupDirectory) = GetResultsFullGroupDirectories(outputResolution);
directories = Directory.GetDirectories(cResultsFullGroupDirectory, "*", SearchOption.TopDirectoryOnly);
foreach (string directory in directories)
{
directoryName = Path.GetFileName(directory);
if (string.IsNullOrEmpty(directoryName) || (directoryName.Length != 2 && directoryName.Length != 4))
continue;
LookForAbandoned(distinctFilteredIds, directory, directoryName);
}
directories = Directory.GetDirectories(dResultsFullGroupDirectory, "*", SearchOption.TopDirectoryOnly);
foreach (string directory in directories)
{
directoryName = Path.GetFileName(directory);
if (string.IsNullOrEmpty(directoryName) || (directoryName.Length != 2 && directoryName.Length != 4))
continue;
LookForAbandoned(distinctFilteredIds, directory, directoryName);
}
directories = Directory.GetDirectories(d2ResultsFullGroupDirectory, "*", SearchOption.TopDirectoryOnly);
foreach (string directory in directories)
{
directoryName = Path.GetFileName(directory);
if (string.IsNullOrEmpty(directoryName) || (directoryName.Length != 2 && directoryName.Length != 4))
continue;
LookForAbandoned(distinctFilteredIds, directory, directoryName);
} }
throw new Exception($"Renamed {renameCollection.Count}(s) files!");
} }
} }
@ -906,14 +960,14 @@ public partial class DlibDotNet
Dictionary<long, List<int>> personKeyToIds; Dictionary<long, List<int>> personKeyToIds;
Dictionary<string, List<MappingFromPhotoPrism>> fileNameToCollection; Dictionary<string, List<MappingFromPhotoPrism>> fileNameToCollection;
(aResultsFullGroupDirectory, bResultsFullGroupDirectory) = GetResultsFullGroupDirectories(); (aResultsFullGroupDirectory, bResultsFullGroupDirectory) = GetResultsFullGroupDirectories();
Dictionary<int, List<LocationContainer<MetadataExtractor.Directory>>> idToLocationContainers = new();
string a2PeopleSingletonDirectory = Property.Models.Stateless.IResult.GetResultsDateGroupDirectory(_Configuration.PropertyConfiguration, nameof(A2_People), "{}"); string a2PeopleSingletonDirectory = Property.Models.Stateless.IResult.GetResultsDateGroupDirectory(_Configuration.PropertyConfiguration, nameof(A2_People), "{}");
a2PeopleContentDirectory = Property.Models.Stateless.IResult.GetResultsDateGroupDirectory(_Configuration.PropertyConfiguration, nameof(A2_People), "([])"); a2PeopleContentDirectory = Property.Models.Stateless.IResult.GetResultsDateGroupDirectory(_Configuration.PropertyConfiguration, nameof(A2_People), "([])");
eDistanceContentDirectory = Property.Models.Stateless.IResult.GetResultsDateGroupDirectory(_Configuration.PropertyConfiguration, nameof(E_Distance), "()"); eDistanceContentDirectory = Property.Models.Stateless.IResult.GetResultsDateGroupDirectory(_Configuration.PropertyConfiguration, nameof(E_Distance), "()");
fPhotoPrismContentDirectory = Property.Models.Stateless.IResult.GetResultsDateGroupDirectory(_Configuration.PropertyConfiguration, nameof(F_PhotoPrism), "()"); fPhotoPrismContentDirectory = Property.Models.Stateless.IResult.GetResultsDateGroupDirectory(_Configuration.PropertyConfiguration, nameof(F_PhotoPrism), "()");
fPhotoPrismSingletonDirectory = Property.Models.Stateless.IResult.GetResultsDateGroupDirectory(_Configuration.PropertyConfiguration, nameof(F_PhotoPrism), "{}"); fPhotoPrismSingletonDirectory = Property.Models.Stateless.IResult.GetResultsDateGroupDirectory(_Configuration.PropertyConfiguration, nameof(F_PhotoPrism), "{}");
propertyLogic = new(_AppSettings.MaxDegreeOfParallelism, _Configuration.PropertyConfiguration, _Resize.FileNameExtension, _Configuration.Reverse, aResultsFullGroupDirectory); propertyLogic = new(_AppSettings.MaxDegreeOfParallelism, _Configuration.PropertyConfiguration, _Resize.FileNameExtension, _Configuration.Reverse, aResultsFullGroupDirectory);
MapLogic mapLogic = new(_AppSettings.MaxDegreeOfParallelism, _Configuration.PropertyConfiguration, _MapConfiguration, _PersonContainers, ticks, a2PeopleSingletonDirectory, eDistanceContentDirectory, idToLocationContainers); MapLogic mapLogic = new(_AppSettings.MaxDegreeOfParallelism, _Configuration.PropertyConfiguration, _MapConfiguration, new(_PersonContainers), ticks, a2PeopleSingletonDirectory, eDistanceContentDirectory);
_PersonContainers.AddRange(Shared.Models.Stateless.Methods.IPersonContainer.GetNonSpecificPeopleCollection(_Configuration.MappingDefaultName, _Configuration.PersonBirthdayFirstYear, _Configuration.PersonCharacters.ToArray(), _PersonContainers, ticks));
int totalSeconds = (int)Math.Floor(new TimeSpan(DateTime.Now.Ticks - ticks).TotalSeconds); int totalSeconds = (int)Math.Floor(new TimeSpan(DateTime.Now.Ticks - ticks).TotalSeconds);
string message = $") Building Container(s) - {totalSeconds} total second(s)"; string message = $") Building Container(s) - {totalSeconds} total second(s)";
ProgressBarOptions options = new() { ProgressCharacter = '─', ProgressBarOnBottom = true, DisableBottomPercentage = true }; ProgressBarOptions options = new() { ProgressCharacter = '─', ProgressBarOnBottom = true, DisableBottomPercentage = true };
@ -949,20 +1003,20 @@ public partial class DlibDotNet
personKeyToIds = mapLogic.GetPersonKeyToIds(); personKeyToIds = mapLogic.GetPersonKeyToIds();
if (!string.IsNullOrEmpty(_Configuration.GenealogicalDataCommunicationFile) && !string.IsNullOrEmpty(a2PeopleContentDirectory) && _GenealogicalDataCommunicationHeaderLines is not null && _GenealogicalDataCommunicationFooterLines is not null && _GenealogicalDataCommunicationHeaderLines.Any() && _GenealogicalDataCommunicationFooterLines.Any()) if (!string.IsNullOrEmpty(_Configuration.GenealogicalDataCommunicationFile) && !string.IsNullOrEmpty(a2PeopleContentDirectory) && _GenealogicalDataCommunicationHeaderLines is not null && _GenealogicalDataCommunicationFooterLines is not null && _GenealogicalDataCommunicationHeaderLines.Any() && _GenealogicalDataCommunicationFooterLines.Any())
Shared.Models.Stateless.Methods.IGenealogicalDataCommunication.CreateTree(_Configuration.MappingDefaultName, _Configuration.PersonBirthdayFormat, _Configuration.PropertyConfiguration.ResultAllInOne, _PersonContainers, _GenealogicalDataCommunicationHeaderLines, _GenealogicalDataCommunicationFooterLines, ticks, a2PeopleContentDirectory, personKeyToIds); Shared.Models.Stateless.Methods.IGenealogicalDataCommunication.CreateTree(_Configuration.MappingDefaultName, _Configuration.PersonBirthdayFormat, _Configuration.PropertyConfiguration.ResultAllInOne, _PersonContainers, _GenealogicalDataCommunicationHeaderLines, _GenealogicalDataCommunicationFooterLines, ticks, a2PeopleContentDirectory, personKeyToIds);
ReadOnlyDictionary<int, List<LocationContainer<MetadataExtractor.Directory>>> idToLocationContainers = mapLogic.GetIdToLocationContainers();
fileNameToCollection = !Directory.Exists(fPhotoPrismSingletonDirectory) ? fileNameToCollection = new() : F_PhotoPrism.GetFileNameToCollection(fPhotoPrismSingletonDirectory); fileNameToCollection = !Directory.Exists(fPhotoPrismSingletonDirectory) ? fileNameToCollection = new() : F_PhotoPrism.GetFileNameToCollection(fPhotoPrismSingletonDirectory);
FullDoWork(argZero, propertyRoot, ticks, aResultsFullGroupDirectory, bResultsFullGroupDirectory, t, containers, propertyLogic, metadata, eDistanceContentDirectory, fileNameToCollection, idToLocationContainers, mapLogic); FullDoWork(argZero, propertyRoot, ticks, aResultsFullGroupDirectory, bResultsFullGroupDirectory, t, containers, propertyLogic, metadata, eDistanceContentDirectory, fileNameToCollection, idToLocationContainers, mapLogic);
LookForAbandoned(containers, idToLocationContainers);
_Distance.Clear(); _Distance.Clear();
if (!personKeyToIds.Any()) if (!personKeyToIds.Any())
personKeyToIds = mapLogic.GetPersonKeyToIds(); personKeyToIds = mapLogic.GetPersonKeyToIds();
(List<int> distinctFilteredIds, List<Shared.Models.Face> distinctFilteredFaces) = GetFilteredDistinct(argZero, containers); List<Shared.Models.Face> distinctFilteredFaces = GetFilteredDistinct(argZero, containers);
LookForAbandoned(idToLocationContainers, distinctFilteredIds);
Mapping[] mappingCollection = Map.Models.Stateless.Methods.IMapLogic.GetSelectedMappingCollection(distinctFilteredFaces); Mapping[] mappingCollection = Map.Models.Stateless.Methods.IMapLogic.GetSelectedMappingCollection(distinctFilteredFaces);
int totalNotMapped = mapLogic.UpdateMappingFromPerson(mappingCollection); int totalNotMapped = mapLogic.UpdateMappingFromPerson(mappingCollection);
string json = System.Text.Json.JsonSerializer.Serialize(mappingCollection); string json = System.Text.Json.JsonSerializer.Serialize(mappingCollection);
File.WriteAllText(Path.Combine(eDistanceContentDirectory, $"{ticks}.json"), json); File.WriteAllText(Path.Combine(eDistanceContentDirectory, $"{ticks}.json"), json);
for (int i = 1; i < 5; i++) for (int i = 1; i < 5; i++)
_ = Shared.Models.Stateless.Methods.IPath.DeleteEmptyDirectories(eDistanceContentDirectory); _ = Shared.Models.Stateless.Methods.IPath.DeleteEmptyDirectories(eDistanceContentDirectory);
_ = Shared.Models.Stateless.Methods.IPath.DeleteEmptyDirectories(eDistanceContentDirectory);
foreach (string outputResolution in _Configuration.OutputResolutions) foreach (string outputResolution in _Configuration.OutputResolutions)
{ {
if (_PropertyRootExistedBefore) if (_PropertyRootExistedBefore)

View File

@ -16,6 +16,7 @@ public class MapLogic : Shared.Models.Methods.IMapLogic
protected readonly ReadOnlyDictionary<int, List<int>> _SkipCollection; protected readonly ReadOnlyDictionary<int, List<int>> _SkipCollection;
protected readonly ReadOnlyDictionary<int, List<int>> _SkipNotSkipCollection; protected readonly ReadOnlyDictionary<int, List<int>> _SkipNotSkipCollection;
protected readonly ReadOnlyDictionary<long, PersonContainer> _PersonKeyToPersonContainer; protected readonly ReadOnlyDictionary<long, PersonContainer> _PersonKeyToPersonContainer;
protected readonly List<LocationContainer<MetadataExtractor.Directory>> _LocationContainers;
protected readonly ReadOnlyDictionary<int, Dictionary<int, PersonContainer[]>> _IdThenNormalizedRectangleToPersonContainers; protected readonly ReadOnlyDictionary<int, Dictionary<int, PersonContainer[]>> _IdThenNormalizedRectangleToPersonContainers;
public Dictionary<int, int[]> KeyValuePairs => throw new NotImplementedException(); public Dictionary<int, int[]> KeyValuePairs => throw new NotImplementedException();
@ -27,7 +28,7 @@ public class MapLogic : Shared.Models.Methods.IMapLogic
private readonly string _EDistanceContentTicksDirectory; private readonly string _EDistanceContentTicksDirectory;
private readonly Shared.Models.Properties.IPropertyConfiguration _PropertyConfiguration; private readonly Shared.Models.Properties.IPropertyConfiguration _PropertyConfiguration;
public MapLogic(int maxDegreeOfParallelism, Shared.Models.Properties.IPropertyConfiguration propertyConfiguration, Configuration? configuration, PersonContainer[] personContainers, long ticks, string a2PeopleSingletonDirectory, string eDistanceContentDirectory, Dictionary<int, List<LocationContainer<MetadataExtractor.Directory>>> idToLocationContainers) public MapLogic(int maxDegreeOfParallelism, Shared.Models.Properties.IPropertyConfiguration propertyConfiguration, Configuration? configuration, ReadOnlyCollection<PersonContainer> personContainers, long ticks, string a2PeopleSingletonDirectory, string eDistanceContentDirectory)
{ {
_Ticks = ticks; _Ticks = ticks;
_Configuration = configuration; _Configuration = configuration;
@ -35,8 +36,6 @@ public class MapLogic : Shared.Models.Methods.IMapLogic
_PropertyConfiguration = propertyConfiguration; _PropertyConfiguration = propertyConfiguration;
if (_Log is null) if (_Log is null)
{ } { }
if (idToLocationContainers is null)
throw new NullReferenceException(nameof(idToLocationContainers));
if (propertyConfiguration.VerifyToSeason is null || !propertyConfiguration.VerifyToSeason.Any()) if (propertyConfiguration.VerifyToSeason is null || !propertyConfiguration.VerifyToSeason.Any())
throw new NullReferenceException(nameof(propertyConfiguration.VerifyToSeason)); throw new NullReferenceException(nameof(propertyConfiguration.VerifyToSeason));
string json; string json;
@ -46,30 +45,29 @@ public class MapLogic : Shared.Models.Methods.IMapLogic
List<PersonContainer> notMappedPersonContainers = new(); List<PersonContainer> notMappedPersonContainers = new();
Dictionary<int, List<int>> skipNotSkipCollection = new(); Dictionary<int, List<int>> skipNotSkipCollection = new();
Dictionary<long, PersonContainer> personKeyToPersonContainer = new(); Dictionary<long, PersonContainer> personKeyToPersonContainer = new();
List<LocationContainer<MetadataExtractor.Directory>> locationContainers = new();
string? rootDirectoryParent = Path.GetDirectoryName(propertyConfiguration.RootDirectory); string? rootDirectoryParent = Path.GetDirectoryName(propertyConfiguration.RootDirectory);
string eDistanceContentTicksDirectory = Path.Combine(eDistanceContentDirectory, $"({ticks})"); string eDistanceContentTicksDirectory = Path.Combine(eDistanceContentDirectory, $"({ticks})");
Dictionary<int, Dictionary<int, PersonContainer[]>> idThenNormalizedRectangleToPersonContainers = new(); Dictionary<int, Dictionary<int, PersonContainer[]>> idThenNormalizedRectangleToPersonContainers = new();
Dictionary<int, List<LocationContainer<MetadataExtractor.Directory>>> idToLocationContainers = new();
if (string.IsNullOrEmpty(rootDirectoryParent)) if (string.IsNullOrEmpty(rootDirectoryParent))
throw new NullReferenceException(nameof(rootDirectoryParent)); throw new NullReferenceException(nameof(rootDirectoryParent));
if (!Directory.Exists(eDistanceContentDirectory)) if (!Directory.Exists(eDistanceContentDirectory))
_ = Directory.CreateDirectory(eDistanceContentDirectory); _ = Directory.CreateDirectory(eDistanceContentDirectory);
if (configuration is not null) if (configuration is not null)
{ {
List<PersonContainer> personContainerCollection = new(personContainers);
Stateless.MapLogic.Set(maxDegreeOfParallelism, Stateless.MapLogic.Set(maxDegreeOfParallelism,
configuration, configuration,
ticks, ticks,
personContainerCollection, personContainers,
a2PeopleSingletonDirectory, a2PeopleSingletonDirectory,
eDistanceContentDirectory, eDistanceContentDirectory,
personKeyToPersonContainer, personKeyToPersonContainer,
notMappedPersonContainers, notMappedPersonContainers,
skipCollection, skipCollection,
skipNotSkipCollection, skipNotSkipCollection,
idToLocationContainers, locationContainers,
idThenNormalizedRectangleToPersonContainers); idThenNormalizedRectangleToPersonContainers);
if (personContainerCollection.Count == personContainers.Length)
throw new NotSupportedException();
} }
foreach (string propertyContentCollectionFile in propertyConfiguration.PropertyContentCollectionFiles) foreach (string propertyContentCollectionFile in propertyConfiguration.PropertyContentCollectionFiles)
{ {
@ -84,6 +82,7 @@ public class MapLogic : Shared.Models.Methods.IMapLogic
throw new NullReferenceException(nameof(collection)); throw new NullReferenceException(nameof(collection));
} }
_SkipCollection = new(skipCollection); _SkipCollection = new(skipCollection);
_LocationContainers = locationContainers;
_SkipNotSkipCollection = new(skipNotSkipCollection); _SkipNotSkipCollection = new(skipNotSkipCollection);
_PersonKeyToPersonContainer = new(personKeyToPersonContainer); _PersonKeyToPersonContainer = new(personKeyToPersonContainer);
_EDistanceContentTicksDirectory = eDistanceContentTicksDirectory; _EDistanceContentTicksDirectory = eDistanceContentTicksDirectory;
@ -97,6 +96,19 @@ public class MapLogic : Shared.Models.Methods.IMapLogic
return result; return result;
} }
public ReadOnlyDictionary<int, List<LocationContainer<MetadataExtractor.Directory>>> GetIdToLocationContainers()
{
Dictionary<int, List<LocationContainer<MetadataExtractor.Directory>>> results = new();
foreach (LocationContainer<MetadataExtractor.Directory> locationContainer in _LocationContainers)
{
if (!results.ContainsKey(locationContainer.Id))
results.Add(locationContainer.Id, new());
results[locationContainer.Id].Add(locationContainer);
}
_LocationContainers.Clear();
return new(results);
}
public Dictionary<long, List<int>> GetPersonKeyToIds() public Dictionary<long, List<int>> GetPersonKeyToIds()
{ {
Dictionary<long, List<int>> results = new(); Dictionary<long, List<int>> results = new();
@ -972,7 +984,7 @@ public class MapLogic : Shared.Models.Methods.IMapLogic
return new(personKeyFormatted, personBirthday); return new(personKeyFormatted, personBirthday);
} }
private List<string> GetPersonKeyFormattedCollection(string[] jLinks, string a2PeopleContentDirectory, PersonContainer[] personContainers, Dictionary<long, List<int>> personKeyToIds) private List<string> GetPersonKeyFormattedCollection(string[] jLinks, string a2PeopleContentDirectory, List<PersonContainer> personContainers, Dictionary<long, List<int>> personKeyToIds)
{ {
if (_Configuration is null) if (_Configuration is null)
throw new NullReferenceException(nameof(_Configuration)); throw new NullReferenceException(nameof(_Configuration));
@ -1030,7 +1042,7 @@ public class MapLogic : Shared.Models.Methods.IMapLogic
return results; return results;
} }
private (int, FileHolder, int, string, string, string, string)[] GetCollectionForSaveFilteredOriginalImagesFromJLinks(string[] jLinks, string a2PeopleContentDirectory, PersonContainer[] personContainers, Mapping[] mappingCollection, Dictionary<long, List<int>> personKeyToIds) private (int, FileHolder, int, string, string, string, string)[] GetCollectionForSaveFilteredOriginalImagesFromJLinks(string[] jLinks, string a2PeopleContentDirectory, List<PersonContainer> personContainers, Mapping[] mappingCollection, Dictionary<long, List<int>> personKeyToIds)
{ {
if (_Configuration is null) if (_Configuration is null)
throw new NullReferenceException(nameof(_Configuration)); throw new NullReferenceException(nameof(_Configuration));
@ -1091,7 +1103,7 @@ public class MapLogic : Shared.Models.Methods.IMapLogic
return results; return results;
} }
public void SaveFilteredOriginalImagesFromJLinks(string[] jLinks, PersonContainer[] personContainers, string a2PeopleContentDirectory, Dictionary<long, List<int>> personKeyToIds, Mapping[] mappingCollection, int totalNotMapped) public void SaveFilteredOriginalImagesFromJLinks(string[] jLinks, List<PersonContainer> personContainers, string a2PeopleContentDirectory, Dictionary<long, List<int>> personKeyToIds, Mapping[] mappingCollection, int totalNotMapped)
{ {
if (_Configuration is null) if (_Configuration is null)
throw new NullReferenceException(nameof(_Configuration)); throw new NullReferenceException(nameof(_Configuration));
@ -1110,7 +1122,7 @@ public class MapLogic : Shared.Models.Methods.IMapLogic
SaveContainers(saveIndividually, totalNotMapped, null, saveContainers); SaveContainers(saveIndividually, totalNotMapped, null, saveContainers);
} }
private List<SaveShortcutsForOutputResolutions> GetCollectionForSaveShortcutsForOutputResolutionsPreMapLogic(string eDistanceContentDirectory, Dictionary<long, List<int>> personKeyToIds, Dictionary<int, List<LocationContainer<MetadataExtractor.Directory>>> idToLocationContainers, Mapping[] mappingCollection) private List<SaveShortcutsForOutputResolutions> GetCollectionForSaveShortcutsForOutputResolutionsPreMapLogic(string eDistanceContentDirectory, Dictionary<long, List<int>> personKeyToIds, ReadOnlyDictionary<int, List<LocationContainer<MetadataExtractor.Directory>>> idToLocationContainers, Mapping[] mappingCollection)
{ {
List<SaveShortcutsForOutputResolutions> results = new(); List<SaveShortcutsForOutputResolutions> results = new();
if (_Configuration is null) if (_Configuration is null)
@ -1166,7 +1178,7 @@ public class MapLogic : Shared.Models.Methods.IMapLogic
return results; return results;
} }
public void SaveShortcutsForOutputResolutionsPreMapLogic(string eDistanceContentDirectory, Dictionary<long, List<int>> personKeyToIds, Dictionary<int, List<LocationContainer<MetadataExtractor.Directory>>> idToLocationContainers, Mapping[] mappingCollection) public void SaveShortcutsForOutputResolutionsPreMapLogic(string eDistanceContentDirectory, Dictionary<long, List<int>> personKeyToIds, ReadOnlyDictionary<int, List<LocationContainer<MetadataExtractor.Directory>>> idToLocationContainers, Mapping[] mappingCollection)
{ {
string hiddenFile; string hiddenFile;
WindowsShortcut windowsShortcut; WindowsShortcut windowsShortcut;

View File

@ -1,5 +1,6 @@
using Humanizer; using Humanizer;
using ShellProgressBar; using ShellProgressBar;
using System.Collections.ObjectModel;
using System.Diagnostics; using System.Diagnostics;
using System.Drawing; using System.Drawing;
using System.Text.Json; using System.Text.Json;
@ -12,36 +13,9 @@ namespace View_by_Distance.Map.Models.Stateless;
internal abstract class MapLogic internal abstract class MapLogic
{ {
private static List<PersonContainer> GetNonSpecificPeopleCollection(Configuration configuration, long ticks, List<long> personKeys) private static void SetPersonCollections(Configuration configuration, ReadOnlyCollection<PersonContainer> personContainers, string? a2PeopleSingletonDirectory, Dictionary<string, string> personKeyFormattedToNewestPersonKeyFormatted, List<string> personKeyFormattedCollection, Dictionary<int, List<int>> skipCollection, Dictionary<int, List<int>> skipNotSkipCollection)
{
List<PersonContainer> results = new();
Person person;
long personKey;
int? approximateYears = null;
PersonBirthday personBirthday;
PersonContainer personContainer;
string[] personDisplayDirectoryAllFiles = Array.Empty<string>();
DateTime incrementDate = new(configuration.PersonBirthdayFirstYear, 1, 1);
for (int i = 0; i < int.MaxValue; i++)
{
personKey = incrementDate.Ticks;
incrementDate = incrementDate.AddDays(1);
if (incrementDate.Ticks > ticks)
break;
if (personKeys.Contains(personKey))
continue;
personBirthday = IPersonBirthday.GetPersonBirthday(personKey);
person = IPerson.GetPerson(configuration.MappingDefaultName, configuration.PersonCharacters.ToArray(), configuration.MappingDefaultName, personKey, personBirthday);
personContainer = new(approximateYears, new PersonBirthday[] { personBirthday }, personDisplayDirectoryAllFiles, configuration.MappingDefaultName, personKey, person);
results.Add(personContainer);
}
return results;
}
private static void SetPersonCollections(Configuration configuration, List<PersonContainer> personContainers, string? a2PeopleSingletonDirectory, List<long> personKeys, Dictionary<string, string> personKeyFormattedToNewestPersonKeyFormatted, List<string> personKeyFormattedCollection, Dictionary<int, List<int>> skipCollection, Dictionary<int, List<int>> skipNotSkipCollection)
{ {
int? id; int? id;
long personKey;
int? normalizedRectangle; int? normalizedRectangle;
string personKeyFormatted; string personKeyFormatted;
string newestPersonKeyFormatted; string newestPersonKeyFormatted;
@ -72,11 +46,6 @@ internal abstract class MapLogic
if (personContainer.Person is null || personContainer.Key is null || personContainer.Birthdays is null || !personContainer.Birthdays.Any()) if (personContainer.Person is null || personContainer.Key is null || personContainer.Birthdays is null || !personContainer.Birthdays.Any())
continue; continue;
foreach (PersonBirthday personBirthday in personContainer.Birthdays) foreach (PersonBirthday personBirthday in personContainer.Birthdays)
{
personKey = personBirthday.Value.Ticks;
personKeys.Add(personKey);
}
foreach (PersonBirthday personBirthday in personContainer.Birthdays)
{ {
personKeyFormatted = IPersonBirthday.GetFormatted(configuration.PersonBirthdayFormat, personBirthday); personKeyFormatted = IPersonBirthday.GetFormatted(configuration.PersonBirthdayFormat, personBirthday);
personKeyFormattedCollection.Add(personKeyFormatted); personKeyFormattedCollection.Add(personKeyFormatted);
@ -316,7 +285,7 @@ internal abstract class MapLogic
return results.ToArray(); return results.ToArray();
} }
private static void SetKeyValuePairs(Configuration configuration, List<PersonContainer> personContainers, Dictionary<long, List<PersonContainer>> personKeyToPersonContainerCollection, Dictionary<string, PersonContainer> personKeyFormattedToPersonContainer, List<(string, string[], int, int)> personKeyFormattedIdThenNormalizedRectangleCollection, Dictionary<long, PersonContainer> personKeyToPersonContainer, Dictionary<int, Dictionary<int, PersonContainer[]>> idThenNormalizedRectangleToPersonContainers, List<(string[], PersonContainer)> possiblyNewPersonDisplayDirectoryNamesAndPersonContainer) private static void SetKeyValuePairs(Configuration configuration, ReadOnlyCollection<PersonContainer> personContainers, Dictionary<long, List<PersonContainer>> personKeyToPersonContainerCollection, Dictionary<string, PersonContainer> personKeyFormattedToPersonContainer, List<(string, string[], int, int)> personKeyFormattedIdThenNormalizedRectangleCollection, Dictionary<long, PersonContainer> personKeyToPersonContainer, Dictionary<int, Dictionary<int, PersonContainer[]>> idThenNormalizedRectangleToPersonContainers, List<(string[], PersonContainer)> possiblyNewPersonDisplayDirectoryNamesAndPersonContainer)
{ {
PersonBirthday? personBirthday; PersonBirthday? personBirthday;
PersonContainer[] distinctPersonContainers; PersonContainer[] distinctPersonContainers;
@ -394,16 +363,14 @@ internal abstract class MapLogic
return results; return results;
} }
private static (int, int) SetCollectionsAndGetUnableToConvertCount(Configuration configuration, long ticks, Dictionary<string, string> personKeyFormattedToNewestPersonKeyFormatted, List<(string, string[], int, int)> personKeyFormattedIdThenNormalizedRectangleCollection, List<(string, string[], string)> collection) private static int SetCollectionsAndGetUnableToConvertCount(Configuration configuration, long ticks, Dictionary<string, string> personKeyFormattedToNewestPersonKeyFormatted, List<(string, string[], int, int)> personKeyFormattedIdThenNormalizedRectangleCollection, List<(string, string[], string)> collection)
{ {
int result = 0; int result = 0;
int? id; int? id;
string checkFile;
int? normalizedRectangle; int? normalizedRectangle;
List<int> normalizedRectangles; List<int> normalizedRectangles;
string? newestPersonKeyFormatted; string? newestPersonKeyFormatted;
string personDisplayDirectoryName; string personDisplayDirectoryName;
List<string> duplicateMappedFaceFiles = new();
Dictionary<int, List<int>> idToNormalizedRectangles = new(); Dictionary<int, List<int>> idToNormalizedRectangles = new();
int totalSeconds = (int)Math.Floor(new TimeSpan(DateTime.Now.Ticks - ticks).TotalSeconds); int totalSeconds = (int)Math.Floor(new TimeSpan(DateTime.Now.Ticks - ticks).TotalSeconds);
string message = $") {collection.Count:000} join from ticks Director(ies) - C - {totalSeconds} total second(s)"; string message = $") {collection.Count:000} join from ticks Director(ies) - C - {totalSeconds} total second(s)";
@ -414,16 +381,9 @@ internal abstract class MapLogic
progressBar.Tick(); progressBar.Tick();
if (!personKeyFormattedToNewestPersonKeyFormatted.TryGetValue(personKeyFormatted, out newestPersonKeyFormatted)) if (!personKeyFormattedToNewestPersonKeyFormatted.TryGetValue(personKeyFormatted, out newestPersonKeyFormatted))
{ {
if (!personDisplayDirectoryNames.Any() || IPerson.IsDefaultName(configuration.MappingDefaultName, personDisplayDirectoryNames[^1])) if (personDisplayDirectoryNames.Any() && !IPerson.IsDefaultName(configuration.MappingDefaultName, personDisplayDirectoryNames[^1]))
continue;
newestPersonKeyFormatted = personKeyFormatted; newestPersonKeyFormatted = personKeyFormatted;
else
{
checkFile = $"{mappedFaceFile}.abd";
if (File.Exists(checkFile))
continue;
File.Move(mappedFaceFile, checkFile);
continue;
}
} }
(id, normalizedRectangle) = IMapping.GetConverted(configuration.FacesFileNameExtension, mappedFaceFile); (id, normalizedRectangle) = IMapping.GetConverted(configuration.FacesFileNameExtension, mappedFaceFile);
if (id is null || normalizedRectangle is null) if (id is null || normalizedRectangle is null)
@ -441,20 +401,15 @@ internal abstract class MapLogic
continue; continue;
personKeyFormattedIdThenNormalizedRectangleCollection.Add(new(newestPersonKeyFormatted, personDisplayDirectoryNames, id.Value, normalizedRectangle.Value)); personKeyFormattedIdThenNormalizedRectangleCollection.Add(new(newestPersonKeyFormatted, personDisplayDirectoryNames, id.Value, normalizedRectangle.Value));
} }
if (duplicateMappedFaceFiles.Any()) return result;
{
duplicateMappedFaceFiles.Sort();
if (duplicateMappedFaceFiles.Any())
{ }
}
return new(result, duplicateMappedFaceFiles.Count);
} }
private static List<PersonContainer> GetNotMappedPersonContainers(Configuration configuration, List<PersonContainer> personContainers, List<long> personKeys, long[] personKeyCollection) private static List<PersonContainer> GetNotMappedPersonContainers(Configuration configuration, ReadOnlyCollection<PersonContainer> personContainers, long[] personKeyCollection)
{ {
List<PersonContainer> results = new(); List<PersonContainer> results = new();
List<PersonContainer> notMappedAndNotNamedPersonKeys = new(); List<PersonContainer> notMappedAndNotNamedPersonKeys = new();
List<PersonContainer> notMappedAndWithNamedPersonKeys = new(); List<PersonContainer> notMappedAndWithNamedPersonKeys = new();
List<long> personKeys = IPersonContainer.GetPersonKeys(personContainers);
foreach (PersonContainer personContainer in personContainers) foreach (PersonContainer personContainer in personContainers)
{ {
if (personContainer.Person is null || personContainer.Key is null || personContainer.Birthdays is null || !personContainer.Birthdays.Any()) if (personContainer.Person is null || personContainer.Key is null || personContainer.Birthdays is null || !personContainer.Birthdays.Any())
@ -484,7 +439,7 @@ internal abstract class MapLogic
return result; return result;
} }
private static void SetPersonKeyToPersonContainer(Configuration configuration, List<PersonContainer> personContainers, long[] personKeyCollection, Dictionary<long, PersonContainer> personKeyToPersonContainer, Dictionary<long, List<PersonContainer>> personKeyToPersonContainerCollection) private static void SetPersonKeyToPersonContainer(Configuration configuration, ReadOnlyCollection<PersonContainer> personContainers, long[] personKeyCollection, Dictionary<long, PersonContainer> personKeyToPersonContainer, Dictionary<long, List<PersonContainer>> personKeyToPersonContainerCollection)
{ {
string? displayDirectoryName; string? displayDirectoryName;
foreach (PersonContainer personContainer in personContainers) foreach (PersonContainer personContainer in personContainers)
@ -601,7 +556,7 @@ internal abstract class MapLogic
return results; return results;
} }
private static List<(long, string)> GetDisplayDirectoryAllFiles(string fileNameExtension, List<PersonContainer> personContainers) private static List<(long, string)> GetDisplayDirectoryAllFiles(string fileNameExtension, ReadOnlyCollection<PersonContainer> personContainers)
{ {
List<(long, string)> results = new(); List<(long, string)> results = new();
List<string> distinct = new(); List<string> distinct = new();
@ -622,7 +577,7 @@ internal abstract class MapLogic
return results; return results;
} }
private static List<(long PersonKey, string File)> GetCollection(Configuration configuration, List<PersonContainer> personContainers, List<(string, string[], string)> collection) private static List<(long PersonKey, string File)> GetCollection(Configuration configuration, ReadOnlyCollection<PersonContainer> personContainers, List<(string, string[], string)> collection)
{ {
List<(long PersonKey, string File)> results = new(); List<(long PersonKey, string File)> results = new();
string file; string file;
@ -757,7 +712,7 @@ internal abstract class MapLogic
} }
} }
private static void SetLocationContainers(int maxDegreeOfParallelism, Configuration configuration, long ticks, List<PersonContainer> personContainers, string eDistanceContentDirectory, Dictionary<int, List<LocationContainer<MetadataExtractor.Directory>>> idToLocationContainers, List<(string, string[], string)> sourceCollection) private static List<LocationContainer<MetadataExtractor.Directory>> GetLocationContainers(int maxDegreeOfParallelism, Configuration configuration, long ticks, ReadOnlyCollection<PersonContainer> personContainers, string eDistanceContentDirectory, List<(string, string[], string)> sourceCollection)
{ {
List<LocationContainer<MetadataExtractor.Directory>> results = new(); List<LocationContainer<MetadataExtractor.Directory>> results = new();
List<(long PersonKey, string File)> collection = GetCollection(configuration, personContainers, sourceCollection); List<(long PersonKey, string File)> collection = GetCollection(configuration, personContainers, sourceCollection);
@ -775,19 +730,13 @@ internal abstract class MapLogic
}); });
} }
LookForPossibleDuplicates(configuration, results); LookForPossibleDuplicates(configuration, results);
foreach (LocationContainer<MetadataExtractor.Directory> locationContainer in results) return results;
{
if (!idToLocationContainers.ContainsKey(locationContainer.Id))
idToLocationContainers.Add(locationContainer.Id, new());
idToLocationContainers[locationContainer.Id].Add(locationContainer);
}
} }
internal static void Set(int maxDegreeOfParallelism, Configuration configuration, long ticks, List<PersonContainer> personContainers, string? a2PeopleSingletonDirectory, string eDistanceContentDirectory, Dictionary<long, PersonContainer> personKeyToPersonContainer, List<PersonContainer> notMappedPersonContainers, Dictionary<int, List<int>> skipCollection, Dictionary<int, List<int>> skipNotSkipCollection, Dictionary<int, List<LocationContainer<MetadataExtractor.Directory>>> idToLocationContainers, Dictionary<int, Dictionary<int, PersonContainer[]>> idThenNormalizedRectangleToPersonContainers) internal static void Set(int maxDegreeOfParallelism, Configuration configuration, long ticks, ReadOnlyCollection<PersonContainer> personContainers, string? a2PeopleSingletonDirectory, string eDistanceContentDirectory, Dictionary<long, PersonContainer> personKeyToPersonContainer, List<PersonContainer> notMappedPersonContainers, Dictionary<int, List<int>> skipCollection, Dictionary<int, List<int>> skipNotSkipCollection, List<LocationContainer<MetadataExtractor.Directory>> locationContainers, Dictionary<int, Dictionary<int, PersonContainer[]>> idThenNormalizedRectangleToPersonContainers)
{ {
string message; string message;
int totalSeconds; int totalSeconds;
List<long> personKeys = new();
List<long?> nullablePersonKeyCollection = new(); List<long?> nullablePersonKeyCollection = new();
List<string> personKeyFormattedCollection = new(); List<string> personKeyFormattedCollection = new();
Dictionary<string, string> personKeyFormattedToNewestPersonKeyFormatted = new(); Dictionary<string, string> personKeyFormattedToNewestPersonKeyFormatted = new();
@ -796,16 +745,16 @@ internal abstract class MapLogic
string[] ticksDirectories = UpdateDateVerifyAndGetTicksDirectories(eDistanceContentDirectory); string[] ticksDirectories = UpdateDateVerifyAndGetTicksDirectories(eDistanceContentDirectory);
List<(string, string[], int, int)> personKeyFormattedIdThenNormalizedRectangleCollection = new(); List<(string, string[], int, int)> personKeyFormattedIdThenNormalizedRectangleCollection = new();
List<(string[], PersonContainer)> possiblyNewPersonDisplayDirectoryNamesAndPersonContainer = new(); List<(string[], PersonContainer)> possiblyNewPersonDisplayDirectoryNamesAndPersonContainer = new();
SetPersonCollections(configuration, personContainers, a2PeopleSingletonDirectory, personKeys, personKeyFormattedToNewestPersonKeyFormatted, personKeyFormattedCollection, skipCollection, skipNotSkipCollection); SetPersonCollections(configuration, personContainers, a2PeopleSingletonDirectory, personKeyFormattedToNewestPersonKeyFormatted, personKeyFormattedCollection, skipCollection, skipNotSkipCollection);
personContainers.AddRange(GetNonSpecificPeopleCollection(configuration, ticks, personKeys)); // personContainers.AddRange(GetNonSpecificPeopleCollection(configuration, ticks, personKeys));
totalSeconds = (int)Math.Floor(new TimeSpan(DateTime.Now.Ticks - ticks).TotalSeconds); totalSeconds = (int)Math.Floor(new TimeSpan(DateTime.Now.Ticks - ticks).TotalSeconds);
message = $") {ticksDirectories.Length:000} compile from and clean ticks Director(ies) - B - {totalSeconds} total second(s)"; message = $") {ticksDirectories.Length:000} compile from and clean ticks Director(ies) - B - {totalSeconds} total second(s)";
List<(string, string[], string)> collection = DeleteEmptyDirectoriesAndGetCollection(configuration, personKeyFormattedCollection, ticksDirectories, message); List<(string, string[], string)> collection = DeleteEmptyDirectoriesAndGetCollection(configuration, personKeyFormattedCollection, ticksDirectories, message);
SetLocationContainers(maxDegreeOfParallelism, configuration, ticks, personContainers, eDistanceContentDirectory, idToLocationContainers, collection); locationContainers.AddRange(GetLocationContainers(maxDegreeOfParallelism, configuration, ticks, personContainers, eDistanceContentDirectory, collection));
(int unableToMatchCount, int duplicateCount) = SetCollectionsAndGetUnableToConvertCount(configuration, ticks, personKeyFormattedToNewestPersonKeyFormatted, personKeyFormattedIdThenNormalizedRectangleCollection, collection); int unableToMatchCount = SetCollectionsAndGetUnableToConvertCount(configuration, ticks, personKeyFormattedToNewestPersonKeyFormatted, personKeyFormattedIdThenNormalizedRectangleCollection, collection);
SetKeyValuePairs(configuration, personContainers, personKeyToPersonContainerCollection, personKeyFormattedToPersonContainer, personKeyFormattedIdThenNormalizedRectangleCollection, personKeyToPersonContainer, idThenNormalizedRectangleToPersonContainers, possiblyNewPersonDisplayDirectoryNamesAndPersonContainer); SetKeyValuePairs(configuration, personContainers, personKeyToPersonContainerCollection, personKeyFormattedToPersonContainer, personKeyFormattedIdThenNormalizedRectangleCollection, personKeyToPersonContainer, idThenNormalizedRectangleToPersonContainers, possiblyNewPersonDisplayDirectoryNamesAndPersonContainer);
totalSeconds = (int)Math.Floor(new TimeSpan(DateTime.Now.Ticks - ticks).TotalSeconds); totalSeconds = (int)Math.Floor(new TimeSpan(DateTime.Now.Ticks - ticks).TotalSeconds);
message = $") {collection.Count:000} message from ticks Director(ies) - D - {duplicateCount} Duplicate Count {unableToMatchCount} Unable To Match Count / {collection.Count} Collection - {totalSeconds} total second(s)"; message = $") {collection.Count:000} message from ticks Director(ies) - D - {unableToMatchCount} Unable To Match Count / {collection.Count} Collection - {totalSeconds} total second(s)";
ProgressBarOptions options = new() { ProgressCharacter = '─', ProgressBarOnBottom = true, DisableBottomPercentage = true }; ProgressBarOptions options = new() { ProgressCharacter = '─', ProgressBarOnBottom = true, DisableBottomPercentage = true };
using (ProgressBar progressBar = new(collection.Count, message, options)) using (ProgressBar progressBar = new(collection.Count, message, options))
{ {
@ -818,7 +767,7 @@ internal abstract class MapLogic
} }
long[] personKeyCollection = (from l in nullablePersonKeyCollection where l is not null select l.Value).Distinct().ToArray(); long[] personKeyCollection = (from l in nullablePersonKeyCollection where l is not null select l.Value).Distinct().ToArray();
SetPersonKeyToPersonContainer(configuration, personContainers, personKeyCollection, personKeyToPersonContainer, personKeyToPersonContainerCollection); SetPersonKeyToPersonContainer(configuration, personContainers, personKeyCollection, personKeyToPersonContainer, personKeyToPersonContainerCollection);
notMappedPersonContainers.AddRange(GetNotMappedPersonContainers(configuration, personContainers, personKeys, personKeyCollection)); notMappedPersonContainers.AddRange(GetNotMappedPersonContainers(configuration, personContainers, personKeyCollection));
if (possiblyNewPersonDisplayDirectoryNamesAndPersonContainer.Any()) if (possiblyNewPersonDisplayDirectoryNamesAndPersonContainer.Any())
SavePossiblyNewPersonContainers(configuration.PersonBirthdayFormat, configuration.PersonCharacters.ToArray(), configuration.FacesFileNameExtension, a2PeopleSingletonDirectory, possiblyNewPersonDisplayDirectoryNamesAndPersonContainer); SavePossiblyNewPersonContainers(configuration.PersonBirthdayFormat, configuration.PersonCharacters.ToArray(), configuration.FacesFileNameExtension, a2PeopleSingletonDirectory, possiblyNewPersonDisplayDirectoryNamesAndPersonContainer);
} }

View File

@ -162,6 +162,19 @@ internal abstract class Container
return results; return results;
} }
private static void CreateShell(Properties.IPropertyConfiguration propertyConfiguration, List<string> directories)
{
string checkDirectory;
int startIndex = propertyConfiguration.RootDirectory.Length;
foreach (string directory in directories)
{
checkDirectory = directory.Insert(startIndex, "-Shell");
if (Directory.Exists(checkDirectory))
continue;
_ = Directory.CreateDirectory(checkDirectory);
}
}
internal static (int, Models.Container[]) GetContainers(Properties.IPropertyConfiguration propertyConfiguration, string aPropertySingletonDirectory) internal static (int, Models.Container[]) GetContainers(Properties.IPropertyConfiguration propertyConfiguration, string aPropertySingletonDirectory)
{ {
List<Models.Container> results = new(); List<Models.Container> results = new();
@ -169,6 +182,7 @@ internal abstract class Container
List<Models.Item>? items; List<Models.Item>? items;
Models.Container container; Models.Container container;
const string extension = ".json"; const string extension = ".json";
List<string> directories = new();
const string fileSearchFilter = "*"; const string fileSearchFilter = "*";
const string directorySearchFilter = "*"; const string directorySearchFilter = "*";
Dictionary<string, List<Models.Item>> directoryToItems = new(); Dictionary<string, List<Models.Item>> directoryToItems = new();
@ -180,6 +194,8 @@ internal abstract class Container
directory = Path.GetDirectoryName(files.First()); directory = Path.GetDirectoryName(files.First());
if (directory is null) if (directory is null)
continue; continue;
if (!directories.Contains(directory))
directories.Add(directory);
if (!directoryToItems.TryGetValue(directory, out items)) if (!directoryToItems.TryGetValue(directory, out items))
{ {
directoryToItems.Add(directory, new()); directoryToItems.Add(directory, new());
@ -187,6 +203,7 @@ internal abstract class Container
throw new Exception(); throw new Exception();
} }
} }
CreateShell(propertyConfiguration, directories);
List<Models.FilePair> filePairs = GetFilePairs(propertyConfiguration, directorySearchFilter, extension, aPropertySingletonDirectory, filesCollection); List<Models.FilePair> filePairs = GetFilePairs(propertyConfiguration, directorySearchFilter, extension, aPropertySingletonDirectory, filesCollection);
List<FilePair> collection = GetFilePairs(propertyConfiguration, aPropertySingletonDirectory, extension, filePairs); List<FilePair> collection = GetFilePairs(propertyConfiguration, aPropertySingletonDirectory, extension, filePairs);
foreach (FilePair filePair in collection) foreach (FilePair filePair in collection)
@ -211,4 +228,27 @@ internal abstract class Container
return (collection.Count, results.ToArray()); return (collection.Count, results.ToArray());
} }
internal static List<int> GetFilteredDistinct(Properties.IPropertyConfiguration propertyConfiguration, Models.Container[] containers)
{
List<int> results = new();
Models.Item[] filteredItems;
foreach (Models.Container container in containers)
{
if (!container.Items.Any())
continue;
filteredItems = GetFilterItems(propertyConfiguration, container);
if (!filteredItems.Any())
continue;
foreach (Models.Item item in filteredItems)
{
if (item.Property?.Id is null || item.ResizedFileHolder is null)
continue;
if (results.Contains(item.Property.Id.Value))
continue;
results.Add(item.Property.Id.Value);
}
}
return results;
}
} }

View File

@ -332,7 +332,7 @@ internal abstract class GenealogicalDataCommunication
_ = IPath.WriteAllText(Path.Combine(directory, $"{personKeyFormatted}.pged"), text, updateDateWhenMatches: false, compareBeforeWrite: true); _ = IPath.WriteAllText(Path.Combine(directory, $"{personKeyFormatted}.pged"), text, updateDateWhenMatches: false, compareBeforeWrite: true);
} }
internal static void CreateTree(string mappingDefaultName, string personBirthdayFormat, string resultAllInOne, Models.PersonContainer[] personContainers, string[] genealogicalDataCommunicationHeaderLines, string[] genealogicalDataCommunicationFooterLines, long ticks, string a2PeopleContentDirectory, Dictionary<long, List<int>> personKeyToIds) internal static void CreateTree(string mappingDefaultName, string personBirthdayFormat, string resultAllInOne, List<Models.PersonContainer> personContainers, string[] genealogicalDataCommunicationHeaderLines, string[] genealogicalDataCommunicationFooterLines, long ticks, string a2PeopleContentDirectory, Dictionary<long, List<int>> personKeyToIds)
{ {
string by; string by;
string[] matches; string[] matches;

View File

@ -33,4 +33,9 @@ public interface IContainer
static (int, Models.Container[]) GetContainers(Properties.IPropertyConfiguration propertyConfiguration, string aPropertySingletonDirectory) => static (int, Models.Container[]) GetContainers(Properties.IPropertyConfiguration propertyConfiguration, string aPropertySingletonDirectory) =>
Container.GetContainers(propertyConfiguration, aPropertySingletonDirectory); Container.GetContainers(propertyConfiguration, aPropertySingletonDirectory);
List<int> TestStatic_GetFilteredDistinct(Properties.IPropertyConfiguration propertyConfiguration, Models.Container[] containers) =>
GetFilteredDistinct(propertyConfiguration, containers);
static List<int> GetFilteredDistinct(Properties.IPropertyConfiguration propertyConfiguration, Models.Container[] containers) =>
Container.GetFilteredDistinct(propertyConfiguration, containers);
} }

View File

@ -36,4 +36,9 @@ public interface IDirectory
static List<FilePair> GetFiles(List<string[]> filesCollection, IReadOnlyDictionary<string, List<string>> fileNamesToFiles, string extension, IReadOnlyDictionary<string, List<string>> compareFileNamesToFiles) => static List<FilePair> GetFiles(List<string[]> filesCollection, IReadOnlyDictionary<string, List<string>> fileNamesToFiles, string extension, IReadOnlyDictionary<string, List<string>> compareFileNamesToFiles) =>
XDirectory.GetFiles(filesCollection, fileNamesToFiles, extension, compareFileNamesToFiles); XDirectory.GetFiles(filesCollection, fileNamesToFiles, extension, compareFileNamesToFiles);
void TestStatic_MoveFiles(List<string> files, string find, string replace) =>
MoveFiles(files, find, replace);
static void MoveFiles(List<string> files, string find, string replace) =>
XDirectory.MoveFiles(files, find, replace);
} }

View File

@ -30,9 +30,9 @@ public interface IGenealogicalDataCommunication
static (string[] headerLines, Dictionary<string, List<string>> individuals, string[] footerLines) GetIndividuals(string genealogicalDataCommunicationFile, bool requireNickName) => static (string[] headerLines, Dictionary<string, List<string>> individuals, string[] footerLines) GetIndividuals(string genealogicalDataCommunicationFile, bool requireNickName) =>
GenealogicalDataCommunication.GetIndividuals(genealogicalDataCommunicationFile, requireNickName); GenealogicalDataCommunication.GetIndividuals(genealogicalDataCommunicationFile, requireNickName);
void TestStatic_CreateTree(string mappingDefaultName, string personBirthdayFormat, string resultAllInOne, Models.PersonContainer[] personContainers, string[] genealogicalDataCommunicationHeaderLines, string[] genealogicalDataCommunicationFooterLines, long ticks, string a2PeopleContentDirectory, Dictionary<long, List<int>> personKeyToIds) => void TestStatic_CreateTree(string mappingDefaultName, string personBirthdayFormat, string resultAllInOne, List<Models.PersonContainer> personContainers, string[] genealogicalDataCommunicationHeaderLines, string[] genealogicalDataCommunicationFooterLines, long ticks, string a2PeopleContentDirectory, Dictionary<long, List<int>> personKeyToIds) =>
CreateTree(mappingDefaultName, personBirthdayFormat, resultAllInOne, personContainers, genealogicalDataCommunicationHeaderLines, genealogicalDataCommunicationFooterLines, ticks, a2PeopleContentDirectory, personKeyToIds); CreateTree(mappingDefaultName, personBirthdayFormat, resultAllInOne, personContainers, genealogicalDataCommunicationHeaderLines, genealogicalDataCommunicationFooterLines, ticks, a2PeopleContentDirectory, personKeyToIds);
static void CreateTree(string mappingDefaultName, string personBirthdayFormat, string resultAllInOne, Models.PersonContainer[] personContainers, string[] genealogicalDataCommunicationHeaderLines, string[] genealogicalDataCommunicationFooterLines, long ticks, string a2PeopleContentDirectory, Dictionary<long, List<int>> personKeyToIds) => static void CreateTree(string mappingDefaultName, string personBirthdayFormat, string resultAllInOne, List<Models.PersonContainer> personContainers, string[] genealogicalDataCommunicationHeaderLines, string[] genealogicalDataCommunicationFooterLines, long ticks, string a2PeopleContentDirectory, Dictionary<long, List<int>> personKeyToIds) =>
GenealogicalDataCommunication.CreateTree(mappingDefaultName, personBirthdayFormat, resultAllInOne, personContainers, genealogicalDataCommunicationHeaderLines, genealogicalDataCommunicationFooterLines, ticks, a2PeopleContentDirectory, personKeyToIds); GenealogicalDataCommunication.CreateTree(mappingDefaultName, personBirthdayFormat, resultAllInOne, personContainers, genealogicalDataCommunicationHeaderLines, genealogicalDataCommunicationFooterLines, ticks, a2PeopleContentDirectory, personKeyToIds);
} }

View File

@ -5,9 +5,19 @@ public interface IPersonContainer
// ... // ...
Models.PersonContainer[] TestStatic_GetPersonContainers(Properties.IStorage storage, string mappingDefaultName, string personBirthdayFormat, char[] personCharacters, string facesFileNameExtension, Dictionary<string, List<string>> individuals) => List<long> TestStatic_GetPersonKeys(IEnumerable<Models.PersonContainer> personContainers) =>
GetPersonKeys(personContainers);
static List<long> GetPersonKeys(IEnumerable<Models.PersonContainer> personContainers) =>
PersonContainer.GetPersonKeys(personContainers);
List<Models.PersonContainer> TestStatic_GetNonSpecificPeopleCollection(string mappingDefaultName, int personBirthdayFirstYear, char[] personCharacters, List<Models.PersonContainer> personContainers, long ticks) =>
GetNonSpecificPeopleCollection(mappingDefaultName, personBirthdayFirstYear, personCharacters, personContainers, ticks);
static List<Models.PersonContainer> GetNonSpecificPeopleCollection(string mappingDefaultName, int personBirthdayFirstYear, char[] personCharacters, List<Models.PersonContainer> personContainers, long ticks) =>
PersonContainer.GetNonSpecificPeopleCollection(mappingDefaultName, personBirthdayFirstYear, personCharacters, personContainers, ticks);
List<Models.PersonContainer> TestStatic_GetPersonContainers(Properties.IStorage storage, string mappingDefaultName, string personBirthdayFormat, char[] personCharacters, string facesFileNameExtension, Dictionary<string, List<string>> individuals) =>
GetPersonContainers(storage, mappingDefaultName, personBirthdayFormat, personCharacters, facesFileNameExtension, individuals); GetPersonContainers(storage, mappingDefaultName, personBirthdayFormat, personCharacters, facesFileNameExtension, individuals);
static Models.PersonContainer[] GetPersonContainers(Properties.IStorage storage, string mappingDefaultName, string personBirthdayFormat, char[] personCharacters, string facesFileNameExtension, Dictionary<string, List<string>> individuals) => static List<Models.PersonContainer> GetPersonContainers(Properties.IStorage storage, string mappingDefaultName, string personBirthdayFormat, char[] personCharacters, string facesFileNameExtension, Dictionary<string, List<string>> individuals) =>
PersonContainer.GetPersonContainers(storage, mappingDefaultName, personBirthdayFormat, personCharacters, facesFileNameExtension, individuals); PersonContainer.GetPersonContainers(storage, mappingDefaultName, personBirthdayFormat, personCharacters, facesFileNameExtension, individuals);
List<(long?, string)> TestStatic_GetDisplay(string personBirthdayFormat, Models.PersonContainer personContainer) => List<(long?, string)> TestStatic_GetDisplay(string personBirthdayFormat, Models.PersonContainer personContainer) =>

View File

@ -56,10 +56,15 @@ public interface IProperty
static DateTime? GetDateTimeFromName(Models.FileHolder fileHolder) => static DateTime? GetDateTimeFromName(Models.FileHolder fileHolder) =>
Property.GetDateTimeFromName(fileHolder); Property.GetDateTimeFromName(fileHolder);
bool TestStatic_NameWithoutExtensionIsIdFormat(string fileNameWithoutExtension) =>
NameWithoutExtensionIsIdFormat(fileNameWithoutExtension);
static bool NameWithoutExtensionIsIdFormat(string fileNameWithoutExtension) =>
Property.NameWithoutExtensionIsIdFormat(fileNameWithoutExtension);
bool TestStatic_NameWithoutExtensionIsIdFormat(Models.FileHolder fileHolder) => bool TestStatic_NameWithoutExtensionIsIdFormat(Models.FileHolder fileHolder) =>
NameWithoutExtensionIsIdFormat(fileHolder); NameWithoutExtensionIsIdFormat(fileHolder);
static bool NameWithoutExtensionIsIdFormat(Models.FileHolder fileHolder) => static bool NameWithoutExtensionIsIdFormat(Models.FileHolder fileHolder) =>
Property.NameWithoutExtensionIsIdFormat(fileHolder); NameWithoutExtensionIsIdFormat(fileHolder.NameWithoutExtension);
List<DateTime> TestStatic_GetDateTimes(Models.Property property) => List<DateTime> TestStatic_GetDateTimes(Models.Property property) =>
GetDateTimes(property); GetDateTimes(property);

View File

@ -277,9 +277,9 @@ internal abstract class PersonContainer
return results; return results;
} }
private static Models.PersonContainer[] GetPersonContainersGroups(string mappingDefaultName, string personBirthdayFormat, string facesFileNameExtension, char[] personCharacters, Dictionary<string, List<string>> individuals, string[] groupDirectories) private static List<Models.PersonContainer> GetPersonContainersGroups(string mappingDefaultName, string personBirthdayFormat, string facesFileNameExtension, char[] personCharacters, Dictionary<string, List<string>> individuals, string[] groupDirectories)
{ {
Models.PersonContainer[] results; List<Models.PersonContainer> results;
const int zero = 0; const int zero = 0;
string groupDirectoryName; string groupDirectoryName;
List<Models.PersonContainer> collection; List<Models.PersonContainer> collection;
@ -292,13 +292,13 @@ internal abstract class PersonContainer
collection = GetPersonContainersInnerGroups(mappingDefaultName, personBirthdayFormat, facesFileNameExtension, personCharacters, individuals, groupDirectory, groupDirectoryName); collection = GetPersonContainersInnerGroups(mappingDefaultName, personBirthdayFormat, facesFileNameExtension, personCharacters, individuals, groupDirectory, groupDirectoryName);
personContainers.AddRange(collection); personContainers.AddRange(collection);
} }
results = (from l in personContainers orderby l.Key is not null, l.Key select l).ToArray(); results = (from l in personContainers orderby l.Key is not null, l.Key select l).ToList();
return results; return results;
} }
internal static Models.PersonContainer[] GetPersonContainers(Properties.IStorage storage, string mappingDefaultName, string personBirthdayFormat, char[] personCharacters, string facesFileNameExtension, Dictionary<string, List<string>> individuals) internal static List<Models.PersonContainer> GetPersonContainers(Properties.IStorage storage, string mappingDefaultName, string personBirthdayFormat, char[] personCharacters, string facesFileNameExtension, Dictionary<string, List<string>> individuals)
{ {
Models.PersonContainer[] results; List<Models.PersonContainer> results;
string a2PeopleSingletonDirectory = Path.Combine(storage.PeopleRootDirectory, "{}"); string a2PeopleSingletonDirectory = Path.Combine(storage.PeopleRootDirectory, "{}");
if (!Directory.Exists(a2PeopleSingletonDirectory)) if (!Directory.Exists(a2PeopleSingletonDirectory))
_ = Directory.CreateDirectory(a2PeopleSingletonDirectory); _ = Directory.CreateDirectory(a2PeopleSingletonDirectory);
@ -311,7 +311,7 @@ internal abstract class PersonContainer
} }
string[] groupDirectories = Directory.GetDirectories(a2PeopleSingletonDirectory, "*", SearchOption.TopDirectoryOnly); string[] groupDirectories = Directory.GetDirectories(a2PeopleSingletonDirectory, "*", SearchOption.TopDirectoryOnly);
if (!groupDirectories.Any()) if (!groupDirectories.Any())
results = Array.Empty<Models.PersonContainer>(); results = new();
else else
results = GetPersonContainersGroups(mappingDefaultName, personBirthdayFormat, facesFileNameExtension, personCharacters, individuals, groupDirectories); results = GetPersonContainersGroups(mappingDefaultName, personBirthdayFormat, facesFileNameExtension, personCharacters, individuals, groupDirectories);
return results; return results;
@ -335,4 +335,48 @@ internal abstract class PersonContainer
return results; return results;
} }
internal static List<long> GetPersonKeys(IEnumerable<Models.PersonContainer> personContainers)
{
List<long> results = new();
long personKey;
foreach (Models.PersonContainer personContainer in personContainers)
{
if (personContainer.Person is null || personContainer.Key is null || personContainer.Birthdays is null || !personContainer.Birthdays.Any())
continue;
foreach (Models.PersonBirthday personBirthday in personContainer.Birthdays)
{
personKey = personBirthday.Value.Ticks;
results.Add(personKey);
}
}
return results;
}
internal static List<Models.PersonContainer> GetNonSpecificPeopleCollection(string mappingDefaultName, int personBirthdayFirstYear, char[] personCharacters, List<Models.PersonContainer> personContainers, long ticks)
{
List<Models.PersonContainer> results = new();
long personKey;
Models.Person person;
int? approximateYears = null;
Models.PersonBirthday personBirthday;
Models.PersonContainer personContainer;
List<long> personKeys = GetPersonKeys(personContainers);
string[] personDisplayDirectoryAllFiles = Array.Empty<string>();
DateTime incrementDate = new(personBirthdayFirstYear, 1, 1);
for (int i = 0; i < int.MaxValue; i++)
{
personKey = incrementDate.Ticks;
incrementDate = incrementDate.AddDays(1);
if (incrementDate.Ticks > ticks)
break;
if (personKeys.Contains(personKey))
continue;
personBirthday = IPersonBirthday.GetPersonBirthday(personKey);
person = IPerson.GetPerson(mappingDefaultName, personCharacters, mappingDefaultName, personKey, personBirthday);
personContainer = new(approximateYears, new Models.PersonBirthday[] { personBirthday }, personDisplayDirectoryAllFiles, mappingDefaultName, personKey, person);
results.Add(personContainer);
}
return results;
}
} }

View File

@ -331,15 +331,15 @@ internal abstract class Property
return result; return result;
} }
internal static bool NameWithoutExtensionIsIdFormat(Models.FileHolder fileHolder) internal static bool NameWithoutExtensionIsIdFormat(string fileNameWithoutExtension)
{ {
bool result; bool result;
if (fileHolder.NameWithoutExtension.Length < 5) if (fileNameWithoutExtension.Length < 5)
result = false; result = false;
else else
{ {
bool skipOneAllAreNumbers = fileHolder.NameWithoutExtension[1..].All(l => char.IsNumber(l)); bool skipOneAllAreNumbers = fileNameWithoutExtension[1..].All(l => char.IsNumber(l));
result = (skipOneAllAreNumbers && fileHolder.NameWithoutExtension[0] == '-') || (skipOneAllAreNumbers && char.IsNumber(fileHolder.NameWithoutExtension[0])); result = (skipOneAllAreNumbers && fileNameWithoutExtension[0] == '-') || (skipOneAllAreNumbers && char.IsNumber(fileNameWithoutExtension[0]));
} }
return result; return result;
} }

View File

@ -73,7 +73,7 @@ internal abstract partial class XDirectory
List<string>? collection; List<string>? collection;
string fileNameUpperExtension; string fileNameUpperExtension;
int length = extension.Length; int length = extension.Length;
List<(string, string)> rename = new(); List<string> renameCollection = new();
foreach (string[] files in jsonFilesCollection) foreach (string[] files in jsonFilesCollection)
{ {
foreach (string file in files) foreach (string file in files)
@ -86,17 +86,13 @@ internal abstract partial class XDirectory
{ {
fileNameUpperExtension = string.Concat(Path.GetFileNameWithoutExtension(fileName), Path.GetExtension(fileName).ToUpper()); fileNameUpperExtension = string.Concat(Path.GetFileNameWithoutExtension(fileName), Path.GetExtension(fileName).ToUpper());
if (fileName == fileNameUpperExtension || !fileNamesToFiles.TryGetValue(fileNameUpperExtension, out collection)) if (fileName == fileNameUpperExtension || !fileNamesToFiles.TryGetValue(fileNameUpperExtension, out collection))
rename.Add(new(file, string.Concat(file, ".del"))); renameCollection.Add(file);
} }
} }
} }
foreach ((string from, string to) in rename) if (renameCollection.Any())
{ IDirectory.MoveFiles(renameCollection, "{}", "{abd}");
if (File.Exists(to)) return renameCollection.Count;
continue;
File.Move(from, to);
}
return rename.Count;
} }
private static void IsNotUniqueLoop(string file, List<string> collection) private static void IsNotUniqueLoop(string file, List<string> collection)
@ -248,4 +244,33 @@ internal abstract partial class XDirectory
return rename.Count; return rename.Count;
} }
internal static void MoveFiles(List<string> files, string find, string replace)
{
string checkFile;
string? checkDirectory;
List<string> directories = new();
foreach (string file in files)
{
checkDirectory = Path.GetDirectoryName(file.Replace(find, replace));
if (string.IsNullOrEmpty(checkDirectory) || directories.Contains(checkDirectory))
continue;
directories.Add(checkDirectory);
}
foreach (string directory in directories)
{
if (Directory.Exists(directory))
continue;
_ = Directory.CreateDirectory(directory);
}
foreach (string file in files)
{
if (!File.Exists(file))
continue;
checkFile = file.Replace(find, replace);
if (File.Exists(checkFile))
continue;
File.Move(file, checkFile);
}
}
} }

View File

@ -244,6 +244,40 @@ public partial class UnitTestHardCoded
NonThrowTryCatch(); NonThrowTryCatch();
} }
[TestMethod]
public void TestMethodRenameDelete()
{
string checkFile;
string source = @"D:\1) Images A\Images-9b89679-Results\A) Property\9b89679\{}";
string[] files = Directory.GetFiles(source, "*.del", SearchOption.AllDirectories);
foreach (string file in files)
{
checkFile = file[..^4];
if (File.Exists(checkFile))
continue;
File.Move(file, checkFile);
}
Assert.IsTrue(true);
NonThrowTryCatch();
}
[TestMethod]
public void TestMethodRenameOld()
{
string checkFile;
string source = @"D:\2) Images B\Not-Copy-Copy-9b89679-Results\E) Distance\9b89679\()";
string[] files = Directory.GetFiles(source, "*.old", SearchOption.AllDirectories);
foreach (string file in files)
{
checkFile = file[..^4];
if (File.Exists(checkFile))
continue;
File.Move(file, checkFile);
}
Assert.IsTrue(true);
NonThrowTryCatch();
}
[TestMethod] [TestMethod]
public void TestMethodAncestryGenealogicalDataCommunication() public void TestMethodAncestryGenealogicalDataCommunication()
{ {