diff --git a/Compare/Compare.cs b/Compare/Compare.cs
index 9bacc79..18e0243 100644
--- a/Compare/Compare.cs
+++ b/Compare/Compare.cs
@@ -160,7 +160,7 @@ public class Compare
}
if (_IsEnvironment.Development && propertyConfiguration.PopulatePropertyId)
throw new Exception("Copy keyValuePairs-####.json file");
- (int j, int f, int t, Shared.Models.Container[] containers) = Shared.Models.Stateless.Methods.IContainer.GetContainers(propertyConfiguration, propertyLogic);
+ (int j, int f, int t, Shared.Models.Container[] containers) = Container.Models.Stateless.Methods.IContainer.GetContainers(propertyConfiguration, propertyLogic);
if (propertyLogic.ExceptionsDirectories.Any())
throw new Exception();
if (propertyConfiguration.PopulatePropertyId && Shared.Models.Stateless.Methods.IProperty.Any(containers))
diff --git a/Container/.vscode/format-report.json b/Container/.vscode/format-report.json
new file mode 100644
index 0000000..0637a08
--- /dev/null
+++ b/Container/.vscode/format-report.json
@@ -0,0 +1 @@
+[]
\ No newline at end of file
diff --git a/Container/.vscode/settings.json b/Container/.vscode/settings.json
new file mode 100644
index 0000000..0852522
--- /dev/null
+++ b/Container/.vscode/settings.json
@@ -0,0 +1,8 @@
+{
+ "cSpell.words": [
+ "dlib",
+ "Exif",
+ "nosj",
+ "Serilog"
+ ]
+}
\ No newline at end of file
diff --git a/Container/Container.csproj b/Container/Container.csproj
new file mode 100644
index 0000000..bc45f6b
--- /dev/null
+++ b/Container/Container.csproj
@@ -0,0 +1,51 @@
+
+
+ enable
+ enable
+ library
+ win-x64;linux-x64
+ net9.0
+
+
+ Phares.View.by.Distance.Container
+ false
+ 9.0.100.1
+ Mike Phares
+ Phares
+ true
+ snupkg
+
+
+
+ true
+
+
+ true
+
+
+ true
+
+
+
+ Windows
+
+
+ OSX
+
+
+ Linux
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Shared/Models/Container.cs b/Container/Models/Container.cs
similarity index 80%
rename from Shared/Models/Container.cs
rename to Container/Models/Container.cs
index 8af98c8..483d840 100644
--- a/Shared/Models/Container.cs
+++ b/Container/Models/Container.cs
@@ -1,7 +1,8 @@
using System.Collections.ObjectModel;
using System.Text.Json;
+using View_by_Distance.Shared.Models;
-namespace View_by_Distance.Shared.Models;
+namespace View_by_Distance.Container.Models;
public record Container(string SourceDirectory, ReadOnlyCollection- Items)
{
diff --git a/Container/Models/Stateless/Methods/Container.cs b/Container/Models/Stateless/Methods/Container.cs
new file mode 100644
index 0000000..e274538
--- /dev/null
+++ b/Container/Models/Stateless/Methods/Container.cs
@@ -0,0 +1,664 @@
+using System.Collections.ObjectModel;
+using System.Text.Json;
+using View_by_Distance.Shared.Models;
+using View_by_Distance.Shared.Models.Properties;
+using View_by_Distance.Shared.Models.Stateless.Methods;
+
+namespace View_by_Distance.Container.Models.Stateless.Methods;
+
+internal abstract class Container
+{
+
+ private record FilePair(bool IsUnique, List Collection, FilePath FilePath, Item Item) { }
+
+ internal static DateTime[] GetContainerDateTimes(ReadOnlyCollection
- items)
+ {
+ DateTime[] results;
+ long containerMinimumTicks = (from l in items select l.FilePath.LastWriteTicks).Min();
+ long containerMaximumTicks = (from l in items select l.FilePath.LastWriteTicks).Max();
+ results = [new(containerMinimumTicks), new(containerMaximumTicks)];
+ return results;
+ }
+
+ internal static ReadOnlyCollection
- GetValidImageItems(IPropertyConfiguration propertyConfiguration, Models.Container container)
+ {
+ List
- results = [];
+ foreach (Item item in container.Items)
+ {
+ if (!item.IsValidImageFormatExtension || propertyConfiguration.IgnoreExtensions.Contains(item.FilePath.ExtensionLowered))
+ continue;
+ results.Add(item);
+ }
+ return container.Items.Count == results.Count ? container.Items : results.AsReadOnly();
+ }
+
+ private static IReadOnlyDictionary> GetFilesKeyValuePairs(ReadOnlyCollection> filePathsCollection)
+ {
+ Dictionary> results = [];
+ List? collection;
+ string fileNameWithoutExtensionMinusOne;
+ foreach (ReadOnlyCollection filePaths in filePathsCollection)
+ {
+ foreach (FilePath filePath in filePaths)
+ {
+ fileNameWithoutExtensionMinusOne = filePath.NameWithoutExtension[..^1];
+ if (!results.TryGetValue(fileNameWithoutExtensionMinusOne, out collection))
+ {
+ results.Add(fileNameWithoutExtensionMinusOne, []);
+ if (!results.TryGetValue(fileNameWithoutExtensionMinusOne, out collection))
+ throw new Exception();
+ }
+ collection.Add(filePath.FullName);
+ }
+ }
+ return results;
+ }
+
+ private static IReadOnlyDictionary> GetFilesKeyValuePairs(ReadOnlyCollection filesCollection)
+ {
+ Dictionary> results = [];
+ string fileNameWithoutExtension;
+ string fileNameWithoutExtensionSecond;
+ string fileNameWithoutExtensionSecondMinusOne;
+ List? collection;
+ foreach (string[] files in filesCollection)
+ {
+ foreach (string file in files)
+ {
+ fileNameWithoutExtension = Path.GetFileNameWithoutExtension(file);
+ fileNameWithoutExtensionSecond = Path.GetFileNameWithoutExtension(fileNameWithoutExtension);
+ if (string.IsNullOrEmpty(fileNameWithoutExtensionSecond) || fileNameWithoutExtensionSecond == fileNameWithoutExtension)
+ continue;
+ fileNameWithoutExtensionSecondMinusOne = fileNameWithoutExtensionSecond[..^1];
+ if (!results.TryGetValue(fileNameWithoutExtensionSecondMinusOne, out collection))
+ {
+ results.Add(fileNameWithoutExtensionSecondMinusOne, []);
+ if (!results.TryGetValue(fileNameWithoutExtensionSecondMinusOne, out collection))
+ throw new Exception();
+ }
+ collection.Add(file);
+ }
+ }
+ return results;
+ }
+
+ private static bool AnyMoved(IReadOnlyDictionary> fileNamesToFiles, string extension, List renameCollection, string[] files)
+ {
+ bool result = false;
+ string checkFile;
+ string directory;
+ string fileNameWith;
+ string checkDirectory;
+ string directoryName;
+ List? collection;
+ string fileNameWithoutExtension;
+ List directoryNames = [];
+ string fileNameWithoutExtensionSecond;
+ string fileNameWithoutExtensionSecondMinusOne;
+ foreach (string file in files)
+ {
+ if (!file.EndsWith(extension))
+ throw new Exception();
+ fileNameWithoutExtension = Path.GetFileNameWithoutExtension(file);
+ fileNameWithoutExtensionSecond = Path.GetFileNameWithoutExtension(fileNameWithoutExtension);
+ if (string.IsNullOrEmpty(fileNameWithoutExtensionSecond) || fileNameWithoutExtensionSecond == fileNameWithoutExtension)
+ continue;
+ fileNameWithoutExtensionSecondMinusOne = fileNameWithoutExtensionSecond[..^1];
+ if (!fileNamesToFiles.TryGetValue(fileNameWithoutExtensionSecondMinusOne, out collection))
+ renameCollection.Add(file);
+ else
+ {
+ directoryNames.Clear();
+ directoryName = Path.GetFileName(Path.GetDirectoryName(file)) ?? throw new Exception();
+ foreach (string f in collection)
+ directoryNames.Add(Path.GetFileName(Path.GetDirectoryName(f)) ?? throw new Exception());
+ if (directoryNames.Count == 0 || directoryNames.Distinct().Count() != 1)
+ continue;
+ if (directoryName != directoryNames[0])
+ {
+ directory = Path.GetDirectoryName(Path.GetDirectoryName(file)) ?? throw new Exception();
+ checkDirectory = Path.Combine(directory, directoryNames[0]);
+ if (!Directory.Exists(checkDirectory))
+ _ = Directory.CreateDirectory(checkDirectory);
+ fileNameWith = collection.Count > 1 ? Path.GetFileName(file) : $"{Path.GetFileName(collection[0])}{extension}";
+ checkFile = Path.Combine(checkDirectory, fileNameWith);
+ if (!result)
+ result = true;
+ if (!File.Exists(checkFile))
+ File.Move(file, checkFile);
+ else
+ {
+ if (new FileInfo(file).LastWriteTime > new FileInfo(checkFile).LastWriteTime)
+ File.Delete(file);
+ else
+ File.Move(file, checkFile, true);
+ }
+ }
+ }
+ }
+ return result;
+ }
+
+ private static int LookForAbandoned(ReadOnlyCollection jsonFilesCollection, IReadOnlyDictionary> fileNamesToFiles, string extension)
+ {
+ int result;
+ bool check;
+ bool moved = false;
+ List renameCollection = [];
+ foreach (string[] files in jsonFilesCollection)
+ {
+ if (files.Length == 0)
+ continue;
+ check = AnyMoved(fileNamesToFiles, extension, renameCollection, files);
+ if (!moved && check)
+ moved = true;
+ }
+ if (renameCollection.Count > 0)
+ IDirectory.MoveFiles(renameCollection, "{}", "{abd}");
+ result = renameCollection.Count;
+ if (moved && result == 0)
+ result = 1;
+ return result;
+ }
+
+ private static List GetFilePairs(IPropertyConfiguration propertyConfiguration, string directorySearchFilter, string extension, string jsonGroupDirectory, ReadOnlyCollection> filePathsCollection, IReadOnlyDictionary> fileNamesToFiles)
+ {
+ List? results = null;
+ int renamed;
+ const bool useCeilingAverage = true;
+ ReadOnlyCollection? jsonFilesCollection = null;
+ IReadOnlyDictionary>? compareFileNamesToFiles = null;
+ for (int i = 0; i < short.MaxValue; i++)
+ {
+ renamed = 0;
+ jsonFilesCollection = IDirectory.GetFilesCollection(jsonGroupDirectory, directorySearchFilter, extension, useCeilingAverage);
+ compareFileNamesToFiles = GetFilesKeyValuePairs(jsonFilesCollection);
+ renamed += LookForAbandoned(jsonFilesCollection, fileNamesToFiles, extension);
+ results = IDirectory.GetFiles(propertyConfiguration, filePathsCollection, fileNamesToFiles, compareFileNamesToFiles);
+ renamed += IDirectory.MaybeMove(propertyConfiguration, results, jsonGroupDirectory, extension);
+ if (renamed == 0)
+ break;
+ if (i > 10)
+ throw new NotImplementedException();
+ }
+ if (results is null || jsonFilesCollection is null || compareFileNamesToFiles is null)
+ throw new NullReferenceException(nameof(results));
+ return results;
+ }
+
+ private static Property? GetProperty(Shared.Models.FilePair filePair)
+ {
+ Property? result;
+ if (filePair.Match is null)
+ result = null;
+ else
+ {
+ string json = File.ReadAllText(filePair.Match);
+ if (string.IsNullOrEmpty(json))
+ result = null;
+ else
+ result = JsonSerializer.Deserialize(json, PropertyGenerationContext.Default.Property);
+ }
+ return result;
+ }
+
+ private static ExifDirectory? GetExifDirectory(Shared.Models.FilePair filePair)
+ {
+ ExifDirectory? result;
+ if (filePair.Match is null)
+ result = null;
+ else
+ {
+ string json = File.ReadAllText(filePair.Match);
+ if (string.IsNullOrEmpty(json))
+ result = null;
+ else
+ result = JsonSerializer.Deserialize(json, ExifDirectorySourceGenerationContext.Default.ExifDirectory);
+ }
+ return result;
+ }
+
+ private static void MoveIf(string fileName, CombinedEnumAndIndex cei, string directory, string fullFileName)
+ {
+ string[] segments = directory.Split(cei.Combined);
+ string? checkDirectory = segments.Length == 1 ?
+ Path.Combine(segments[0], $"{cei.Combined[2..]}") :
+ segments.Length == 2 ?
+ $"{segments[0]}{cei.Combined[2..]}{segments[1]}" :
+ null;
+ if (checkDirectory is not null && Directory.Exists(checkDirectory))
+ {
+ string checkFile = Path.Combine(checkDirectory, fileName);
+ if (File.Exists(checkFile))
+ File.Move(checkFile, fullFileName);
+ }
+ }
+
+ private static void RenameFile(string extension, Shared.Models.FilePair filePair, FilePath filePath, char change, ReadOnlyCollection filePaths)
+ {
+ string checkFile;
+ if (filePath.DirectoryFullPath.Contains("Results") && filePath.DirectoryFullPath.Contains("Resize"))
+ File.Delete(filePath.FullName);
+ if (!string.IsNullOrEmpty(filePair.Match))
+ {
+ string directory = Path.GetDirectoryName(filePair.Match) ?? throw new Exception();
+ string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(filePair.Match);
+ string fileNameWithoutExtensionSecond = Path.GetFileNameWithoutExtension(Path.GetFileNameWithoutExtension(filePair.Match));
+ string extensionSecond = Path.GetExtension(fileNameWithoutExtension);
+ checkFile = Path.Combine(directory, $"{fileNameWithoutExtensionSecond[..^1]}{change}{extensionSecond}{extension}");
+ if (!File.Exists(checkFile))
+ File.Move(filePair.Match, checkFile);
+ }
+ foreach (FilePath f in filePaths)
+ {
+ checkFile = Path.Combine(f.DirectoryFullPath, $"{f.NameWithoutExtension[..^1]}{change}{f.ExtensionLowered}");
+ if (File.Exists(checkFile))
+ continue;
+ File.Move(f.FullName, checkFile);
+ }
+ }
+
+ private static void ParallelFor(IDlibDotNet dlibDotNet, IPropertyConfiguration propertyConfiguration, string jsonGroupDirectory, string extension, ReadOnlyDictionary>? keyValuePairs, ReadOnlyDictionary? splatNineIdentifiers, int rootDirectoryLength, Shared.Models.FilePair filePair, List results)
+ {
+ dlibDotNet?.Tick();
+ bool abandoned = false;
+ FileHolder sourceDirectoryFileHolder;
+ Property? property = GetProperty(filePair);
+ FileHolder fileHolder = IFileHolder.Get(filePair.Path);
+ ExifDirectory? exifDirectory = GetExifDirectory(filePair);
+ FilePath filePath = FilePath.Get(propertyConfiguration, fileHolder, index: null);
+ bool? fileSizeChanged = property is not null ? property.FileSize != filePath.Length : null;
+ bool isValidImageFormatExtension = propertyConfiguration.ValidImageFormatExtensions.Contains(filePath.ExtensionLowered);
+ bool? shouldIgnore = property is null || property.Keywords is null ? null : propertyConfiguration.IgnoreRulesKeyWords.Any(l => property.Keywords.Contains(l));
+ bool? isArchive = filePath.Id is null || splatNineIdentifiers is null ? null : splatNineIdentifiers.TryGetValue(filePath.Id.Value, out Identifier? identifier);
+ if (property is not null && filePath.Id is not null && filePath.HasIgnoreKeyword is not null && filePath.HasDateTimeOriginal is not null)
+ {
+ char? change;
+ ReadOnlyCollection? filePaths = null;
+ char hasIgnoreKeyword = IId.GetHasIgnoreKeyword(filePath).ToString()[0];
+ char hasDateTimeOriginal = IId.GetHasDateTimeOriginal(filePath).ToString()[0];
+ char missingDateTimeOriginal = IId.GetMissingDateTimeOriginal(filePath).ToString()[0];
+ if (shouldIgnore is not null && shouldIgnore.Value)
+ {
+ if (filePath.NameWithoutExtension[^1] == hasIgnoreKeyword)
+ change = null;
+ else
+ {
+ change = hasIgnoreKeyword;
+ if (keyValuePairs is null || !keyValuePairs.TryGetValue(filePath.Id.Value, out filePaths) || filePaths is null)
+ throw new NotSupportedException($"Rename File! <{filePath.FileNameFirstSegment}>");
+ }
+ }
+ else if ((shouldIgnore is null || !shouldIgnore.Value) && property.DateTimeOriginal is null)
+ {
+ if (filePath.NameWithoutExtension[^1] == missingDateTimeOriginal)
+ change = null;
+ else
+ {
+ change = missingDateTimeOriginal;
+ if (keyValuePairs is null || !keyValuePairs.TryGetValue(filePath.Id.Value, out filePaths) || filePaths is null)
+ throw new NotSupportedException($"Rename File! <{filePath.FileNameFirstSegment}>");
+ }
+ }
+ else if (filePath.NameWithoutExtension[^1] != hasDateTimeOriginal)
+ {
+ change = hasDateTimeOriginal;
+ if (keyValuePairs is null || !keyValuePairs.TryGetValue(filePath.Id.Value, out filePaths) || filePaths is null)
+ throw new NotSupportedException($"Rename File! <{filePath.FileNameFirstSegment}>");
+ }
+ else
+ change = null;
+ if (filePaths is not null && change is not null)
+ RenameFile(extension, filePair, filePath, change.Value, filePaths);
+ }
+ string relativePath = Shared.Models.Stateless.Methods.IPath.GetRelativePath(filePair.Path, rootDirectoryLength, forceExtensionToLower: true);
+ bool? lastWriteTimeChanged = property is not null ? propertyConfiguration.PropertiesChangedForProperty || property.LastWriteTime.Ticks != filePath.LastWriteTicks : null;
+ if (filePair.Match is not null)
+ sourceDirectoryFileHolder = IFileHolder.Get(filePair.Match);
+ else if (!filePair.IsUnique)
+ sourceDirectoryFileHolder = IFileHolder.Get(Path.GetFullPath(string.Concat(jsonGroupDirectory, relativePath, extension)));
+ else
+ {
+ string fileName = Path.GetFileName(filePair.Path);
+ CombinedEnumAndIndex cei = Shared.Models.Stateless.Methods.IPath.GetCombinedEnumAndIndex(propertyConfiguration, filePath);
+ string directory = Path.Combine(jsonGroupDirectory, cei.Combined);
+ string jsonFileName = $"{fileName}{extension}";
+ string fullFileName = Path.Combine(directory, jsonFileName);
+ MoveIf(jsonFileName, cei, directory, fullFileName);
+ sourceDirectoryFileHolder = IFileHolder.Get(fullFileName);
+ }
+ if (sourceDirectoryFileHolder.CreationTime is not null && sourceDirectoryFileHolder.LastWriteTime is not null && filePath.LastWriteTicks != sourceDirectoryFileHolder.CreationTime.Value.Ticks)
+ {
+ File.SetCreationTime(sourceDirectoryFileHolder.FullName, new(filePath.LastWriteTicks));
+ File.SetLastWriteTime(sourceDirectoryFileHolder.FullName, sourceDirectoryFileHolder.LastWriteTime.Value);
+ }
+ Item item = Item.Get(filePath, sourceDirectoryFileHolder, relativePath, isArchive, filePair.IsNotUniqueAndNeedsReview, filePair.IsUnique, isValidImageFormatExtension, property, abandoned, fileSizeChanged, lastWriteTimeChanged);
+ lock (results)
+ results.Add(new(filePair.IsUnique, filePair.Collection, filePath, item));
+ }
+
+ private static List GetFilePairs(IDlibDotNet dlibDotNet, IPropertyConfiguration propertyConfiguration, string aPropertySingletonDirectory, string filesCollectionDirectory, ReadOnlyDictionary>? keyValuePairs, ReadOnlyDictionary? splatNineIdentifiers, ReadOnlyCollection> filePathsCollection, string directorySearchFilter)
+ {
+ List results = [];
+ const string extension = ".json";
+ List filePairs;
+ string jsonGroupDirectory = aPropertySingletonDirectory;
+ int maxDegreeOfParallelism = Environment.ProcessorCount;
+ int filesCollectionDirectoryLength = filesCollectionDirectory.Length;
+ ParallelOptions parallelOptions = new() { MaxDegreeOfParallelism = maxDegreeOfParallelism };
+ IReadOnlyDictionary> fileNamesToFiles = GetFilesKeyValuePairs(filePathsCollection);
+ filePairs = GetFilePairs(propertyConfiguration, directorySearchFilter, extension, jsonGroupDirectory, filePathsCollection, fileNamesToFiles);
+ _ = Parallel.For(0, filePairs.Count, parallelOptions, (i, state) =>
+ ParallelFor(dlibDotNet, propertyConfiguration, jsonGroupDirectory, extension, keyValuePairs, splatNineIdentifiers, filesCollectionDirectoryLength, filePairs[i], results));
+ return results;
+ }
+
+ private static (int, Models.Container[]) GetContainers(IDlibDotNet dlibDotNet, IPropertyConfiguration propertyConfiguration, string filesCollectionDirectory, ReadOnlyDictionary>? keyValuePairs, ReadOnlyDictionary? splatNineIdentifiers, ReadOnlyCollection> filePathsCollection, string directorySearchFilter)
+ {
+ List results = [];
+ string directory;
+ List
- ? items;
+ Models.Container container;
+ List directories = [];
+ Dictionary> directoryToItems = [];
+ foreach (ReadOnlyCollection filePaths in filePathsCollection)
+ {
+ if (filePaths.Count == 0)
+ continue;
+ directory = filePaths[0].DirectoryFullPath;
+ if (directory is null)
+ continue;
+ if (!directories.Contains(directory))
+ directories.Add(directory);
+ if (!directoryToItems.TryGetValue(directory, out items))
+ {
+ directoryToItems.Add(directory, []);
+ if (!directoryToItems.TryGetValue(directory, out items))
+ throw new Exception();
+ }
+ }
+ (string aResultsFullGroupDirectory, _) = dlibDotNet.GetResultsFullGroupDirectories();
+ string aPropertySingletonDirectory = Path.Combine(aResultsFullGroupDirectory, propertyConfiguration.ResultSingleton);
+ if (!Directory.Exists(aPropertySingletonDirectory))
+ _ = Directory.CreateDirectory(aPropertySingletonDirectory);
+ List filePairs = GetFilePairs(dlibDotNet, propertyConfiguration, aPropertySingletonDirectory, filesCollectionDirectory, keyValuePairs, splatNineIdentifiers, filePathsCollection, directorySearchFilter);
+ foreach (FilePair filePair in filePairs)
+ {
+ if (!directoryToItems.TryGetValue(filePair.FilePath.DirectoryFullPath, out items))
+ {
+ directoryToItems.Add(filePair.FilePath.DirectoryFullPath, []);
+ if (!directoryToItems.TryGetValue(filePair.FilePath.DirectoryFullPath, out items))
+ throw new Exception();
+ }
+ items.Add(filePair.Item);
+ }
+ foreach (KeyValuePair> keyValuePair in directoryToItems)
+ {
+ if (keyValuePair.Value.Count == 0)
+ continue;
+ container = new(keyValuePair.Key, new(keyValuePair.Value));
+ results.Add(container);
+ }
+ return (filePairs.Count, results.ToArray());
+ }
+
+ private static void AnyMovedFace(IReadOnlyDictionary> fileNamesToFiles, List directories)
+ {
+ bool result = false;
+ string checkFile;
+ string subDirectory;
+ string directoryName;
+ string checkDirectory;
+ List? collection;
+ string directoryNameWith;
+ string directoryNameMinusOne;
+ List directoryNames = [];
+ foreach (string directory in directories)
+ {
+ directoryNameMinusOne = Path.GetFileName(directory)[..^1];
+ if (!fileNamesToFiles.TryGetValue(directoryNameMinusOne, out collection))
+ throw new Exception();
+ directoryNames.Clear();
+ foreach (string f in collection)
+ directoryNames.Add(Path.GetFileName(Path.GetDirectoryName(f)) ?? throw new Exception());
+ if (directoryNames.Count == 0 || directoryNames.Distinct().Count() != 1)
+ continue;
+ directoryName = Path.GetFileName(Path.GetDirectoryName(directory)) ?? throw new Exception();
+ if (directoryName != directoryNames[0])
+ {
+ subDirectory = Path.GetDirectoryName(Path.GetDirectoryName(directory)) ?? throw new Exception();
+ checkDirectory = Path.Combine(subDirectory, directoryNames[0]);
+ if (!Directory.Exists(checkDirectory))
+ _ = Directory.CreateDirectory(checkDirectory);
+ directoryNameWith = collection.Count > 1 ? directoryName : $"{Path.GetFileNameWithoutExtension(collection[0])}";
+ checkFile = Path.Combine(checkDirectory, directoryNameWith);
+ if (!result)
+ result = true;
+ if (!Directory.Exists(checkFile))
+ Directory.Move(directory, checkFile);
+ else
+ {
+ if (new DirectoryInfo(directory).LastWriteTime > new DirectoryInfo(checkFile).LastWriteTime)
+ Directory.Delete(directory, recursive: true);
+ else
+ {
+ Directory.Delete(checkFile, recursive: true);
+ Directory.Move(directory, checkFile);
+ }
+ }
+ }
+ }
+ }
+
+ private static void AnyMovedFace(string extension, string hiddenExtension, IReadOnlyDictionary> fileNamesToFiles, string jsonGroupDirectory)
+ {
+ string directory;
+ string checkFile;
+ string directoryName;
+ List files = [];
+ string[] fileNameSegments;
+ List directories = [];
+ files.AddRange(Directory.GetFiles(jsonGroupDirectory, $"*{extension}", SearchOption.AllDirectories));
+ files.AddRange(Directory.GetFiles(jsonGroupDirectory, $"*{hiddenExtension}", SearchOption.AllDirectories));
+ foreach (string file in files)
+ {
+ directory = Path.GetDirectoryName(file) ?? throw new Exception();
+ if (!directories.Contains(directory))
+ directories.Add(directory);
+ directoryName = Path.GetFileName(directory);
+ fileNameSegments = Path.GetFileName(file).Split('.');
+ if (fileNameSegments[0] != directoryName)
+ {
+ fileNameSegments[0] = string.Empty;
+ checkFile = Path.Combine(directory, $"{directoryName}{string.Join('.', fileNameSegments)}");
+ if (!File.Exists(checkFile))
+ File.Move(file, checkFile);
+ else
+ {
+ if (new FileInfo(file).LastWriteTime > new FileInfo(checkFile).LastWriteTime)
+ File.Delete(file);
+ else
+ File.Move(file, checkFile, true);
+ }
+ }
+ }
+ if (directories.Count > 0)
+ AnyMovedFace(fileNamesToFiles, directories);
+ }
+
+ private static void AnyMovedDistance(string extension, IReadOnlyDictionary> fileNamesToFiles, string jsonGroupDirectory)
+ {
+ bool result = false;
+ string fileName;
+ string checkFile;
+ string directory;
+ List? collection;
+ string[] fileNameSegments;
+ List fileNames = [];
+ string fileNameSegmentsZeroMinusOne;
+ string[] files = Directory.GetFiles(jsonGroupDirectory, $"*{extension}", SearchOption.AllDirectories);
+ foreach (string file in files)
+ {
+ fileName = Path.GetFileName(file);
+ fileNameSegments = fileName.Split('.');
+ fileNameSegmentsZeroMinusOne = fileNameSegments[0][..^1];
+ if (!fileNamesToFiles.TryGetValue(fileNameSegmentsZeroMinusOne, out collection))
+ continue;
+ fileNames.Clear();
+ foreach (string f in collection)
+ fileNames.Add(Path.GetFileNameWithoutExtension(f) ?? throw new Exception());
+ if (fileNames.Count == 0 || fileNames.Distinct().Count() != 1)
+ continue;
+ if (fileNameSegments[0] != fileNames[0])
+ {
+ fileNameSegments[0] = string.Empty;
+ directory = Path.GetDirectoryName(file) ?? throw new Exception();
+ checkFile = Path.Combine(directory, $"{fileNames[0]}{string.Join('.', fileNameSegments)}");
+ if (!result)
+ result = true;
+ if (!File.Exists(checkFile))
+ File.Move(file, checkFile);
+ else
+ {
+ if (new FileInfo(file).LastWriteTime > new FileInfo(checkFile).LastWriteTime)
+ File.Delete(file);
+ else
+ File.Move(file, checkFile, true);
+ }
+ }
+ }
+ }
+
+ private static void DoGetFilePairsForRemaining(IDlibDotNet dlibDotNet, IPropertyConfiguration propertyConfiguration, string facesFileNameExtension, string facesHiddenFileNameExtension, string eDistanceContentDirectory, ReadOnlyCollection> filePathsCollection, string directorySearchFilter)
+ {
+ const string extension = ".json";
+ (_, string bResultsFullGroupDirectory) = dlibDotNet.GetResultsFullGroupDirectories();
+ IReadOnlyDictionary> fileNamesToFiles = GetFilesKeyValuePairs(filePathsCollection);
+ string bMetaSingletonDirectory = Path.Combine(bResultsFullGroupDirectory, propertyConfiguration.ResultSingleton);
+ if (!Directory.Exists(bMetaSingletonDirectory))
+ _ = Directory.CreateDirectory(bMetaSingletonDirectory);
+ _ = GetFilePairs(propertyConfiguration, directorySearchFilter, extension, bMetaSingletonDirectory, filePathsCollection, fileNamesToFiles);
+ (string cResultsFullGroupDirectory, _, string dResultsFullGroupDirectory, _) = dlibDotNet.GetResultsFullGroupDirectories("Original");
+ string cResizeSingletonDirectory = Path.Combine(cResultsFullGroupDirectory, propertyConfiguration.ResultSingleton);
+ if (!Directory.Exists(cResizeSingletonDirectory))
+ _ = Directory.CreateDirectory(cResizeSingletonDirectory);
+ _ = GetFilePairs(propertyConfiguration, directorySearchFilter, extension, cResizeSingletonDirectory, filePathsCollection, fileNamesToFiles);
+ string dFaceCollectionDirectory = Path.Combine(dResultsFullGroupDirectory, propertyConfiguration.ResultCollection);
+ if (!Directory.Exists(dFaceCollectionDirectory))
+ _ = Directory.CreateDirectory(dFaceCollectionDirectory);
+ _ = GetFilePairs(propertyConfiguration, directorySearchFilter, extension, dFaceCollectionDirectory, filePathsCollection, fileNamesToFiles);
+ string dFaceContentDirectory = Path.Combine(dResultsFullGroupDirectory, propertyConfiguration.ResultContent);
+ if (!Directory.Exists(dFaceContentDirectory))
+ _ = Directory.CreateDirectory(dFaceContentDirectory);
+ AnyMovedFace(facesFileNameExtension, facesHiddenFileNameExtension, fileNamesToFiles, dFaceContentDirectory);
+ AnyMovedDistance(facesFileNameExtension, fileNamesToFiles, eDistanceContentDirectory);
+ }
+
+ internal static ReadOnlyCollection GetContainers(IDlibDotNet dlibDotNet, IPropertyConfiguration propertyConfiguration, string facesFileNameExtension, string facesHiddenFileNameExtension, string eDistanceContentDirectory, string filesCollectionDirectory, ReadOnlyDictionary>? keyValuePairs, ReadOnlyDictionary? splatNineIdentifiers, ReadOnlyCollection> filePathsCollection)
+ {
+ Models.Container[] results;
+ const string directorySearchFilter = "*";
+ (_, results) = GetContainers(dlibDotNet, propertyConfiguration, filesCollectionDirectory, keyValuePairs, splatNineIdentifiers, filePathsCollection, directorySearchFilter);
+ if (keyValuePairs is not null)
+ DoGetFilePairsForRemaining(dlibDotNet, propertyConfiguration, facesFileNameExtension, facesHiddenFileNameExtension, eDistanceContentDirectory, filePathsCollection, directorySearchFilter);
+ return results.AsReadOnly();
+ }
+
+ private static IDlibDotNet GetDlibDotNet() =>
+ throw new NotImplementedException();
+
+ internal static (int, Models.Container[]) GetContainers(IPropertyConfiguration propertyConfiguration, ReadOnlyDictionary? splatNineIdentifiers, string _)
+ {
+ int count;
+ Models.Container[] results;
+ const bool useCeilingAverage = true;
+ const string fileSearchFilter = "*";
+ IDlibDotNet dlibDotNet = GetDlibDotNet();
+ const string directorySearchFilter = "*";
+ ReadOnlyDictionary>? keyValuePairs = null;
+ ReadOnlyCollection filesCollection = IDirectory.GetFilesCollection(propertyConfiguration.RootDirectory, directorySearchFilter, fileSearchFilter, useCeilingAverage);
+ ReadOnlyCollection> filePathsCollection = IDirectory.GetFilePathCollections(propertyConfiguration, filesCollection);
+ (count, results) = GetContainers(dlibDotNet, propertyConfiguration, propertyConfiguration.RootDirectory, keyValuePairs, splatNineIdentifiers, filePathsCollection, directorySearchFilter);
+ return (count, results);
+ }
+
+ internal static List GetFilteredDistinctIds(IPropertyConfiguration propertyConfiguration, ReadOnlyCollection readOnlyContainers)
+ {
+ List results = [];
+ ReadOnlyCollection
- filteredItems;
+ foreach (Models.Container container in readOnlyContainers)
+ {
+ if (container.Items.Count == 0)
+ continue;
+ filteredItems = GetValidImageItems(propertyConfiguration, container);
+ if (filteredItems.Count == 0)
+ continue;
+ foreach (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;
+ }
+
+ internal static List GetFilteredDistinctFileNameFirstSegments(IPropertyConfiguration propertyConfiguration, ReadOnlyCollection readOnlyContainers)
+ {
+ List results = [];
+ ReadOnlyCollection
- filteredItems;
+ foreach (Models.Container container in readOnlyContainers)
+ {
+ if (container.Items.Count == 0)
+ continue;
+ filteredItems = GetValidImageItems(propertyConfiguration, container);
+ if (filteredItems.Count == 0)
+ continue;
+ foreach (Item item in filteredItems)
+ {
+ if (item.Property?.Id is null || item.ResizedFileHolder is null)
+ continue;
+ if (results.Contains(item.FilePath.FileNameFirstSegment))
+ continue;
+ results.Add(item.FilePath.FileNameFirstSegment);
+ }
+ }
+ return results;
+ }
+
+ internal static ReadOnlyCollection
- GetValidImageItems(IPropertyConfiguration propertyConfiguration, ReadOnlyCollection containers, bool distinctItems, bool filterItems)
+ {
+ List
- results = [];
+ List distinct = [];
+ ReadOnlyCollection
- filteredItems;
+ foreach (Models.Container container in containers)
+ {
+ if (container.Items.Count == 0)
+ continue;
+ if (!filterItems)
+ filteredItems = container.Items;
+ else
+ {
+ filteredItems = GetValidImageItems(propertyConfiguration, container);
+ if (filteredItems.Count == 0)
+ continue;
+ }
+ foreach (Item item in filteredItems)
+ {
+ if (item.Property?.Id is null || item.ResizedFileHolder is null)
+ continue;
+ if (distinctItems)
+ {
+ if (distinct.Contains(item.Property.Id.Value))
+ continue;
+ distinct.Add(item.Property.Id.Value);
+ }
+ results.Add(item);
+ }
+ }
+ return results.AsReadOnly();
+ }
+
+}
\ No newline at end of file
diff --git a/Container/Models/Stateless/Methods/IContainer.cs b/Container/Models/Stateless/Methods/IContainer.cs
new file mode 100644
index 0000000..a877a0f
--- /dev/null
+++ b/Container/Models/Stateless/Methods/IContainer.cs
@@ -0,0 +1,51 @@
+using System.Collections.ObjectModel;
+using View_by_Distance.Shared.Models;
+using View_by_Distance.Shared.Models.Properties;
+using View_by_Distance.Shared.Models.Stateless.Methods;
+
+namespace View_by_Distance.Container.Models.Stateless.Methods;
+
+public interface IContainer
+{
+
+ DateTime[] TestStatic_GetContainerDateTimes(ReadOnlyCollection
- items) =>
+ GetContainerDateTimes(items);
+ static DateTime[] GetContainerDateTimes(ReadOnlyCollection
- items) =>
+ Container.GetContainerDateTimes(items);
+
+ ReadOnlyCollection
- TestStatic_GetValidImageItems(IPropertyConfiguration propertyConfiguration, Models.Container container) =>
+ GetValidImageItems(propertyConfiguration, container);
+ static ReadOnlyCollection
- GetValidImageItems(IPropertyConfiguration propertyConfiguration, Models.Container container) =>
+ Container.GetValidImageItems(propertyConfiguration, container);
+
+ (int, Models.Container[]) TestStatic_GetContainers(IPropertyConfiguration propertyConfiguration, string aPropertySingletonDirectory) =>
+ GetContainers(propertyConfiguration, aPropertySingletonDirectory);
+ static (int, Models.Container[]) GetContainers(IPropertyConfiguration propertyConfiguration, string aPropertySingletonDirectory) =>
+ GetContainers(propertyConfiguration, null, aPropertySingletonDirectory);
+
+ (int, Models.Container[]) TestStatic_GetContainers(IPropertyConfiguration propertyConfiguration, ReadOnlyDictionary? splatNineIdentifiers, string aPropertySingletonDirectory) =>
+ GetContainers(propertyConfiguration, splatNineIdentifiers, aPropertySingletonDirectory);
+ static (int, Models.Container[]) GetContainers(IPropertyConfiguration propertyConfiguration, ReadOnlyDictionary? splatNineIdentifiers, string aPropertySingletonDirectory) =>
+ Container.GetContainers(propertyConfiguration, splatNineIdentifiers, aPropertySingletonDirectory);
+
+ ReadOnlyCollection TestStatic_GetContainers(IDlibDotNet dlibDotNet, IPropertyConfiguration propertyConfiguration, string facesFileNameExtension, string facesHiddenFileNameExtension, string eDistanceContentDirectory, string filesCollectionDirectory, ReadOnlyDictionary>? keyValuePairs, ReadOnlyDictionary? splatNineIdentifiers, ReadOnlyCollection> filePathsCollection) =>
+ GetContainers(dlibDotNet, propertyConfiguration, facesFileNameExtension, facesHiddenFileNameExtension, eDistanceContentDirectory, filesCollectionDirectory, keyValuePairs, splatNineIdentifiers, filePathsCollection);
+ static ReadOnlyCollection GetContainers(IDlibDotNet dlibDotNet, IPropertyConfiguration propertyConfiguration, string facesFileNameExtension, string facesHiddenFileNameExtension, string eDistanceContentDirectory, string filesCollectionDirectory, ReadOnlyDictionary>? keyValuePairs, ReadOnlyDictionary? splatNineIdentifiers, ReadOnlyCollection> filePathsCollection) =>
+ Container.GetContainers(dlibDotNet, propertyConfiguration, facesFileNameExtension, facesHiddenFileNameExtension, eDistanceContentDirectory, filesCollectionDirectory, keyValuePairs, splatNineIdentifiers, filePathsCollection);
+
+ List TestStatic_GetFilteredDistinctIds(IPropertyConfiguration propertyConfiguration, ReadOnlyCollection readOnlyContainers) =>
+ GetFilteredDistinctIds(propertyConfiguration, readOnlyContainers);
+ static List GetFilteredDistinctIds(IPropertyConfiguration propertyConfiguration, ReadOnlyCollection readOnlyContainers) =>
+ Container.GetFilteredDistinctIds(propertyConfiguration, readOnlyContainers);
+
+ List TestStatic_GetFilteredDistinctFileNameFirstSegments(IPropertyConfiguration propertyConfiguration, ReadOnlyCollection readOnlyContainers) =>
+ GetFilteredDistinctFileNameFirstSegments(propertyConfiguration, readOnlyContainers);
+ static List GetFilteredDistinctFileNameFirstSegments(IPropertyConfiguration propertyConfiguration, ReadOnlyCollection readOnlyContainers) =>
+ Container.GetFilteredDistinctFileNameFirstSegments(propertyConfiguration, readOnlyContainers);
+
+ ReadOnlyCollection
- TestStatic_GetValidImageItems(IPropertyConfiguration propertyConfiguration, ReadOnlyCollection containers, bool distinctItems, bool filterItems) =>
+ GetValidImageItems(propertyConfiguration, containers, distinctItems, filterItems);
+ static ReadOnlyCollection
- GetValidImageItems(IPropertyConfiguration propertyConfiguration, ReadOnlyCollection containers, bool distinctItems, bool filterItems) =>
+ Container.GetValidImageItems(propertyConfiguration, containers, distinctItems, filterItems);
+
+}
\ No newline at end of file
diff --git a/Date-Group/DateGroup.cs b/Date-Group/DateGroup.cs
index 699b44f..3075263 100644
--- a/Date-Group/DateGroup.cs
+++ b/Date-Group/DateGroup.cs
@@ -57,11 +57,11 @@ public class DateGroup
string aPropertySingletonDirectory = Path.Combine(aResultsFullGroupDirectory, "{}");
if (!Directory.Exists(aPropertySingletonDirectory))
_ = Directory.CreateDirectory(aPropertySingletonDirectory);
- (int t, Container[] containers) = Shared.Models.Stateless.Methods.IContainer.GetContainers(propertyConfiguration, aPropertySingletonDirectory);
+ (int t, Container.Models.Container[] containers) = Container.Models.Stateless.Methods.IContainer.GetContainers(propertyConfiguration, aPropertySingletonDirectory);
A_Property propertyLogic = GetPropertyLogic(reverse, aResultsFullGroupDirectory, aResultsFullGroupDirectory);
if (propertyLogic.ExceptionsDirectories.Count != 0)
throw new Exception();
- if (propertyConfiguration.PopulatePropertyId && (configuration.ByCreateDateShortcut || configuration.ByHash) && Shared.Models.Stateless.Methods.IProperty.Any(containers))
+ if (propertyConfiguration.PopulatePropertyId && (configuration.ByCreateDateShortcut || configuration.ByHash) && Property.Models.Stateless.IProperty.Any(containers))
{
propertyLogic.SavePropertyParallelWork(ticks, metadata, t, containers);
if (propertyLogic.ExceptionsDirectories.Count != 0)
@@ -302,7 +302,7 @@ public class DateGroup
return result;
}
- private static Item[] GetFilterItems(Container container)
+ private static Item[] GetFilterItems(Container.Models.Container container)
{
List
- results = [];
foreach (Item item in container.Items)
@@ -313,7 +313,7 @@ public class DateGroup
return results.ToArray();
}
- private (Item Item, long LastWriteTimeTicks, long MinimumDateTimeTicks, string[] Destination)[] GetFileMoveCollectionAll(Property.Models.Configuration configuration, string destinationRoot, Container[] containers)
+ private (Item Item, long LastWriteTimeTicks, long MinimumDateTimeTicks, string[] Destination)[] GetFileMoveCollectionAll(Property.Models.Configuration configuration, string destinationRoot, Container.Models.Container[] containers)
{
(Item Item, long LastWriteTimeTicks, long MinimumDateTimeTicks, string[] Destination)[] results;
Item[] filteredItems;
@@ -322,7 +322,7 @@ public class DateGroup
string destinationDirectory;
List<(Item Item, long LastWriteTimeTicks, long MinimumDateTimeTicks, string[] Destination)> fileMoveCollection = [];
List<(Item Item, long LastWriteTimeTicks, long MinimumDateTimeTicks, string[] Destination)> fileMoveCollectionDirectory;
- foreach (Container container in containers)
+ foreach (Container.Models.Container container in containers)
{
if (container.Items.Count == 0)
continue;
@@ -352,7 +352,7 @@ public class DateGroup
return results;
}
- private void MoveFiles(Property.Models.Configuration configuration, string destinationRoot, Container[] containers)
+ private void MoveFiles(Property.Models.Configuration configuration, string destinationRoot, Container.Models.Container[] containers)
{
string checkDirectory;
bool hasDuplicate;
@@ -453,7 +453,7 @@ public class DateGroup
_ = Shared.Models.Stateless.Methods.IPath.DeleteEmptyDirectories(configuration.RootDirectory);
}
- private static void CreateDateShortcut(Property.Models.Configuration configuration, Container[] containers)
+ private static void CreateDateShortcut(Property.Models.Configuration configuration, Container.Models.Container[] containers)
{
string path;
string fileName;
@@ -468,17 +468,17 @@ public class DateGroup
WindowsShortcut windowsShortcut;
TimeSpan threeStandardDeviationHigh;
string aPropertyContentDirectory = Property.Models.Stateless.IResult.GetResultsDateGroupDirectory(configuration, nameof(A_Property), "()");
- foreach (Container container in containers)
+ foreach (Container.Models.Container container in containers)
{
if (container.Items.Count == 0)
continue;
selectedTotal = 0;
- threeStandardDeviationHigh = Shared.Models.Stateless.Methods.IProperty.GetThreeStandardDeviationHigh(minimum, container);
+ threeStandardDeviationHigh = Property.Models.Stateless.IProperty.GetThreeStandardDeviationHigh(minimum, container);
if (threeStandardDeviationHigh.TotalHours > maximumHours)
threeStandardDeviationHigh = new(maximumHours, 0, 0);
for (int i = 0; i < container.Items.Count; i++)
{
- (i, dateTimes, selectedItems) = Shared.Models.Stateless.Methods.IProperty.Get(container, threeStandardDeviationHigh, i);
+ (i, dateTimes, selectedItems) = Property.Models.Stateless.IProperty.Get(container, threeStandardDeviationHigh, i);
selectedTotal += selectedItems.Count;
foreach (Item item in selectedItems)
{
diff --git a/Drag-Drop-Search/Drag-Drop-Search.csproj b/Drag-Drop-Search/Drag-Drop-Search.csproj
index 4a00c5c..0ff8c20 100644
--- a/Drag-Drop-Search/Drag-Drop-Search.csproj
+++ b/Drag-Drop-Search/Drag-Drop-Search.csproj
@@ -34,6 +34,7 @@
+
diff --git a/Drag-Drop-Search/DragDropSearch.cs b/Drag-Drop-Search/DragDropSearch.cs
index 4afe950..1811159 100644
--- a/Drag-Drop-Search/DragDropSearch.cs
+++ b/Drag-Drop-Search/DragDropSearch.cs
@@ -107,9 +107,9 @@ public partial class DragDropSearch : Form
private void LoadData()
{
- Container[] containers;
+ Container.Models.Container[] containers;
string aPropertySingletonDirectory = Property.Models.Stateless.IResult.GetResultsDateGroupDirectory(_Configuration.PropertyConfiguration, nameof(A_Property), "{}");
- (_, containers) = IContainer.GetContainers(_Configuration.PropertyConfiguration, aPropertySingletonDirectory);
+ (_, containers) = View_by_Distance.Container.Models.Stateless.Methods.IContainer.GetContainers(_Configuration.PropertyConfiguration, aPropertySingletonDirectory);
List
- collection = Program.GetItemCollection(_Configuration, containers);
foreach (Item item in collection)
{
diff --git a/Drag-Drop-Search/Program.cs b/Drag-Drop-Search/Program.cs
index eaf86ac..cda8153 100644
--- a/Drag-Drop-Search/Program.cs
+++ b/Drag-Drop-Search/Program.cs
@@ -12,7 +12,7 @@ public class Program
// ApplicationConfiguration.Initialize();
Application.Run(new DragDropSearch());
- private static Item[] GetFilterItems(Models.Configuration configuration, Container container)
+ private static Item[] GetFilterItems(Models.Configuration configuration, Container.Models.Container container)
{
List
- results = [];
foreach (Item item in container.Items)
@@ -24,11 +24,11 @@ public class Program
return results.ToArray();
}
- public static List
- GetItemCollection(Models.Configuration configuration, Container[] containers)
+ public static List
- GetItemCollection(Models.Configuration configuration, Container.Models.Container[] containers)
{
List
- results = [];
Item[] filteredItems;
- foreach (Container container in containers)
+ foreach (Container.Models.Container container in containers)
{
if (container.Items.Count == 0)
continue;
diff --git a/Duplicate-Search/DuplicateSearch.cs b/Duplicate-Search/DuplicateSearch.cs
index 2ac2c2f..82e1694 100644
--- a/Duplicate-Search/DuplicateSearch.cs
+++ b/Duplicate-Search/DuplicateSearch.cs
@@ -30,7 +30,7 @@ public class DuplicateSearch
else
{
Configuration.Verify(configuration, requireExist: false);
- Container[] containers = GetContainers(ticks, configuration);
+ Container.Models.Container[] containers = GetContainers(ticks, configuration);
string argZero = args.Count > 0 ? Path.GetFullPath(args[0]) : Path.GetFullPath(configuration.RootDirectory);
bool argZeroIsConfigurationRootDirectory = configuration.RootDirectory == argZero;
string destinationRoot = Property.Models.Stateless.IResult.GetResultsGroupDirectory(configuration, "Z) Moved");
@@ -125,10 +125,10 @@ public class DuplicateSearch
}
}
- private static Container[] GetContainers(long ticks, Configuration configuration)
+ private static Container.Models.Container[] GetContainers(long ticks, Configuration configuration)
{
int f;
- Container[] containers;
+ Container.Models.Container[] containers;
int totalSeconds = (int)Math.Floor(new TimeSpan(DateTime.Now.Ticks - ticks).TotalSeconds);
string message = $") Building Container(s) - {totalSeconds} total second(s)";
ProgressBarOptions options = new() { ProgressCharacter = '─', ProgressBarOnBottom = true, DisableBottomPercentage = true };
@@ -136,12 +136,12 @@ public class DuplicateSearch
{
progressBar.Tick();
string aPropertySingletonDirectory = Property.Models.Stateless.IResult.GetResultsDateGroupDirectory(configuration, nameof(A_Property), "{}");
- (f, containers) = Shared.Models.Stateless.Methods.IContainer.GetContainers(configuration, aPropertySingletonDirectory);
+ (f, containers) = Container.Models.Stateless.Methods.IContainer.GetContainers(configuration, aPropertySingletonDirectory);
}
return containers;
}
- private static Dictionary> GetIdToCollection(string argZero, Configuration configuration, bool argZeroIsConfigurationRootDirectory, Container[] containers, string destinationRoot, List preloadIds)
+ private static Dictionary> GetIdToCollection(string argZero, Configuration configuration, bool argZeroIsConfigurationRootDirectory, Container.Models.Container[] containers, string destinationRoot, List preloadIds)
{
Dictionary> results = [];
string directory;
@@ -157,16 +157,16 @@ public class DuplicateSearch
foreach (int id in preloadIds)
results.Add(id, [null]);
}
- foreach (Container container in containers)
+ foreach (Container.Models.Container container in containers)
{
if (container.Items.Count == 0)
continue;
if (!argZeroIsConfigurationRootDirectory && !container.SourceDirectory.StartsWith(argZero))
continue;
- validImageItems = Shared.Models.Stateless.Methods.IContainer.GetValidImageItems(configuration, container);
+ validImageItems = Container.Models.Stateless.Methods.IContainer.GetValidImageItems(configuration, container);
if (validImageItems.Count == 0)
continue;
- containerDateTimes = Shared.Models.Stateless.Methods.IContainer.GetContainerDateTimes(validImageItems);
+ containerDateTimes = Container.Models.Stateless.Methods.IContainer.GetContainerDateTimes(validImageItems);
foreach (Item item in validImageItems)
{
if (item.Property?.Id is null)
diff --git a/FaceParts/Models/_D2_FaceParts.cs b/FaceParts/Models/_D2_FaceParts.cs
index 3cff1a3..2164d5b 100644
--- a/FaceParts/Models/_D2_FaceParts.cs
+++ b/FaceParts/Models/_D2_FaceParts.cs
@@ -403,7 +403,7 @@ public class D2_FaceParts
}
}
- public void SaveFaceLandmarkImages(Configuration configuration, string d2ResultsFullGroupDirectory, FilePath filePath, List> subFileTuples, List parseExceptions, MappingFromItem mappingFromItem, ExifDirectory exifDirectory, List faces, bool saveRotated)
+ public void SaveFaceLandmarkImages(Property.Models.Configuration configuration, string d2ResultsFullGroupDirectory, FilePath filePath, List> subFileTuples, List parseExceptions, MappingFromItem mappingFromItem, ExifDirectory exifDirectory, List faces, bool saveRotated)
{
FileInfo fileInfo;
bool check = false;
diff --git a/Instance/DlibDotNet.cs b/Instance/DlibDotNet.cs
index dd5281f..9729cc4 100644
--- a/Instance/DlibDotNet.cs
+++ b/Instance/DlibDotNet.cs
@@ -300,6 +300,7 @@ public partial class DlibDotNet : IDlibDotNet, IDisposable
string message;
MapLogic? mapLogic;
A_Property propertyLogic;
+ IDlibDotNet dlibDotNet = this;
string eDistanceContentDirectory;
string? a2PeopleContentDirectory;
string aResultsFullGroupDirectory;
@@ -314,15 +315,17 @@ public partial class DlibDotNet : IDlibDotNet, IDisposable
bool configurationOutputResolutionsHas = false;
ReadOnlyDictionary> personKeyToIds;
ReadOnlyDictionary? splatNineIdentifiers = null;
+ ReadOnlyDictionary>? keyValuePairs = null;
ReadOnlyCollection>? filePathsCollection = null;
bool runToDoCollectionFirst = GetRunToDoCollectionFirst(_Configuration, ticks);
- (aResultsFullGroupDirectory, bResultsFullGroupDirectory) = GetResultsFullGroupDirectories();
+ (aResultsFullGroupDirectory, bResultsFullGroupDirectory) = dlibDotNet.GetResultsFullGroupDirectories();
ProgressBarOptions options = new() { ProgressCharacter = '─', ProgressBarOnBottom = true, DisableBottomPercentage = true };
Shared.Models.Stateless.Methods.IPath.ChangeDateForEmptyDirectories(_Configuration.PropertyConfiguration.RootDirectory, ticks);
a2PeopleContentDirectory = Property.Models.Stateless.IResult.GetResultsDateGroupDirectory(_Configuration.PropertyConfiguration, nameof(A2_People), "([])");
+ B_Metadata metadata = new(_Configuration.PropertyConfiguration, _Configuration.ForceMetadataLastWriteTimeToCreationTime, _Configuration.PropertiesChangedForMetadata, bResultsFullGroupDirectory);
eDistanceContentDirectory = Property.Models.Stateless.IResult.GetResultsDateGroupDirectory(_Configuration.PropertyConfiguration, nameof(E_Distance), _Configuration.PropertyConfiguration.ResultContent);
string a2PeopleSingletonDirectory = Property.Models.Stateless.IResult.GetResultsDateGroupDirectory(_Configuration.PropertyConfiguration, nameof(A2_People), _Configuration.PropertyConfiguration.ResultSingleton);
- _ = Directory.CreateDirectory(Path.Combine(eDistanceContentDirectory, $"{ticks}"));
+ _ = Directory.CreateDirectory(Path.Combine(eDistanceContentDirectory, ticks.ToString()));
if (runToDoCollectionFirst)
mapLogic = null;
else
@@ -335,7 +338,8 @@ public partial class DlibDotNet : IDlibDotNet, IDisposable
if (!runToDoCollectionFirst)
break;
(filesCollectionRootDirectory, filePathsCollection, filesCollectionCountIsOne) = GetFilesCollectionThenCopyOrMove(ticks, fileSearchFilter, directorySearchFilter, options, outputResolution);
- splatNineIdentifiers = GetSplatNineIdentifiersAndHideSplatNine(_Configuration.PropertyConfiguration, bResultsFullGroupDirectory, filePathsCollection);
+ keyValuePairs = FilePath.GetKeyValuePairs(filePathsCollection);
+ splatNineIdentifiers = GetSplatNineIdentifiersAndHideSplatNine(_Configuration.PropertyConfiguration, bResultsFullGroupDirectory, keyValuePairs);
break;
}
fPhotoPrismContentDirectory = Property.Models.Stateless.IResult.GetResultsDateGroupDirectory(_Configuration.PropertyConfiguration, nameof(F_PhotoPrism), _Configuration.PropertyConfiguration.ResultContent);
@@ -357,7 +361,7 @@ public partial class DlibDotNet : IDlibDotNet, IDisposable
}
argZero = SaveUrlAndGetNewRootDirectory(filePathsCollection.First());
_Configuration.PropertyConfiguration.ChangeRootDirectory(argZero);
- (aResultsFullGroupDirectory, bResultsFullGroupDirectory) = GetResultsFullGroupDirectories();
+ (aResultsFullGroupDirectory, bResultsFullGroupDirectory) = dlibDotNet.GetResultsFullGroupDirectories();
propertyRoot = Property.Models.Stateless.IResult.GetResultsGroupDirectory(_Configuration.PropertyConfiguration, nameof(A_Property), create: false);
propertyLogic = new(_AppSettings.MaxDegreeOfParallelism, _Configuration.PropertyConfiguration, _Resize.FileNameExtension, _Configuration.Reverse, aResultsFullGroupDirectory);
}
@@ -367,7 +371,7 @@ public partial class DlibDotNet : IDlibDotNet, IDisposable
{
if (outputResolution.Any(char.IsNumber))
continue;
- (cResultsFullGroupDirectory, _, _, _) = GetResultsFullGroupDirectories(outputResolution);
+ (cResultsFullGroupDirectory, _, _, _) = dlibDotNet.GetResultsFullGroupDirectories(outputResolution);
filesCollectionRootDirectory = Path.Combine(cResultsFullGroupDirectory, _Configuration.PropertyConfiguration.ResultContent);
filePathsCollection = IDirectory.GetFilePathCollections(_Configuration.PropertyConfiguration, directorySearchFilter, fileSearchFilter, filesCollectionRootDirectory, useCeilingAverage: true);
break;
@@ -375,20 +379,17 @@ public partial class DlibDotNet : IDlibDotNet, IDisposable
}
if (filesCollectionRootDirectory is null || filePathsCollection is null)
throw new NullReferenceException(nameof(filePathsCollection));
- string aPropertySingletonDirectory = Path.Combine(aResultsFullGroupDirectory, _Configuration.PropertyConfiguration.ResultSingleton);
- if (!Directory.Exists(aPropertySingletonDirectory))
- _ = Directory.CreateDirectory(aPropertySingletonDirectory);
int count = filePathsCollection.Select(l => l.Count).Sum();
message = $") Building Container(s) - {(int)Math.Floor(new TimeSpan(DateTime.Now.Ticks - ticks).TotalSeconds)} total second(s)";
_ProgressBar = new(count, message, options);
- ReadOnlyCollection readOnlyContainers = Shared.Models.Stateless.Methods.IContainer.GetContainers(this, _Configuration.PropertyConfiguration, aPropertySingletonDirectory, filesCollectionRootDirectory, splatNineIdentifiers, filePathsCollection);
+ ReadOnlyCollection readOnlyContainers = Container.Models.Stateless.Methods.IContainer.GetContainers(this, _Configuration.PropertyConfiguration, _Faces.FileNameExtension, _Faces.HiddenFileNameExtension, eDistanceContentDirectory, filesCollectionRootDirectory, keyValuePairs, splatNineIdentifiers, filePathsCollection);
_ProgressBar.Dispose();
mapLogic ??= new(_AppSettings.MaxDegreeOfParallelism, _Configuration.PropertyConfiguration, _MapConfiguration, _Distance, personContainers, ticks, a2PeopleContentDirectory, a2PeopleSingletonDirectory, eDistanceContentDirectory);
DeleteContinueFiles(personContainers);
if (!runToDoCollectionFirst)
MapFaceFileLogic(ticks, personContainers, mapLogic, a2PeopleContentDirectory, eDistanceContentDirectory, options);
- FullDoWork(argZero, propertyRoot, ticks, aResultsFullGroupDirectory, bResultsFullGroupDirectory, fPhotoPrismSingletonDirectory, count, readOnlyContainers, propertyLogic, mapLogic);
- ReadOnlyCollection
- distinctValidImageItems = Shared.Models.Stateless.Methods.IContainer.GetValidImageItems(_Configuration.PropertyConfiguration, readOnlyContainers, distinctItems: true, filterItems: true);
+ FullDoWork(argZero, propertyRoot, ticks, aResultsFullGroupDirectory, fPhotoPrismSingletonDirectory, count, metadata, readOnlyContainers, propertyLogic, mapLogic);
+ ReadOnlyCollection
- distinctValidImageItems = Container.Models.Stateless.Methods.IContainer.GetValidImageItems(_Configuration.PropertyConfiguration, readOnlyContainers, distinctItems: true, filterItems: true);
if (_Configuration.LookForAbandoned)
{
string dResultsFullGroupDirectory;
@@ -396,7 +397,7 @@ public partial class DlibDotNet : IDlibDotNet, IDisposable
foreach (string outputResolution in _Configuration.OutputResolutions)
{
_ProgressBar = new(5, nameof(mapLogic.LookForAbandoned), options);
- (cResultsFullGroupDirectory, _, dResultsFullGroupDirectory, d2ResultsFullGroupDirectory) = GetResultsFullGroupDirectories(outputResolution);
+ (cResultsFullGroupDirectory, _, dResultsFullGroupDirectory, d2ResultsFullGroupDirectory) = dlibDotNet.GetResultsFullGroupDirectories(outputResolution);
mapLogic.LookForAbandoned(this, _Configuration.PropertyConfiguration, bResultsFullGroupDirectory, readOnlyContainers, cResultsFullGroupDirectory, dResultsFullGroupDirectory, d2ResultsFullGroupDirectory);
_ProgressBar.Dispose();
}
@@ -437,7 +438,7 @@ public partial class DlibDotNet : IDlibDotNet, IDisposable
string dResultsFullGroupDirectory;
string c2ResultsFullGroupDirectory;
string d2ResultsFullGroupDirectory;
- (cResultsFullGroupDirectory, c2ResultsFullGroupDirectory, dResultsFullGroupDirectory, d2ResultsFullGroupDirectory) = GetResultsFullGroupDirectories(outputResolution);
+ (cResultsFullGroupDirectory, c2ResultsFullGroupDirectory, dResultsFullGroupDirectory, d2ResultsFullGroupDirectory) = dlibDotNet.GetResultsFullGroupDirectories(outputResolution);
_ = Shared.Models.Stateless.Methods.IPath.DeleteEmptyDirectories(Path.Combine(aResultsFullGroupDirectory, _Configuration.PropertyConfiguration.ResultSingleton));
_ = Shared.Models.Stateless.Methods.IPath.DeleteEmptyDirectories(Path.Combine(bResultsFullGroupDirectory, _Configuration.PropertyConfiguration.ResultSingleton));
_ = Shared.Models.Stateless.Methods.IPath.DeleteEmptyDirectories(Path.Combine(cResultsFullGroupDirectory, _Configuration.PropertyConfiguration.ResultSingleton));
@@ -549,33 +550,32 @@ public partial class DlibDotNet : IDlibDotNet, IDisposable
return result;
}
- private void FullDoWork(string argZero, string propertyRoot, long ticks, string aResultsFullGroupDirectory, string bResultsFullGroupDirectory, string fPhotoPrismSingletonDirectory, int count, ReadOnlyCollection readOnlyContainers, A_Property propertyLogic, MapLogic mapLogic)
+ private void FullDoWork(string argZero, string propertyRoot, long ticks, string aResultsFullGroupDirectory, string fPhotoPrismSingletonDirectory, int count, B_Metadata metadata, ReadOnlyCollection readOnlyContainers, A_Property propertyLogic, MapLogic mapLogic)
{
int total;
int notMapped;
string message;
bool exceptions;
int totalSeconds;
- Container container;
int totalNotMapped = 0;
+ IDlibDotNet dlibDotNet = this;
bool outputResolutionHasNumber;
bool anyNullOrNoIsUniqueFileName;
string cResultsFullGroupDirectory;
string dResultsFullGroupDirectory;
string c2ResultsFullGroupDirectory;
string d2ResultsFullGroupDirectory;
+ Container.Models.Container container;
ReadOnlyCollection
- filteredItems;
- int containersLength = readOnlyContainers.Count;
List> sourceDirectoryChanges = [];
int maxDegreeOfParallelism = _AppSettings.MaxDegreeOfParallelism;
Dictionary> fileNameToCollection = !Directory.Exists(fPhotoPrismSingletonDirectory) ? fileNameToCollection = [] : F_PhotoPrism.GetFileNameToCollection(fPhotoPrismSingletonDirectory);
string dResultsDateGroupDirectory = Property.Models.Stateless.IResult.GetResultsDateGroupDirectory(_Configuration.PropertyConfiguration, nameof(D_Face));
- B_Metadata metadata = new(_Configuration.PropertyConfiguration, _Configuration.ForceMetadataLastWriteTimeToCreationTime, _Configuration.PropertiesChangedForMetadata, bResultsFullGroupDirectory);
foreach (string outputResolution in _Configuration.OutputResolutions)
{
total = 0;
outputResolutionHasNumber = outputResolution.Any(char.IsNumber);
- (cResultsFullGroupDirectory, c2ResultsFullGroupDirectory, dResultsFullGroupDirectory, d2ResultsFullGroupDirectory) = GetResultsFullGroupDirectories(outputResolution);
+ (cResultsFullGroupDirectory, c2ResultsFullGroupDirectory, dResultsFullGroupDirectory, d2ResultsFullGroupDirectory) = dlibDotNet.GetResultsFullGroupDirectories(outputResolution);
_Faces.Update(dResultsFullGroupDirectory);
_Resize.Update(cResultsFullGroupDirectory);
_FaceParts.Update(d2ResultsFullGroupDirectory);
@@ -587,13 +587,13 @@ public partial class DlibDotNet : IDlibDotNet, IDisposable
continue;
if (!_ArgZeroIsConfigurationRootDirectory && !container.SourceDirectory.StartsWith(argZero))
continue;
- filteredItems = Shared.Models.Stateless.Methods.IContainer.GetValidImageItems(_Configuration.PropertyConfiguration, container);
+ filteredItems = Container.Models.Stateless.Methods.IContainer.GetValidImageItems(_Configuration.PropertyConfiguration, container);
if (filteredItems.Count == 0)
continue;
sourceDirectoryChanges.Clear();
anyNullOrNoIsUniqueFileName = filteredItems.Any(l => !l.IsUniqueFileName);
totalSeconds = (int)Math.Floor(new TimeSpan(DateTime.Now.Ticks - ticks).TotalSeconds);
- message = $"{i + 1:000} [{filteredItems.Count:000}] / {containersLength:000} - {total} / {count} total - {totalSeconds} total second(s) - {outputResolution} - <{container.SourceDirectory}> - total not mapped {totalNotMapped:000000}";
+ message = $"{totalSeconds} total second(s) - {outputResolution} - {i + 1:000} / {readOnlyContainers.Count:000} - {total} / {count} total - <{container.SourceDirectory}> [{filteredItems.Count:000}] - total not mapped {totalNotMapped:000000}";
propertyLogic.SetAngleBracketCollection(aResultsFullGroupDirectory, container.SourceDirectory, anyNullOrNoIsUniqueFileName);
if (outputResolutionHasNumber)
_Resize.SetAngleBracketCollection(cResultsFullGroupDirectory, container.SourceDirectory);
@@ -629,7 +629,7 @@ public partial class DlibDotNet : IDlibDotNet, IDisposable
total += container.Items.Count;
}
totalSeconds = (int)Math.Floor(new TimeSpan(DateTime.Now.Ticks - ticks).TotalSeconds);
- message = $"### [###] / {containersLength:000} - {total} / {count} total - {totalSeconds} total second(s) - {outputResolution} - <> - total not mapped {totalNotMapped:000000}";
+ message = $"{totalSeconds} total second(s) - {outputResolution} - ### [###] / {readOnlyContainers.Count:000} - {total} / {count} total - <> - total not mapped {totalNotMapped:000000}";
ProgressBarOptions options = new() { ProgressCharacter = '─', ProgressBarOnBottom = true, DisableBottomPercentage = true };
using ProgressBar progressBar = new(1, message, options);
progressBar.Tick();
@@ -678,14 +678,24 @@ public partial class DlibDotNet : IDlibDotNet, IDisposable
return results.AsReadOnly();
}
+ private static Identifier GetIdentifier(Property.Models.Configuration propertyConfiguration, FilePath filePath, KeyValuePair> keyValuePair)
+ {
+ Identifier result;
+ if (filePath.Id is null)
+ throw new Exception();
+ string[] directoryNames = keyValuePair.Value.Select(l => l.DirectoryFullPath.Replace('\\', '/')).ToArray();
+ string paddedId = IId.GetPaddedId(propertyConfiguration, filePath.Id.Value, filePath.HasIgnoreKeyword, filePath.HasDateTimeOriginal, index: null);
+ result = new(directoryNames, filePath.ExtensionLowered, filePath.HasDateTimeOriginal, filePath.Id.Value, filePath.Length, paddedId, filePath.LastWriteTicks);
+ return result;
+ }
+
private static ReadOnlyDictionary GetSplatNineIdentifiers(Property.Models.Configuration propertyConfiguration, string bResultsFullGroupDirectory, ReadOnlyDictionary> keyValuePairs)
{
Dictionary results = [];
string json;
- string paddedId;
FilePath? filePath;
Identifier identifier;
- string[] directoryNames;
+ List identifiers = [];
string rootDirectory = propertyConfiguration.RootDirectory.Replace('\\', '/');
string bMetadataCollectionDirectory = Path.Combine(bResultsFullGroupDirectory, propertyConfiguration.ResultCollection);
if (!Directory.Exists(bMetadataCollectionDirectory))
@@ -700,24 +710,31 @@ public partial class DlibDotNet : IDlibDotNet, IDisposable
break;
filePath = null;
}
- if (filePath?.Id is null)
+ if (filePath is null)
+ {
+ filePath = keyValuePair.Value[0];
+ if (filePath.Id is null)
+ continue;
+ identifier = GetIdentifier(propertyConfiguration, filePath, keyValuePair);
+ identifiers.Add(identifier);
continue;
- directoryNames = keyValuePair.Value.Select(l => l.DirectoryFullPath.Replace('\\', '/')).ToArray();
- paddedId = IId.GetPaddedId(propertyConfiguration, filePath.Id.Value, filePath.HasIgnoreKeyword, filePath.HasDateTimeOriginal, index: null);
- identifier = new(directoryNames, filePath.ExtensionLowered, filePath.HasDateTimeOriginal, filePath.Id.Value, filePath.Length, paddedId, filePath.LastWriteTicks);
+ }
+ else if (filePath.Id is null)
+ continue;
+ identifier = GetIdentifier(propertyConfiguration, filePath, keyValuePair);
+ identifiers.Add(identifier);
results.Add(keyValuePair.Key, identifier);
}
json = JsonSerializer.Serialize(results.Values.ToArray(), IdentifierCollectionSourceGenerationContext.Default.IdentifierArray);
_ = Shared.Models.Stateless.Methods.IPath.WriteAllText(Path.Combine(bMetadataCollectionDirectory, "!9.json"), json, updateDateWhenMatches: false, compareBeforeWrite: true, updateToWhenMatches: null);
- json = JsonSerializer.Serialize((from l in results orderby l.Value.PaddedId select l.Value).ToArray(), IdentifierCollectionSourceGenerationContext.Default.IdentifierArray);
+ json = JsonSerializer.Serialize((from l in identifiers orderby l.PaddedId select l).ToArray(), IdentifierCollectionSourceGenerationContext.Default.IdentifierArray);
_ = Shared.Models.Stateless.Methods.IPath.WriteAllText(Path.Combine(bMetadataCollectionDirectory, ".json"), json.Replace(rootDirectory, string.Empty), updateDateWhenMatches: false, compareBeforeWrite: true, updateToWhenMatches: null);
return results.AsReadOnly();
}
- private static ReadOnlyDictionary GetSplatNineIdentifiersAndHideSplatNine(Property.Models.Configuration propertyConfiguration, string bResultsFullGroupDirectory, ReadOnlyCollection> filePathsCollection)
+ private static ReadOnlyDictionary GetSplatNineIdentifiersAndHideSplatNine(Property.Models.Configuration propertyConfiguration, string bResultsFullGroupDirectory, ReadOnlyDictionary> keyValuePairs)
{
ReadOnlyDictionary results;
- ReadOnlyDictionary> keyValuePairs = FilePath.GetKeyValuePairs(filePathsCollection);
if (keyValuePairs.Count == 0)
results = new(new Dictionary());
else
@@ -730,7 +747,7 @@ public partial class DlibDotNet : IDlibDotNet, IDisposable
return results;
}
- private ReadOnlyCollection GetMappings(Property.Models.Configuration propertyConfiguration, string eDistanceContentDirectory, ReadOnlyCollection readOnlyContainers, MapLogic mapLogic, bool distinctItems)
+ private ReadOnlyCollection GetMappings(Property.Models.Configuration propertyConfiguration, string eDistanceContentDirectory, ReadOnlyCollection readOnlyContainers, MapLogic mapLogic, bool distinctItems)
{
List results = [];
int count = 0;
@@ -743,14 +760,14 @@ public partial class DlibDotNet : IDlibDotNet, IDisposable
DateTime[] containerDateTimes;
MappingFromItem mappingFromItem;
ReadOnlyCollection
- filteredItems;
- foreach (Container container in readOnlyContainers)
+ foreach (Container.Models.Container container in readOnlyContainers)
{
if (container.Items.Count == 0)
continue;
- filteredItems = Shared.Models.Stateless.Methods.IContainer.GetValidImageItems(propertyConfiguration, container);
+ filteredItems = Container.Models.Stateless.Methods.IContainer.GetValidImageItems(propertyConfiguration, container);
if (filteredItems.Count == 0)
continue;
- containerDateTimes = Shared.Models.Stateless.Methods.IContainer.GetContainerDateTimes(filteredItems);
+ containerDateTimes = Container.Models.Stateless.Methods.IContainer.GetContainerDateTimes(filteredItems);
focusRelativePath = Path.GetFullPath(string.Concat(_Configuration.PropertyConfiguration.RootDirectory, _Configuration.FocusDirectory));
isFocusRelativePath = string.IsNullOrEmpty(_Configuration.FocusDirectory) ? null : container.SourceDirectory.StartsWith(focusRelativePath);
foreach (Item item in filteredItems)
@@ -927,8 +944,9 @@ public partial class DlibDotNet : IDlibDotNet, IDisposable
private List GetSaveContainers(long ticks, ReadOnlyCollection personContainers, string a2PeopleSingletonDirectory, string eDistanceContentDirectory, ProgressBarOptions options, MapLogic mapLogic, string outputResolution)
{
List results;
+ IDlibDotNet dlibDotNet = this;
long[] jLinkResolvedPersonKeys = _JLinkResolvedDirectories.Select(l => l.PersonKey).ToArray();
- (string cResultsFullGroupDirectory, string _, string dResultsFullGroupDirectory, string d2ResultsFullGroupDirectory) = GetResultsFullGroupDirectories(outputResolution);
+ (string cResultsFullGroupDirectory, string _, string dResultsFullGroupDirectory, string d2ResultsFullGroupDirectory) = dlibDotNet.GetResultsFullGroupDirectories(outputResolution);
string dFacesContentDirectory = Path.Combine(dResultsFullGroupDirectory, _Configuration.PropertyConfiguration.ResultContent);
ReadOnlyDictionary> mapped = Map.Models.Stateless.Methods.IMapLogic.GetMapped(_AppSettings.MaxDegreeOfParallelism, _Configuration.PropertyConfiguration, _MapConfiguration, ticks, personContainers, a2PeopleSingletonDirectory, eDistanceContentDirectory);
if (mapped.Count == 0 && !_Configuration.SaveSortingWithoutPerson)
@@ -968,9 +986,10 @@ public partial class DlibDotNet : IDlibDotNet, IDisposable
return results;
}
- private void MapLogic(long ticks, ReadOnlyCollection containers, string fPhotoPrismContentDirectory, MapLogic mapLogic, string outputResolution, ReadOnlyDictionary> personKeyToIds, ReadOnlyCollection distinctValidImageFaces, ReadOnlyCollection distinctValidImageMappingCollection)
+ private void MapLogic(long ticks, ReadOnlyCollection containers, string fPhotoPrismContentDirectory, MapLogic mapLogic, string outputResolution, ReadOnlyDictionary> personKeyToIds, ReadOnlyCollection distinctValidImageFaces, ReadOnlyCollection distinctValidImageMappingCollection)
{
- (_, _, string dResultsFullGroupDirectory, string d2ResultsFullGroupDirectory) = GetResultsFullGroupDirectories(outputResolution);
+ IDlibDotNet dlibDotNet = this;
+ (_, _, string dResultsFullGroupDirectory, string d2ResultsFullGroupDirectory) = dlibDotNet.GetResultsFullGroupDirectories(outputResolution);
string dFacesContentDirectory = Path.Combine(dResultsFullGroupDirectory, _Configuration.PropertyConfiguration.ResultContent);
string d2FacePartsContentDirectory = Path.Combine(d2ResultsFullGroupDirectory, _Configuration.PropertyConfiguration.ResultContent);
string d2FacePartsContentCollectionDirectory = Path.Combine(d2ResultsFullGroupDirectory, _Configuration.PropertyConfiguration.ResultContentCollection);
@@ -1141,7 +1160,7 @@ public partial class DlibDotNet : IDlibDotNet, IDisposable
string d2ResultsFullGroupDirectory,
List> sourceDirectoryChanges,
Dictionary> fileNameToCollection,
- Container container,
+ Container.Models.Container container,
Item item,
DateTime[] containerDateTimes,
bool? isFocusRelativePath)
@@ -1202,12 +1221,10 @@ public partial class DlibDotNet : IDlibDotNet, IDisposable
}
if (resizedFileHolder.Exists && item.FilePath.HasIgnoreKeyword is not null && item.FilePath.HasIgnoreKeyword.Value != shouldIgnore.Value)
{
- if (!item.FilePath.DirectoryFullPath.Contains("Results") || !item.FilePath.DirectoryFullPath.Contains("Resize"))
- throw new NotSupportedException($"Rename File! <{item.FilePath.FileNameFirstSegment}>");
- else
- {
+ if (item.FilePath.DirectoryFullPath.Contains("Results") && item.FilePath.DirectoryFullPath.Contains("Resize"))
File.Delete(resizedFileHolder.FullName);
- }
+ else
+ throw new NotSupportedException($"Rename File! <{item.FilePath.FileNameFirstSegment}>");
}
}
if (property is null || item.Property is null)
@@ -1297,14 +1314,14 @@ public partial class DlibDotNet : IDlibDotNet, IDisposable
string d2ResultsFullGroupDirectory,
List> sourceDirectoryChanges,
Dictionary> fileNameToCollection,
- Container container,
+ Container.Models.Container container,
ReadOnlyCollection
- filteredItems,
string message)
{
int result = 0;
int exceptionsCount = 0;
ParallelOptions parallelOptions = new() { MaxDegreeOfParallelism = maxDegreeOfParallelism };
- DateTime[] containerDateTimes = Shared.Models.Stateless.Methods.IContainer.GetContainerDateTimes(filteredItems);
+ DateTime[] containerDateTimes = Container.Models.Stateless.Methods.IContainer.GetContainerDateTimes(filteredItems);
ProgressBarOptions options = new() { ProgressCharacter = '─', ProgressBarOnBottom = true, DisableBottomPercentage = true };
string focusRelativePath = Path.GetFullPath(string.Concat(_Configuration.PropertyConfiguration.RootDirectory, _Configuration.FocusDirectory));
bool? isFocusRelativePath = string.IsNullOrEmpty(_Configuration.FocusDirectory) ? null : container.SourceDirectory.StartsWith(focusRelativePath);
@@ -1340,7 +1357,7 @@ public partial class DlibDotNet : IDlibDotNet, IDisposable
return (result, exceptionsCount > 0);
}
- private (string, string) GetResultsFullGroupDirectories()
+ (string, string) IDlibDotNet.GetResultsFullGroupDirectories()
{
string aResultsFullGroupDirectory = Property.Models.Stateless.IResult.GetResultsFullGroupDirectory(
_Configuration.PropertyConfiguration,
@@ -1359,7 +1376,7 @@ public partial class DlibDotNet : IDlibDotNet, IDisposable
return new(aResultsFullGroupDirectory, bResultsFullGroupDirectory);
}
- private (string, string, string, string) GetResultsFullGroupDirectories(string outputResolution)
+ (string, string, string, string) IDlibDotNet.GetResultsFullGroupDirectories(string outputResolution)
{
string cResultsFullGroupDirectory = Property.Models.Stateless.IResult.GetResultsFullGroupDirectory(
_Configuration.PropertyConfiguration,
@@ -1503,8 +1520,9 @@ public partial class DlibDotNet : IDlibDotNet, IDisposable
private (string, ReadOnlyCollection>, bool) GetFilesCollectionThenCopyOrMove(long ticks, string fileSearchFilter, string directorySearchFilter, ProgressBarOptions options, string outputResolution)
{
ProgressBar progressBar;
+ IDlibDotNet dlibDotNet = this;
string filesCollectionRootDirectory = _Configuration.PropertyConfiguration.RootDirectory;
- (string cResultsFullGroupDirectory, _, _, _) = GetResultsFullGroupDirectories(outputResolution);
+ (string cResultsFullGroupDirectory, _, _, _) = dlibDotNet.GetResultsFullGroupDirectories(outputResolution);
IReadOnlyDictionary>> fileGroups = Shared.Models.Stateless.Methods.IPath.GetKeyValuePairs(_Configuration.PropertyConfiguration, cResultsFullGroupDirectory, [_Configuration.PropertyConfiguration.ResultContent, _Configuration.PropertyConfiguration.ResultContentCollection]);
ReadOnlyCollection> filePathsCollection = IDirectory.GetFilePathCollections(_Configuration.PropertyConfiguration, directorySearchFilter, fileSearchFilter, filesCollectionRootDirectory, useCeilingAverage: false);
int count = filePathsCollection.Select(l => l.Count).Sum();
diff --git a/Instance/Instance.csproj b/Instance/Instance.csproj
index d8b80ac..1aaef30 100644
--- a/Instance/Instance.csproj
+++ b/Instance/Instance.csproj
@@ -51,6 +51,7 @@
+
diff --git a/Map/Map.csproj b/Map/Map.csproj
index 5d56d1e..643acd2 100644
--- a/Map/Map.csproj
+++ b/Map/Map.csproj
@@ -41,6 +41,8 @@
+
+
\ No newline at end of file
diff --git a/Map/Models/MapLogic.cs b/Map/Models/MapLogic.cs
index c2e5fd4..7bbc980 100644
--- a/Map/Models/MapLogic.cs
+++ b/Map/Models/MapLogic.cs
@@ -460,7 +460,7 @@ public partial class MapLogic : Shared.Models.Methods.IMapLogic
return result;
}
- private (long?, string?) GetDirectory(Configuration configuration, string by, string segmentB)
+ private (long?, string?) GetDirectory(Configuration configuration, string by, LocationContainer _, string segmentB)
{
long? ticks = null;
const int zero = 0;
@@ -537,22 +537,22 @@ public partial class MapLogic : Shared.Models.Methods.IMapLogic
return result;
}
- private Record Get(Configuration configuration, string by, long? personKey, string? displayDirectoryName, string segmentB)
+ private Record Get(Configuration configuration, string by, LocationContainer locationContainer, string? displayDirectoryName, string segmentB)
{
long? ticks;
string? directory;
string? debugDirectory;
string? personDirectory;
- if (personKey is null || string.IsNullOrEmpty(displayDirectoryName))
+ if (locationContainer.PersonKey is null || string.IsNullOrEmpty(displayDirectoryName))
{
debugDirectory = null;
- (ticks, directory) = GetDirectory(configuration, by, segmentB);
+ (ticks, directory) = GetDirectory(configuration, by, locationContainer, segmentB);
personDirectory = directory is null ? null : Path.Combine(directory, $"X+{ticks}");
}
else
{
ticks = null;
- string personKeyFormatted = IPersonBirthday.GetFormatted(configuration.PersonBirthdayFormat, personKey.Value);
+ string personKeyFormatted = IPersonBirthday.GetFormatted(configuration.PersonBirthdayFormat, locationContainer.PersonKey.Value);
debugDirectory = Path.Combine(_EDistanceContentTicksDirectory, by, personKeyFormatted, displayDirectoryName);
directory = Path.Combine(_EDistanceContentTicksDirectory, by, personKeyFormatted, segmentB);
personDirectory = Path.Combine(directory, displayDirectoryName, "lnk");
@@ -880,7 +880,7 @@ public partial class MapLogic : Shared.Models.Methods.IMapLogic
displayDirectoryName = GetDisplayDirectoryName(locationContainer.DisplayDirectoryName, locationContainer, personKeyToPersonContainer);
isCounterPersonYear = locationContainer.PersonKey is not null && IPersonBirthday.IsCounterPersonYear(locationContainer.PersonKey.Value);
(by, _, isBySorting) = Stateless.MapLogic.Get(useFiltersCounter, _Configuration.SaveIndividually, sortingContainersAny, forceSingleImageHumanized, locationContainer.LengthPermyriad, locationContainer.PersonKey, displayDirectoryName);
- record = Get(_Configuration, by, locationContainer.PersonKey, displayDirectoryName, segmentB);
+ record = Get(_Configuration, by, locationContainer, displayDirectoryName, segmentB);
if (string.IsNullOrEmpty(record.Directory) || string.IsNullOrEmpty(record.PersonDirectory))
continue;
directory = record.Directory;
@@ -1406,14 +1406,14 @@ public partial class MapLogic : Shared.Models.Methods.IMapLogic
return new(directoriesAndDateTimes, collection);
}
- public void SaveShortcutsForOutputResolutionsDuringMapLogic(ReadOnlyCollection containers, ReadOnlyDictionary> personKeyToIds, string dFacesContentDirectory, ReadOnlyCollection distinctValidImageMappingCollection)
+ public void SaveShortcutsForOutputResolutionsDuringMapLogic(ReadOnlyCollection containers, ReadOnlyDictionary> personKeyToIds, string dFacesContentDirectory, ReadOnlyCollection distinctValidImageMappingCollection)
{
if (_Configuration is null)
throw new NullReferenceException(nameof(_Configuration));
WindowsShortcut windowsShortcut;
List<(string, DateTime[])> directoriesAndDateTimes;
List collection;
- ReadOnlyCollection- validImageItems = IContainer.GetValidImageItems(_PropertyConfiguration, containers, distinctItems: true, filterItems: true);
+ ReadOnlyCollection
- validImageItems = Container.Models.Stateless.Methods.IContainer.GetValidImageItems(_PropertyConfiguration, containers, distinctItems: true, filterItems: true);
(directoriesAndDateTimes, collection) = GetCollectionForSaveShortcutsForOutputResolutionsDuringMapLogic(personKeyToIds, dFacesContentDirectory, validImageItems, distinctValidImageMappingCollection);
string[] directories = (from l in collection select l.Directory).Distinct().ToArray();
foreach (string directory in directories)
@@ -1499,14 +1499,14 @@ public partial class MapLogic : Shared.Models.Methods.IMapLogic
public bool? IsFocusPerson(int? skipPersonWithMoreThen, long[] jLinkResolvedPersonKeys, ReadOnlyDictionary>? wholePercentagesToPersonContainers, MappingFromLocation mappingFromLocation) =>
IsFocusPerson(skipPersonWithMoreThen, jLinkResolvedPersonKeys, wholePercentagesToPersonContainers, mappingFromLocation.WholePercentages);
- public void LookForAbandoned(IDlibDotNet dlibDotNet, Property.Models.Configuration propertyConfiguration, string bResultsFullGroupDirectory, ReadOnlyCollection readOnlyContainers, string cResultsFullGroupDirectory, string dResultsFullGroupDirectory, string d2ResultsFullGroupDirectory)
+ public void LookForAbandoned(IDlibDotNet dlibDotNet, Property.Models.Configuration propertyConfiguration, string bResultsFullGroupDirectory, ReadOnlyCollection readOnlyContainers, string cResultsFullGroupDirectory, string dResultsFullGroupDirectory, string d2ResultsFullGroupDirectory)
{
string[] directories;
string? directoryName;
- List distinctFilteredIds = IContainer.GetFilteredDistinctIds(propertyConfiguration, readOnlyContainers);
+ List distinctFilteredIds = Container.Models.Stateless.Methods.IContainer.GetFilteredDistinctIds(propertyConfiguration, readOnlyContainers);
LookForAbandoned(propertyConfiguration, distinctFilteredIds);
dlibDotNet.Tick();
- List distinctFilteredFileNameFirstSegments = IContainer.GetFilteredDistinctFileNameFirstSegments(propertyConfiguration, readOnlyContainers);
+ List distinctFilteredFileNameFirstSegments = Container.Models.Stateless.Methods.IContainer.GetFilteredDistinctFileNameFirstSegments(propertyConfiguration, readOnlyContainers);
Stateless.LookForAbandonedLogic.LookForAbandoned(propertyConfiguration, bResultsFullGroupDirectory, distinctFilteredFileNameFirstSegments);
dlibDotNet.Tick();
directories = Directory.GetDirectories(cResultsFullGroupDirectory, "*", SearchOption.TopDirectoryOnly);
diff --git a/Map/Models/Stateless/DistanceLogic.cs b/Map/Models/Stateless/DistanceLogic.cs
index 5b1e341..93aa685 100644
--- a/Map/Models/Stateless/DistanceLogic.cs
+++ b/Map/Models/Stateless/DistanceLogic.cs
@@ -22,7 +22,6 @@ internal abstract class DistanceLogic
internal record TicksDirectory(DateTime AlternateDirectoryDateTime,
string Directory,
DateTime DirectoryDateTime,
- string DirectoryName,
bool? IsLocationContainerDebugDirectory,
float? TotalDays);
@@ -86,53 +85,55 @@ internal abstract class DistanceLogic
float? totalDays;
long? next = null;
string? checkDirectory;
- string ticksDirectoryName;
DateTime directoryDateTime;
DirectoryInfo directoryInfo;
+ TicksDirectory ticksDirectory;
long? lastDirectoryTicks = null;
DateTime dateTime = DateTime.Now;
DateTime alternateDirectoryDateTime;
+ string ticksDirectoryNameFirstSegment;
bool? isLocationContainerDebugDirectory;
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)
+ string[] ticksFullPaths = Directory.GetDirectories(eDistanceContentDirectory, "*", SearchOption.TopDirectoryOnly);
+ foreach (string ticksFullPath in ticksFullPaths)
{
- ticksDirectoryName = Path.GetFileName(ticksDirectory);
- if (ticksDirectoryName.Length < 3)
+ ticksDirectoryNameFirstSegment = Path.GetFileName(ticksFullPath).Split('.')[0];
+ if (ticksDirectoryNameFirstSegment.Length < 3)
continue;
- if (!long.TryParse(ticksDirectoryName, out long directoryTicks))
+ if (!long.TryParse(ticksDirectoryNameFirstSegment, out long directoryTicks))
throw new NotSupportedException();
if (next is null)
next = new DateTime(directoryTicks).Ticks;
else
{
next += month;
- checkDirectory = Path.GetDirectoryName(ticksDirectory);
+ checkDirectory = Path.GetDirectoryName(ticksFullPath);
if (string.IsNullOrEmpty(checkDirectory))
{
if (string.IsNullOrEmpty(checkDirectory))
continue;
checkDirectory = Path.Combine(checkDirectory, next.Value.ToString());
- if (ticksDirectory == checkDirectory || !checkDirectory.EndsWith(configuration.LocationContainerDirectoryPattern))
+ if (ticksFullPath == checkDirectory || !checkDirectory.EndsWith(configuration.LocationContainerDirectoryPattern))
continue;
- Directory.Move(ticksDirectory, checkDirectory);
+ Directory.Move(ticksFullPath, checkDirectory);
continue;
}
}
- directoryInfo = new(ticksDirectory);
+ directoryInfo = new(ticksFullPath);
directoryDateTime = new DateTime(directoryTicks);
if (directoryInfo.CreationTime.Ticks != directoryTicks)
- Directory.SetCreationTime(ticksDirectory, new DateTime(directoryTicks));
+ Directory.SetCreationTime(ticksFullPath, new DateTime(directoryTicks));
if (directoryInfo.LastWriteTime.Ticks != directoryTicks)
- Directory.SetLastWriteTime(ticksDirectory, new DateTime(directoryTicks));
+ Directory.SetLastWriteTime(ticksFullPath, new DateTime(directoryTicks));
alternateDirectoryDateTime = new DateTime(directoryDateTime.Year, directoryDateTime.Month, directoryDateTime.Day).AddMonths(1);
- isLocationContainerDebugDirectory = configuration.LocationContainerDebugDirectory is null ? null : ticksDirectoryName.EndsWith(configuration.LocationContainerDebugDirectory);
+ isLocationContainerDebugDirectory = configuration.LocationContainerDebugDirectory is null ? null : ticksDirectoryNameFirstSegment.EndsWith(configuration.LocationContainerDebugDirectory);
totalDays = lastDirectoryTicks is null || new TimeSpan(dateTime.Ticks - directoryTicks).TotalDays < 1 ? null : (float)new TimeSpan(directoryTicks - lastDirectoryTicks.Value).TotalDays;
- results.Add(new(alternateDirectoryDateTime, ticksDirectory, new(directoryTicks), ticksDirectoryName, isLocationContainerDebugDirectory, totalDays));
+ ticksDirectory = new(alternateDirectoryDateTime, ticksFullPath, new(directoryTicks), isLocationContainerDebugDirectory, totalDays);
+ results.Add(ticksDirectory);
if (directoryDateTime.Hour == 0 && directoryDateTime.Minute == 0 && directoryDateTime.Second == 0)
continue;
lastDirectoryTicks = directoryTicks;
@@ -216,9 +217,37 @@ internal abstract class DistanceLogic
}
}
- private static List GetRecords(Shared.Models.Properties.IPropertyConfiguration propertyConfiguration, Configuration configuration, bool? isDefault, string[] files, int directoryNumber, string personKeyFormatted, int? linksCount, List distinct, string? personDisplayDirectoryName)
+ private static string GetCheckFile(TicksDirectory ticksDirectory, string @enum, string fileName, string file)
+ {
+ string result;
+ string checkDirectory;
+ string directory = file;
+ List collection = [];
+ for (int i = 0; i < file.Length; i++)
+ {
+ directory = Path.GetDirectoryName(directory) ?? throw new Exception();
+ if (directory == ticksDirectory.Directory)
+ break;
+ collection.Add(Path.GetFileName(directory));
+ }
+ collection.Reverse();
+ checkDirectory = $"{ticksDirectory.Directory}.{@enum}";
+ foreach (string directoryName in collection)
+ checkDirectory = Path.Combine(checkDirectory, directoryName);
+ if (!Directory.Exists(checkDirectory))
+ _ = Directory.CreateDirectory(checkDirectory);
+ result = Path.Combine(checkDirectory, fileName);
+ if (File.Exists(result))
+ throw new Exception($"File <{fileName}> already exists!");
+ File.Move(file, result);
+ return result;
+ }
+
+ private static List GetRecords(Shared.Models.Properties.IPropertyConfiguration propertyConfiguration, Configuration configuration, TicksDirectory ticksDirectory, bool? isDefault, string[] files, int directoryNumber, string personKeyFormatted, int? linksCount, List distinct, string? personDisplayDirectoryName)
{
List results = [];
+ string @enum;
+ Record record;
string fileName;
string checkFile;
FilePath filePath;
@@ -244,8 +273,26 @@ internal abstract class DistanceLogic
File.Move(file, checkFile);
continue;
}
+ if (file.StartsWith(ticksDirectory.Directory))
+ {
+ @enum = IPath.GetEnum(filePath).ToString();
+ if (!ticksDirectory.Directory.EndsWith(@enum))
+ {
+ checkFile = GetCheckFile(ticksDirectory, @enum, fileName, file);
+ fileHolder = IFileHolder.Get(checkFile);
+ filePath = FilePath.Get(propertyConfiguration, fileHolder, index: null);
+ if (filePath.Id is null)
+ continue;
+ }
+ }
distinct.Add(fileName);
- results.Add(new(directoryNumber, isDefault, linksCount, filePath, personDisplayDirectoryName, personKeyFormatted));
+ record = new(DirectoryNumber: directoryNumber,
+ IsDefault: isDefault,
+ LinksCount: linksCount,
+ MappedFaceFilePath: filePath,
+ PersonDisplayDirectoryName: personDisplayDirectoryName,
+ PersonKeyFormatted: personKeyFormatted);
+ results.Add(record);
}
return results;
}
@@ -311,6 +358,7 @@ internal abstract class DistanceLogic
DateTime dateTime;
TimeSpan timeSpan;
int directoryNumber;
+ List records;
string? checkDirectory;
ProgressBar progressBar;
string[] yearDirectories;
@@ -340,8 +388,7 @@ internal abstract class DistanceLogic
progressBar = new(ticksDirectories.Count, message, options);
foreach (TicksDirectory ticksDirectory in ticksDirectories)
{
- if (i == 1)
- progressBar.Tick();
+ progressBar.Tick();
personKeyFormattedDirectories = Directory.GetDirectories(ticksDirectory.Directory, "*", SearchOption.TopDirectoryOnly);
foreach (string personKeyFormattedDirectory in personKeyFormattedDirectories)
{
@@ -368,23 +415,6 @@ internal abstract class DistanceLogic
linksCount = null;
else
linksCount = GetLinksCount(yearDirectory);
- 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(propertyConfiguration, configuration, isDefault, files, directoryNumber, personKeyFormatted, linksCount, 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("Try deleting *.lnk files!");
@@ -467,7 +497,9 @@ internal abstract class DistanceLogic
Directory.Move(personNameDirectory, personFirstInitialDirectory);
files = Directory.GetFiles(personFirstInitialDirectory, "*", SearchOption.TopDirectoryOnly);
}
- results.AddRange(GetRecords(propertyConfiguration, configuration, isDefault, files, directoryNumber, personKeyFormatted, linksCount, distinct, personDisplayDirectoryName));
+ records = GetRecords(propertyConfiguration, configuration, ticksDirectory, isDefault, files, directoryNumber, personKeyFormatted, linksCount, distinct, personDisplayDirectoryName);
+ if (records.Count > 0)
+ results.AddRange(records);
personNameLinkDirectories = Directory.GetDirectories(personFirstInitialDirectory, "*", SearchOption.TopDirectoryOnly);
foreach (string personNameLinkDirectory in personNameLinkDirectories)
{
diff --git a/Map/Models/Stateless/MapLogic.cs b/Map/Models/Stateless/MapLogic.cs
index 3c106ff..72cb0cc 100644
--- a/Map/Models/Stateless/MapLogic.cs
+++ b/Map/Models/Stateless/MapLogic.cs
@@ -13,17 +13,17 @@ namespace View_by_Distance.Map.Models.Stateless;
internal abstract class MapLogic
{
+ internal record Duplicate(long PersonKey,
+ int Id,
+ FilePath FilePath,
+ float? Percent);
+
internal record MappedFile(long PersonKey,
string PersonKeyFormatted,
string? PersonDisplayDirectoryName,
int? DirectoryNumber,
FilePath FilePath);
- internal record Duplicate(long PersonKey,
- int Id,
- FilePath FilePath,
- float? Percent);
-
internal record PersonKeyFormattedIdThenWholePercentages(string PersonKeyFormatted,
string? PersonDisplayDirectoryName,
bool? IsDefault,
@@ -188,6 +188,7 @@ internal abstract class MapLogic
private static List GetDisplayDirectoryAllFiles(string fileNameExtension, string personBirthdayFormat, ReadOnlyCollection personContainers)
{
List results = [];
+ MappedFile mappedFile;
string personKeyFormatted;
List distinct = [];
foreach (PersonContainer personContainer in personContainers)
@@ -202,7 +203,12 @@ internal abstract class MapLogic
continue;
distinct.Add(personContainer.DisplayDirectoryAllFilePaths[i].Name);
personKeyFormatted = IPersonBirthday.GetFormatted(personBirthdayFormat, personContainer.Key.Value);
- results.Add(new(personContainer.Key.Value, personKeyFormatted, personContainer.DisplayDirectoryName, null, personContainer.DisplayDirectoryAllFilePaths[i]));
+ mappedFile = new(PersonKey: personContainer.Key.Value,
+ PersonKeyFormatted: personKeyFormatted,
+ PersonDisplayDirectoryName: personContainer.DisplayDirectoryName,
+ DirectoryNumber: null,
+ FilePath: personContainer.DisplayDirectoryAllFilePaths[i]);
+ results.Add(mappedFile);
}
}
return results;
@@ -462,6 +468,7 @@ internal abstract class MapLogic
string checkFile;
FilePath filePath;
FileHolder fileHolder;
+ MappedFile mappedFile;
List distinct = [];
PersonBirthday? personBirthday;
PersonContainer? personContainer;
@@ -481,7 +488,12 @@ internal abstract class MapLogic
personDisplayDirectoryName = record.PersonDisplayDirectoryName;
else
personDisplayDirectoryName = personContainer.DisplayDirectoryName;
- results.Add(new(personKey, record.PersonKeyFormatted, personDisplayDirectoryName, record.DirectoryNumber, record.MappedFaceFilePath));
+ mappedFile = new(PersonKey: personKey,
+ PersonKeyFormatted: record.PersonKeyFormatted,
+ PersonDisplayDirectoryName: personDisplayDirectoryName,
+ DirectoryNumber: record.DirectoryNumber,
+ FilePath: record.MappedFaceFilePath);
+ results.Add(mappedFile);
}
for (int i = results.Count - 1; i > -1; i--)
{
@@ -501,7 +513,11 @@ internal abstract class MapLogic
File.Move(filePath.FullName, checkFile);
fileHolder = IFileHolder.Get(checkFile);
filePath = FilePath.Get(propertyConfiguration, fileHolder, index: null);
- results[i] = new(results[i].PersonKey, results[i].PersonKeyFormatted, results[i].PersonDisplayDirectoryName, results[i].DirectoryNumber, filePath);
+ results[i] = new(PersonKey: results[i].PersonKey,
+ PersonKeyFormatted: results[i].PersonKeyFormatted,
+ PersonDisplayDirectoryName: results[i].PersonDisplayDirectoryName,
+ DirectoryNumber: results[i].DirectoryNumber,
+ FilePath: filePath);
}
return results;
}
@@ -791,6 +807,7 @@ internal abstract class MapLogic
int? wholePercentages;
List wholePercentagesCollection;
Dictionary> idToWholePercentagesCollection = [];
+ PersonKeyFormattedIdThenWholePercentages personKeyFormattedIdThenWholePercentages;
int totalSeconds = (int)Math.Floor(new TimeSpan(DateTime.Now.Ticks - ticks).TotalSeconds);
string message = $") {records.Count:000} join from ticks Director(ies) - C - {totalSeconds} total second(s)";
ProgressBarOptions options = new() { ProgressCharacter = '─', ProgressBarOnBottom = true, DisableBottomPercentage = true };
@@ -808,7 +825,14 @@ internal abstract class MapLogic
wholePercentagesCollection = idToWholePercentagesCollection[record.MappedFaceFilePath.Id.Value];
wholePercentagesCollection.Add(wholePercentages.Value);
idToWholePercentagesCollection[record.MappedFaceFilePath.Id.Value].Add(wholePercentages.Value);
- results.Add(new(record.PersonKeyFormatted, record.PersonDisplayDirectoryName, record.IsDefault, record.LinksCount, record.MappedFaceFilePath, record.MappedFaceFilePath.Id.Value, wholePercentages.Value));
+ personKeyFormattedIdThenWholePercentages = new(PersonKeyFormatted: record.PersonKeyFormatted,
+ PersonDisplayDirectoryName: record.PersonDisplayDirectoryName,
+ IsDefault: record.IsDefault,
+ LinksCount: record.LinksCount,
+ MappedFaceFilePath: record.MappedFaceFilePath,
+ Id: record.MappedFaceFilePath.Id.Value,
+ WholePercentages: wholePercentages.Value);
+ results.Add(personKeyFormattedIdThenWholePercentages);
}
return results.AsReadOnly();
}
diff --git a/Metadata/Metadata.csproj b/Metadata/Metadata.csproj
index 0996706..dd07f56 100644
--- a/Metadata/Metadata.csproj
+++ b/Metadata/Metadata.csproj
@@ -34,10 +34,10 @@
+
-
\ No newline at end of file
diff --git a/Metadata/Models/B_Metadata.cs b/Metadata/Models/B_Metadata.cs
index fe34414..dae1ad5 100644
--- a/Metadata/Models/B_Metadata.cs
+++ b/Metadata/Models/B_Metadata.cs
@@ -148,7 +148,7 @@ public class B_Metadata : IMetadata
DateTime? result = null;
DateTime? dateTime;
DateTime checkDateTime;
- string dateTimeFormat = Property.Models.Stateless.IProperty.DateTimeFormat();
+ string dateTimeFormat = Stateless.Methods.IMetadata.DateTimeFormat();
MetadataExtractor.Formats.Exif.ExifDirectoryBase? exifDirectoryBase = directories.OfType().FirstOrDefault();
results.Add(new DateTime(filePath.CreationTicks));
results.Add(new DateTime(filePath.LastWriteTicks));
@@ -158,7 +158,7 @@ public class B_Metadata : IMetadata
results.Add(checkDateTime);
else
{
- dateTime = Property.Models.Stateless.IProperty.GetDateTime(dateTimeFormat, exifDirectoryBase.GetString(MetadataExtractor.Formats.Exif.ExifDirectoryBase.TagDateTime));
+ dateTime = Stateless.Methods.IMetadata.GetDateTime(dateTimeFormat, exifDirectoryBase.GetString(MetadataExtractor.Formats.Exif.ExifDirectoryBase.TagDateTime));
if (dateTime is not null)
results.Add(dateTime.Value);
}
@@ -166,7 +166,7 @@ public class B_Metadata : IMetadata
results.Add(checkDateTime);
else
{
- dateTime = Property.Models.Stateless.IProperty.GetDateTime(dateTimeFormat, exifDirectoryBase.GetString(MetadataExtractor.Formats.Exif.ExifDirectoryBase.TagDateTimeDigitized));
+ dateTime = Stateless.Methods.IMetadata.GetDateTime(dateTimeFormat, exifDirectoryBase.GetString(MetadataExtractor.Formats.Exif.ExifDirectoryBase.TagDateTimeDigitized));
if (dateTime is not null)
results.Add(dateTime.Value);
}
@@ -177,7 +177,7 @@ public class B_Metadata : IMetadata
}
else
{
- dateTime = Property.Models.Stateless.IProperty.GetDateTime(dateTimeFormat, exifDirectoryBase.GetString(MetadataExtractor.Formats.Exif.ExifDirectoryBase.TagDateTimeOriginal));
+ dateTime = Stateless.Methods.IMetadata.GetDateTime(dateTimeFormat, exifDirectoryBase.GetString(MetadataExtractor.Formats.Exif.ExifDirectoryBase.TagDateTimeOriginal));
if (dateTime is not null)
{
result ??= dateTime.Value;
@@ -195,7 +195,7 @@ public class B_Metadata : IMetadata
}
else
{
- dateTime = Property.Models.Stateless.IProperty.GetDateTime(dateTimeFormat, aviDirectory.GetString(MetadataExtractor.Formats.Avi.AviDirectory.TagDateTimeOriginal));
+ dateTime = Stateless.Methods.IMetadata.GetDateTime(dateTimeFormat, aviDirectory.GetString(MetadataExtractor.Formats.Avi.AviDirectory.TagDateTimeOriginal));
if (dateTime is not null)
{
result ??= dateTime.Value;
@@ -213,7 +213,7 @@ public class B_Metadata : IMetadata
}
else
{
- dateTime = Property.Models.Stateless.IProperty.GetDateTime(dateTimeFormat, quickTimeMovieHeaderDirectory.GetString(MetadataExtractor.Formats.QuickTime.QuickTimeMovieHeaderDirectory.TagCreated));
+ dateTime = Stateless.Methods.IMetadata.GetDateTime(dateTimeFormat, quickTimeMovieHeaderDirectory.GetString(MetadataExtractor.Formats.QuickTime.QuickTimeMovieHeaderDirectory.TagCreated));
if (dateTime is not null)
{
result ??= dateTime.Value;
@@ -231,7 +231,7 @@ public class B_Metadata : IMetadata
}
else
{
- dateTime = Property.Models.Stateless.IProperty.GetDateTime(dateTimeFormat, quickTimeTrackHeaderDirectory.GetString(MetadataExtractor.Formats.QuickTime.QuickTimeTrackHeaderDirectory.TagCreated));
+ dateTime = Stateless.Methods.IMetadata.GetDateTime(dateTimeFormat, quickTimeTrackHeaderDirectory.GetString(MetadataExtractor.Formats.QuickTime.QuickTimeTrackHeaderDirectory.TagCreated));
if (dateTime is not null)
{
result ??= dateTime.Value;
diff --git a/Metadata/Models/Stateless/Base.cs b/Metadata/Models/Stateless/Base.cs
index 97ad98c..2575ec5 100644
--- a/Metadata/Models/Stateless/Base.cs
+++ b/Metadata/Models/Stateless/Base.cs
@@ -1,3 +1,4 @@
+using System.Globalization;
using View_by_Distance.Shared.Models;
namespace View_by_Distance.Metadata.Models.Stateless.Methods;
@@ -47,4 +48,23 @@ internal static class Base
return result;
}
+#pragma warning restore CA1416
+
+ internal static DateTime? GetDateTime(string dateTimeFormat, string? value)
+ {
+ DateTime? result;
+ string alternateFormat = "ddd MMM dd HH:mm:ss yyyy";
+ if (value is not null && DateTime.TryParse(value, out DateTime dateTime))
+ result = dateTime;
+ else if (value is not null && value.Length == dateTimeFormat.Length && DateTime.TryParseExact(value, dateTimeFormat, CultureInfo.InvariantCulture, DateTimeStyles.None, out dateTime))
+ result = dateTime;
+ else if (value is not null && value.Length == alternateFormat.Length && DateTime.TryParseExact(value, alternateFormat, CultureInfo.InvariantCulture, DateTimeStyles.None, out dateTime))
+ result = dateTime;
+ else
+ result = null;
+ return result;
+ }
+
+#pragma warning disable CA1416
+
}
\ No newline at end of file
diff --git a/Metadata/Models/Stateless/Methods/IMetadata.cs b/Metadata/Models/Stateless/Methods/IMetadata.cs
index 81926dc..352ae9a 100644
--- a/Metadata/Models/Stateless/Methods/IMetadata.cs
+++ b/Metadata/Models/Stateless/Methods/IMetadata.cs
@@ -64,4 +64,14 @@ public interface IMetadata
// static Dictionary GetMetadataCollection(FileInfo fileInfo, List> subFileTuples, List parseExceptions) =>
// Metadata.GetMetadataCollection(fileInfo, subFileTuples, parseExceptions);
+ string TestStatic_DateTimeFormat() =>
+ DateTimeFormat();
+ static string DateTimeFormat() =>
+ "yyyy:MM:dd HH:mm:ss";
+
+ DateTime? TestStatic_GetDateTime(string dateTimeFormat, string? value) =>
+ GetDateTime(dateTimeFormat, value);
+ static DateTime? GetDateTime(string dateTimeFormat, string? value) =>
+ Base.GetDateTime(dateTimeFormat, value);
+
}
\ No newline at end of file
diff --git a/Property/Models/A_Property.cs b/Property/Models/A_Property.cs
index cd037cb..62e3057 100644
--- a/Property/Models/A_Property.cs
+++ b/Property/Models/A_Property.cs
@@ -239,7 +239,7 @@ public class A_Property
SetAngleBracketCollection(aResultsFullGroupDirectory, sourceDirectory, anyNullOrNoIsUniqueFileName);
}
- private void SavePropertyParallelWork(int maxDegreeOfParallelism, Shared.Models.Methods.IMetadata metadata, List exceptions, List> sourceDirectoryChanges, Container container, ReadOnlyCollection
- items, string message)
+ private void SavePropertyParallelWork(int maxDegreeOfParallelism, Shared.Models.Methods.IMetadata metadata, List exceptions, List> sourceDirectoryChanges, Container.Models.Container container, ReadOnlyCollection
- items, string message)
{
List> sourceDirectoryFileTuples = [];
ParallelOptions parallelOptions = new() { MaxDegreeOfParallelism = maxDegreeOfParallelism };
@@ -268,14 +268,14 @@ public class A_Property
});
}
- public void SavePropertyParallelWork(long ticks, Shared.Models.Methods.IMetadata metadata, int t, Container[] containers)
+ public void SavePropertyParallelWork(long ticks, Shared.Models.Methods.IMetadata metadata, int t, Container.Models.Container[] containers)
{
int total = 0;
string message;
int totalSeconds;
- Container container;
bool anyNullOrNoIsUniqueFileName;
List exceptions = [];
+ Container.Models.Container container;
int containersLength = containers.Length;
const string outputResolution = "Original";
List> sourceDirectoryChanges = [];
diff --git a/Property/Models/Stateless/IProperty.cs b/Property/Models/Stateless/IProperty.cs
index d44a183..5d0ecff 100644
--- a/Property/Models/Stateless/IProperty.cs
+++ b/Property/Models/Stateless/IProperty.cs
@@ -55,4 +55,24 @@ public interface IProperty
static (DateTime?, DateTime[], int?, string?) Get(IPropertyConfiguration propertyConfiguration, bool populateId, IMetadata? metadata, FileHolder fileHolder, bool isIgnoreExtension, bool isValidImageFormatExtension, ASCIIEncoding asciiEncoding) =>
Property.Get(populateId, metadata, FilePath.Get(propertyConfiguration, fileHolder, index: null), isIgnoreExtension, isValidImageFormatExtension, asciiEncoding);
+ TimeSpan TestStatic_GetThreeStandardDeviationHigh(int minimum, Container.Models.Container container) =>
+ GetThreeStandardDeviationHigh(minimum, container);
+ static TimeSpan GetThreeStandardDeviationHigh(int minimum, Container.Models.Container container) =>
+ Property.GetThreeStandardDeviationHigh(minimum, container);
+
+ (int, List, List) TestStatic_Get(Container.Models.Container container, TimeSpan threeStandardDeviationHigh, int i) =>
+ Get(container, threeStandardDeviationHigh, i);
+ static (int, List, List) Get(Container.Models.Container container, TimeSpan threeStandardDeviationHigh, int i) =>
+ Property.Get(container, threeStandardDeviationHigh, i);
+
+ bool TestStatic_Any(Container.Models.Container[] propertyHolderCollections) =>
+ Any(propertyHolderCollections);
+ static bool Any(Container.Models.Container[] propertyHolderCollections) =>
+ Property.Any(propertyHolderCollections);
+
+ double TestStatic_GetStandardDeviation(List values, double average) =>
+ GetStandardDeviation(values, average);
+ static double GetStandardDeviation(List values, double average) =>
+ Property.GetStandardDeviation(values, average);
+
}
\ No newline at end of file
diff --git a/Property/Models/Stateless/Property.cs b/Property/Models/Stateless/Property.cs
index b294a1f..ee90854 100644
--- a/Property/Models/Stateless/Property.cs
+++ b/Property/Models/Stateless/Property.cs
@@ -366,4 +366,112 @@ internal partial class Property
return new(property?.DateTimeOriginal, dateTimes, property?.Id, message);
}
+ internal static double GetStandardDeviation(List values, double average)
+ {
+ double result = 0;
+ if (values.Count == 0)
+ throw new Exception("Collection must have at least one value!");
+ double sum = values.Sum(l => (l - average) * (l - average));
+ result = Math.Sqrt(sum / values.Count);
+ return result;
+ }
+
+ private static long GetThreeStandardDeviationHigh(ref List ticksCollection, long min)
+ {
+ long result;
+ ticksCollection = (from l in ticksCollection select l - min).ToList();
+ double sum = ticksCollection.Sum();
+ double average = sum / ticksCollection.Count;
+ double standardDeviation = GetStandardDeviation(ticksCollection, average);
+ result = (long)Math.Ceiling(average + min + (standardDeviation * 3));
+ return result;
+ }
+
+ internal static TimeSpan GetThreeStandardDeviationHigh(int minimum, Container.Models.Container container)
+ {
+ TimeSpan result;
+ DateTime? minimumDateTime;
+ List ticksCollection = [];
+ foreach (Shared.Models.Item item in container.Items)
+ {
+ if (item.Property is null)
+ continue;
+ minimumDateTime = Shared.Models.Methods.IProperty.GetMinimumDateTime(item.Property);
+ if (minimumDateTime is null)
+ continue;
+ ticksCollection.Add(minimumDateTime.Value.Ticks);
+ }
+ long threeStandardDeviationHigh;
+ long min;
+ if (ticksCollection.Count == 0)
+ min = 0;
+ else
+ min = ticksCollection.Min();
+ if (ticksCollection.Count < minimum)
+ threeStandardDeviationHigh = long.MaxValue;
+ else
+ threeStandardDeviationHigh = GetThreeStandardDeviationHigh(ref ticksCollection, min);
+ result = new TimeSpan(threeStandardDeviationHigh - min);
+ return result;
+ }
+
+ internal static (int, List, List) Get(Container.Models.Container container, TimeSpan threeStandardDeviationHigh, int i)
+ {
+ List results = [];
+ int j = i;
+ long? ticks;
+ TimeSpan timeSpan;
+ Shared.Models.Item item;
+ DateTime? minimumDateTime;
+ Shared.Models.Item nextItem;
+ DateTime? nextMinimumDateTime;
+ List dateTimes = [];
+ for (; j < container.Items.Count; j++)
+ {
+ ticks = null;
+ item = container.Items[j];
+ if (item.Property is null)
+ continue;
+ minimumDateTime = Shared.Models.Methods.IProperty.GetMinimumDateTime(item.Property);
+ if (minimumDateTime is null)
+ continue;
+ for (int k = j + 1; k < container.Items.Count; k++)
+ {
+ nextItem = container.Items[k];
+ if (nextItem.Property is null)
+ continue;
+ nextMinimumDateTime = Shared.Models.Methods.IProperty.GetMinimumDateTime(nextItem.Property);
+ if (nextMinimumDateTime is null)
+ continue;
+ ticks = nextMinimumDateTime.Value.Ticks;
+ break;
+ }
+ results.Add(item);
+ dateTimes.Add(minimumDateTime.Value);
+ if (ticks.HasValue)
+ {
+ timeSpan = new(ticks.Value - minimumDateTime.Value.Ticks);
+ if (timeSpan > threeStandardDeviationHigh)
+ break;
+ }
+ }
+ return new(j, dateTimes, results);
+ }
+
+ internal static bool Any(Container.Models.Container[] containers)
+ {
+ bool result = false;
+ foreach (Container.Models.Container container in containers)
+ {
+ if (container.Items.Count == 0)
+ continue;
+ if ((from l in container.Items where l.Any() select true).Any())
+ {
+ result = true;
+ break;
+ }
+ }
+ return result;
+ }
+
}
\ No newline at end of file
diff --git a/Property/Property.csproj b/Property/Property.csproj
index 7b27266..4b5560c 100644
--- a/Property/Property.csproj
+++ b/Property/Property.csproj
@@ -46,6 +46,7 @@
+
\ No newline at end of file
diff --git a/Resize/Models/_C_Resize.cs b/Resize/Models/_C_Resize.cs
index bd523ae..40a1c83 100644
--- a/Resize/Models/_C_Resize.cs
+++ b/Resize/Models/_C_Resize.cs
@@ -315,7 +315,7 @@ public class C_Resize
throw new Exception();
}
- public void SaveResizedSubfile(Configuration configuration, string outputResolution, string cResultsFullGroupDirectory, List> subFileTuples, Item item, Shared.Models.Property property, MappingFromItem mappingFromItem, Dictionary outputResolutionToResize)
+ public void SaveResizedSubfile(Property.Models.Configuration configuration, string outputResolution, string cResultsFullGroupDirectory, List> subFileTuples, Item item, Shared.Models.Property property, MappingFromItem mappingFromItem, Dictionary outputResolutionToResize)
{
if (mappingFromItem.ResizedFileHolder is null)
throw new NullReferenceException(nameof(mappingFromItem.ResizedFileHolder));
@@ -462,7 +462,7 @@ public class C_Resize
}
}
- public Dictionary GetResizeKeyValuePairs(Configuration configuration, string cResultsFullGroupDirectory, FilePath filePath, List> subFileTuples, List parseExceptions, Shared.Models.Property property, MappingFromItem mappingFromItem)
+ public Dictionary GetResizeKeyValuePairs(Property.Models.Configuration configuration, string cResultsFullGroupDirectory, FilePath filePath, List> subFileTuples, List parseExceptions, Shared.Models.Property property, MappingFromItem mappingFromItem)
{
Dictionary? results;
string json;
diff --git a/Shared/Models/FilePair.cs b/Shared/Models/FilePair.cs
index 44e057a..3fbed92 100644
--- a/Shared/Models/FilePair.cs
+++ b/Shared/Models/FilePair.cs
@@ -3,7 +3,7 @@ using System.Text.Json.Serialization;
namespace View_by_Distance.Shared.Models;
-internal record FilePair(string Path,
+public record FilePair(string Path,
bool IsUnique,
bool? IsNotUniqueAndNeedsReview,
List Collection,
@@ -20,6 +20,6 @@ internal record FilePair(string Path,
[JsonSourceGenerationOptions(WriteIndented = true)]
[JsonSerializable(typeof(FilePair))]
-internal partial class FilePairSourceGenerationContext : JsonSerializerContext
+public partial class FilePairSourceGenerationContext : JsonSerializerContext
{
}
\ No newline at end of file
diff --git a/Shared/Models/Methods/IContainer.cs b/Shared/Models/Methods/IContainer.cs
deleted file mode 100644
index 3b7a13e..0000000
--- a/Shared/Models/Methods/IContainer.cs
+++ /dev/null
@@ -1,8 +0,0 @@
-namespace View_by_Distance.Shared.Models.Methods;
-
-public interface IContainer : Stateless.Methods.IContainer
-{ // ...
-
- //
-
-}
\ No newline at end of file
diff --git a/Shared/Models/Stateless/Methods/Container.cs b/Shared/Models/Stateless/Methods/Container.cs
deleted file mode 100644
index 057499d..0000000
--- a/Shared/Models/Stateless/Methods/Container.cs
+++ /dev/null
@@ -1,302 +0,0 @@
-using System.Collections.ObjectModel;
-using System.Text.Json;
-
-namespace View_by_Distance.Shared.Models.Stateless.Methods;
-
-internal abstract class Container
-{
-
- private record FilePair(bool IsUnique, List Collection, FilePath FilePath, Models.Item Item) { }
-
- internal static DateTime[] GetContainerDateTimes(ReadOnlyCollection items)
- {
- DateTime[] results;
- long containerMinimumTicks = (from l in items select l.FilePath.LastWriteTicks).Min();
- long containerMaximumTicks = (from l in items select l.FilePath.LastWriteTicks).Max();
- results = [new(containerMinimumTicks), new(containerMaximumTicks)];
- return results;
- }
-
- internal static ReadOnlyCollection GetValidImageItems(Properties.IPropertyConfiguration propertyConfiguration, Models.Container container)
- {
- List results = [];
- foreach (Models.Item item in container.Items)
- {
- if (!item.IsValidImageFormatExtension || propertyConfiguration.IgnoreExtensions.Contains(item.FilePath.ExtensionLowered))
- continue;
- results.Add(item);
- }
- return container.Items.Count == results.Count ? container.Items : results.AsReadOnly();
- }
-
- private static List GetFilePairs(Properties.IPropertyConfiguration propertyConfiguration, string directorySearchFilter, string extension, string aPropertySingletonDirectory, ReadOnlyCollection> filePathsCollection)
- {
- int renamed;
- const bool useCeilingAverage = true;
- List? filePairs = null;
- ReadOnlyCollection? jsonFilesCollection = null;
- IReadOnlyDictionary>? compareFileNamesToFiles = null;
- IReadOnlyDictionary> fileNamesToFiles = XDirectory.GetFilesKeyValuePairs(filePathsCollection);
- for (int i = 0; i < short.MaxValue; i++)
- {
- renamed = 0;
- jsonFilesCollection = IDirectory.GetFilesCollection(aPropertySingletonDirectory, directorySearchFilter, extension, useCeilingAverage);
- compareFileNamesToFiles = XDirectory.GetFilesKeyValuePairs(jsonFilesCollection);
- renamed += XDirectory.LookForAbandoned(jsonFilesCollection, fileNamesToFiles, extension);
- filePairs = XDirectory.GetFiles(propertyConfiguration, filePathsCollection, fileNamesToFiles, extension, compareFileNamesToFiles);
- renamed += XDirectory.MaybeMove(propertyConfiguration, filePairs, aPropertySingletonDirectory, extension);
- if (renamed == 0)
- break;
- if (i > 10)
- throw new NotImplementedException();
- }
- if (filePairs is null || jsonFilesCollection is null || compareFileNamesToFiles is null)
- throw new NullReferenceException(nameof(filePairs));
- return filePairs;
- }
-
- private static Models.Property? GetProperty(Models.FilePair filePair)
- {
- Models.Property? result;
- if (filePair.Match is null)
- result = null;
- else
- {
- string json = File.ReadAllText(filePair.Match);
- if (string.IsNullOrEmpty(json))
- result = null;
- else
- result = JsonSerializer.Deserialize(json, PropertyGenerationContext.Default.Property);
- }
- return result;
- }
-
- private static void MoveIf(string fileName, CombinedEnumAndIndex cei, string directory, string fullFileName)
- {
- string[] segments = directory.Split(cei.Combined);
- string? checkDirectory = segments.Length == 1 ?
- Path.Combine(segments[0], $"{cei.Combined[2..]}") :
- segments.Length == 2 ?
- $"{segments[0]}{cei.Combined[2..]}{segments[1]}" :
- null;
- if (checkDirectory is not null && Directory.Exists(checkDirectory))
- {
- string checkFile = Path.Combine(checkDirectory, fileName);
- if (File.Exists(checkFile))
- File.Move(checkFile, fullFileName);
- }
- }
-
- private static void ParallelFor(IDlibDotNet? dlibDotNet, Properties.IPropertyConfiguration propertyConfiguration, string aPropertySingletonDirectory, string extension, int rootDirectoryLength, ReadOnlyDictionary? splatNineIdentifiers, Models.FilePair filePair, List results)
- {
- dlibDotNet?.Tick();
- bool abandoned = false;
- Models.FileHolder sourceDirectoryFileHolder;
- Models.Property? property = GetProperty(filePair);
- Models.FileHolder imageFileHolder = IFileHolder.Get(filePair.Path);
- FilePath filePath = FilePath.Get(propertyConfiguration, imageFileHolder, index: null);
- bool? fileSizeChanged = property is not null ? property.FileSize != filePath.Length : null;
- bool isValidImageFormatExtension = propertyConfiguration.ValidImageFormatExtensions.Contains(filePath.ExtensionLowered);
- bool? shouldIgnore = property is null || property.Keywords is null ? null : propertyConfiguration.IgnoreRulesKeyWords.Any(l => property.Keywords.Contains(l));
- bool? isArchive = filePath.Id is null || splatNineIdentifiers is null ? null : splatNineIdentifiers.TryGetValue(filePath.Id.Value, out Identifier? identifier);
- if (shouldIgnore is not null)
- {
- if (shouldIgnore.Value)
- {
- FileInfo fileInfo = new(filePath.FullName);
- if (!fileInfo.Attributes.HasFlag(FileAttributes.Hidden))
- File.SetAttributes(imageFileHolder.FullName, FileAttributes.Hidden);
- }
- if (filePath.HasIgnoreKeyword is not null && filePath.HasIgnoreKeyword.Value != shouldIgnore.Value)
- {
- if (filePath.DirectoryFullPath.Contains("Results") && filePath.DirectoryFullPath.Contains("Resize"))
- File.Delete(filePath.FullName);
- else
- throw new NotSupportedException($"Rename File! <{filePath.FileNameFirstSegment}>");
- }
- }
- string relativePath = IPath.GetRelativePath(filePair.Path, rootDirectoryLength, forceExtensionToLower: true);
- bool? lastWriteTimeChanged = property is not null ? propertyConfiguration.PropertiesChangedForProperty || property.LastWriteTime.Ticks != filePath.LastWriteTicks : null;
- if (filePair.Match is not null)
- sourceDirectoryFileHolder = IFileHolder.Get(filePair.Match);
- else if (!filePair.IsUnique)
- sourceDirectoryFileHolder = IFileHolder.Get(Path.GetFullPath(string.Concat(aPropertySingletonDirectory, relativePath, extension)));
- else
- {
- string fileName = Path.GetFileName(filePair.Path);
- CombinedEnumAndIndex cei = IPath.GetCombinedEnumAndIndex(propertyConfiguration, filePath);
- string directory = Path.Combine(aPropertySingletonDirectory, cei.Combined);
- string jsonFileName = $"{fileName}{extension}";
- string fullFileName = Path.Combine(directory, jsonFileName);
- MoveIf(jsonFileName, cei, directory, fullFileName);
- sourceDirectoryFileHolder = IFileHolder.Get(fullFileName);
- }
- if (sourceDirectoryFileHolder.CreationTime is not null && sourceDirectoryFileHolder.LastWriteTime is not null && filePath.LastWriteTicks != sourceDirectoryFileHolder.CreationTime.Value.Ticks)
- {
- File.SetCreationTime(sourceDirectoryFileHolder.FullName, new(filePath.LastWriteTicks));
- File.SetLastWriteTime(sourceDirectoryFileHolder.FullName, sourceDirectoryFileHolder.LastWriteTime.Value);
- }
- Models.Item item = Models.Item.Get(filePath, sourceDirectoryFileHolder, relativePath, isArchive, filePair.IsNotUniqueAndNeedsReview, filePair.IsUnique, isValidImageFormatExtension, property, abandoned, fileSizeChanged, lastWriteTimeChanged);
- lock (results)
- results.Add(new(filePair.IsUnique, filePair.Collection, filePath, item));
- }
-
- private static List GetFilePairs(IDlibDotNet? dlibDotNet, Properties.IPropertyConfiguration propertyConfiguration, string aPropertySingletonDirectory, string filesCollectionDirectory, ReadOnlyDictionary? splatNineIdentifiers, ReadOnlyCollection> filePathsCollection, string directorySearchFilter)
- {
- List results = [];
- const string extension = ".json";
- int maxDegreeOfParallelism = Environment.ProcessorCount;
- int filesCollectionDirectoryLength = filesCollectionDirectory.Length;
- ParallelOptions parallelOptions = new() { MaxDegreeOfParallelism = maxDegreeOfParallelism };
- List filePairs = GetFilePairs(propertyConfiguration, directorySearchFilter, extension, aPropertySingletonDirectory, filePathsCollection);
- _ = Parallel.For(0, filePairs.Count, parallelOptions, (i, state) => ParallelFor(dlibDotNet, propertyConfiguration, aPropertySingletonDirectory, extension, filesCollectionDirectoryLength, splatNineIdentifiers, filePairs[i], results));
- return results;
- }
-
- private static (int, Models.Container[]) GetContainers(IDlibDotNet? dlibDotNet, Properties.IPropertyConfiguration propertyConfiguration, string aPropertySingletonDirectory, string filesCollectionDirectory, ReadOnlyDictionary? splatNineIdentifiers, ReadOnlyCollection> filePathsCollection, string directorySearchFilter)
- {
- List results = [];
- string directory;
- List? items;
- Models.Container container;
- List directories = [];
- Dictionary> directoryToItems = [];
- foreach (ReadOnlyCollection filePaths in filePathsCollection)
- {
- if (filePaths.Count == 0)
- continue;
- directory = filePaths[0].DirectoryFullPath;
- if (directory is null)
- continue;
- if (!directories.Contains(directory))
- directories.Add(directory);
- if (!directoryToItems.TryGetValue(directory, out items))
- {
- directoryToItems.Add(directory, []);
- if (!directoryToItems.TryGetValue(directory, out items))
- throw new Exception();
- }
- }
- List filePairs = GetFilePairs(dlibDotNet, propertyConfiguration, aPropertySingletonDirectory, filesCollectionDirectory, splatNineIdentifiers, filePathsCollection, directorySearchFilter);
- foreach (FilePair filePair in filePairs)
- {
- if (!directoryToItems.TryGetValue(filePair.FilePath.DirectoryFullPath, out items))
- {
- directoryToItems.Add(filePair.FilePath.DirectoryFullPath, []);
- if (!directoryToItems.TryGetValue(filePair.FilePath.DirectoryFullPath, out items))
- throw new Exception();
- }
- items.Add(filePair.Item);
- }
- foreach (KeyValuePair> keyValuePair in directoryToItems)
- {
- if (keyValuePair.Value.Count == 0)
- continue;
- container = new(keyValuePair.Key, new(keyValuePair.Value));
- results.Add(container);
- }
- return (filePairs.Count, results.ToArray());
- }
-
- internal static ReadOnlyCollection GetContainers(IDlibDotNet dlibDotNet, Properties.IPropertyConfiguration propertyConfiguration, string aPropertySingletonDirectory, string filesCollectionDirectory, ReadOnlyDictionary? splatNineIdentifiers, ReadOnlyCollection> filePathsCollection)
- {
- Models.Container[] results;
- const string directorySearchFilter = "*";
- (_, results) = GetContainers(dlibDotNet, propertyConfiguration, aPropertySingletonDirectory, filesCollectionDirectory, splatNineIdentifiers, filePathsCollection, directorySearchFilter);
- return results.AsReadOnly();
- }
-
- internal static (int, Models.Container[]) GetContainers(Properties.IPropertyConfiguration propertyConfiguration, ReadOnlyDictionary? splatNineIdentifiers, string aPropertySingletonDirectory)
- {
- int count;
- Models.Container[] results;
- IDlibDotNet? dlibDotNet = null;
- const bool useCeilingAverage = true;
- const string fileSearchFilter = "*";
- const string directorySearchFilter = "*";
- ReadOnlyCollection filesCollection = IDirectory.GetFilesCollection(propertyConfiguration.RootDirectory, directorySearchFilter, fileSearchFilter, useCeilingAverage);
- ReadOnlyCollection> filePathsCollection = IDirectory.GetFilePathCollections(propertyConfiguration, filesCollection);
- (count, results) = GetContainers(dlibDotNet, propertyConfiguration, aPropertySingletonDirectory, propertyConfiguration.RootDirectory, splatNineIdentifiers, filePathsCollection, directorySearchFilter);
- return (count, results);
- }
-
- internal static List GetFilteredDistinctIds(Properties.IPropertyConfiguration propertyConfiguration, ReadOnlyCollection readOnlyContainers)
- {
- List results = [];
- ReadOnlyCollection filteredItems;
- foreach (Models.Container container in readOnlyContainers)
- {
- if (container.Items.Count == 0)
- continue;
- filteredItems = GetValidImageItems(propertyConfiguration, container);
- if (filteredItems.Count == 0)
- 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;
- }
-
- internal static List GetFilteredDistinctFileNameFirstSegments(Properties.IPropertyConfiguration propertyConfiguration, ReadOnlyCollection readOnlyContainers)
- {
- List results = [];
- ReadOnlyCollection filteredItems;
- foreach (Models.Container container in readOnlyContainers)
- {
- if (container.Items.Count == 0)
- continue;
- filteredItems = GetValidImageItems(propertyConfiguration, container);
- if (filteredItems.Count == 0)
- continue;
- foreach (Models.Item item in filteredItems)
- {
- if (item.Property?.Id is null || item.ResizedFileHolder is null)
- continue;
- if (results.Contains(item.FilePath.FileNameFirstSegment))
- continue;
- results.Add(item.FilePath.FileNameFirstSegment);
- }
- }
- return results;
- }
-
- internal static ReadOnlyCollection GetValidImageItems(Properties.IPropertyConfiguration propertyConfiguration, ReadOnlyCollection containers, bool distinctItems, bool filterItems)
- {
- List results = [];
- List distinct = [];
- ReadOnlyCollection filteredItems;
- foreach (Models.Container container in containers)
- {
- if (container.Items.Count == 0)
- continue;
- if (!filterItems)
- filteredItems = container.Items;
- else
- {
- filteredItems = GetValidImageItems(propertyConfiguration, container);
- if (filteredItems.Count == 0)
- continue;
- }
- foreach (Models.Item item in filteredItems)
- {
- if (item.Property?.Id is null || item.ResizedFileHolder is null)
- continue;
- if (distinctItems)
- {
- if (distinct.Contains(item.Property.Id.Value))
- continue;
- distinct.Add(item.Property.Id.Value);
- }
- results.Add(item);
- }
- }
- return results.AsReadOnly();
- }
-
-}
\ No newline at end of file
diff --git a/Shared/Models/Stateless/Methods/IContainer.cs b/Shared/Models/Stateless/Methods/IContainer.cs
deleted file mode 100644
index ddf82e2..0000000
--- a/Shared/Models/Stateless/Methods/IContainer.cs
+++ /dev/null
@@ -1,48 +0,0 @@
-using System.Collections.ObjectModel;
-
-namespace View_by_Distance.Shared.Models.Stateless.Methods;
-
-public interface IContainer
-{
-
- DateTime[] TestStatic_GetContainerDateTimes(ReadOnlyCollection items) =>
- GetContainerDateTimes(items);
- static DateTime[] GetContainerDateTimes(ReadOnlyCollection items) =>
- Container.GetContainerDateTimes(items);
-
- ReadOnlyCollection TestStatic_GetValidImageItems(Properties.IPropertyConfiguration propertyConfiguration, Models.Container container) =>
- GetValidImageItems(propertyConfiguration, container);
- static ReadOnlyCollection GetValidImageItems(Properties.IPropertyConfiguration propertyConfiguration, Models.Container container) =>
- Container.GetValidImageItems(propertyConfiguration, container);
-
- (int, Models.Container[]) TestStatic_GetContainers(Properties.IPropertyConfiguration propertyConfiguration, string aPropertySingletonDirectory) =>
- GetContainers(propertyConfiguration, aPropertySingletonDirectory);
- static (int, Models.Container[]) GetContainers(Properties.IPropertyConfiguration propertyConfiguration, string aPropertySingletonDirectory) =>
- GetContainers(propertyConfiguration, null, aPropertySingletonDirectory);
-
- (int, Models.Container[]) TestStatic_GetContainers(Properties.IPropertyConfiguration propertyConfiguration, ReadOnlyDictionary? splatNineIdentifiers, string aPropertySingletonDirectory) =>
- GetContainers(propertyConfiguration, splatNineIdentifiers, aPropertySingletonDirectory);
- static (int, Models.Container[]) GetContainers(Properties.IPropertyConfiguration propertyConfiguration, ReadOnlyDictionary? splatNineIdentifiers, string aPropertySingletonDirectory) =>
- Container.GetContainers(propertyConfiguration, splatNineIdentifiers, aPropertySingletonDirectory);
-
- ReadOnlyCollection TestStatic_GetContainers(IDlibDotNet dlibDotNet, Properties.IPropertyConfiguration propertyConfiguration, string aPropertySingletonDirectory, string filesCollectionDirectory, ReadOnlyDictionary? splatNineIdentifiers, ReadOnlyCollection> filePathsCollection) =>
- GetContainers(dlibDotNet, propertyConfiguration, aPropertySingletonDirectory, filesCollectionDirectory, splatNineIdentifiers, filePathsCollection);
- static ReadOnlyCollection GetContainers(IDlibDotNet dlibDotNet, Properties.IPropertyConfiguration propertyConfiguration, string aPropertySingletonDirectory, string filesCollectionDirectory, ReadOnlyDictionary? splatNineIdentifiers, ReadOnlyCollection> filePathsCollection) =>
- Container.GetContainers(dlibDotNet, propertyConfiguration, aPropertySingletonDirectory, filesCollectionDirectory, splatNineIdentifiers, filePathsCollection);
-
- List TestStatic_GetFilteredDistinctIds(Properties.IPropertyConfiguration propertyConfiguration, ReadOnlyCollection readOnlyContainers) =>
- GetFilteredDistinctIds(propertyConfiguration, readOnlyContainers);
- static List GetFilteredDistinctIds(Properties.IPropertyConfiguration propertyConfiguration, ReadOnlyCollection readOnlyContainers) =>
- Container.GetFilteredDistinctIds(propertyConfiguration, readOnlyContainers);
-
- List TestStatic_GetFilteredDistinctFileNameFirstSegments(Properties.IPropertyConfiguration propertyConfiguration, ReadOnlyCollection readOnlyContainers) =>
- GetFilteredDistinctFileNameFirstSegments(propertyConfiguration, readOnlyContainers);
- static List GetFilteredDistinctFileNameFirstSegments(Properties.IPropertyConfiguration propertyConfiguration, ReadOnlyCollection readOnlyContainers) =>
- Container.GetFilteredDistinctFileNameFirstSegments(propertyConfiguration, readOnlyContainers);
-
- ReadOnlyCollection