FilePath ready to test

This commit is contained in:
Mike Phares 2023-12-24 11:29:36 -07:00
parent af491371a3
commit 7007a9df2e
60 changed files with 960 additions and 857 deletions

14
.vscode/mklink.md vendored Normal file
View File

@ -0,0 +1,14 @@
---
type: "note"
created: "2023-10-20T03:56:21.490Z"
updated: "2023-10-20T03:57:15.006Z"
---
# mklink
```bash
```
```bash
mklink /J "D:\1-Images-A\Images-4083e56a-Results\A2)People\4083e56a\{}\!" "D:\1-Images-A\Images-4083e56a-Results\E)Distance\4083e56a\{}\!"
```

View File

@ -1,3 +1,4 @@
using System.Collections.ObjectModel;
using System.Drawing;
using System.Text;
using View_by_Distance.Shared.Models;
@ -21,7 +22,7 @@ public class C2_BlurHasher : IBlurHasher
public void Update(string resultsFullGroupDirectory)
{
_FileGroups.Clear();
Dictionary<string, string[]> keyValuePairs = Shared.Models.Stateless.Methods.IPath.GetKeyValuePairs(_PropertyConfiguration, resultsFullGroupDirectory, [_PropertyConfiguration.ResultContent, _PropertyConfiguration.ResultSingleton]);
ReadOnlyDictionary<string, string[]> keyValuePairs = Shared.Models.Stateless.Methods.IPath.GetKeyValuePairs(_PropertyConfiguration, resultsFullGroupDirectory, [_PropertyConfiguration.ResultContent, _PropertyConfiguration.ResultSingleton]);
foreach (KeyValuePair<string, string[]> keyValuePair in keyValuePairs)
_FileGroups.Add(keyValuePair.Key, keyValuePair.Value);
}
@ -39,17 +40,17 @@ public class C2_BlurHasher : IBlurHasher
return result;
}
string IBlurHasher.GetFile(FileHolder fileHolder)
string IBlurHasher.GetFile(FilePath filePath)
{
string result;
if (_FileGroups.Count == 0)
throw new Exception("Call Update first!");
(_, int directoryIndex) = Shared.Models.Stateless.Methods.IPath.GetDirectoryNameAndIndex(_PropertyConfiguration.ResultAllInOneSubdirectoryLength, fileHolder.Name);
result = Path.Combine(_FileGroups[_PropertyConfiguration.ResultSingleton][directoryIndex], $"{fileHolder.Name}.csv");
(_, int directoryIndex) = Shared.Models.Stateless.Methods.IPath.GetDirectoryNameAndIndex(_PropertyConfiguration, filePath);
result = Path.Combine(_FileGroups[_PropertyConfiguration.ResultSingleton][directoryIndex], $"{filePath.Name}.csv");
return result;
}
string IBlurHasher.EncodeAndSave(FileHolder fileHolder)
string IBlurHasher.EncodeAndSave(FilePath filePath, FileHolder fileHolder)
{
string result;
if (_FileGroups.Count == 0)
@ -57,7 +58,7 @@ public class C2_BlurHasher : IBlurHasher
int actualByte;
string extension = ".png";
IBlurHasher blurHasher = this;
string file = blurHasher.GetFile(fileHolder);
string file = blurHasher.GetFile(filePath);
#pragma warning disable CA1416
Image image = Image.FromFile(fileHolder.FullName);
int outputWidth = (int)(image.Width * .25);
@ -71,7 +72,7 @@ public class C2_BlurHasher : IBlurHasher
string fileNameWithoutExtension = $"{componentsX}x{componentsY}-{outputWidth}x{outputHeight}-{joined}";
string contents = string.Concat(result, Environment.NewLine, fileNameWithoutExtension, Environment.NewLine, extension);
_ = Shared.Models.Stateless.Methods.IPath.WriteAllText(file, contents, updateDateWhenMatches: false, compareBeforeWrite: true, updateToWhenMatches: null);
(_, int directoryIndex) = Shared.Models.Stateless.Methods.IPath.GetDirectoryNameAndIndex(_PropertyConfiguration.ResultAllInOneSubdirectoryLength, joined);
(_, int directoryIndex) = Shared.Models.Stateless.Methods.IPath.GetDirectoryNameAndIndex(_PropertyConfiguration, filePath);
file = Path.Combine(_FileGroups[_PropertyConfiguration.ResultContent][directoryIndex], $"{fileNameWithoutExtension}{extension}");
if (!File.Exists(file))
{

View File

@ -6,6 +6,7 @@ using System.Collections.ObjectModel;
using View_by_Distance.Copy.Distinct.Models;
using View_by_Distance.Shared.Models;
using View_by_Distance.Shared.Models.Methods;
using View_by_Distance.Shared.Models.Stateless.Methods;
namespace View_by_Distance.Copy.Distinct;
@ -17,7 +18,7 @@ public class CopyDistinct
private readonly Configuration _Configuration;
private readonly IsEnvironment _IsEnvironment;
private readonly IConfigurationRoot _ConfigurationRoot;
private readonly IReadOnlyDictionary<string, string[]> _FileGroups;
private readonly ReadOnlyDictionary<string, string[]> _FileGroups;
private readonly Property.Models.Configuration _PropertyConfiguration;
public CopyDistinct(List<string> args, ILogger<Program> logger, IsEnvironment isEnvironment, IConfigurationRoot configurationRoot, AppSettings appSettings, string workingDirectory, bool isSilent, IConsole console)
@ -63,7 +64,7 @@ public class CopyDistinct
const string directorySearchFilter = "*";
string copyTo = Path.GetFullPath(_AppSettings.CopyTo);
bool move = copyTo == _PropertyConfiguration.RootDirectory;
ReadOnlyCollection<string[]> filesCollection = Shared.Models.Stateless.Methods.IDirectory.GetFilesCollection(_PropertyConfiguration.RootDirectory, directorySearchFilter, fileSearchFilter, useCeilingAverage);
ReadOnlyCollection<string[]> filesCollection = IDirectory.GetFilesCollection(_PropertyConfiguration.RootDirectory, directorySearchFilter, fileSearchFilter, useCeilingAverage);
bool anyLenFiles = filesCollection.Any(l => l.Any(m => m.EndsWith("len")));
if (!move)
moveBack = false;
@ -92,13 +93,15 @@ public class CopyDistinct
return (move, new(filesCollection), anyLenFiles, moveBack);
}
private static (string[], List<(FileHolder, string?, string)>) GetMoveBackToDoCollection(ReadOnlyCollection<string[]> filesCollection)
private static (string[], List<(FilePath, string)>) GetMoveBackToDoCollection(Property.Models.Configuration propertyConfiguration, ReadOnlyCollection<string[]> filesCollection)
{
List<(FileHolder, string?, string)> results = [];
List<(FilePath, string)> results = [];
string key;
string? value;
string fileName;
FilePath filePath;
string? directory;
FileHolder fileHolder;
string destinationFile;
List<string> distinctFound = [];
List<string> distinctNeeded = [];
@ -146,7 +149,9 @@ public class CopyDistinct
directory = Path.GetDirectoryName(value);
if (string.IsNullOrEmpty(directory))
continue;
results.Add(new(new(file), null, value));
fileHolder = Shared.Models.Stateless.Methods.IFileHolder.Get(file);
filePath = FilePath.Get(propertyConfiguration, fileHolder, index: null);
results.Add(new(filePath, value));
if (!distinctDirectories.Contains(directory))
distinctDirectories.Add(directory);
}
@ -161,21 +166,21 @@ public class CopyDistinct
string[] distinctDirectories;
ConsoleKey? consoleKey = null;
string message = nameof(CopyDistinct);
List<(FileHolder, string?, string)> toDoCollection;
List<(FilePath, string)> toDoCollection;
int count = filesCollection.Select(l => l.Length).Sum();
ProgressBarOptions options = new() { ProgressCharacter = '─', ProgressBarOnBottom = true, DisableBottomPercentage = true };
if (moveBack)
{
if (!anyLenFiles)
throw new NotSupportedException();
(distinctDirectories, toDoCollection) = GetMoveBackToDoCollection(filesCollection);
(distinctDirectories, toDoCollection) = GetMoveBackToDoCollection(_PropertyConfiguration, filesCollection);
}
else
{
progressBar = new(count, message, options);
string key = string.IsNullOrEmpty(_AppSettings.ResultDirectoryKey) ? _PropertyConfiguration.ResultAllInOne : _AppSettings.ResultDirectoryKey;
string[] directories = _FileGroups[key];
(distinctDirectories, toDoCollection) = Shared.Models.Stateless.Methods.IDirectory.GetToDoCollection(_PropertyConfiguration, _AppSettings.CopyDuplicates, _AppSettings.IfCanUseId, filesCollection, directories, () => progressBar.Tick());
(distinctDirectories, toDoCollection) = IDirectory.GetToDoCollection(_PropertyConfiguration, _AppSettings.CopyDuplicates, _AppSettings.IfCanUseId, filesCollection, directories, () => progressBar.Tick());
progressBar.Dispose();
}
foreach (string distinctDirectory in distinctDirectories)
@ -212,7 +217,7 @@ public class CopyDistinct
else
{
progressBar = new(count, message, options);
results.AddRange(Shared.Models.Stateless.Methods.IDirectory.CopyOrMove(toDoCollection, move, moveBack, () => progressBar.Tick()));
results.AddRange(IDirectory.CopyOrMove(toDoCollection, move, moveBack, () => progressBar.Tick()));
progressBar.Dispose();
if (move || moveBack)
logger?.LogInformation("Done moving");

View File

@ -11,7 +11,7 @@ namespace View_by_Distance.Distance.Models;
public partial class E_Distance : IDistance<MetadataExtractor.Directory>
{
internal record Record(string File, FaceRecognitionDotNet.FaceEncoding FaceRecognitionDotNetFaceEncoding);
internal record Record(FilePath FilePath, FaceRecognitionDotNet.FaceEncoding FaceRecognitionDotNetFaceEncoding);
private readonly List<string> _Moved;
private readonly List<double?> _Debug;
@ -40,11 +40,11 @@ public partial class E_Distance : IDistance<MetadataExtractor.Directory>
_RangeDistanceToleranceAverage = rangeDistanceTolerance.Average();
}
private static void MoveUnableToMatch(string file)
private static void MoveUnableToMatch(FilePath filePath)
{
string checkFile = $"{file}.unk";
if (File.Exists(file) && !File.Exists(checkFile))
File.Move(file, checkFile);
string checkFile = $"{filePath.FullName}.unk";
if (File.Exists(filePath.FullName) && !File.Exists(checkFile))
File.Move(filePath.FullName, checkFile);
}
private FaceDistanceContainer[] GetFaceDistanceContainers(MappingFromItem mappingFromItem, List<Face> intersectFaces)
@ -150,7 +150,7 @@ public partial class E_Distance : IDistance<MetadataExtractor.Directory>
return results;
}
private static FileInfo? CheckFileThenGetFileInfo(string facesFileNameExtension, MappingFromItem mappingFromItem, string file, List<(Face, double?)> checkFaces)
private static FileInfo? CheckFileThenGetFileInfo(string facesFileNameExtension, FilePath filePath, MappingFromItem mappingFromItem, string file, List<(Face, double?)> checkFaces)
{
FileInfo? result = null;
string checkFile;
@ -165,7 +165,7 @@ public partial class E_Distance : IDistance<MetadataExtractor.Directory>
mappedFaceDirectory = Path.GetDirectoryName(file);
if (mappedFaceDirectory is null)
throw new NotSupportedException();
deterministicHashCodeKey = Shared.Models.Stateless.Methods.IMapping.GetDeterministicHashCodeKey(mappingFromItem.Id, face.Location, Shared.Models.Stateless.ILocation.Digits, face.OutputResolution);
deterministicHashCodeKey = Shared.Models.Stateless.Methods.IMapping.GetDeterministicHashCodeKey(filePath, face.Location, Shared.Models.Stateless.ILocation.Digits, face.OutputResolution);
checkFile = Path.Combine(mappedFaceDirectory, $"{deterministicHashCodeKey}{mappingFromItem.ImageFileHolder.ExtensionLowered}{facesFileNameExtension}");
if (checkFile == file)
continue;
@ -201,10 +201,9 @@ public partial class E_Distance : IDistance<MetadataExtractor.Directory>
}
}
public void LookForMatchFacesAndPossiblyRename(string facesFileNameExtension, MappingFromItem mappingFromItem, List<Face> faces, ReadOnlyCollection<LocationContainer<MetadataExtractor.Directory>> locationContainers)
public void LookForMatchFacesAndPossiblyRename(string facesFileNameExtension, FilePath filePath, MappingFromItem mappingFromItem, List<Face> faces, ReadOnlyCollection<LocationContainer<MetadataExtractor.Directory>> locationContainers)
{
string? json;
string fileName;
string[] matches;
FileInfo? fileInfo;
List<Face> intersectFaces;
@ -215,10 +214,9 @@ public partial class E_Distance : IDistance<MetadataExtractor.Directory>
checkFaces.Clear();
foreach (LocationContainer<MetadataExtractor.Directory> locationContainer in locationContainers)
{
if (_Renamed.Contains(locationContainer.File))
if (_Renamed.Contains(locationContainer.FilePath.FullName))
continue;
fileName = Path.GetFileName(locationContainer.File);
if (locationContainer.FromDistanceContent && _DuplicateMappedFaceFiles.Contains(fileName))
if (locationContainer.FromDistanceContent && _DuplicateMappedFaceFiles.Contains(locationContainer.FilePath.Name))
continue;
checkFaces.Clear();
if (locationContainer.Directories.Count == 0)
@ -231,7 +229,7 @@ public partial class E_Distance : IDistance<MetadataExtractor.Directory>
if (json is null)
{
if (_DistanceMoveUnableToMatch)
MoveUnableToMatch(locationContainer.File);
MoveUnableToMatch(locationContainer.FilePath);
continue;
}
if (filteredFaces.Length > 0)
@ -254,42 +252,42 @@ public partial class E_Distance : IDistance<MetadataExtractor.Directory>
if (checkFaces.Count == 0)
{
if (_DistanceMoveUnableToMatch)
MoveUnableToMatch(locationContainer.File);
MoveUnableToMatch(locationContainer.FilePath);
continue;
}
if (checkFaces.Count != 1)
{
if (_DistanceMoveUnableToMatch)
MoveUnableToMatch(locationContainer.File);
MoveUnableToMatch(locationContainer.FilePath);
continue;
}
fileInfo = CheckFileThenGetFileInfo(facesFileNameExtension, mappingFromItem, locationContainer.File, checkFaces);
fileInfo = CheckFileThenGetFileInfo(facesFileNameExtension, filePath, mappingFromItem, locationContainer.FilePath.FullName, checkFaces);
if (fileInfo is not null)
{
if (_DistanceRenameToMatch && fileInfo is not null)
{
if (fileInfo.Exists)
File.Delete(locationContainer.File);
File.Delete(locationContainer.FilePath.FullName);
else
File.Move(locationContainer.File, fileInfo.FullName);
File.WriteAllText($"{fileInfo.FullName}.old", $"{fileInfo.FullName}{Environment.NewLine}{locationContainer.File}");
_Renamed.Add(locationContainer.File);
File.Move(locationContainer.FilePath.FullName, fileInfo.FullName);
File.WriteAllText($"{fileInfo.FullName}.old", $"{fileInfo.FullName}{Environment.NewLine}{locationContainer.FilePath.FullName}");
_Renamed.Add(locationContainer.FilePath.FullName);
}
continue;
}
if (_AllMappedFaceFileNames.Contains(fileName))
if (_AllMappedFaceFileNames.Contains(locationContainer.FilePath.Name))
{
lock (_AllMappedFaceFiles)
matches = (from l in _AllMappedFaceFiles where l != locationContainer.File && Path.GetFileName(l) == fileName select l).ToArray();
matches = (from l in _AllMappedFaceFiles where l != locationContainer.FilePath.FullName && Path.GetFileName(l) == locationContainer.FilePath.Name select l).ToArray();
if (locationContainer.FromDistanceContent && matches.Length > 0)
AppendMatchingDuplicates(locationContainer.File, matches);
AppendMatchingDuplicates(locationContainer.FilePath.FullName, matches);
}
if (!locationContainer.FromDistanceContent)
continue;
lock (_AllMappedFaceFiles)
_AllMappedFaceFiles.Add(locationContainer.File);
_AllMappedFaceFiles.Add(locationContainer.FilePath.FullName);
lock (_AllMappedFaceFileNames)
_AllMappedFaceFileNames.Add(fileName);
_AllMappedFaceFileNames.Add(locationContainer.FilePath.Name);
}
}
@ -491,13 +489,13 @@ public partial class E_Distance : IDistance<MetadataExtractor.Directory>
List<FaceDistance> faceDistanceEncodings = [];
foreach (Record record in records)
{
files.Add(record.File);
files.Add(record.FilePath.FullName);
faceDistanceEncodings.Add(new(record.FaceRecognitionDotNetFaceEncoding));
}
foreach (Record record in records)
{
mappedRelations = [];
fileHolder = new(record.File);
fileHolder = Shared.Models.Stateless.Methods.IFileHolder.Get(record.FilePath.FullName);
if (files.Count > 1)
{
faceDistanceEncoding = new(record.FaceRecognitionDotNetFaceEncoding);
@ -538,7 +536,7 @@ public partial class E_Distance : IDistance<MetadataExtractor.Directory>
if (modelsFaceEncoding is null)
throw new NotSupportedException();
faceRecognitionDotNetFaceEncoding = FaceRecognition.LoadFaceEncoding(modelsFaceEncoding.RawEncoding);
records.Add(new(locationContainer.File, faceRecognitionDotNetFaceEncoding));
records.Add(new(locationContainer.FilePath, faceRecognitionDotNetFaceEncoding));
}
result = GetRelationCollections(faceDistancePermyriad, locationContainerDistanceTake, locationContainerDistanceTolerance, records);
return result;

View File

@ -114,7 +114,7 @@ public partial class DragDropSetPropertyItem : Form
bool isValidImageFormatExtension;
foreach (string file in files)
{
fileHolder = new(file);
fileHolder = IFileHolder.Get(file);
isValidImageFormatExtension = _PropertyConfiguration.ValidImageFormatExtensions.Contains(fileHolder.ExtensionLowered);
isIgnoreExtension = isValidImageFormatExtension && _PropertyConfiguration.IgnoreExtensions.Contains(fileHolder.ExtensionLowered);
(dateTimeOriginal, _, id, message) = Property.Models.Stateless.IProperty.Get(_PropertyConfiguration.PopulatePropertyId, fileHolder, isIgnoreExtension, isValidImageFormatExtension, asciiEncoding);

View File

@ -187,11 +187,11 @@ public class DuplicateSearch
mappingFromItem = collection[zero];
if (mappingFromItem is not null)
{
resizedFileHolder = new(mappingFromItem.ResizedFileHolder.FullName.Replace($"0{duplicates}", $"1{duplicates}"));
resizedFileHolder = Shared.Models.Stateless.Methods.IFileHolder.Get(mappingFromItem.ResizedFileHolder.FullName.Replace($"0{duplicates}", $"1{duplicates}"));
collection[0] = new(mappingFromItem.ContainerDateTimes, item.Property.DateTimeDigitized, item.Property.DateTimeOriginal, mappingFromItem.Id, mappingFromItem.ImageFileHolder, mappingFromItem.IsWrongYear, item.Property.Keywords ?? [], mappingFromItem.MinimumDateTime, item.Property.Model, mappingFromItem.RelativePath, resizedFileHolder);
}
}
resizedFileHolder = new(string.Concat(Path.Combine(destinationRoot, directory), item.RelativePath));
resizedFileHolder = Shared.Models.Stateless.Methods.IFileHolder.Get(string.Concat(Path.Combine(destinationRoot, directory), item.RelativePath));
mappingFromItem = Shared.Models.Stateless.Methods.IMappingFromItem.GetMappingFromItem(containerDateTimes, item, resizedFileHolder);
collection.Add(mappingFromItem);
}

View File

@ -101,7 +101,7 @@ public class D_Face
public void Update(string dResultsFullGroupDirectory)
{
_FileGroups.Clear();
Dictionary<string, string[]> keyValuePairs = Shared.Models.Stateless.Methods.IPath.GetKeyValuePairs(_PropertyConfiguration, dResultsFullGroupDirectory, [_PropertyConfiguration.ResultCollection, _PropertyConfiguration.ResultContent]);
ReadOnlyDictionary<string, string[]> keyValuePairs = Shared.Models.Stateless.Methods.IPath.GetKeyValuePairs(_PropertyConfiguration, dResultsFullGroupDirectory, [_PropertyConfiguration.ResultCollection, _PropertyConfiguration.ResultContent]);
foreach (KeyValuePair<string, string[]> keyValuePair in keyValuePairs)
_FileGroups.Add(keyValuePair.Key, keyValuePair.Value);
}
@ -302,7 +302,7 @@ public class D_Face
locationContainer.Directories,
locationContainer.DirectoryNumber,
locationContainer.DisplayDirectoryName,
locationContainer.File,
locationContainer.FilePath,
locationContainer.FromDistanceContent,
locationContainer.Id,
location,
@ -316,7 +316,7 @@ public class D_Face
return results;
}
public List<Shared.Models.Face> GetFaces(string outputResolution, string dResultsFullGroupDirectory, List<Tuple<string, DateTime>> subFileTuples, List<string> parseExceptions, Shared.Models.Property property, MappingFromItem mappingFromItem, Dictionary<string, int[]> outputResolutionToResize, ReadOnlyCollection<LocationContainer<MetadataExtractor.Directory>>? locationContainers, List<MappingFromPhotoPrism>? mappingFromPhotoPrismCollection)
public List<Shared.Models.Face> GetFaces(string outputResolution, string dResultsFullGroupDirectory, FilePath filePath, List<Tuple<string, DateTime>> subFileTuples, List<string> parseExceptions, Shared.Models.Property property, MappingFromItem mappingFromItem, Dictionary<string, int[]> outputResolutionToResize, ReadOnlyCollection<LocationContainer<MetadataExtractor.Directory>>? locationContainers, List<MappingFromPhotoPrism>? mappingFromPhotoPrismCollection)
{
List<Shared.Models.Face>? results;
if (string.IsNullOrEmpty(dResultsFullGroupDirectory))
@ -325,7 +325,7 @@ public class D_Face
List<Location>? locations;
string[] changesFrom = [nameof(A_Property), nameof(B_Metadata), nameof(C_Resize)];
List<DateTime> dateTimes = (from l in subFileTuples where changesFrom.Contains(l.Item1) select l.Item2).ToList();
(_, int directoryIndex) = Shared.Models.Stateless.Methods.IPath.GetDirectoryNameAndIndex(_PropertyConfiguration.ResultAllInOneSubdirectoryLength, mappingFromItem.ImageFileHolder.Name);
(_, int directoryIndex) = Shared.Models.Stateless.Methods.IPath.GetDirectoryNameAndIndex(_PropertyConfiguration, filePath);
FileInfo fileInfo = new(Path.Combine(_FileGroups[_PropertyConfiguration.ResultCollection][directoryIndex], $"{mappingFromItem.ImageFileHolder.NameWithoutExtension}{mappingFromItem.ImageFileHolder.ExtensionLowered}.json"));
if (_ForceFaceLastWriteTimeToCreationTime && !fileInfo.Exists && File.Exists(Path.ChangeExtension(fileInfo.FullName, ".delete")))
{
@ -394,7 +394,7 @@ public class D_Face
return results;
}
public List<(Shared.Models.Face, FileInfo?, string, bool)> SaveFaces(string f, string dResultsFullGroupDirectory, List<Tuple<string, DateTime>> subFileTuples, List<string> parseExceptions, MappingFromItem mappingFromItem, List<Shared.Models.Face> faces)
public List<(Shared.Models.Face, FileInfo?, string, bool)> SaveFaces(string f, string dResultsFullGroupDirectory, FilePath filePath, List<Tuple<string, DateTime>> subFileTuples, List<string> parseExceptions, MappingFromItem mappingFromItem, List<Shared.Models.Face> faces)
{
List<(Shared.Models.Face, FileInfo?, string, bool Save)> results = [];
bool save;
@ -402,7 +402,7 @@ public class D_Face
string deterministicHashCodeKey;
string[] changesFrom = [nameof(A_Property), nameof(B_Metadata), nameof(C_Resize)];
List<DateTime> dateTimes = (from l in subFileTuples where changesFrom.Contains(l.Item1) select l.Item2).ToList();
(_, int directoryIndex) = Shared.Models.Stateless.Methods.IPath.GetDirectoryNameAndIndex(_PropertyConfiguration.ResultAllInOneSubdirectoryLength, mappingFromItem.ImageFileHolder.Name);
(_, int directoryIndex) = Shared.Models.Stateless.Methods.IPath.GetDirectoryNameAndIndex(_PropertyConfiguration, filePath);
string directory = Path.Combine(_FileGroups[_PropertyConfiguration.ResultContent][directoryIndex], mappingFromItem.ImageFileHolder.NameWithoutExtension);
bool directoryExists = Directory.Exists(directory);
foreach (Shared.Models.Face face in faces)
@ -413,7 +413,7 @@ public class D_Face
results.Add(new(face, null, string.Empty, save));
continue;
}
deterministicHashCodeKey = Shared.Models.Stateless.Methods.IMapping.GetDeterministicHashCodeKey(mappingFromItem.Id, face.Location, Shared.Models.Stateless.ILocation.Digits, face.OutputResolution);
deterministicHashCodeKey = Shared.Models.Stateless.Methods.IMapping.GetDeterministicHashCodeKey(filePath, face.Location, Shared.Models.Stateless.ILocation.Digits, face.OutputResolution);
fileInfo = new FileInfo(Path.Combine(directory, $"{deterministicHashCodeKey}{mappingFromItem.ImageFileHolder.ExtensionLowered}{_FileNameExtension}"));
if (!directoryExists)
save = true;

View File

@ -1,3 +1,4 @@
using System.Collections.ObjectModel;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
@ -51,7 +52,7 @@ public class D2_FaceParts
public void Update(string dResultsFullGroupDirectory)
{
_FileGroups.Clear();
Dictionary<string, string[]> keyValuePairs = Shared.Models.Stateless.Methods.IPath.GetKeyValuePairs(_PropertyConfiguration, dResultsFullGroupDirectory, [_PropertyConfiguration.ResultContent]);
ReadOnlyDictionary<string, string[]> keyValuePairs = Shared.Models.Stateless.Methods.IPath.GetKeyValuePairs(_PropertyConfiguration, dResultsFullGroupDirectory, [_PropertyConfiguration.ResultContent]);
foreach (KeyValuePair<string, string[]> keyValuePair in keyValuePairs)
_FileGroups.Add(keyValuePair.Key, keyValuePair.Value);
}
@ -182,7 +183,7 @@ public class D2_FaceParts
return result;
}
private void SaveFaceParts(int pointSize, IFileHolder resizedFileHolder, bool saveRotated, List<(Shared.Models.Face, string, string)> collection)
private void SaveFaceParts(int pointSize, FileHolder resizedFileHolder, bool saveRotated, List<(Shared.Models.Face, string, string)> collection)
{
int x;
int y;
@ -244,7 +245,7 @@ public class D2_FaceParts
#pragma warning restore CA1416
public void SaveFaceLandmarkImages(Configuration configuration, List<Tuple<string, DateTime>> subFileTuples, List<string> parseExceptions, MappingFromItem mappingFromItem, List<Shared.Models.Face> faces, bool saveRotated)
public void SaveFaceLandmarkImages(Configuration configuration, FilePath filePath, List<Tuple<string, DateTime>> subFileTuples, List<string> parseExceptions, MappingFromItem mappingFromItem, List<Shared.Models.Face> faces, bool saveRotated)
{
FileInfo fileInfo;
bool check = false;
@ -257,7 +258,7 @@ public class D2_FaceParts
List<(Shared.Models.Face, string, string)> collection = [];
string[] changesFrom = [nameof(A_Property), nameof(B_Metadata), nameof(C_Resize), nameof(D_Face)];
List<DateTime> dateTimes = (from l in subFileTuples where changesFrom.Contains(l.Item1) select l.Item2).ToList();
(_, int directoryIndex) = Shared.Models.Stateless.Methods.IPath.GetDirectoryNameAndIndex(_PropertyConfiguration.ResultAllInOneSubdirectoryLength, mappingFromItem.ImageFileHolder.Name);
(_, int directoryIndex) = Shared.Models.Stateless.Methods.IPath.GetDirectoryNameAndIndex(_PropertyConfiguration, filePath);
string directory = Path.Combine(_FileGroups[_PropertyConfiguration.ResultContent][directoryIndex], mappingFromItem.ImageFileHolder.NameWithoutExtension);
bool directoryExists = Directory.Exists(directory);
foreach (Shared.Models.Face face in faces)
@ -267,7 +268,7 @@ public class D2_FaceParts
collection.Add(new(face, string.Empty, string.Empty));
continue;
}
deterministicHashCodeKey = Shared.Models.Stateless.Methods.IMapping.GetDeterministicHashCodeKey(mappingFromItem.Id, face.Location, Shared.Models.Stateless.ILocation.Digits, face.OutputResolution);
deterministicHashCodeKey = Shared.Models.Stateless.Methods.IMapping.GetDeterministicHashCodeKey(filePath, face.Location, Shared.Models.Stateless.ILocation.Digits, face.OutputResolution);
fileInfo = new FileInfo(Path.Combine(directory, $"{deterministicHashCodeKey}{mappingFromItem.ImageFileHolder.ExtensionLowered}{_FileNameExtension}"));
if (string.IsNullOrEmpty(fileInfo.DirectoryName))
continue;

View File

@ -127,7 +127,7 @@ public partial class DlibDotNet
_ = Shared.Models.Stateless.Methods.IPath.DeleteEmptyDirectories(Path.Combine(peopleRootDirectory, propertyConfiguration.ResultSingleton));
string a2PeopleSingletonDirectory = Property.Models.Stateless.IResult.GetResultsDateGroupDirectory(configuration.PropertyConfiguration, nameof(A2_People), "{}");
string a2PeopleContentDirectory = Property.Models.Stateless.IResult.GetResultsDateGroupDirectory(configuration.PropertyConfiguration, nameof(A2_People), "([])");
personContainers = new(IPersonContainer.GetPersonContainers(a2PeopleSingletonDirectory, configuration.PersonBirthdayFormat, configuration.PersonCharacters.ToArray(), _Faces.FileNameExtension));
personContainers = new(IPersonContainer.GetPersonContainers(a2PeopleSingletonDirectory, configuration.PersonBirthdayFormat, configuration.PersonCharacters.ToArray(), configuration.PropertyConfiguration, _Faces.FileNameExtension));
if (configuration.JLinks.Where(l => !string.IsNullOrEmpty(l)).Any())
{
_JLinkResolvedDirectories.AddRange(Map.Models.Stateless.Methods.IMapLogic.GetJLinkDirectories(configuration.GenealogicalDataCommunicationFile, configuration.JLinks, configuration.PersonBirthdayFormat, configuration.PersonCharacters.ToArray(), a2PeopleSingletonDirectory, a2PeopleContentDirectory));
@ -237,6 +237,7 @@ public partial class DlibDotNet
private ReadOnlyCollection<int> GetNotNineCollection(ReadOnlyCollection<string[]> filesCollection)
{
List<int> results = [];
FilePath filePath;
FileHolder fileHolder;
foreach (string[] files in filesCollection)
{
@ -244,11 +245,11 @@ public partial class DlibDotNet
{
if (!file.Contains(" !9"))
continue;
fileHolder = new(file);
(_, int? id) = IDirectory.GetId(_Configuration.PropertyConfiguration.Offset, fileHolder);
if (id is null)
fileHolder = Shared.Models.Stateless.Methods.IFileHolder.Get(file);
filePath = FilePath.Get(_Configuration.PropertyConfiguration, fileHolder, index: null);
if (filePath.Id is null)
continue;
results.Add(id.Value);
results.Add(filePath.Id.Value);
}
}
return new(results);
@ -332,7 +333,7 @@ public partial class DlibDotNet
if (outputResolution.Any(char.IsNumber))
continue;
(cResultsFullGroupDirectory, _, _, _) = GetResultsFullGroupDirectories(outputResolution);
filesCollectionRootDirectory = Path.Combine(cResultsFullGroupDirectory, _Configuration.PropertyConfiguration.ResultContent, _Configuration.PropertyConfiguration.ResultAllInOne);
filesCollectionRootDirectory = Path.Combine(cResultsFullGroupDirectory, _Configuration.PropertyConfiguration.ResultContent);
filesCollection = IDirectory.GetFilesCollection(filesCollectionRootDirectory, directorySearchFilter, fileSearchFilter, useCeilingAverage: true);
count = filesCollection.Select(l => l.Length).Sum();
break;
@ -370,6 +371,8 @@ public partial class DlibDotNet
ReadOnlyCollection<Mapping> distinctFilteredMappingCollection = GetMappings(_Configuration.PropertyConfiguration, eDistanceContentDirectory, containers, mapLogic, distinctItems: true);
if (runToDoCollectionFirst)
{
if (!Directory.Exists(eDistanceContentDirectory))
_ = Directory.CreateDirectory(eDistanceContentDirectory);
string json = JsonSerializer.Serialize(distinctFilteredMappingCollection);
File.WriteAllText(Path.Combine(eDistanceContentDirectory, $"{ticks}.json"), json);
}
@ -462,6 +465,7 @@ public partial class DlibDotNet
Uri uri;
string? line;
string fileName;
FilePath filePath;
Task<byte[]> task;
string relativePath;
FileHolder fileHolder;
@ -487,8 +491,9 @@ public partial class DlibDotNet
extensionLowered = Path.GetExtension(uri.LocalPath);
relativePath = Shared.Models.Stateless.Methods.IPath.GetRelativePath(sourceDirectoryFile, length, forceExtensionToLower: true);
isValidImageFormatExtension = _Configuration.PropertyConfiguration.ValidImageFormatExtensions.Contains(extensionLowered);
fileHolder = new(sourceDirectoryFile);
_ = new Item(fileHolder, relativePath, isValidImageFormatExtension);
fileHolder = Shared.Models.Stateless.Methods.IFileHolder.Get(sourceDirectoryFile);
filePath = FilePath.Get(_Configuration.PropertyConfiguration, fileHolder, index: null);
_ = new Item(filePath, fileHolder, relativePath, isValidImageFormatExtension);
// container.Items.Add(item);
}
_Logger?.LogInformation(". . .");
@ -774,12 +779,6 @@ public partial class DlibDotNet
_Logger?.LogInformation(string.Concat("Moved <", item.ImageFileHolder.FullName, '>'));
}
private void LogNameWithoutExtensionIsIdFormatBut(Item item)
{
_Logger?.LogInformation($"Name without extension is Id format but doesn't match id <{item.ImageFileHolder.FullName}>");
File.Move(item.ImageFileHolder.FullName, $"{item.ImageFileHolder.FullName}.rename");
}
private int GetNotMappedCountAndUpdateMappingFromPersonThenSetMapping(MapLogic mapLogic, Item item, bool? isFocusRelativePath, ReadOnlyCollection<LocationContainer<MetadataExtractor.Directory>> locationContainers, MappingFromItem mappingFromItem, List<MappingFromPhotoPrism>? mappingFromPhotoPrismCollection, List<Shared.Models.Face> faces)
{
int result;
@ -801,7 +800,7 @@ public partial class DlibDotNet
bool? isFocusModel = GetIsFocusModel(item.Property);
long[] jLinkResolvedPersonKeys = _JLinkResolvedDirectories.Select(l => l.PersonKey).ToArray();
ReadOnlyDictionary<int, ReadOnlyCollection<PersonContainer>>? wholePercentagesToPersonContainers;
ReadOnlyCollection<string> locationContainersFiles = new((from l in locationContainers select l.File).ToArray());
ReadOnlyCollection<string> locationContainersFiles = new((from l in locationContainers select l.FilePath.FullName).ToArray());
foreach (Shared.Models.Face face in faces)
{
wholePercentagesToPersonContainers = mapLogic.GetWholePercentagesToPersonContainers(item.Property?.Id);
@ -826,7 +825,7 @@ public partial class DlibDotNet
confidencePercent = Shared.Models.Stateless.Methods.ILocation.GetConfidencePercent(_Configuration.FaceConfidencePercent, face.Location.Confidence);
faceAreaPermyriad = IMapping.GetAreaPermyriad(_Configuration.FaceAreaPermyriad, face.Location, face.OutputResolution);
wholePercentRectangle = Shared.Models.Stateless.Methods.ILocation.GetWholePercentages(face.Location, Shared.Models.Stateless.ILocation.Digits, face.OutputResolution);
deterministicHashCodeKey = IMapping.GetDeterministicHashCodeKey(item.Property.Id.Value, face.Location, Shared.Models.Stateless.ILocation.Digits, face.OutputResolution);
deterministicHashCodeKey = IMapping.GetDeterministicHashCodeKey(item.FilePath, face.Location, Shared.Models.Stateless.ILocation.Digits, face.OutputResolution);
mappingFromLocation = new(faceAreaPermyriad, confidencePercent, deterministicHashCodeKey, eyeα, eyeReview, wholePercentRectangle);
inSkipCollection = mapLogic.InSkipCollection(item.Property.Id.Value, mappingFromLocation);
mappingFromFilterPre = new(inSkipCollection, isFocusModel, isFocusRelativePath);
@ -834,7 +833,7 @@ public partial class DlibDotNet
isFocusPerson = mapLogic.IsFocusPerson(_Configuration.SkipPersonWithMoreThen, jLinkResolvedPersonKeys, wholePercentagesToPersonContainers, mappingFromLocation);
mappingFromFilterPost = new(canReMap, inSkipCollection, isFocusPerson);
}
mapping = new(mappingFromFilterPost, mappingFromFilterPre, mappingFromItem, mappingFromLocation, mappingFromPhotoPrismCollection);
mapping = new(item.FilePath, mappingFromFilterPost, mappingFromFilterPre, mappingFromItem, mappingFromLocation, mappingFromPhotoPrismCollection);
notMapped += mapLogic.UpdateMappingFromPerson(wholePercentagesToPersonContainers, mapping);
face.SetMapping(mapping);
}
@ -904,7 +903,7 @@ public partial class DlibDotNet
else
{
wholePercentRectangle = Shared.Models.Stateless.Methods.ILocation.GetWholePercentages(Shared.Models.Stateless.ILocation.Digits);
deterministicHashCodeKey = IMapping.GetDeterministicHashCodeKey(item.Property.Id.Value, Shared.Models.Stateless.ILocation.Digits);
deterministicHashCodeKey = IMapping.GetDeterministicHashCodeKey(item.FilePath, Shared.Models.Stateless.ILocation.Digits);
mappingFromLocation = new(faceAreaPermyriad, confidencePercent, deterministicHashCodeKey, eyeα, eyeReview, wholePercentRectangle);
inSkipCollection = mapLogic.InSkipCollection(item.Property.Id.Value, mappingFromLocation);
mappingFromFilterPre = new(inSkipCollection, isFocusModel, isFocusRelativePath);
@ -912,7 +911,7 @@ public partial class DlibDotNet
isFocusPerson = mapLogic.IsFocusPerson(_Configuration.SkipPersonWithMoreThen, jLinkResolvedPersonKeys, wholePercentagesToPersonContainers, mappingFromLocation);
mappingFromFilterPost = new(canReMap, inSkipCollection, isFocusPerson);
}
result = new(mappingFromFilterPost, mappingFromFilterPre, mappingFromItem, mappingFromLocation, mappingFromPhotoPrismCollection: null);
result = new(item.FilePath, mappingFromFilterPost, mappingFromFilterPre, mappingFromItem, mappingFromLocation, mappingFromPhotoPrismCollection: null);
int notMapped = mapLogic.UpdateMappingFromPerson(wholePercentagesToPersonContainers, result);
return (result, notMapped);
}
@ -940,8 +939,8 @@ public partial class DlibDotNet
DateTime dateTime = DateTime.Now;
Shared.Models.Property? property;
List<string> parseExceptions = [];
List<Tuple<string, DateTime>> subFileTuples = [];
string[] changesFrom = [nameof(A_Property)];
List<Tuple<string, DateTime>> subFileTuples = [];
FileHolder resizedFileHolder = _Resize.GetResizedFileHolder(cResultsFullGroupDirectory, item, outputResolutionHasNumber);
ReadOnlyCollection<LocationContainer<MetadataExtractor.Directory>> locationContainers = mapLogic.GetLocationContainers(item);
if (item.Property is null || item.Property.Id is null || !item.SourceDirectoryFileHolder.Exists || item.SourceDirectoryFileHolder.CreationTime is null || item.SourceDirectoryFileHolder.LastWriteTime is null || item.Any())
@ -973,18 +972,12 @@ public partial class DlibDotNet
subFileTuples.Add(new Tuple<string, DateTime>(nameof(A_Property), item.SourceDirectoryFileHolder.LastWriteTime.Value));
else
subFileTuples.Add(new Tuple<string, DateTime>(nameof(A_Property), new FileInfo(item.SourceDirectoryFileHolder.FullName).LastWriteTime));
short sortOrderOnlyLengthIndex = IDirectory.GetSortOrderOnlyLengthIndex(_Configuration.PropertyConfiguration.Offset);
bool nameWithoutExtensionIsIdFormat = Shared.Models.Stateless.Methods.IProperty.NameWithoutExtensionIsIdFormat(item.ImageFileHolder);
bool nameWithoutExtensionIsPaddedIdFormat = IDirectory.NameWithoutExtensionIsPaddedIdFormat(item.ImageFileHolder, sortOrderOnlyLengthIndex);
if (nameWithoutExtensionIsIdFormat && item.ImageFileHolder.NameWithoutExtension != item.Property.Id.ToString())
LogNameWithoutExtensionIsIdFormatBut(item);
if (nameWithoutExtensionIsPaddedIdFormat && item.ImageFileHolder.NameWithoutExtension.EndsWith(item.Property.Id.Value.ToString()[1..]))
LogNameWithoutExtensionIsIdFormatBut(item);
FilePath filePath = FilePath.Get(_Configuration.PropertyConfiguration, item.ImageFileHolder, index: null);
if (resizedFileHolder.Exists && item.Property.Width is not null && item.Property.Width.Value > 4 && _Configuration.SaveBlurHashForOutputResolutions.Contains(outputResolution))
{
string? file = _BlurHasher.GetFile(resizedFileHolder);
string? file = _BlurHasher.GetFile(item.FilePath);
if (file is not null && !File.Exists(file))
_ = _BlurHasher.EncodeAndSave(resizedFileHolder);
_ = _BlurHasher.EncodeAndSave(item.FilePath, resizedFileHolder);
}
}
if (property is null || item.Property is null)
@ -992,7 +985,7 @@ public partial class DlibDotNet
item.SetResizedFileHolder(_Resize.FileNameExtension, resizedFileHolder);
MappingFromItem mappingFromItem = IMappingFromItem.GetMappingFromItem(containerDateTimes, item, resizedFileHolder);
Map.Models.Stateless.Methods.IMapLogic.SetCreationTimeMaybeMoveToDecade(_Configuration.PropertyConfiguration, _Configuration.MoveToDecade && _Configuration.LocationContainerDistanceTolerance is null, mappingFromItem, locationContainers);
ReadOnlyDictionary<string, MetadataExtractorDirectory> metadataExtractorDirectories = metadata.GetMetadataCollection(subFileTuples, parseExceptions, changesFrom, mappingFromItem);
ReadOnlyDictionary<string, MetadataExtractorDirectory> metadataExtractorDirectories = metadata.GetMetadataCollection(item.FilePath, subFileTuples, parseExceptions, changesFrom, mappingFromItem);
if (_AppSettings.Places.Count > 0)
{
float latitude;
@ -1015,7 +1008,7 @@ public partial class DlibDotNet
distance += 1;
}
}
Dictionary<string, int[]> outputResolutionToResize = _Resize.GetResizeKeyValuePairs(_Configuration.PropertyConfiguration, cResultsFullGroupDirectory, subFileTuples, parseExceptions, item.Property, mappingFromItem);
Dictionary<string, int[]> outputResolutionToResize = _Resize.GetResizeKeyValuePairs(_Configuration.PropertyConfiguration, cResultsFullGroupDirectory, item.FilePath, subFileTuples, parseExceptions, item.Property, mappingFromItem);
if (_Configuration.SaveResizedSubfiles)
_Resize.SaveResizedSubfile(_Configuration.PropertyConfiguration, outputResolution, cResultsFullGroupDirectory, subFileTuples, item, item.Property, mappingFromItem, outputResolutionToResize);
if (!_Configuration.LoadOrCreateThenSaveImageFacesResultsForOutputResolutions.Contains(outputResolution))
@ -1027,21 +1020,21 @@ public partial class DlibDotNet
List<MappingFromPhotoPrism>? mappingFromPhotoPrismCollection;
if (!fileNameToCollection.TryGetValue(mappingFromItem.Id, out mappingFromPhotoPrismCollection))
mappingFromPhotoPrismCollection = null;
faces = _Faces.GetFaces(outputResolution, dResultsFullGroupDirectory, subFileTuples, parseExceptions, property, mappingFromItem, outputResolutionToResize, locationContainers, mappingFromPhotoPrismCollection);
faces = _Faces.GetFaces(outputResolution, dResultsFullGroupDirectory, item.FilePath, subFileTuples, parseExceptions, property, mappingFromItem, outputResolutionToResize, locationContainers, mappingFromPhotoPrismCollection);
result = GetNotMappedCountAndUpdateMappingFromPersonThenSetMapping(mapLogic, item, isFocusRelativePath, locationContainers, mappingFromItem, mappingFromPhotoPrismCollection, faces);
List<(Shared.Models.Face, FileInfo?, string, bool Saved)> faceCollection = _Faces.SaveFaces(_FaceParts.FileNameExtension, dResultsFullGroupDirectory, subFileTuples, parseExceptions, mappingFromItem, faces);
List<(Shared.Models.Face, FileInfo?, string, bool Saved)> faceCollection = _Faces.SaveFaces(_FaceParts.FileNameExtension, dResultsFullGroupDirectory, item.FilePath, subFileTuples, parseExceptions, mappingFromItem, faces);
if (_Configuration.CopyFacesAndSaveFaceLandmarkForOutputResolutions.Contains(outputResolution))
_FaceParts.CopyFacesAndSaveFaceLandmarkImage(facePartsCollectionDirectory, mappingFromItem, faceCollection);
if ((_Configuration.DistanceMoveUnableToMatch || _Configuration.DistanceRenameToMatch)
&& _Configuration.LoadOrCreateThenSaveDistanceResultsForOutputResolutions.Contains(outputResolution)
&& locationContainers is not null && faceCollection.All(l => !l.Saved))
_Distance.LookForMatchFacesAndPossiblyRename(_Faces.FileNameExtension, mappingFromItem, faces, locationContainers);
_Distance.LookForMatchFacesAndPossiblyRename(_Faces.FileNameExtension, item.FilePath, mappingFromItem, faces, locationContainers);
(bool review, int[] eyesCollection) = Shared.Models.Stateless.Methods.IFace.GetEyeCollection(_Configuration.EyeThreshold, faces);
if (review || _Configuration.SaveFaceLandmarkForOutputResolutions.Contains(outputResolution))
{
bool saveRotated = false;
string sourceDirectorySegment = Property.Models.Stateless.IResult.GetRelativePath(_Configuration.PropertyConfiguration, container.SourceDirectory);
_FaceParts.SaveFaceLandmarkImages(_Configuration.PropertyConfiguration, subFileTuples, parseExceptions, mappingFromItem, faces, saveRotated);
_FaceParts.SaveFaceLandmarkImages(_Configuration.PropertyConfiguration, item.FilePath, subFileTuples, parseExceptions, mappingFromItem, faces, saveRotated);
}
}
lock (sourceDirectoryChanges)
@ -1233,7 +1226,7 @@ public partial class DlibDotNet
int count = filesCollection.Select(l => l.Length).Sum();
string message = $") Selecting for ## pattern directory - {(int)Math.Floor(new TimeSpan(DateTime.Now.Ticks - ticks).TotalSeconds)} total second(s)";
progressBar = new(count, message, options);
(string[] distinctDirectories, List<(FileHolder, string?, string)> toDoCollection) = IDirectory.GetToDoCollection(_Configuration.PropertyConfiguration, filesCollection, fileGroups[_Configuration.PropertyConfiguration.ResultContent], () => progressBar.Tick());
(string[] distinctDirectories, List<(FilePath, string)> toDoCollection) = IDirectory.GetToDoCollection(_Configuration.PropertyConfiguration, filesCollection, fileGroups[_Configuration.PropertyConfiguration.ResultContent], () => progressBar.Tick());
progressBar.Dispose();
foreach (string distinctDirectory in distinctDirectories)
{

View File

@ -5,8 +5,8 @@
<OutputType>Exe</OutputType>
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
<TargetFramework>net8.0</TargetFramework>
<UserSecretsId>2999dda1-5329-4d9f-9d68-cccfabe0e47f</UserSecretsId>
</PropertyGroup>
<UserSecretsId>2999dda1-5329-4d9f-9d68-cccfabe0e47f</UserSecretsId>
</PropertyGroup>
<PropertyGroup>
<PackageId>Phares.View.by.Distance.Instance</PackageId>
<GeneratePackageOnBuild>false</GeneratePackageOnBuild>

View File

@ -200,9 +200,9 @@ public partial class MapLogic : Shared.Models.Methods.IMapLogic
continue;
foreach (LocationContainer<MetadataExtractor.Directory> locationContainer in keyValuePair.Value)
{
if (locationContainer.File.Contains('!'))
if (locationContainer.FilePath.FullName.Contains('!'))
continue;
renameCollection.Add(locationContainer.File);
renameCollection.Add(locationContainer.FilePath.FullName);
}
}
if (renameCollection.Count > 0)
@ -259,7 +259,7 @@ public partial class MapLogic : Shared.Models.Methods.IMapLogic
readOnlyPersonKeyFormattedCollection = new(personKeyFormattedCollection);
readOnlyPersonKeyFormattedToNewestPersonKeyFormatted = new(personKeyFormattedToNewestPersonKeyFormatted);
}
List<Stateless.Record> records = Stateless.DistanceLogic.DeleteEmptyDirectoriesAndGetCollection(configuration, ticks, eDistanceContentDirectory, readOnlyPersonKeyFormattedToNewestPersonKeyFormatted, readOnlyPersonKeyFormattedCollection);
List<Stateless.Record> records = Stateless.DistanceLogic.DeleteEmptyDirectoriesAndGetCollection(propertyConfiguration, configuration, ticks, eDistanceContentDirectory, readOnlyPersonKeyFormattedToNewestPersonKeyFormatted, readOnlyPersonKeyFormattedCollection);
ReadOnlyCollection<(Stateless.MapLogic.PersonKeyFormattedIdThenWholePercentages, PersonContainer)> readOnlyPossiblyNewPersonDisplayDirectoryNamesAndPersonContainer;
ReadOnlyCollection<Stateless.MapLogic.PersonKeyFormattedIdThenWholePercentages> personKeyFormattedIdThenWholePercentagesCollection = Stateless.MapLogic.GetPersonKeyFormattedIdThenWholePercentages(configuration, ticks, records);
//
@ -300,6 +300,7 @@ public partial class MapLogic : Shared.Models.Methods.IMapLogic
personContainers,
readOnlyPersonKeyToCount));
locationContainers.AddRange(Stateless.MapLogic.GetLocationContainers(maxDegreeOfParallelism,
propertyConfiguration,
configuration,
ticks,
personContainers,
@ -431,17 +432,17 @@ public partial class MapLogic : Shared.Models.Methods.IMapLogic
else
{
string checkFile;
string facesDirectory = Stateless.MapLogic.GetFacesDirectory(_PropertyConfiguration, dFacesContentDirectory, mapping.MappingFromItem);
FileHolder faceFileHolder = new(Path.Combine(facesDirectory, $"{mapping.MappingFromLocation.DeterministicHashCodeKey}{mapping.MappingFromItem.ImageFileHolder.ExtensionLowered}{_Configuration.FacesFileNameExtension}"));
string facesDirectory = Stateless.MapLogic.GetFacesDirectory(_PropertyConfiguration, dFacesContentDirectory, mapping.FilePath, mapping.MappingFromItem);
FileHolder faceFileHolder = IFileHolder.Get(Path.Combine(facesDirectory, $"{mapping.MappingFromLocation.DeterministicHashCodeKey}{mapping.MappingFromItem.ImageFileHolder.ExtensionLowered}{_Configuration.FacesFileNameExtension}"));
if (!faceFileHolder.Exists)
result = null;
else
{
string shortcutFile = string.Empty;
string facePartsDirectory = Stateless.MapLogic.GetFacePartsDirectory(_PropertyConfiguration, d2FacePartsContentDirectory, mapping.MappingFromItem);
string facePartsDirectory = Stateless.MapLogic.GetFacePartsDirectory(_PropertyConfiguration, d2FacePartsContentDirectory, mapping.FilePath, mapping.MappingFromItem);
checkFile = Path.Combine(directory, $"{mapping.MappingFromLocation.DeterministicHashCodeKey}{mapping.MappingFromItem.ImageFileHolder.ExtensionLowered}");
FileHolder hiddenFaceFileHolder = new(Path.Combine(facesDirectory, $"{mapping.MappingFromLocation.DeterministicHashCodeKey}{mapping.MappingFromItem.ImageFileHolder.ExtensionLowered}{_Configuration.FacesHiddenFileNameExtension}"));
FileHolder facePartsFileHolder = new(Path.Combine(facePartsDirectory, $"{mapping.MappingFromLocation.DeterministicHashCodeKey}{mapping.MappingFromItem.ImageFileHolder.ExtensionLowered}{_Configuration.FacePartsFileNameExtension}"));
FileHolder hiddenFaceFileHolder = IFileHolder.Get(Path.Combine(facesDirectory, $"{mapping.MappingFromLocation.DeterministicHashCodeKey}{mapping.MappingFromItem.ImageFileHolder.ExtensionLowered}{_Configuration.FacesHiddenFileNameExtension}"));
FileHolder facePartsFileHolder = IFileHolder.Get(Path.Combine(facePartsDirectory, $"{mapping.MappingFromLocation.DeterministicHashCodeKey}{mapping.MappingFromItem.ImageFileHolder.ExtensionLowered}{_Configuration.FacePartsFileNameExtension}"));
result = new(checkFile, directory, faceFileHolder, hiddenFaceFileHolder, facePartsFileHolder, mapping.MappingFromItem.ResizedFileHolder, shortcutFile);
}
}
@ -616,8 +617,8 @@ public partial class MapLogic : Shared.Models.Methods.IMapLogic
if (saveIndividually && question.MappingFromLocation.WholePercentages == mapping.MappingFromLocation.WholePercentages)
results.Add(new(Path.Combine(directory, "Maybe")));
}
facesDirectory = Stateless.MapLogic.GetFacesDirectory(_PropertyConfiguration, dFacesContentDirectory, mapping.MappingFromItem);
faceFileHolder = new(Path.Combine(facesDirectory, $"{mapping.MappingFromLocation.DeterministicHashCodeKey}{mapping.MappingFromItem.ImageFileHolder.ExtensionLowered}{_Configuration.FacesFileNameExtension}"));
facesDirectory = Stateless.MapLogic.GetFacesDirectory(_PropertyConfiguration, dFacesContentDirectory, mapping.FilePath, mapping.MappingFromItem);
faceFileHolder = IFileHolder.Get(Path.Combine(facesDirectory, $"{mapping.MappingFromLocation.DeterministicHashCodeKey}{mapping.MappingFromItem.ImageFileHolder.ExtensionLowered}{_Configuration.FacesFileNameExtension}"));
if (!faceFileHolder.Exists)
continue;
if (isByMapping)
@ -627,19 +628,19 @@ public partial class MapLogic : Shared.Models.Methods.IMapLogic
}
else if (saveIndividually)
{
facePartsDirectory = Stateless.MapLogic.GetFacePartsDirectory(_PropertyConfiguration, d2FacePartsContentDirectory, mapping.MappingFromItem);
facePartsFileHolder = new(Path.Combine(facePartsDirectory, $"{mapping.MappingFromLocation.DeterministicHashCodeKey}{mapping.MappingFromItem.ImageFileHolder.ExtensionLowered}{_Configuration.FacePartsFileNameExtension}"));
facePartsDirectory = Stateless.MapLogic.GetFacePartsDirectory(_PropertyConfiguration, d2FacePartsContentDirectory, mapping.FilePath, mapping.MappingFromItem);
facePartsFileHolder = IFileHolder.Get(Path.Combine(facePartsDirectory, $"{mapping.MappingFromLocation.DeterministicHashCodeKey}{mapping.MappingFromItem.ImageFileHolder.ExtensionLowered}{_Configuration.FacePartsFileNameExtension}"));
(saveContainer, SaveContainer? extraSaveContainer) = Stateless.MapLogic.GetContainers(_Configuration.FacesFileNameExtension, _Configuration.FacePartsFileNameExtension, directory, faceFileHolder, facePartsFileHolder, mapping);
if (extraSaveContainer is not null)
results.Add(extraSaveContainer);
}
else
{
facePartsDirectory = Stateless.MapLogic.GetFacePartsDirectory(_PropertyConfiguration, d2FacePartsContentDirectory, mapping.MappingFromItem);
facePartsDirectory = Stateless.MapLogic.GetFacePartsDirectory(_PropertyConfiguration, d2FacePartsContentDirectory, mapping.FilePath, mapping.MappingFromItem);
shortcutFile = Path.Combine(record.PersonDirectory, $"{mapping.MappingFromLocation.DeterministicHashCodeKey}{mapping.MappingFromItem.ImageFileHolder.ExtensionLowered}.lnk");
checkFile = Path.Combine(directory, $"{mapping.MappingFromLocation.DeterministicHashCodeKey}{mapping.MappingFromItem.ImageFileHolder.ExtensionLowered}");
hiddenFaceFileHolder = new(Path.Combine(facesDirectory, $"{mapping.MappingFromLocation.DeterministicHashCodeKey}{mapping.MappingFromItem.ImageFileHolder.ExtensionLowered}{_Configuration.FacesHiddenFileNameExtension}"));
facePartsFileHolder = new(Path.Combine(facePartsDirectory, $"{mapping.MappingFromLocation.DeterministicHashCodeKey}{mapping.MappingFromItem.ImageFileHolder.ExtensionLowered}{_Configuration.FacePartsFileNameExtension}"));
hiddenFaceFileHolder = IFileHolder.Get(Path.Combine(facesDirectory, $"{mapping.MappingFromLocation.DeterministicHashCodeKey}{mapping.MappingFromItem.ImageFileHolder.ExtensionLowered}{_Configuration.FacesHiddenFileNameExtension}"));
facePartsFileHolder = IFileHolder.Get(Path.Combine(facePartsDirectory, $"{mapping.MappingFromLocation.DeterministicHashCodeKey}{mapping.MappingFromItem.ImageFileHolder.ExtensionLowered}{_Configuration.FacePartsFileNameExtension}"));
saveContainer = new(checkFile, directory, faceFileHolder, hiddenFaceFileHolder, facePartsFileHolder, mapping.MappingFromItem.ResizedFileHolder, shortcutFile);
}
results.Add(saveContainer);
@ -747,8 +748,7 @@ public partial class MapLogic : Shared.Models.Methods.IMapLogic
key = string.Concat(personKeyFormatted, '\t', segmentB);
if (!keyToCount.ContainsKey(key))
keyToCount.Add(key, new());
if (!keyToCount.ContainsKey(key))
keyToCount.Add(key, 0);
_ = keyToCount.TryAdd(key, 0);
keyToCount[key]++;
if (!_Configuration.SaveIndividually && keyToCount[key] < _Configuration.SortingMaximumPerKey)
segmentC = null;
@ -828,13 +828,13 @@ public partial class MapLogic : Shared.Models.Methods.IMapLogic
results.Add(new(record.PersonDirectory));
if (_Configuration.SaveIndividually && question.MappingFromLocation.WholePercentages == question.MappingFromLocation.WholePercentages)
results.Add(new(Path.Combine(directory, "Maybe")));
facesDirectory = Stateless.MapLogic.GetFacesDirectory(_PropertyConfiguration, dFacesContentDirectory, question.MappingFromItem);
faceFileHolder = new(Path.Combine(facesDirectory, $"{question.MappingFromLocation.DeterministicHashCodeKey}{question.MappingFromItem.ImageFileHolder.ExtensionLowered}{_Configuration.FacesFileNameExtension}"));
facePartsDirectory = Stateless.MapLogic.GetFacePartsDirectory(_PropertyConfiguration, d2FacePartsContentDirectory, question.MappingFromItem);
facesDirectory = Stateless.MapLogic.GetFacesDirectory(_PropertyConfiguration, dFacesContentDirectory, question.FilePath, question.MappingFromItem);
faceFileHolder = IFileHolder.Get(Path.Combine(facesDirectory, $"{question.MappingFromLocation.DeterministicHashCodeKey}{question.MappingFromItem.ImageFileHolder.ExtensionLowered}{_Configuration.FacesFileNameExtension}"));
facePartsDirectory = Stateless.MapLogic.GetFacePartsDirectory(_PropertyConfiguration, d2FacePartsContentDirectory, question.FilePath, question.MappingFromItem);
shortcutFile = Path.Combine(record.PersonDirectory, $"{question.MappingFromLocation.DeterministicHashCodeKey}{question.MappingFromItem.ImageFileHolder.ExtensionLowered}.lnk");
checkFile = Path.Combine(directory, $"{question.MappingFromLocation.DeterministicHashCodeKey}{question.MappingFromItem.ImageFileHolder.ExtensionLowered}");
hiddenFaceFileHolder = new(Path.Combine(facesDirectory, $"{question.MappingFromLocation.DeterministicHashCodeKey}{question.MappingFromItem.ImageFileHolder.ExtensionLowered}{_Configuration.FacesHiddenFileNameExtension}"));
facePartsFileHolder = new(Path.Combine(facePartsDirectory, $"{question.MappingFromLocation.DeterministicHashCodeKey}{question.MappingFromItem.ImageFileHolder.ExtensionLowered}{_Configuration.FacePartsFileNameExtension}"));
hiddenFaceFileHolder = IFileHolder.Get(Path.Combine(facesDirectory, $"{question.MappingFromLocation.DeterministicHashCodeKey}{question.MappingFromItem.ImageFileHolder.ExtensionLowered}{_Configuration.FacesHiddenFileNameExtension}"));
facePartsFileHolder = IFileHolder.Get(Path.Combine(facePartsDirectory, $"{question.MappingFromLocation.DeterministicHashCodeKey}{question.MappingFromItem.ImageFileHolder.ExtensionLowered}{_Configuration.FacePartsFileNameExtension}"));
saveContainer = new(checkFile, directory, faceFileHolder, hiddenFaceFileHolder, facePartsFileHolder, question.MappingFromItem.ResizedFileHolder, shortcutFile);
results.Add(saveContainer);
if (!_Configuration.SaveIndividually && isBySorting && question.MappingFromPerson is null)
@ -988,6 +988,7 @@ public partial class MapLogic : Shared.Models.Methods.IMapLogic
throw new NullReferenceException(nameof(_Configuration));
List<string> results = [];
string[] files;
List<int>? ids;
string checkDirectory;
string[] checkDirectories;
string personKeyFormatted;
@ -1019,10 +1020,10 @@ public partial class MapLogic : Shared.Models.Methods.IMapLogic
(personKeyFormatted, personBirthday) = GetPersonBirthday(windowsShortcut.Path);
if (personBirthday is null)
throw new NotSupportedException(fileNameWithoutExtension);
if (!personKeyToIds.ContainsKey(personBirthday.Value.Ticks))
if (!personKeyToIds.TryGetValue(personBirthday.Value.Ticks, out ids))
collection.Add(new(personBirthday.Value.Ticks, Path.Combine(checkDirectory, personKeyFormatted, fileNameWithoutExtension)));
else
collection.Add(new(personBirthday.Value.Ticks, Path.Combine(checkDirectory, personKeyFormatted, fileNameWithoutExtension, $"{personKeyToIds[personBirthday.Value.Ticks].Count} Face(s)")));
collection.Add(new(personBirthday.Value.Ticks, Path.Combine(checkDirectory, personKeyFormatted, fileNameWithoutExtension, $"{ids.Count} Face(s)")));
foreach ((long personKey, string displayDirectoryName) in collection)
{
matches = (from l in personContainers where l.Key == personKey && l.ApproximateYears.HasValue select l).ToArray();
@ -1161,6 +1162,7 @@ public partial class MapLogic : Shared.Models.Methods.IMapLogic
{
if (_Configuration is null)
throw new NullReferenceException(nameof(_Configuration));
List<int>? ids;
string fileName;
string fullName;
string directory;
@ -1215,7 +1217,7 @@ public partial class MapLogic : Shared.Models.Methods.IMapLogic
personDirectory = Path.Combine(directory, "Unknown");
fileName = Path.Combine(personDirectory, $"{mapping.MappingFromItem.ResizedFileHolder.Name}.lnk");
collection.Add(new(mapping.MappingFromItem.ResizedFileHolder.FullName, personDirectory, mapping.MappingFromItem.GetDateTimeOriginalThenMinimumDateTime(), fileName, mapping.MappingFromLocation?.DeterministicHashCodeKey, MakeAllHidden: false));
facesDirectory = Stateless.MapLogic.GetFacesDirectory(_PropertyConfiguration, dFacesContentDirectory, mapping.MappingFromItem);
facesDirectory = Stateless.MapLogic.GetFacesDirectory(_PropertyConfiguration, dFacesContentDirectory, mapping.FilePath, mapping.MappingFromItem);
if (mapping.MappingFromLocation is null)
continue;
fullName = Path.Combine(facesDirectory, $"{mapping.MappingFromLocation.DeterministicHashCodeKey}{mapping.MappingFromItem.ImageFileHolder.ExtensionLowered}{_Configuration.FacesFileNameExtension}");
@ -1235,10 +1237,10 @@ public partial class MapLogic : Shared.Models.Methods.IMapLogic
directoriesAndDateTimes.Add(new(mapping.MappingFromItem.ResizedFileHolder.DirectoryName, mapping.MappingFromItem.ContainerDateTimes));
}
directory = Path.Combine(mapping.MappingFromItem.ResizedFileHolder.DirectoryName, $"{_PropertyConfiguration.ResultAllInOne}Shortcuts", personKeyFormatted);
if (!personKeyToIds.ContainsKey(mapping.MappingFromPerson.PersonKey))
if (!personKeyToIds.TryGetValue(mapping.MappingFromPerson.PersonKey, out ids))
personDirectory = Path.Combine(directory, mapping.MappingFromPerson.DisplayDirectoryName);
else
personDirectory = Path.Combine(directory, mapping.MappingFromPerson.DisplayDirectoryName, $"{personKeyToIds[mapping.MappingFromPerson.PersonKey].Count} Face(s)");
personDirectory = Path.Combine(directory, mapping.MappingFromPerson.DisplayDirectoryName, $"{ids.Count} Face(s)");
fileName = Path.Combine(directory, $"{mapping.MappingFromItem.ResizedFileHolder.Name}.lnk");
collection.Add(new(mapping.MappingFromItem.ResizedFileHolder.FullName, personDirectory, mapping.MappingFromItem.GetDateTimeOriginalThenMinimumDateTime(), fileName, mapping.MappingFromLocation?.DeterministicHashCodeKey, MakeAllHidden: false));
}

View File

@ -39,24 +39,22 @@ internal abstract class DecadeLogic
string checkDirectory;
string? yearDirectory;
string yearDirectoryName;
string? personNameDirectory;
string personNameDirectoryName;
string? personKeyFormattedDirectory;
string? personKeyFormattedDirectoryName;
foreach (LocationContainer<MetadataExtractor.Directory> locationContainer in locationContainers)
{
if (!File.Exists(locationContainer.File))
if (!File.Exists(locationContainer.FilePath.FullName))
continue;
dateTime = mappingFromItem.DateTimeOriginal is null ? mappingFromItem.MinimumDateTime : mappingFromItem.DateTimeOriginal.Value;
if (locationContainer.CreationDateOnly.Year != dateTime.Year || locationContainer.CreationDateOnly.Month != dateTime.Month || locationContainer.CreationDateOnly.Day != dateTime.Day)
File.SetCreationTime(locationContainer.File, dateTime);
File.SetCreationTime(locationContainer.FilePath.FullName, dateTime);
if (!moveToDecade)
continue;
personNameDirectory = Path.GetDirectoryName(locationContainer.File);
if (string.IsNullOrEmpty(personNameDirectory))
if (string.IsNullOrEmpty(locationContainer.FilePath.DirectoryName))
continue;
personNameDirectoryName = Path.GetFileName(personNameDirectory);
yearDirectory = Path.GetDirectoryName(personNameDirectory);
personNameDirectoryName = Path.GetFileName(locationContainer.FilePath.DirectoryName);
yearDirectory = Path.GetDirectoryName(locationContainer.FilePath.DirectoryName);
if (string.IsNullOrEmpty(yearDirectory))
continue;
yearDirectoryName = Path.GetFileName(yearDirectory);
@ -72,7 +70,7 @@ internal abstract class DecadeLogic
checkDirectory = Path.Combine(personKeyFormattedDirectory, halfDecade, personNameDirectoryName);
if (!Directory.Exists(checkDirectory))
_ = Directory.CreateDirectory(checkDirectory);
File.Move(locationContainer.File, Path.Combine(checkDirectory, Path.GetFileName(locationContainer.File)));
File.Move(locationContainer.FilePath.FullName, Path.Combine(checkDirectory, locationContainer.FilePath.Name));
}
}

View File

@ -1,8 +1,10 @@
using Humanizer;
using ShellProgressBar;
using System.Buffers;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.Globalization;
using View_by_Distance.Shared.Models;
using View_by_Distance.Shared.Models.Stateless.Methods;
namespace View_by_Distance.Map.Models.Stateless;
@ -11,7 +13,7 @@ internal record Record(string PersonKeyFormatted,
int DirectoryNumber,
string? PersonDisplayDirectoryName,
bool? IsDefault,
string MappedFaceFile);
FilePath MappedFaceFilePath);
internal abstract class DistanceLogic
{
@ -208,31 +210,36 @@ internal abstract class DistanceLogic
}
}
private static List<Record> GetRecords(Configuration configuration, bool? isDefault, string[] files, int directoryNumber, string personKeyFormatted, List<string> distinct, string? personDisplayDirectoryName)
private static List<Record> GetRecords(Shared.Models.Properties.IPropertyConfiguration propertyConfiguration, Configuration configuration, bool? isDefault, string[] files, int directoryNumber, string personKeyFormatted, List<string> distinct, string? personDisplayDirectoryName)
{
List<Record> results = [];
int? id;
string fileName;
string checkFile;
FilePath filePath;
FileHolder fileHolder;
int? wholePercentages;
foreach (string mappedFaceFile in files)
foreach (string file in files)
{
if (mappedFaceFile.EndsWith(".lnk"))
if (file.EndsWith(".lnk"))
continue;
(id, wholePercentages) = IMapping.GetConverted(configuration.FacesFileNameExtension, mappedFaceFile);
if (id is null || wholePercentages is null)
fileHolder = IFileHolder.Get(file);
filePath = FilePath.Get(propertyConfiguration, fileHolder, index: null);
if (filePath.Id is null)
continue;
fileName = Path.GetFileName(mappedFaceFile);
wholePercentages = IMapping.GetWholePercentages(configuration.FacesFileNameExtension, filePath);
if (wholePercentages is null)
continue;
fileName = Path.GetFileName(file);
if (distinct.Contains(fileName))
{
checkFile = $"{mappedFaceFile}.dup";
checkFile = $"{file}.dup";
if (File.Exists(checkFile))
continue;
File.Move(mappedFaceFile, checkFile);
File.Move(file, checkFile);
continue;
}
distinct.Add(fileName);
results.Add(new(personKeyFormatted, directoryNumber, personDisplayDirectoryName, isDefault, mappedFaceFile));
results.Add(new(personKeyFormatted, directoryNumber, personDisplayDirectoryName, isDefault, filePath));
}
return results;
}
@ -256,7 +263,7 @@ internal abstract class DistanceLogic
Directory.Move(personKeyDirectory, newestPersonKeyDirectory);
}
internal static List<Record> DeleteEmptyDirectoriesAndGetCollection(Configuration configuration, long ticks, string eDistanceContentDirectory, ReadOnlyDictionary<string, string> personKeyFormattedToNewestPersonKeyFormatted, ReadOnlyCollection<string> personKeyFormattedCollection)
internal static List<Record> DeleteEmptyDirectoriesAndGetCollection(Shared.Models.Properties.IPropertyConfiguration propertyConfiguration, Configuration configuration, long ticks, string eDistanceContentDirectory, ReadOnlyDictionary<string, string> personKeyFormattedToNewestPersonKeyFormatted, ReadOnlyCollection<string> personKeyFormattedCollection)
{
List<Record> results = [];
bool check;
@ -271,9 +278,9 @@ internal abstract class DistanceLogic
ProgressBar progressBar;
string[] yearDirectories;
string personKeyFormatted;
List<string> distinct = [];
string? personFirstInitial;
bool isReservedDirectoryName;
List<string> distinct = [];
string[] personNameDirectories;
string? newestPersonKeyFormatted;
string? personDisplayDirectoryName;
@ -331,7 +338,7 @@ internal abstract class DistanceLogic
isDefault = null;
personDisplayDirectoryName = null;
files = Directory.GetFiles(yearDirectory, "*", SearchOption.TopDirectoryOnly);
results.AddRange(GetRecords(configuration, isDefault, files, directoryNumber, personKeyFormatted, distinct, personDisplayDirectoryName));
results.AddRange(GetRecords(propertyConfiguration, configuration, isDefault, files, directoryNumber, personKeyFormatted, distinct, personDisplayDirectoryName));
files = Directory.GetFiles(yearDirectory, "*.lnk", SearchOption.AllDirectories);
foreach (string file in files)
File.Delete(file);
@ -403,7 +410,7 @@ internal abstract class DistanceLogic
else
{
personFirstInitial = personDisplayDirectoryName[..1];
if (personFirstInitial.All(l => char.IsDigit(l)))
if (personFirstInitial.All(char.IsDigit))
{
foreach (string file in files)
File.Delete(file);
@ -419,7 +426,7 @@ internal abstract class DistanceLogic
Directory.Move(personNameDirectory, personFirstInitialDirectory);
files = Directory.GetFiles(personFirstInitialDirectory, "*", SearchOption.TopDirectoryOnly);
}
results.AddRange(GetRecords(configuration, isDefault, files, directoryNumber, personKeyFormatted, distinct, personDisplayDirectoryName));
results.AddRange(GetRecords(propertyConfiguration, configuration, isDefault, files, directoryNumber, personKeyFormatted, distinct, personDisplayDirectoryName));
personNameLinkDirectories = Directory.GetDirectories(personFirstInitialDirectory, "*", SearchOption.TopDirectoryOnly);
foreach (string personNameLinkDirectory in personNameLinkDirectories)
{

View File

@ -1,3 +1,4 @@
using View_by_Distance.Shared.Models;
using View_by_Distance.Shared.Models.Stateless.Methods;
namespace View_by_Distance.Map.Models.Stateless;
@ -7,21 +8,20 @@ internal abstract class LookForAbandonedLogic
internal static void LookForAbandoned(Property.Models.Configuration propertyConfiguration, List<int> distinctFilteredIds, string directory, string directoryName)
{
string fileNameWithoutExtension;
bool nameWithoutExtensionIsIdFormat;
FilePath filePath;
FileHolder fileHolder;
string fileNameFirstSegment;
List<string> renameCollection = [];
bool nameWithoutExtensionIsPaddedIdFormat;
short sortOrderOnlyLengthIndex = IDirectory.GetSortOrderOnlyLengthIndex(propertyConfiguration.Offset);
string[] distinctFilteredIdsValues = distinctFilteredIds.Select(l => l.ToString()).ToArray();
string[] files = Directory.GetFiles(directory, "*", SearchOption.AllDirectories);
foreach (string file in files)
{
fileNameWithoutExtension = Path.GetFileNameWithoutExtension(Path.GetFileNameWithoutExtension(Path.GetFileNameWithoutExtension(file)));
nameWithoutExtensionIsIdFormat = IProperty.NameWithoutExtensionIsIdFormat(fileNameWithoutExtension);
nameWithoutExtensionIsPaddedIdFormat = IDirectory.NameWithoutExtensionIsPaddedIdFormat(fileNameWithoutExtension, sortOrderOnlyLengthIndex);
if (!nameWithoutExtensionIsIdFormat && !nameWithoutExtensionIsPaddedIdFormat)
fileHolder = IFileHolder.Get(file);
filePath = FilePath.Get(propertyConfiguration, fileHolder, index: null);
fileNameFirstSegment = fileHolder.NameWithoutExtension.Split('.')[0];
if (!filePath.IsIntelligentIdFormat && filePath.SortOrder is null)
continue;
if (distinctFilteredIdsValues.Contains(fileNameWithoutExtension))
if (distinctFilteredIdsValues.Contains(fileNameFirstSegment))
continue;
renameCollection.Add(file);
}

View File

@ -17,66 +17,67 @@ internal abstract class MapLogic
string PersonKeyFormatted,
string? PersonDisplayDirectoryName,
int? DirectoryNumber,
string File);
FilePath FilePath);
internal record Duplicate(long PersonKey,
int Id,
string File,
FilePath FilePath,
float? Percent);
internal record PersonKeyFormattedIdThenWholePercentages(string PersonKeyFormatted,
string? PersonDisplayDirectoryName,
bool? IsDefault,
string MappedFaceFile,
FilePath MappedFaceFilePath,
int Id,
int WholePercentages);
internal static void SetSkipCollections(Configuration configuration, ReadOnlyCollection<PersonContainer> personContainers, string? a2PeopleSingletonDirectory, Dictionary<int, List<(string, int)>> skipCollection, Dictionary<int, List<(string, int)>> skipNotSkipCollection)
{
int? id;
string fileName;
string checkFile;
int? wholePercentages;
List<FilePath> distinct = [];
List<string> distinctFiles = [];
List<string> distinctFileName = [];
bool skipNotSkipDirectoriesAny = configuration.SkipNotSkipDirectories.Length > 0;
string[] checkDirectories = (from l in configuration.SkipNotSkipDirectories select Path.GetFullPath($"{a2PeopleSingletonDirectory}{l}")).ToArray();
foreach (PersonContainer personContainer in personContainers)
{
foreach (string personDisplayDirectoryAllFile in personContainer.DisplayDirectoryAllFiles)
foreach (FilePath personDisplayDirectoryAllFilePath in personContainer.DisplayDirectoryAllFilePaths)
{
if (!personDisplayDirectoryAllFile.EndsWith(configuration.FacesFileNameExtension))
if (personDisplayDirectoryAllFilePath.ExtensionLowered != configuration.FacesFileNameExtension)
continue;
if (distinctFiles.Contains(personDisplayDirectoryAllFile))
if (distinctFiles.Contains(personDisplayDirectoryAllFilePath.FullName))
continue;
distinctFiles.Add(personDisplayDirectoryAllFile);
distinctFiles.Add(personDisplayDirectoryAllFilePath.FullName);
distinct.Add(personDisplayDirectoryAllFilePath);
}
}
foreach (string distinctFile in distinctFiles)
foreach (FilePath filePath in distinct)
{
fileName = Path.GetFileName(distinctFile);
if (distinctFileName.Contains(fileName))
if (distinctFileName.Contains(filePath.Name))
{
checkFile = $"{distinctFile}.dup";
checkFile = $"{filePath.FullName}.dup";
if (File.Exists(checkFile))
continue;
File.Move(distinctFile, checkFile);
File.Move(filePath.FullName, checkFile);
continue;
}
(id, wholePercentages) = IMapping.GetConverted(configuration.FacesFileNameExtension, distinctFile);
if (id is null || wholePercentages is null)
if (filePath.Id is null)
continue;
if (!skipNotSkipDirectoriesAny || !checkDirectories.Any(l => distinctFile.StartsWith(l)))
wholePercentages = IMapping.GetWholePercentages(configuration.FacesFileNameExtension, filePath);
if (wholePercentages is null)
continue;
if (!skipNotSkipDirectoriesAny || !checkDirectories.Any(l => filePath.FullName.StartsWith(l)))
{
if (!skipCollection.ContainsKey(id.Value))
skipCollection.Add(id.Value, []);
skipCollection[id.Value].Add((distinctFile, wholePercentages.Value));
if (!skipCollection.ContainsKey(filePath.Id.Value))
skipCollection.Add(filePath.Id.Value, []);
skipCollection[filePath.Id.Value].Add((filePath.FullName, wholePercentages.Value));
}
else
{
if (!skipNotSkipCollection.ContainsKey(id.Value))
skipNotSkipCollection.Add(id.Value, []);
skipNotSkipCollection[id.Value].Add((distinctFile, wholePercentages.Value));
if (!skipNotSkipCollection.ContainsKey(filePath.Id.Value))
skipNotSkipCollection.Add(filePath.Id.Value, []);
skipNotSkipCollection[filePath.Id.Value].Add((filePath.FullName, wholePercentages.Value));
}
}
}
@ -96,8 +97,7 @@ internal abstract class MapLogic
if (personContainer.Birthdays.Length < 1)
continue;
newestPersonKeyFormatted = IPersonBirthday.GetFormatted(configuration.PersonBirthdayFormat, personContainer.Key.Value);
if (!personKeyFormattedToNewestPersonKeyFormatted.ContainsKey(personKeyFormatted))
personKeyFormattedToNewestPersonKeyFormatted.Add(personKeyFormatted, newestPersonKeyFormatted);
_ = personKeyFormattedToNewestPersonKeyFormatted.TryAdd(personKeyFormatted, newestPersonKeyFormatted);
}
}
}
@ -184,23 +184,21 @@ internal abstract class MapLogic
private static List<MappedFile> GetDisplayDirectoryAllFiles(string fileNameExtension, string personBirthdayFormat, ReadOnlyCollection<PersonContainer> personContainers)
{
List<MappedFile> results = [];
string fileName;
string personKeyFormatted;
List<string> distinct = [];
foreach (PersonContainer personContainer in personContainers)
{
if (personContainer.Key is null)
continue;
for (int i = personContainer.DisplayDirectoryAllFiles.Length - 1; i > -1; i--)
for (int i = personContainer.DisplayDirectoryAllFilePaths.Count - 1; i > -1; i--)
{
if (!personContainer.DisplayDirectoryAllFiles[i].EndsWith(fileNameExtension))
if (personContainer.DisplayDirectoryAllFilePaths[i].ExtensionLowered != fileNameExtension)
continue;
fileName = Path.GetFileName(personContainer.DisplayDirectoryAllFiles[i]);
if (distinct.Contains(fileName))
if (distinct.Contains(personContainer.DisplayDirectoryAllFilePaths[i].Name))
continue;
distinct.Add(fileName);
distinct.Add(personContainer.DisplayDirectoryAllFilePaths[i].Name);
personKeyFormatted = IPersonBirthday.GetFormatted(personBirthdayFormat, personContainer.Key.Value);
results.Add(new(personContainer.Key.Value, personKeyFormatted, personContainer.DisplayDirectoryName, null, personContainer.DisplayDirectoryAllFiles[i]));
results.Add(new(personContainer.Key.Value, personKeyFormatted, personContainer.DisplayDirectoryName, null, personContainer.DisplayDirectoryAllFilePaths[i]));
}
}
return results;
@ -213,30 +211,30 @@ internal abstract class MapLogic
{
if (duplicate.Percent is null)
continue;
_ = Process.Start("explorer.exe", string.Concat("\"", Path.GetDirectoryName(duplicate.File), "\""));
_ = Process.Start("explorer.exe", string.Concat("\"", duplicate.FilePath.DirectoryName, "\""));
personKeyFormatted = IPersonBirthday.GetFormatted(configuration.PersonBirthdayFormat, duplicate.PersonKey);
}
foreach ((long personKey, int id, string file, float? percent) in duplicates)
foreach ((long personKey, int id, FilePath filePath, float? percent) in duplicates)
{
if (percent is not null && percent.Value == 0)
continue;
_ = Process.Start("explorer.exe", string.Concat("\"", Path.GetDirectoryName(file), "\""));
_ = Process.Start("explorer.exe", string.Concat("\"", filePath.DirectoryName, "\""));
personKeyFormatted = IPersonBirthday.GetFormatted(configuration.PersonBirthdayFormat, personKey);
}
foreach ((long personKey, int id, string file, float? percent) in duplicates)
foreach ((long personKey, int id, FilePath filePath, float? percent) in duplicates)
{
if (percent is not null && percent.Value > 0)
continue;
_ = Process.Start("explorer.exe", string.Concat("\"", Path.GetDirectoryName(file), "\""));
_ = Process.Start("explorer.exe", string.Concat("\"", filePath.DirectoryName, "\""));
personKeyFormatted = IPersonBirthday.GetFormatted(configuration.PersonBirthdayFormat, personKey);
}
}
internal static string GetFacesDirectory(Shared.Models.Properties.IPropertyConfiguration propertyConfiguration, string dFacesContentDirectory, MappingFromItem mappingFromItem)
internal static string GetFacesDirectory(Shared.Models.Properties.IPropertyConfiguration propertyConfiguration, string dFacesContentDirectory, FilePath filePath, MappingFromItem mappingFromItem)
{
string result;
(string directoryName, _) = IPath.GetDirectoryNameAndIndex(propertyConfiguration.ResultAllInOneSubdirectoryLength, mappingFromItem.ImageFileHolder.NameWithoutExtension);
result = Path.Combine(dFacesContentDirectory, propertyConfiguration.ResultAllInOne, directoryName, mappingFromItem.ImageFileHolder.NameWithoutExtension);
(string directoryName, _) = IPath.GetDirectoryNameAndIndex(propertyConfiguration, filePath);
result = Path.Combine(dFacesContentDirectory, directoryName, mappingFromItem.ImageFileHolder.NameWithoutExtension);
return result;
}
@ -286,8 +284,7 @@ internal abstract class MapLogic
personKeyToPersonContainerCollection.Add(personContainer.Key.Value, []);
personKeyToPersonContainerCollection[personContainer.Key.Value].Add(personContainer);
newestPersonKeyFormatted = IPersonBirthday.GetFormatted(configuration.PersonBirthdayFormat, personContainer.Key.Value);
if (!personKeyFormattedToPersonContainer.ContainsKey(newestPersonKeyFormatted))
personKeyFormattedToPersonContainer.Add(newestPersonKeyFormatted, personContainer);
_ = personKeyFormattedToPersonContainer.TryAdd(newestPersonKeyFormatted, personContainer);
}
foreach (KeyValuePair<long, List<PersonContainer>> keyValuePair in personKeyToPersonContainerCollection)
{
@ -379,7 +376,7 @@ internal abstract class MapLogic
int? approximateYears = null;
PersonBirthday personBirthday;
PersonContainer personContainer;
string[] personDisplayDirectoryAllFiles = [];
List<FilePath> personDisplayDirectoryAllFilePaths = [];
DateTime incrementDate = new(configuration.PersonBirthdayFirstYear, 1, 1);
long oneHour = new DateTime(1, 1, 1, 1, 0, 0).Ticks - new DateTime(1, 1, 1).Ticks;
for (int i = 0; i < int.MaxValue; i++)
@ -409,7 +406,7 @@ internal abstract class MapLogic
if (check)
continue;
personBirthday = IPersonBirthday.GetPersonBirthday(personKey + (oneHour * 2));
personContainer = new(approximateYears, [personBirthday], personDisplayDirectoryAllFiles, configuration.MappingDefaultName, personKey);
personContainer = new(approximateYears, [personBirthday], new(personDisplayDirectoryAllFilePaths), configuration.MappingDefaultName, personKey);
results.Add(personContainer);
if (results.Count > 99)
break;
@ -429,13 +426,13 @@ internal abstract class MapLogic
return result;
}
private static List<MappedFile> GetMappedFiles(Configuration configuration, ReadOnlyCollection<PersonContainer> personContainers, List<Record> records)
private static List<MappedFile> GetMappedFiles(Shared.Models.Properties.IPropertyConfiguration propertyConfiguration, Configuration configuration, ReadOnlyCollection<PersonContainer> personContainers, List<Record> records)
{
List<MappedFile> results = [];
string file;
long personKey;
string fileName;
string checkFile;
FilePath filePath;
FileHolder fileHolder;
List<string> distinct = [];
PersonBirthday? personBirthday;
results.AddRange(GetDisplayDirectoryAllFiles(configuration.FacesFileNameExtension, configuration.PersonBirthdayFormat, personContainers));
@ -444,50 +441,66 @@ internal abstract class MapLogic
personBirthday = IPersonBirthday.GetPersonBirthday(configuration.PersonBirthdayFormat, record.PersonKeyFormatted);
if (personBirthday is null)
continue;
fileName = Path.GetFileName(record.MappedFaceFile);
if (distinct.Contains(fileName))
if (distinct.Contains(record.MappedFaceFilePath.Name))
continue;
distinct.Add(fileName);
distinct.Add(record.MappedFaceFilePath.Name);
personKey = personBirthday.Value.Ticks;
results.Add(new(personKey, record.PersonKeyFormatted, record.PersonDisplayDirectoryName, record.DirectoryNumber, record.MappedFaceFile));
results.Add(new(personKey, record.PersonKeyFormatted, record.PersonDisplayDirectoryName, record.DirectoryNumber, record.MappedFaceFilePath));
}
for (int i = results.Count - 1; i > -1; i--)
{
file = results[i].File;
if (file.EndsWith(".old"))
filePath = results[i].FilePath;
if (filePath.Name.EndsWith(".old"))
{
results.RemoveAt(i);
continue;
}
if (!file.EndsWith(".dup") && !file.EndsWith(".unk") && !file.EndsWith(".abd"))
if (!filePath.Name.EndsWith(".dup") && !filePath.Name.EndsWith(".unk") && !filePath.Name.EndsWith(".abd"))
continue;
if (!File.Exists(file))
if (!File.Exists(filePath.Name))
continue;
checkFile = file[..^4];
checkFile = filePath.FullName[..^4];
if (File.Exists(checkFile))
continue;
File.Move(file, checkFile);
results[i] = new(results[i].PersonKey, results[i].PersonKeyFormatted, results[i].PersonDisplayDirectoryName, results[i].DirectoryNumber, file[..^4]);
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);
}
return results;
}
private static void ParallelFor(Configuration configuration, Dictionary<int, List<(string, int)>> skipCollection, List<LocationContainer<MetadataExtractor.Directory>> locationContainers, MappedFile mappedFile)
private static void ParallelFor(Shared.Models.Properties.IPropertyConfiguration propertyConfiguration, Configuration configuration, Dictionary<int, List<(string, int)>> skipCollection, List<LocationContainer<MetadataExtractor.Directory>> locationContainers, MappedFile mappedFile)
{
int? id;
string checkFile;
DateOnly dateOnly;
FilePath filePath;
string[] fileMatches;
FileHolder fileHolder;
int? wholePercentages;
const string lnk = ".lnk";
int? id, wholePercentages;
string personDisplayDirectoryName;
const bool fromDistanceContent = true;
IReadOnlyList<MetadataExtractor.Directory> directories;
List<(string File, int WholePercentages)>? wholePercentagesCollection;
if (!mappedFile.File.EndsWith(lnk))
(id, wholePercentages) = IMapping.GetConverted(configuration.FacesFileNameExtension, mappedFile.File);
if (!mappedFile.FilePath.Name.EndsWith(lnk))
{
if (mappedFile.FilePath.Id is null)
return;
id = mappedFile.FilePath.Id;
wholePercentages = IMapping.GetWholePercentages(configuration.FacesFileNameExtension, mappedFile.FilePath);
}
else
(id, wholePercentages) = IMapping.GetConverted(configuration.FacesFileNameExtension, mappedFile.File[..^4]);
if (id is null || wholePercentages is null)
{
fileHolder = IFileHolder.Get(mappedFile.FilePath.FullName[..^4]);
filePath = FilePath.Get(propertyConfiguration, fileHolder, index: null);
if (filePath.Id is null)
return;
id = filePath.Id;
wholePercentages = IMapping.GetWholePercentages(configuration.FacesFileNameExtension, filePath);
}
if (wholePercentages is null)
return;
if (string.IsNullOrEmpty(configuration.LocationContainerDebugDirectory) && skipCollection.TryGetValue(id.Value, out wholePercentagesCollection))
{
@ -503,11 +516,11 @@ internal abstract class MapLogic
continue;
}
}
dateOnly = DateOnly.FromDateTime(new FileInfo(mappedFile.File).CreationTime);
if (mappedFile.File.EndsWith(lnk) || (!configuration.DistanceMoveUnableToMatch && !configuration.DistanceRenameToMatch) || !File.Exists(mappedFile.File))
dateOnly = DateOnly.FromDateTime(new DateTime(mappedFile.FilePath.CreationTicks));
if (mappedFile.FilePath.Name.EndsWith(lnk) || (!configuration.DistanceMoveUnableToMatch && !configuration.DistanceRenameToMatch) || !File.Exists(mappedFile.FilePath.FullName))
directories = new List<MetadataExtractor.Directory>();
else
directories = MetadataExtractor.ImageMetadataReader.ReadMetadata(mappedFile.File);
directories = MetadataExtractor.ImageMetadataReader.ReadMetadata(mappedFile.FilePath.FullName);
RectangleF? rectangle = ILocation.GetPercentagesRectangle(configuration.LocationDigits, wholePercentages.Value);
personDisplayDirectoryName = mappedFile.PersonDisplayDirectoryName is null ? configuration.MappingDefaultName : mappedFile.PersonDisplayDirectoryName;
lock (locationContainers)
@ -515,7 +528,7 @@ internal abstract class MapLogic
directories,
mappedFile.DirectoryNumber,
personDisplayDirectoryName,
mappedFile.File,
mappedFile.FilePath,
fromDistanceContent,
id.Value,
null,
@ -529,11 +542,11 @@ internal abstract class MapLogic
string key;
float? percent;
float itemPercentagesArea;
List<string> delete = [];
List<FilePath> delete = [];
List<Duplicate> duplicates = [];
RectangleF? itemPercentagesRectangle;
(string File, int WholePercentages) item;
Dictionary<string, (string, int)> distinct = [];
(FilePath FilePath, int WholePercentages) item;
Dictionary<string, (FilePath, int)> distinct = [];
foreach (LocationContainer<MetadataExtractor.Directory> locationContainer in locationContainers)
{
key = string.Concat(locationContainer.PersonKey, locationContainer.Id);
@ -549,12 +562,12 @@ internal abstract class MapLogic
itemPercentagesArea = itemPercentagesRectangle.Value.Width * itemPercentagesRectangle.Value.Height;
percent = ILocation.GetIntersectPercent(itemPercentagesRectangle.Value, itemPercentagesArea, locationContainer.Rectangle.Value);
}
delete.Add(item.File);
delete.Add(locationContainer.File);
duplicates.Add(new(locationContainer.PersonKey, locationContainer.Id, locationContainer.File, percent));
delete.Add(item.FilePath);
delete.Add(locationContainer.FilePath);
duplicates.Add(new(locationContainer.PersonKey, locationContainer.Id, locationContainer.FilePath, percent));
continue;
}
distinct.Add(key, new(locationContainer.File, locationContainer.WholePercentages));
distinct.Add(key, new(locationContainer.FilePath, locationContainer.WholePercentages));
}
if (!configuration.DeletePossibleDuplicates && duplicates.Count > 0)
OpenPossibleDuplicates(configuration, duplicates);
@ -562,10 +575,10 @@ internal abstract class MapLogic
{
if (delete.Count > 8)
throw new Exception("Something maybe wrong!");
foreach (string file in delete)
foreach (FilePath filePath in delete)
{
if (File.Exists(file))
File.Delete(file);
if (File.Exists(filePath.FullName))
File.Delete(filePath.FullName);
}
}
}
@ -584,10 +597,10 @@ internal abstract class MapLogic
else
{
string checkFile = Path.Combine(directory, $"{keyMapping.MappingFromItem.ImageFileHolder.Name}{facePartsFileNameExtension}");
result = new(checkFile, directory, new(facePartsContentCollectionFile));
result = new(checkFile, directory, IFileHolder.Get(facePartsContentCollectionFile));
}
string facesDirectory = GetFacesDirectory(propertyConfiguration, dFacesContentDirectory, keyMapping.MappingFromItem);
FileHolder faceFileHolder = new(Path.Combine(facesDirectory, $"{keyMapping.MappingFromLocation.DeterministicHashCodeKey}{keyMapping.MappingFromItem.ImageFileHolder.ExtensionLowered}{facesFileNameExtension}"));
string facesDirectory = GetFacesDirectory(propertyConfiguration, dFacesContentDirectory, keyMapping.FilePath, keyMapping.MappingFromItem);
FileHolder faceFileHolder = IFileHolder.Get(Path.Combine(facesDirectory, $"{keyMapping.MappingFromLocation.DeterministicHashCodeKey}{keyMapping.MappingFromItem.ImageFileHolder.ExtensionLowered}{facesFileNameExtension}"));
if (!faceFileHolder.Exists)
saveContainer = null;
else
@ -714,8 +727,7 @@ internal abstract class MapLogic
}
if (personContainer.Key is null)
throw new Exception();
if (!personKeyToCount.ContainsKey(personContainer.Key.Value))
personKeyToCount.Add(personContainer.Key.Value, 0);
_ = personKeyToCount.TryAdd(personContainer.Key.Value, 0);
personKeyToCount[personContainer.Key.Value]++;
possiblyNewPersonDisplayDirectoryNamesAndPersonContainer.Add(new(personKeyFormattedIdThenWholePercentages, personContainer));
}
@ -731,29 +743,30 @@ internal abstract class MapLogic
return results;
}
internal static ReadOnlyCollection<PersonKeyFormattedIdThenWholePercentages> GetPersonKeyFormattedIdThenWholePercentages(Configuration configuration, long ticks, List<Record> collection)
internal static ReadOnlyCollection<PersonKeyFormattedIdThenWholePercentages> GetPersonKeyFormattedIdThenWholePercentages(Configuration configuration, long ticks, List<Record> records)
{
List<PersonKeyFormattedIdThenWholePercentages> results = [];
int? id;
int? wholePercentages;
List<int> wholePercentagesCollection;
Dictionary<int, List<int>> idToWholePercentagesCollection = [];
int totalSeconds = (int)Math.Floor(new TimeSpan(DateTime.Now.Ticks - ticks).TotalSeconds);
string message = $") {collection.Count:000} join from ticks Director(ies) - C - {totalSeconds} total second(s)";
string message = $") {records.Count:000} join from ticks Director(ies) - C - {totalSeconds} total second(s)";
ProgressBarOptions options = new() { ProgressCharacter = '─', ProgressBarOnBottom = true, DisableBottomPercentage = true };
using ProgressBar progressBar = new(collection.Count, message, options);
foreach (Record record in collection)
using ProgressBar progressBar = new(records.Count, message, options);
foreach (Record record in records)
{
progressBar.Tick();
(id, wholePercentages) = IMapping.GetConverted(configuration.FacesFileNameExtension, record.MappedFaceFile);
if (id is null || wholePercentages is null)
if (record.MappedFaceFilePath.Id is null)
continue;
if (!idToWholePercentagesCollection.ContainsKey(id.Value))
idToWholePercentagesCollection.Add(id.Value, []);
wholePercentagesCollection = idToWholePercentagesCollection[id.Value];
wholePercentages = IMapping.GetWholePercentages(configuration.FacesFileNameExtension, record.MappedFaceFilePath);
if (wholePercentages is null)
continue;
if (!idToWholePercentagesCollection.ContainsKey(record.MappedFaceFilePath.Id.Value))
idToWholePercentagesCollection.Add(record.MappedFaceFilePath.Id.Value, []);
wholePercentagesCollection = idToWholePercentagesCollection[record.MappedFaceFilePath.Id.Value];
wholePercentagesCollection.Add(wholePercentages.Value);
idToWholePercentagesCollection[id.Value].Add(wholePercentages.Value);
results.Add(new(record.PersonKeyFormatted, record.PersonDisplayDirectoryName, record.IsDefault, record.MappedFaceFile, id.Value, wholePercentages.Value));
idToWholePercentagesCollection[record.MappedFaceFilePath.Id.Value].Add(wholePercentages.Value);
results.Add(new(record.PersonKeyFormatted, record.PersonDisplayDirectoryName, record.IsDefault, record.MappedFaceFilePath, record.MappedFaceFilePath.Id.Value, wholePercentages.Value));
}
return new(results);
}
@ -801,16 +814,17 @@ internal abstract class MapLogic
int? approximateYears = null;
PersonBirthday? personBirthday;
PersonContainer personContainer;
List<PersonContainer>? collection;
displayDirectoryName = configuration.MappingDefaultName;
foreach (KeyValuePair<long, int> keyValuePair in personKeyToCount)
{
if (personKeyToPersonContainer.ContainsKey(keyValuePair.Key))
continue;
personBirthday = IPersonBirthday.GetPersonBirthday(keyValuePair.Key);
if (!personKeyToPersonContainerCollection.ContainsKey(keyValuePair.Key))
if (!personKeyToPersonContainerCollection.TryGetValue(keyValuePair.Key, out collection))
personContainer = new(approximateYears, personBirthday, displayDirectoryName, keyValuePair.Key);
else
personContainer = new(approximateYears, personBirthday, personKeyToPersonContainerCollection[keyValuePair.Key][zero].PersonDirectory, displayDirectoryName, keyValuePair.Key);
personContainer = new(approximateYears, personBirthday, collection[zero].PersonDirectory, displayDirectoryName, keyValuePair.Key);
personKeyToPersonContainer.Add(keyValuePair.Key, personContainer);
}
}
@ -825,8 +839,8 @@ internal abstract class MapLogic
string checkFile;
const int zero = 0;
string personKeyFormatted;
string[] deleteCollection;
List<string> distinct = [];
FilePath[] deleteCollection;
PersonBirthday personBirthday;
string personDisplayDirectory;
DateTime dateTime = new(ticks);
@ -837,49 +851,49 @@ internal abstract class MapLogic
continue;
if (a2PeopleSingletonDirectory is null || personContainer.Key is null || personContainer.Birthdays is null || personContainer.PersonDirectory is null || personContainer.Birthdays.Length == 0)
continue;
fileName = $"{Path.GetFileName(personKeyFormattedIdThenWholePercentages.MappedFaceFile)}{configuration.FacesHiddenFileNameExtension}";
fileName = $"{Path.GetFileName(personKeyFormattedIdThenWholePercentages.MappedFaceFilePath.FullName)}{configuration.FacesHiddenFileNameExtension}";
personBirthday = personContainer.Birthdays[zero];
personKey = personBirthday.Value.Ticks;
personKeyFormatted = IPersonBirthday.GetFormatted(configuration.PersonBirthdayFormat, personBirthday);
personDisplayDirectory = Path.Combine(a2PeopleSingletonDirectory, personContainer.PersonDirectory.Char.ToString(), personContainer.PersonDirectory.Group, personContainer.DisplayDirectoryName);
personKeyFormattedDirectory = Path.GetFullPath(Path.Combine(personDisplayDirectory, personKeyFormatted));
deleteCollection = (from l in personContainer.DisplayDirectoryAllFiles where l.StartsWith(personKeyFormattedDirectory) select l).ToArray();
if (personContainer.DisplayDirectoryAllFiles.Length != 0 && deleteCollection.Length == 0)
deleteCollection = (from l in personContainer.DisplayDirectoryAllFilePaths where l.FullName.StartsWith(personKeyFormattedDirectory) select l).ToArray();
if (personContainer.DisplayDirectoryAllFilePaths.Count != 0 && deleteCollection.Length == 0)
throw new NotSupportedException();
if (!Directory.Exists(personKeyFormattedDirectory))
_ = Directory.CreateDirectory(personKeyFormattedDirectory);
_ = readOnlyPersonKeyToCount.TryGetValue(personKey, out count);
_ = Directory.CreateDirectory(Path.Combine(personDisplayDirectory, count.ToString("0000")));
Directory.SetLastWriteTime(personDisplayDirectory, dateTime.AddMinutes(count));
matches = (from l in personContainer.DisplayDirectoryAllFiles where l.EndsWith(fileName) select true).ToArray();
matches = (from l in personContainer.DisplayDirectoryAllFilePaths where l.FullName.EndsWith(fileName) select true).ToArray();
if (matches.Length > 0)
continue;
matches = (from l in personContainer.DisplayDirectoryAllFiles where l.EndsWith(configuration.FacesHiddenFileNameExtension) select true).ToArray();
matches = (from l in personContainer.DisplayDirectoryAllFilePaths where l.FullName.EndsWith(configuration.FacesHiddenFileNameExtension) select true).ToArray();
if (matches.Length > 0)
continue;
if (!File.Exists(personKeyFormattedIdThenWholePercentages.MappedFaceFile))
if (!File.Exists(personKeyFormattedIdThenWholePercentages.MappedFaceFilePath.FullName))
continue;
checkFile = Path.Combine(personKeyFormattedDirectory, $"{Path.GetFileName(personKeyFormattedIdThenWholePercentages.MappedFaceFile)}{configuration.FacesHiddenFileNameExtension}");
checkFile = Path.Combine(personKeyFormattedDirectory, $"{Path.GetFileName(personKeyFormattedIdThenWholePercentages.MappedFaceFilePath.FullName)}{configuration.FacesHiddenFileNameExtension}");
if (File.Exists(checkFile))
continue;
File.Copy(personKeyFormattedIdThenWholePercentages.MappedFaceFile, checkFile);
foreach (string delete in deleteCollection)
File.Copy(personKeyFormattedIdThenWholePercentages.MappedFaceFilePath.FullName, checkFile);
foreach (FilePath delete in deleteCollection)
{
if (delete.EndsWith(".lnk"))
if (delete.ExtensionLowered == ".lnk")
continue;
if (!File.Exists(delete))
if (!File.Exists(delete.FullName))
continue;
File.Delete(delete);
File.Delete(delete.FullName);
}
Directory.SetLastWriteTime(personDisplayDirectory, DateTime.Now);
distinct.Add(personKeyFormattedIdThenWholePercentages.PersonKeyFormatted);
}
}
internal static List<LocationContainer<MetadataExtractor.Directory>> GetLocationContainers(int maxDegreeOfParallelism, Configuration configuration, long ticks, ReadOnlyCollection<PersonContainer> personContainers, Dictionary<int, List<(string, int)>> skipCollection, List<Record> records)
internal static List<LocationContainer<MetadataExtractor.Directory>> GetLocationContainers(int maxDegreeOfParallelism, Shared.Models.Properties.IPropertyConfiguration propertyConfiguration, Configuration configuration, long ticks, ReadOnlyCollection<PersonContainer> personContainers, Dictionary<int, List<(string, int)>> skipCollection, List<Record> records)
{
List<LocationContainer<MetadataExtractor.Directory>> results = [];
List<MappedFile> mappedFiles = GetMappedFiles(configuration, personContainers, records);
List<MappedFile> mappedFiles = GetMappedFiles(propertyConfiguration, configuration, personContainers, records);
if (mappedFiles.Count > 0 && (configuration.DistanceMoveUnableToMatch || configuration.DistanceRenameToMatch))
{
int totalSeconds = (int)Math.Floor(new TimeSpan(DateTime.Now.Ticks - ticks).TotalSeconds);
@ -890,7 +904,7 @@ internal abstract class MapLogic
_ = Parallel.For(0, mappedFiles.Count, parallelOptions, (i, state) =>
{
progressBar.Tick();
ParallelFor(configuration, skipCollection, results, mappedFiles[i]);
ParallelFor(propertyConfiguration, configuration, skipCollection, results, mappedFiles[i]);
});
}
if (string.IsNullOrEmpty(configuration.LocationContainerDebugDirectory))
@ -904,33 +918,27 @@ internal abstract class MapLogic
internal static int CopyManualFiles(Configuration configuration, long ticks, ReadOnlyCollection<PersonContainer> personContainers, string eDistanceContentTicksDirectory)
{
int result = 0;
string fileName;
string checkFile;
string? directory;
string dateDirectory;
string directoryName;
string checkDirectory;
string personKeyFormatted;
PersonBirthday personBirthday;
List<string> distinct = [];
PersonBirthday personBirthday;
DateTime dateTime = new(ticks);
string by = nameof(Shared.Models.Stateless.IMapLogic.ManualCopy);
foreach (PersonContainer personContainer in personContainers)
{
if (personContainer.Key is null)
continue;
for (int i = personContainer.DisplayDirectoryAllFiles.Length - 1; i > -1; i--)
for (int i = personContainer.DisplayDirectoryAllFilePaths.Count - 1; i > -1; i--)
{
if (!personContainer.DisplayDirectoryAllFiles[i].EndsWith(configuration.FacesFileNameExtension))
if (personContainer.DisplayDirectoryAllFilePaths[i].ExtensionLowered != configuration.FacesFileNameExtension)
continue;
fileName = Path.GetFileName(personContainer.DisplayDirectoryAllFiles[i]);
if (distinct.Contains(fileName))
if (distinct.Contains(personContainer.DisplayDirectoryAllFilePaths[i].Name))
continue;
distinct.Add(fileName);
directory = Path.GetDirectoryName(personContainer.DisplayDirectoryAllFiles[i]);
if (string.IsNullOrEmpty(directory))
continue;
directoryName = Path.GetFileName(directory);
distinct.Add(personContainer.DisplayDirectoryAllFilePaths[i].Name);
directoryName = Path.GetFileName(personContainer.DisplayDirectoryAllFilePaths[i].DirectoryName);
if (directoryName != personContainer.DisplayDirectoryName)
continue;
personBirthday = IPersonBirthday.GetPersonBirthday(personContainer.Key.Value);
@ -939,12 +947,13 @@ internal abstract class MapLogic
checkDirectory = Path.Combine(dateDirectory, personContainer.DisplayDirectoryName);
if (!Directory.Exists(checkDirectory))
_ = Directory.CreateDirectory(checkDirectory);
checkFile = Path.Combine(dateDirectory, fileName);
checkFile = Path.Combine(dateDirectory, personContainer.DisplayDirectoryAllFilePaths[i].Name);
if (File.Exists(checkFile))
continue;
File.Move(personContainer.DisplayDirectoryAllFiles[i], checkFile);
personContainer.DisplayDirectoryAllFiles[i] = string.Empty;
result++;
File.Move(personContainer.DisplayDirectoryAllFilePaths[i].FullName, checkFile);
throw new NotImplementedException("readonly null?");
// personContainer.DisplayDirectoryAllFilePaths[i] = null;
// result++;
}
}
return result;
@ -961,11 +970,11 @@ internal abstract class MapLogic
return result;
}
internal static string GetFacePartsDirectory(Shared.Models.Properties.IPropertyConfiguration propertyConfiguration, string d2FacePartsContentDirectory, MappingFromItem mappingFromItem)
internal static string GetFacePartsDirectory(Shared.Models.Properties.IPropertyConfiguration propertyConfiguration, string d2FacePartsContentDirectory, FilePath filePath, MappingFromItem mappingFromItem)
{
string result;
(string directoryName, _) = IPath.GetDirectoryNameAndIndex(propertyConfiguration.ResultAllInOneSubdirectoryLength, mappingFromItem.ImageFileHolder.NameWithoutExtension);
result = Path.Combine(d2FacePartsContentDirectory, propertyConfiguration.ResultAllInOne, directoryName, mappingFromItem.ImageFileHolder.NameWithoutExtension);
(string directoryName, _) = IPath.GetDirectoryNameAndIndex(propertyConfiguration, filePath);
result = Path.Combine(d2FacePartsContentDirectory, directoryName, mappingFromItem.ImageFileHolder.NameWithoutExtension);
return result;
}
@ -975,7 +984,7 @@ internal abstract class MapLogic
string shortcutFile;
if (sortingContainer?.Source.MappingFromLocation is null)
throw new NullReferenceException(nameof(sortingContainer.Source.MappingFromLocation));
FileHolder faceFileHolder = new($"C:/{sortingContainer.Sorting.Id}.{sortingContainer.Sorting.WholePercentages}");
FileHolder faceFileHolder = IFileHolder.Get($"C:/{sortingContainer.Sorting.Id}.{sortingContainer.Sorting.WholePercentages}");
if (keyMapping.MappingFromPerson is not null && keyMapping.MappingFromLocation is not null)
shortcutFile = Path.Combine(directory, $"{keyMapping.MappingFromLocation.DeterministicHashCodeKey}{keyMapping.MappingFromItem.ImageFileHolder.ExtensionLowered}.{sortingContainer.Sorting.DistancePermyriad}.lnk");
else

View File

@ -19,7 +19,7 @@ internal abstract class RelationLogic
{
if (!locationContainer.FromDistanceContent)
continue;
if (!locationContainer.File.Contains(configuration.LocationContainerDirectoryPattern))
if (!locationContainer.FilePath.FullName.Contains(configuration.LocationContainerDirectoryPattern))
continue;
if (!personKeyTo.TryGetValue(locationContainer.PersonKey, out yearTo))
{
@ -312,9 +312,9 @@ internal abstract class RelationLogic
{
lines.Clear();
if (movedFiles.TryGetValue(relationFileHolder.FullName, out file))
fileHolder = new(file);
fileHolder = IFileHolder.Get(file);
else
fileHolder = new(relationFileHolder.FullName);
fileHolder = IFileHolder.Get(relationFileHolder.FullName);
if (!relationFileHolder.Exists || relationFileHolder.CreationTime is null)
continue;
if (isCounterPersonYear)
@ -344,9 +344,9 @@ internal abstract class RelationLogic
{
relation = relations[i];
if (movedFiles.TryGetValue(relation.File, out file))
fileHolder = new(file);
fileHolder = IFileHolder.Get(file);
else
fileHolder = new(relation.File);
fileHolder = IFileHolder.Get(relation.File);
if (!fileHolder.Exists || fileHolder.CreationTime is null)
continue;
fileNameWithoutExtension = Path.GetFileNameWithoutExtension(fileHolder.NameWithoutExtension);

View File

@ -16,7 +16,7 @@ public class B_Metadata : IMetadata<MetadataExtractor.Directory>
private readonly bool _PropertiesChangedForMetadata;
private readonly IPropertyConfiguration _PropertyConfiguration;
private readonly bool _ForceMetadataLastWriteTimeToCreationTime;
private readonly IReadOnlyDictionary<string, string[]> _FileGroups;
private readonly ReadOnlyDictionary<string, string[]> _FileGroups;
private readonly JsonSerializerOptions _WriteIndentedJsonSerializerOptions;
public B_Metadata(IPropertyConfiguration propertyConfiguration)
@ -43,12 +43,12 @@ public class B_Metadata : IMetadata<MetadataExtractor.Directory>
return result;
}
public ReadOnlyDictionary<string, MetadataExtractorDirectory> GetMetadataCollection(List<Tuple<string, DateTime>> subFileTuples, List<string> parseExceptions, string[] changesFrom, MappingFromItem mappingFromItem)
public ReadOnlyDictionary<string, MetadataExtractorDirectory> GetMetadataCollection(FilePath filePath, List<Tuple<string, DateTime>> subFileTuples, List<string> parseExceptions, string[] changesFrom, MappingFromItem mappingFromItem)
{
Dictionary<string, MetadataExtractorDirectory>? results = null;
string json = string.Empty;
List<DateTime> dateTimes = (from l in subFileTuples where changesFrom.Contains(l.Item1) select l.Item2).ToList();
(_, int directoryIndex) = Shared.Models.Stateless.Methods.IPath.GetDirectoryNameAndIndex(_PropertyConfiguration.ResultAllInOneSubdirectoryLength, mappingFromItem.ImageFileHolder.Name);
(_, int directoryIndex) = Shared.Models.Stateless.Methods.IPath.GetDirectoryNameAndIndex(_PropertyConfiguration, filePath);
FileInfo fileInfo = new(Path.Combine(_FileGroups[_PropertyConfiguration.ResultSingleton][directoryIndex], $"{mappingFromItem.ImageFileHolder.NameWithoutExtension}{mappingFromItem.ImageFileHolder.ExtensionLowered}.json"));
if (_ForceMetadataLastWriteTimeToCreationTime && !fileInfo.Exists && File.Exists(Path.ChangeExtension(fileInfo.FullName, ".delete")))
{

View File

@ -6,7 +6,6 @@ using System.Text;
using View_by_Distance.Move.By.Id.Models;
using View_by_Distance.Shared.Models;
using View_by_Distance.Shared.Models.Methods;
using View_by_Distance.Shared.Models.Stateless.Methods;
namespace View_by_Distance.Move.By.Id;
@ -105,31 +104,28 @@ public class MoveById
int? id;
string? message;
string[] matches;
FilePath filePath;
FileHolder fileHolder;
bool isIgnoreExtension;
const string jpeg = ".jpeg";
bool isValidImageFormatExtension;
ASCIIEncoding asciiEncoding = new();
bool nameWithoutExtensionIsIdFormat;
bool nameWithoutExtensionIsPaddedIdFormat;
short sortOrderOnlyLengthIndex = IDirectory.GetSortOrderOnlyLengthIndex(_PropertyConfiguration.Offset);
foreach (string file in allFiles)
{
progressBar.Tick();
fileHolder = new(file);
fileHolder = Shared.Models.Stateless.Methods.IFileHolder.Get(file);
filePath = FilePath.Get(_Configuration.PropertyConfiguration, fileHolder, index: null);
if (fileHolder.ExtensionLowered == ".id" || fileHolder.DirectoryName is null)
continue;
if (allFiles.Contains($"{fileHolder.FullName}.id"))
continue;
isValidImageFormatExtension = _PropertyConfiguration.ValidImageFormatExtensions.Contains(fileHolder.ExtensionLowered);
nameWithoutExtensionIsIdFormat = Shared.Models.Stateless.Methods.IProperty.NameWithoutExtensionIsIdFormat(fileHolder);
isIgnoreExtension = isValidImageFormatExtension && _PropertyConfiguration.IgnoreExtensions.Contains(fileHolder.ExtensionLowered);
nameWithoutExtensionIsPaddedIdFormat = IDirectory.NameWithoutExtensionIsPaddedIdFormat(fileHolder, sortOrderOnlyLengthIndex);
if (!isIgnoreExtension && !isValidImageFormatExtension)
{
if (fileHolder.ExtensionLowered == jpeg)
continue;
if (nameWithoutExtensionIsIdFormat || nameWithoutExtensionIsPaddedIdFormat)
if (filePath.IsIntelligentIdFormat || filePath.SortOrder is not null)
continue;
}
(_, _, id, message) = Property.Models.Stateless.IProperty.Get(_PropertyConfiguration.PopulatePropertyId, fileHolder, isIgnoreExtension, isValidImageFormatExtension, asciiEncoding);

View File

@ -83,7 +83,7 @@ public class OffsetDateTimeOriginal
string[] files = Directory.GetFiles(checkDirectory, "*", SearchOption.TopDirectoryOnly);
foreach (string file in files)
{
fileHolder = new(file);
fileHolder = Shared.Models.Stateless.Methods.IFileHolder.Get(file);
isValidImageFormatExtension = _PropertyConfiguration.ValidImageFormatExtensions.Contains(fileHolder.ExtensionLowered);
isIgnoreExtension = isValidImageFormatExtension && _PropertyConfiguration.IgnoreExtensions.Contains(fileHolder.ExtensionLowered);
(dateTimeOriginal, dateTimes, id, message) = Property.Models.Stateless.IProperty.Get(_PropertyConfiguration.PopulatePropertyId, fileHolder, isIgnoreExtension, isValidImageFormatExtension, asciiEncoding);
@ -193,8 +193,8 @@ public class OffsetDateTimeOriginal
bool targetIsIgnoreExtension;
DateTime? badDateTimeOriginal;
DateTime? targetDateTimeOriginal;
FileHolder badFileHolder = new(badFiles.First());
FileHolder targetFileHolder = new(targetFiles.First());
FileHolder badFileHolder = Shared.Models.Stateless.Methods.IFileHolder.Get(badFiles.First());
FileHolder targetFileHolder = Shared.Models.Stateless.Methods.IFileHolder.Get(targetFiles.First());
bool badIsValidImageFormatExtension = _PropertyConfiguration.ValidImageFormatExtensions.Contains(badFileHolder.ExtensionLowered);
bool targetIsValidImageFormatExtension = _PropertyConfiguration.ValidImageFormatExtensions.Contains(targetFileHolder.ExtensionLowered);
badIsIgnoreExtension = badIsValidImageFormatExtension && _PropertyConfiguration.IgnoreExtensions.Contains(badFileHolder.ExtensionLowered);

View File

@ -1,4 +1,5 @@
using ShellProgressBar;
using System.Collections.ObjectModel;
using System.Text;
using System.Text.Json;
using View_by_Distance.Property.Models.Stateless;
@ -21,7 +22,7 @@ public class A_Property
private readonly Configuration _Configuration;
private readonly List<string> _AngleBracketCollection;
private readonly IPropertyConfiguration _PropertyConfiguration;
private readonly IReadOnlyDictionary<string, string[]> _FileGroups;
private readonly ReadOnlyDictionary<string, string[]> _FileGroups;
public A_Property(int maxDegreeOfParallelism, Configuration propertyConfiguration, string outputExtension, bool reverse, string aResultsFullGroupDirectory)
{
@ -56,7 +57,7 @@ public class A_Property
fileInfo = new(Path.Combine(angleBracket.Replace("<>", _PropertyConfiguration.ResultSingleton), $"{item.ImageFileHolder.NameWithoutExtension}{item.ImageFileHolder.ExtensionLowered}.json"));
else
{
(_, int directoryIndex) = Shared.Models.Stateless.Methods.IPath.GetDirectoryNameAndIndex(_PropertyConfiguration.ResultAllInOneSubdirectoryLength, item.ImageFileHolder.Name);
(_, int directoryIndex) = Shared.Models.Stateless.Methods.IPath.GetDirectoryNameAndIndex(_PropertyConfiguration, item.FilePath);
fileInfo = new(Path.Combine(_FileGroups[_PropertyConfiguration.ResultSingleton][directoryIndex], $"{item.ImageFileHolder.NameWithoutExtension}{item.ImageFileHolder.ExtensionLowered}.json"));
}
List<DateTime> dateTimes = (from l in sourceDirectoryFileTuples where l is not null && changesFrom.Contains(l.Item1) select l.Item2).ToList();
@ -133,7 +134,7 @@ public class A_Property
}
if (result is null)
{
id ??= item.ImageFileHolder.Id;
id ??= item.FilePath.Id;
(_, _, result) = Stateless.Property.GetProperty(populateId, metadata, item.ImageFileHolder, result, isIgnoreExtension, item.IsValidImageFormatExtension, id, _ASCIIEncoding);
json = JsonSerializer.Serialize(result, PropertyGenerationContext.Default.Property);
if (populateId && Shared.Models.Stateless.Methods.IPath.WriteAllText(fileInfo.FullName, json, updateDateWhenMatches: true, compareBeforeWrite: true))

View File

@ -12,6 +12,7 @@ public class Configuration
public bool? ForcePropertyLastWriteTimeToCreationTime { get; set; }
public string[]? IgnoreExtensions { get; set; }
public string[]? IgnoreRulesKeyWords { get; set; }
public int? IntMinValueLength { get; set; }
public int? MaxImagesInDirectoryForTopLevelFirstPass { get; set; }
public string? ModelName { init; get; }
public int? NumberOfJitters { init; get; }
@ -47,6 +48,7 @@ public class Configuration
if (configuration.ForcePropertyLastWriteTimeToCreationTime is null) throw new NullReferenceException(nameof(configuration.ForcePropertyLastWriteTimeToCreationTime));
if (configuration.IgnoreExtensions is null) throw new NullReferenceException(nameof(configuration.IgnoreExtensions));
if (configuration.IgnoreRulesKeyWords is null) throw new NullReferenceException(nameof(configuration.IgnoreRulesKeyWords));
if (configuration.IntMinValueLength is null) throw new NullReferenceException(nameof(configuration.IntMinValueLength));
if (configuration.MaxImagesInDirectoryForTopLevelFirstPass is null) throw new NullReferenceException(nameof(configuration.MaxImagesInDirectoryForTopLevelFirstPass));
// if (configuration.ModelName is null) throw new NullReferenceException(nameof(configuration.ModelName));
// if (configuration.NumberOfJitters is null) throw new NullReferenceException(nameof(configuration.NumberOfJitters));
@ -71,6 +73,7 @@ public class Configuration
configuration.ForcePropertyLastWriteTimeToCreationTime.Value,
configuration.IgnoreExtensions,
configuration.IgnoreRulesKeyWords,
configuration.IntMinValueLength.Value,
configuration.MaxImagesInDirectoryForTopLevelFirstPass.Value,
configuration.ModelName,
configuration.NumberOfJitters,

View File

@ -15,6 +15,7 @@ public class Configuration : Shared.Models.Properties.IPropertyConfiguration
public bool ForcePropertyLastWriteTimeToCreationTime { init; get; }
public string[] IgnoreExtensions { init; get; }
public string[] IgnoreRulesKeyWords { init; get; }
public int IntMinValueLength { init; get; }
public int MaxImagesInDirectoryForTopLevelFirstPass { init; get; }
public string? ModelName { init; get; }
public int? NumberOfJitters { init; get; }
@ -39,6 +40,7 @@ public class Configuration : Shared.Models.Properties.IPropertyConfiguration
bool forcePropertyLastWriteTimeToCreationTime,
string[] ignoreExtensions,
string[] ignoreRulesKeyWords,
int intMinValueLength,
int maxImagesInDirectoryForTopLevelFirstPass,
string? modelName,
int? numberOfJitters,
@ -64,6 +66,7 @@ public class Configuration : Shared.Models.Properties.IPropertyConfiguration
ForcePropertyLastWriteTimeToCreationTime = forcePropertyLastWriteTimeToCreationTime;
IgnoreExtensions = ignoreExtensions;
IgnoreRulesKeyWords = ignoreRulesKeyWords;
IntMinValueLength = intMinValueLength;
MaxImagesInDirectoryForTopLevelFirstPass = maxImagesInDirectoryForTopLevelFirstPass;
ModelName = modelName;
NumberOfJitters = numberOfJitters;

View File

@ -13,11 +13,6 @@ public interface IProperty
static string DateTimeFormat() =>
"yyyy:MM:dd HH:mm:ss";
int TestStatic_GetDeterministicHashCode(byte[] value) =>
GetDeterministicHashCode(value);
static int GetDeterministicHashCode(byte[] value) =>
Property.GetDeterministicHashCode(value);
byte[] TestStatic_GetBytes(string value) =>
GetBytes(value);
static byte[] GetBytes(string value) =>

View File

@ -139,25 +139,6 @@ internal partial class Property
return results;
}
internal static int GetDeterministicHashCode(byte[] value)
{
int result;
unchecked
{
int hash1 = (5381 << 16) + 5381;
int hash2 = hash1;
for (int i = 0; i < value.Length; i += 2)
{
hash1 = ((hash1 << 5) + hash1) ^ value[i];
if (i == value.Length - 1)
break;
hash2 = ((hash2 << 5) + hash2) ^ value[i + 1];
}
result = hash1 + (hash2 * 1566083941);
}
return result;
}
#pragma warning disable CA1416
internal static PropertyItem GetPropertyItem(ConstructorInfo constructorInfo, int id, short type, string value)
@ -260,7 +241,7 @@ internal partial class Property
bytes = new byte[length];
Marshal.Copy(intPtr, bytes, 0, length);
bitmap.UnlockBits(bitmapData);
id ??= GetDeterministicHashCode(bytes);
id ??= Shared.Models.Stateless.Methods.IId.GetDeterministicHashCode(bytes);
}
dateTimeFormat = IProperty.DateTimeFormat();
if (image.PropertyIdList.Contains((int)IExif.Tags.DateTime))

View File

@ -127,17 +127,16 @@ public class Rename
}
if (records.Count != 0)
{
int intMinValueLength = int.MinValue.ToString().Length;
foreach (Record record in records)
{
if (record.Id is null)
continue;
if (intMinValueLength < record.Id.Value.ToString().Length)
if (_PropertyConfiguration.IntMinValueLength < record.Id.Value.ToString().Length)
throw new NotSupportedException();
}
message = $"{intMinValueLength}) comparing records";
message = $"{_PropertyConfiguration.IntMinValueLength}) comparing records";
progressBar = new(records.Count, message, options);
toDoCollection.AddRange(GetToDoCollection(progressBar, nefPresent, records, intMinValueLength));
toDoCollection.AddRange(GetToDoCollection(progressBar, nefPresent, records));
progressBar.Dispose();
}
foreach ((FileHolder fileHolder, string directory, string to) in toDoCollection)
@ -204,7 +203,7 @@ public class Rename
if (distinct.Contains(lines[1]))
continue;
distinct.Add(lines[1]);
fileHolder = new(lines[0]);
fileHolder = Shared.Models.Stateless.Methods.IFileHolder.Get(lines[0]);
results.Add(new(fileHolder, directory, lines[1]));
}
return results;
@ -216,6 +215,7 @@ public class Rename
int? id;
string? message;
string? directory;
FilePath filePath;
DateTime[] dateTimes;
FileHolder fileHolder;
string[]? ffmpegFiles;
@ -223,26 +223,22 @@ public class Rename
DateTime? dateTimeOriginal;
bool isValidImageFormatExtension;
ASCIIEncoding asciiEncoding = new();
bool nameWithoutExtensionIsIdFormat;
bool nameWithoutExtensionIsPaddedIdFormat;
IReadOnlyList<MetadataExtractor.Directory> directories;
short sortOrderOnlyLengthIndex = IDirectory.GetSortOrderOnlyLengthIndex(_PropertyConfiguration.Offset);
for (int i = 0; i < files.Length; i++)
{
progressBar.Tick();
fileHolder = new(files[i]);
fileHolder = Shared.Models.Stateless.Methods.IFileHolder.Get(files[i]);
if (!fileHolder.Exists)
continue;
directory = Path.GetDirectoryName(files[i]);
if (string.IsNullOrEmpty(directory))
continue;
filePath = FilePath.Get(_Configuration.PropertyConfiguration, fileHolder, index: i);
if (fileHolder.ExtensionLowered == ".paddedId" || fileHolder.ExtensionLowered == ".lsv" || fileHolder.DirectoryName is null)
continue;
if (files.Contains($"{fileHolder.FullName}.paddedId"))
continue;
nameWithoutExtensionIsIdFormat = Shared.Models.Stateless.Methods.IProperty.NameWithoutExtensionIsIdFormat(fileHolder);
nameWithoutExtensionIsPaddedIdFormat = IDirectory.NameWithoutExtensionIsPaddedIdFormat(fileHolder, sortOrderOnlyLengthIndex);
if (nameWithoutExtensionIsIdFormat || nameWithoutExtensionIsPaddedIdFormat)
if (filePath.IsIntelligentIdFormat || filePath.SortOrder is not null)
continue;
isValidImageFormatExtension = _PropertyConfiguration.ValidImageFormatExtensions.Contains(fileHolder.ExtensionLowered);
isIgnoreExtension = isValidImageFormatExtension && _PropertyConfiguration.IgnoreExtensions.Contains(fileHolder.ExtensionLowered);
@ -262,7 +258,7 @@ public class Rename
ffmpegFiles = Directory.GetFiles(fileHolder.DirectoryName, $"{fileHolder.Name}-*.jpg", SearchOption.TopDirectoryOnly);
if (ffmpegFiles.Length == 0)
continue;
fileHolder = new(ffmpegFiles.First());
fileHolder = Shared.Models.Stateless.Methods.IFileHolder.Get(ffmpegFiles.First());
if (!fileHolder.Name.EndsWith("-0001.jpg"))
throw new Exception();
isValidImageFormatExtension = _PropertyConfiguration.ValidImageFormatExtensions.Contains(fileHolder.ExtensionLowered);
@ -275,7 +271,7 @@ public class Rename
(dateTimeOriginal, dateTimes, id, message) = Property.Models.Stateless.IProperty.Get(_PropertyConfiguration.PopulatePropertyId, metadata, fileHolder, isIgnoreExtension, isValidImageFormatExtension, asciiEncoding);
if (ffmpegFiles is not null)
{
fileHolder = new(files[i]);
fileHolder = Shared.Models.Stateless.Methods.IFileHolder.Get(files[i]);
foreach (string ffmpegFile in ffmpegFiles)
File.Delete(ffmpegFile);
}
@ -286,7 +282,7 @@ public class Rename
return results;
}
private List<(FileHolder, string, string)> GetToDoCollection(ProgressBar progressBar, bool nefPresent, List<Record> records, int intMinValueLength)
private List<(FileHolder, string, string)> GetToDoCollection(ProgressBar progressBar, bool nefPresent, List<Record> records)
{
List<(FileHolder, string, string)> results = [];
int season;
@ -330,7 +326,7 @@ public class Rename
if (distinct.Contains(checkFile))
continue;
distinct.Add(checkFile);
results.Add(new(new($"{fileHolder.FullName}.paddedId"), fileHolder.DirectoryName, checkFile));
results.Add(new(Shared.Models.Stateless.Methods.IFileHolder.Get($"{fileHolder.FullName}.paddedId"), fileHolder.DirectoryName, checkFile));
}
checkFile = Path.Combine(fileHolder.DirectoryName, $"{fileHolder.NameWithoutExtension}{jpg}");
if (File.Exists(checkFile))
@ -340,13 +336,13 @@ public class Rename
distinct.Add(checkFile);
results.Add(new(fileHolder, fileHolder.DirectoryName, checkFile));
if (nefPresent)
results.Add(new(new($"{fileHolder.FullName[..^4]}.tif"), fileHolder.DirectoryName, $"{checkFile[..^4]}.tif"));
results.Add(new(Shared.Models.Stateless.Methods.IFileHolder.Get($"{fileHolder.FullName[..^4]}.tif"), fileHolder.DirectoryName, $"{checkFile[..^4]}.tif"));
if (nefPresent)
results.Add(new(new($"{fileHolder.FullName[..^4]}.nef"), fileHolder.DirectoryName, $"{checkFile[..^4]}.nef"));
results.Add(new(Shared.Models.Stateless.Methods.IFileHolder.Get($"{fileHolder.FullName[..^4]}.nef"), fileHolder.DirectoryName, $"{checkFile[..^4]}.nef"));
if (File.Exists(checkFile))
continue;
File.Move(fileHolder.FullName, checkFile);
fileHolder = new(checkFile);
fileHolder = Shared.Models.Stateless.Methods.IFileHolder.Get(checkFile);
if (fileHolder.DirectoryName is null)
continue;
}
@ -398,15 +394,15 @@ public class Rename
distinct.Add(checkFile);
results.Add(new(fileHolder, fileHolder.DirectoryName, checkFile));
if (nefPresent)
results.Add(new(new($"{fileHolder.FullName[..^4]}.tif"), fileHolder.DirectoryName, $"{checkFile[..^4]}.tif"));
results.Add(new(Shared.Models.Stateless.Methods.IFileHolder.Get($"{fileHolder.FullName[..^4]}.tif"), fileHolder.DirectoryName, $"{checkFile[..^4]}.tif"));
if (nefPresent)
results.Add(new(new($"{fileHolder.FullName[..^4]}.nef"), fileHolder.DirectoryName, $"{checkFile[..^4]}.nef"));
results.Add(new(Shared.Models.Stateless.Methods.IFileHolder.Get($"{fileHolder.FullName[..^4]}.nef"), fileHolder.DirectoryName, $"{checkFile[..^4]}.nef"));
}
else
{
if (record.Id is null)
continue;
paddedId = IDirectory.GetPaddedId(intMinValueLength, record.Index, record.Id.Value);
paddedId = IId.GetPaddedId(_PropertyConfiguration, record.Index, record.Id.Value);
checkFileExtension = fileHolder.ExtensionLowered == jpeg ? jpg : fileHolder.ExtensionLowered;
checkFile = Path.Combine(seasonDirectory, $"{paddedId}{checkFileExtension}");
if (checkFile == fileHolder.FullName)
@ -422,9 +418,9 @@ public class Rename
distinct.Add(checkFile);
results.Add(new(fileHolder, seasonDirectory, checkFile));
if (nefPresent)
results.Add(new(new($"{fileHolder.FullName[..^4]}.tif"), seasonDirectory, $"{checkFile[..^4]}.tif"));
results.Add(new(Shared.Models.Stateless.Methods.IFileHolder.Get($"{fileHolder.FullName[..^4]}.tif"), seasonDirectory, $"{checkFile[..^4]}.tif"));
if (nefPresent)
results.Add(new(new($"{fileHolder.FullName[..^4]}.nef"), seasonDirectory, $"{checkFile[..^4]}.nef"));
results.Add(new(Shared.Models.Stateless.Methods.IFileHolder.Get($"{fileHolder.FullName[..^4]}.nef"), seasonDirectory, $"{checkFile[..^4]}.nef"));
}
}
return results;

View File

@ -1,3 +1,4 @@
using System.Collections.ObjectModel;
using System.Drawing;
using System.Drawing.Imaging;
using System.Reflection;
@ -75,7 +76,7 @@ public class C_Resize
public void Update(string cResultsFullGroupDirectory)
{
_FileGroups.Clear();
Dictionary<string, string[]> keyValuePairs = Shared.Models.Stateless.Methods.IPath.GetKeyValuePairs(_PropertyConfiguration, cResultsFullGroupDirectory, [_PropertyConfiguration.ResultSingleton]);
ReadOnlyDictionary<string, string[]> keyValuePairs = Shared.Models.Stateless.Methods.IPath.GetKeyValuePairs(_PropertyConfiguration, cResultsFullGroupDirectory, [_PropertyConfiguration.ResultSingleton]);
foreach (KeyValuePair<string, string[]> keyValuePair in keyValuePairs)
_FileGroups.Add(keyValuePair.Key, keyValuePair.Value);
}
@ -415,32 +416,32 @@ public class C_Resize
return results;
}
private FileHolder GetResizedFileHolder(string cResultsFullGroupDirectory, Item item, bool outputResolutionHasNumber, string fileName)
private FileHolder GetResizedFileHolder(string cResultsFullGroupDirectory, FilePath filePath, bool outputResolutionHasNumber, string fileName)
{
FileHolder result;
if (outputResolutionHasNumber)
result = new(Path.Combine(AngleBracketCollection[0].Replace("<>", _PropertyConfiguration.ResultContent), fileName));
result = Shared.Models.Stateless.Methods.IFileHolder.Get(Path.Combine(AngleBracketCollection[0].Replace("<>", _PropertyConfiguration.ResultContent), fileName));
else
{
(string directoryName, _) = Shared.Models.Stateless.Methods.IPath.GetDirectoryNameAndIndex(_PropertyConfiguration.ResultAllInOneSubdirectoryLength, item.ImageFileHolder.Name);
result = new(Path.Combine(cResultsFullGroupDirectory, _PropertyConfiguration.ResultContent, _PropertyConfiguration.ResultAllInOne, directoryName, fileName));
(string directoryName, _) = Shared.Models.Stateless.Methods.IPath.GetDirectoryNameAndIndex(_PropertyConfiguration, filePath);
result = Shared.Models.Stateless.Methods.IFileHolder.Get(Path.Combine(cResultsFullGroupDirectory, _PropertyConfiguration.ResultContent, directoryName, fileName));
}
return result;
}
public FileHolder GetResizedFileHolder(string cResultsFullGroupDirectory, Item item, bool outputResolutionHasNumber) =>
GetResizedFileHolder(cResultsFullGroupDirectory, item, outputResolutionHasNumber, item.ImageFileHolder.Name);
GetResizedFileHolder(cResultsFullGroupDirectory, item.FilePath, outputResolutionHasNumber, item.ImageFileHolder.Name);
public FileHolder GetResizedFileHolder(string cResultsFullGroupDirectory, Item item, bool outputResolutionHasNumber, int id) =>
GetResizedFileHolder(cResultsFullGroupDirectory, item, outputResolutionHasNumber, $"{id}{item.ImageFileHolder.ExtensionLowered}");
GetResizedFileHolder(cResultsFullGroupDirectory, item.FilePath, outputResolutionHasNumber, $"{id}{item.ImageFileHolder.ExtensionLowered}");
public Dictionary<string, int[]> GetResizeKeyValuePairs(Configuration configuration, string cResultsFullGroupDirectory, List<Tuple<string, DateTime>> subFileTuples, List<string> parseExceptions, Shared.Models.Property property, MappingFromItem mappingFromItem)
public Dictionary<string, int[]> GetResizeKeyValuePairs(Configuration configuration, string cResultsFullGroupDirectory, FilePath filePath, List<Tuple<string, DateTime>> subFileTuples, List<string> parseExceptions, Shared.Models.Property property, MappingFromItem mappingFromItem)
{
Dictionary<string, int[]>? results;
string json;
string[] changesFrom = [nameof(A_Property), nameof(B_Metadata)];
List<DateTime> dateTimes = (from l in subFileTuples where changesFrom.Contains(l.Item1) select l.Item2).ToList();
(_, int directoryIndex) = Shared.Models.Stateless.Methods.IPath.GetDirectoryNameAndIndex(_PropertyConfiguration.ResultAllInOneSubdirectoryLength, mappingFromItem.ImageFileHolder.Name);
(_, int directoryIndex) = Shared.Models.Stateless.Methods.IPath.GetDirectoryNameAndIndex(_PropertyConfiguration, filePath);
FileInfo fileInfo = new(Path.Combine(_FileGroups[_PropertyConfiguration.ResultSingleton][directoryIndex], $"{mappingFromItem.ImageFileHolder.NameWithoutExtension}{mappingFromItem.ImageFileHolder.ExtensionLowered}.json"));
if (_ForceResizeLastWriteTimeToCreationTime && !fileInfo.Exists && File.Exists(Path.ChangeExtension(fileInfo.FullName, ".delete")))
{

View File

@ -21,7 +21,7 @@ public class SetCreatedDate
private readonly Configuration _Configuration;
private readonly IsEnvironment _IsEnvironment;
private readonly IConfigurationRoot _ConfigurationRoot;
private readonly IReadOnlyDictionary<string, string[]> _FileGroups;
private readonly ReadOnlyDictionary<string, string[]> _FileGroups;
private readonly Property.Models.Configuration _PropertyConfiguration;
public SetCreatedDate(List<string> args, ILogger<Program> logger, IsEnvironment isEnvironment, IConfigurationRoot configurationRoot, AppSettings appSettings, string workingDirectory, bool isSilent, IConsole console)
@ -77,7 +77,7 @@ public class SetCreatedDate
foreach (string file in files)
{
progressBar.Tick();
fileHolder = new(file);
fileHolder = Shared.Models.Stateless.Methods.IFileHolder.Get(file);
if (fileHolder.ExtensionLowered == ".id" || fileHolder.ExtensionLowered == ".lsv" || fileHolder.DirectoryName is null)
continue;
if (_PropertyConfiguration.IgnoreExtensions.Contains(fileHolder.ExtensionLowered))

View File

@ -1,75 +1,57 @@
using System.Text.Json;
using System.Text.Json.Serialization;
namespace View_by_Distance.Shared.Models;
public class FileHolder : Properties.IFileHolder
public record FileHolder(DateTime? CreationTime,
string? DirectoryName,
bool Exists,
string ExtensionLowered,
string FullName,
DateTime? LastWriteTime,
long? Length,
string Name,
string NameWithoutExtension)
{
protected readonly DateTime? _CreationTime;
protected readonly string? _DirectoryName;
protected readonly bool _Exists;
protected readonly string _ExtensionLowered;
protected readonly string _FullName;
protected readonly int? _Id;
protected readonly DateTime? _LastWriteTime;
protected readonly long? _Length;
protected readonly string _Name;
protected readonly string _NameWithoutExtension;
public DateTime? CreationTime => _CreationTime;
public string? DirectoryName => _DirectoryName;
public bool Exists => _Exists;
public string ExtensionLowered => _ExtensionLowered;
public string FullName => _FullName;
public int? Id => _Id;
public DateTime? LastWriteTime => _LastWriteTime;
public long? Length => _Length;
public string Name => _Name;
public string NameWithoutExtension => _NameWithoutExtension;
public FileHolder(DateTime? creationTime, string? directoryName, bool exists, string extensionLowered, string fullName, int? id, DateTime? lastWriteTime, long? length, string name, string nameWithoutExtension)
{
_CreationTime = creationTime;
_DirectoryName = directoryName;
_Exists = exists;
_ExtensionLowered = extensionLowered;
_FullName = fullName;
_Id = id;
_LastWriteTime = lastWriteTime;
_Length = length;
_Name = name;
_NameWithoutExtension = nameWithoutExtension;
}
public FileHolder(FileInfo fileInfo, int? id)
{
if (fileInfo.Exists)
{
_CreationTime = fileInfo.CreationTime;
_CreationTime = fileInfo.CreationTime;
_LastWriteTime = fileInfo.LastWriteTime;
_Length = fileInfo.Length;
}
_DirectoryName = fileInfo.DirectoryName;
_Exists = fileInfo.Exists;
_ExtensionLowered = fileInfo.Extension.ToLower();
_Id = id;
_FullName = fileInfo.FullName;
_Name = fileInfo.Name;
_NameWithoutExtension = Path.GetFileNameWithoutExtension(fileInfo.FullName);
}
public FileHolder(string fileName) :
this(new FileInfo(fileName), null)
{ }
public FileHolder(string fileName, int? id) :
this(new FileInfo(fileName), id)
{ }
public override string ToString()
{
string result = JsonSerializer.Serialize(this, new JsonSerializerOptions() { WriteIndented = true });
string result = JsonSerializer.Serialize(this, FileHolderSourceGenerationContext.Default.FileHolder);
return result;
}
public static FileHolder Get(FileInfo fileInfo)
{
FileHolder result;
if (!fileInfo.Exists)
result = new(null,
fileInfo.DirectoryName,
fileInfo.Exists,
fileInfo.Extension.ToLower(),
fileInfo.FullName,
null,
null,
fileInfo.Name,
Path.GetFileNameWithoutExtension(fileInfo.FullName));
else
{
result = new(fileInfo.CreationTime,
fileInfo.DirectoryName,
fileInfo.Exists,
fileInfo.Extension.ToLower(),
fileInfo.FullName,
fileInfo.LastWriteTime,
fileInfo.Length,
fileInfo.Name,
Path.GetFileNameWithoutExtension(fileInfo.FullName));
}
return result;
}
}
[JsonSourceGenerationOptions(WriteIndented = true)]
[JsonSerializable(typeof(FileHolder))]
public partial class FileHolderSourceGenerationContext : JsonSerializerContext
{
}

View File

@ -1,3 +1,25 @@
using System.Text.Json;
using System.Text.Json.Serialization;
namespace View_by_Distance.Shared.Models;
public record FilePair(string Path, bool IsUnique, bool? IsNotUniqueAndNeedsReview, List<string> Collection, string? Match) { }
internal record FilePair(string Path,
bool IsUnique,
bool? IsNotUniqueAndNeedsReview,
List<string> Collection,
string? Match)
{
public override string ToString()
{
string result = JsonSerializer.Serialize(this, FilePairSourceGenerationContext.Default.FilePair);
return result;
}
}
[JsonSourceGenerationOptions(WriteIndented = true)]
[JsonSerializable(typeof(FilePair))]
internal partial class FilePairSourceGenerationContext : JsonSerializerContext
{
}

86
Shared/Models/FilePath.cs Normal file
View File

@ -0,0 +1,86 @@
using System.Text.Json;
using System.Text.Json.Serialization;
using View_by_Distance.Shared.Models.Stateless.Methods;
namespace View_by_Distance.Shared.Models;
public record FilePath(long CreationTicks,
string DirectoryName,
string ExtensionLowered,
string FileNameFirstSegment,
string FullName,
int? Id,
bool IsIntelligentIdFormat,
long LastWriteTicks,
long Length,
string Name,
string NameWithoutExtension,
int? SortOrder)
{
public override string ToString()
{
string result = JsonSerializer.Serialize(this, FilePathSourceGenerationContext.Default.FilePath);
return result;
}
public static FilePath Get(Properties.IPropertyConfiguration propertyConfiguration, FileHolder fileHolder, int? index)
{
if (fileHolder.CreationTime is null)
throw new NullReferenceException(nameof(fileHolder.CreationTime));
if (fileHolder.LastWriteTime is null)
throw new NullReferenceException(nameof(fileHolder.LastWriteTime));
if (fileHolder.Length is null)
throw new NullReferenceException(nameof(fileHolder.Length));
FilePath result;
int? id;
int? sortOder;
string fileNameFirstSegment = fileHolder.Name.Split('.')[0];
int sortOrderOnlyLengthIndex = propertyConfiguration.Offset.ToString().Length;
string fileDirectoryName = fileHolder.DirectoryName ?? throw new NullReferenceException();
bool fileNameFirstSegmentIsIntelligentIdFormat = IId.NameWithoutExtensionIsIntelligentIdFormat(propertyConfiguration, fileNameFirstSegment);
bool fileNameFirstSegmentIsPaddedIntelligentIdFormat = IId.NameWithoutExtensionIsPaddedIntelligentIdFormat(propertyConfiguration, sortOrderOnlyLengthIndex, fileNameFirstSegment);
bool fileNameFirstSegmentIsIdFormat = !fileNameFirstSegmentIsPaddedIntelligentIdFormat && !fileNameFirstSegmentIsIntelligentIdFormat && IId.NameWithoutExtensionIsIdFormat(propertyConfiguration, fileHolder);
if (!fileNameFirstSegmentIsIdFormat && !fileNameFirstSegmentIsIntelligentIdFormat && !fileNameFirstSegmentIsPaddedIntelligentIdFormat)
(id, sortOder) = (null, null);
else if (fileNameFirstSegmentIsIntelligentIdFormat)
(id, sortOder) = (IId.GetId(propertyConfiguration, fileNameFirstSegment), null);
else if (fileNameFirstSegmentIsPaddedIntelligentIdFormat)
{
if (!int.TryParse(fileNameFirstSegment[..sortOrderOnlyLengthIndex], out int absoluteValueOfSortOrder))
(id, sortOder) = (null, null);
else
(id, sortOder) = (IId.GetId(propertyConfiguration, fileNameFirstSegment[sortOrderOnlyLengthIndex..]), absoluteValueOfSortOrder);
}
else if (fileNameFirstSegmentIsIdFormat)
{
if (index is null)
throw new NullReferenceException(nameof(index));
if (!int.TryParse(fileNameFirstSegment, out int valueOfFileNameFirstSegment))
throw new NotSupportedException();
(id, sortOder) = (valueOfFileNameFirstSegment, propertyConfiguration.Offset + index);
}
else
throw new NotSupportedException();
result = new(fileHolder.CreationTime.Value.Ticks,
fileDirectoryName,
fileHolder.ExtensionLowered,
fileNameFirstSegment,
fileHolder.FullName,
id,
fileNameFirstSegmentIsIntelligentIdFormat,
fileHolder.LastWriteTime.Value.Ticks,
fileHolder.Length.Value,
fileHolder.Name,
fileHolder.NameWithoutExtension,
sortOder);
return result;
}
}
[JsonSourceGenerationOptions(WriteIndented = true)]
[JsonSerializable(typeof(FilePath))]
public partial class FilePathSourceGenerationContext : JsonSerializerContext
{
}

View File

@ -8,6 +8,7 @@ public class Item : Properties.IItem
protected List<Face> _Faces;
protected readonly bool? _FileSizeChanged;
protected readonly FilePath _FilePath;
protected readonly FileHolder _ImageFileHolder;
protected bool? _IsNotUniqueAndNeedsReview;
protected bool _IsUniqueFileName;
@ -20,6 +21,7 @@ public class Item : Properties.IItem
protected readonly FileHolder _SourceDirectoryFileHolder;
public List<Face> Faces => _Faces;
public bool? FileSizeChanged => _FileSizeChanged;
public FilePath FilePath => _FilePath;
public FileHolder ImageFileHolder => _ImageFileHolder;
public bool? IsNotUniqueAndNeedsReview => _IsNotUniqueAndNeedsReview;
public bool IsUniqueFileName => _IsUniqueFileName;
@ -32,9 +34,10 @@ public class Item : Properties.IItem
public FileHolder SourceDirectoryFileHolder => _SourceDirectoryFileHolder;
[JsonConstructor]
public Item(List<Face> faces, bool? fileSizeChanged, FileHolder imageFileHolder, bool? isNotUniqueAndNeedsReview, bool isUniqueFileName, bool isValidImageFormatExtension, bool? lastWriteTimeChanged, bool? moved, Property? property, string relativePath, FileHolder? resizedFileHolder, FileHolder sourceDirectoryFileHolder)
public Item(List<Face> faces, FilePath filePath, bool? fileSizeChanged, FileHolder imageFileHolder, bool? isNotUniqueAndNeedsReview, bool isUniqueFileName, bool isValidImageFormatExtension, bool? lastWriteTimeChanged, bool? moved, Property? property, string relativePath, FileHolder? resizedFileHolder, FileHolder sourceDirectoryFileHolder)
{
_Faces = faces;
_FilePath = filePath;
_FileSizeChanged = fileSizeChanged;
_ImageFileHolder = imageFileHolder;
_IsNotUniqueAndNeedsReview = isNotUniqueAndNeedsReview;
@ -48,8 +51,8 @@ public class Item : Properties.IItem
_SourceDirectoryFileHolder = sourceDirectoryFileHolder;
}
public Item(FileHolder sourceDirectoryFileHolder, string relativePath, FileHolder imageFileInfo, bool? isNotUniqueAndNeedsReview, bool isUniqueFileName, bool isValidImageFormatExtension, Property? property, bool? abandoned, bool? fileSizeChanged, bool? lastWriteTimeChanged) :
this([], fileSizeChanged, imageFileInfo, isNotUniqueAndNeedsReview, isUniqueFileName, isValidImageFormatExtension, lastWriteTimeChanged, null, property, relativePath, null, sourceDirectoryFileHolder)
public Item(FilePath filePath, FileHolder sourceDirectoryFileHolder, string relativePath, FileHolder imageFileInfo, bool? isNotUniqueAndNeedsReview, bool isUniqueFileName, bool isValidImageFormatExtension, Property? property, bool? abandoned, bool? fileSizeChanged, bool? lastWriteTimeChanged) :
this([], filePath, fileSizeChanged, imageFileInfo, isNotUniqueAndNeedsReview, isUniqueFileName, isValidImageFormatExtension, lastWriteTimeChanged, null, property, relativePath, null, sourceDirectoryFileHolder)
{
if (relativePath.EndsWith(".json"))
throw new ArgumentException("Can not be a *.json file!");
@ -57,8 +60,8 @@ public class Item : Properties.IItem
throw new ArgumentException("Can not be a *.json file!");
}
public Item(FileHolder sourceDirectoryFileHolder, string relativePath, bool isValidImageFormatExtension) :
this(sourceDirectoryFileHolder, relativePath, sourceDirectoryFileHolder, null, false, isValidImageFormatExtension, null, null, null, null)
public Item(FilePath filePath, FileHolder sourceDirectoryFileHolder, string relativePath, bool isValidImageFormatExtension) :
this(filePath, sourceDirectoryFileHolder, relativePath, sourceDirectoryFileHolder, null, false, isValidImageFormatExtension, null, null, null, null)
{ }
public override string ToString()

View File

@ -6,7 +6,7 @@ public record LocationContainer<T>(DateOnly CreationDateOnly,
IReadOnlyList<T> Directories,
int? DirectoryNumber,
string DisplayDirectoryName,
string File,
FilePath FilePath,
bool FromDistanceContent,
int Id,
Location? Location,

View File

@ -11,6 +11,7 @@ public class Mapping : Properties.IMapping
public string? _SegmentC;
protected SortingContainer? _SortingContainer;
public int? By => _By;
public FilePath FilePath { init; get; }
public MappingFromFilterPost MappingFromFilterPost { init; get; }
public MappingFromFilterPre MappingFromFilterPre { init; get; }
public MappingFromItem MappingFromItem { init; get; }
@ -21,9 +22,10 @@ public class Mapping : Properties.IMapping
public SortingContainer? SortingContainer => _SortingContainer;
[JsonConstructor]
public Mapping(int? by, MappingFromFilterPost mappingFromFilterPost, MappingFromFilterPre mappingFromFilterPre, MappingFromItem mappingFromItem, MappingFromLocation? mappingFromLocation, MappingFromPerson? mappingFromPerson, List<MappingFromPhotoPrism>? mappingFromPhotoPrismCollection, string? segmentC, SortingContainer? sortingContainer)
public Mapping(int? by, FilePath filePath, MappingFromFilterPost mappingFromFilterPost, MappingFromFilterPre mappingFromFilterPre, MappingFromItem mappingFromItem, MappingFromLocation? mappingFromLocation, MappingFromPerson? mappingFromPerson, List<MappingFromPhotoPrism>? mappingFromPhotoPrismCollection, string? segmentC, SortingContainer? sortingContainer)
{
_By = by;
FilePath = filePath;
_SegmentC = segmentC;
MappingFromFilterPost = mappingFromFilterPost;
MappingFromFilterPre = mappingFromFilterPre;
@ -34,8 +36,8 @@ public class Mapping : Properties.IMapping
_SortingContainer = sortingContainer;
}
public Mapping(MappingFromFilterPost mappingFromFilterPost, MappingFromFilterPre mappingFromFilterPre, MappingFromItem mappingFromItem, MappingFromLocation? mappingFromLocation, List<MappingFromPhotoPrism>? mappingFromPhotoPrismCollection) :
this(null, mappingFromFilterPost, mappingFromFilterPre, mappingFromItem, mappingFromLocation, null, mappingFromPhotoPrismCollection, null, null)
public Mapping(FilePath filePath, MappingFromFilterPost mappingFromFilterPost, MappingFromFilterPre mappingFromFilterPre, MappingFromItem mappingFromItem, MappingFromLocation? mappingFromLocation, List<MappingFromPhotoPrism>? mappingFromPhotoPrismCollection) :
this(null, filePath, mappingFromFilterPost, mappingFromFilterPre, mappingFromItem, mappingFromLocation, null, mappingFromPhotoPrismCollection, null, null)
{ }
public override string ToString()

View File

@ -3,9 +3,9 @@ namespace View_by_Distance.Shared.Models.Methods;
public interface IBlurHasher
{
string GetFile(FilePath filePath);
string Encode(FileHolder fileHolder);
string GetFile(FileHolder fileHolder);
string EncodeAndSave(FileHolder fileHolder);
void Update(string resultsFullGroupDirectory);
string EncodeAndSave(FilePath filePath, FileHolder fileHolder);
}

View File

@ -1,3 +1,4 @@
using System.Collections.ObjectModel;
using System.Text.Json;
using System.Text.Json.Serialization;
@ -8,18 +9,18 @@ public class PersonContainer : Properties.IPersonContainer
public int? ApproximateYears { init; get; }
public PersonBirthday[]? Birthdays { init; get; }
public string[] DisplayDirectoryAllFiles { init; get; }
public ReadOnlyCollection<FilePath> DisplayDirectoryAllFilePaths { init; get; }
public string DisplayDirectoryName { init; get; }
public long? Key { init; get; }
public bool? KeyIsMaxBirthday { init; get; }
public PersonDirectory? PersonDirectory { init; get; }
[JsonConstructor]
public PersonContainer(int? approximateYears, PersonBirthday[]? birthdays, string[] displayDirectoryAllFiles, string displayDirectoryName, long? key, PersonDirectory? personDirectory)
public PersonContainer(int? approximateYears, PersonBirthday[]? birthdays, ReadOnlyCollection<FilePath> displayDirectoryAllFiles, string displayDirectoryName, long? key, PersonDirectory? personDirectory)
{
ApproximateYears = approximateYears;
Birthdays = birthdays;
DisplayDirectoryAllFiles = displayDirectoryAllFiles;
DisplayDirectoryAllFilePaths = displayDirectoryAllFiles;
DisplayDirectoryName = displayDirectoryName;
Key = key;
PersonDirectory = personDirectory;
@ -27,22 +28,22 @@ public class PersonContainer : Properties.IPersonContainer
}
public PersonContainer(char[] personCharacters, PersonBirthday birthday, string displayDirectoryName, PersonDirectory personDirectory) :
this(Stateless.Methods.IAge.GetApproximateYears(personCharacters, displayDirectoryName), [birthday], [], displayDirectoryName, birthday.Value.Ticks, personDirectory)
this(Stateless.Methods.IAge.GetApproximateYears(personCharacters, displayDirectoryName), [birthday], new([]), displayDirectoryName, birthday.Value.Ticks, personDirectory)
{ }
public PersonContainer(int? approximateYears, PersonBirthday birthdays, string displayDirectoryName, long key) :
this(approximateYears, [birthdays], [], displayDirectoryName, key, null)
this(approximateYears, [birthdays], new([]), displayDirectoryName, key, null)
{ }
public PersonContainer(int? approximateYears, PersonBirthday birthdays, PersonDirectory? personDirectory, string displayDirectoryName, long key) :
this(approximateYears, [birthdays], [], displayDirectoryName, key, personDirectory)
this(approximateYears, [birthdays], new([]), displayDirectoryName, key, personDirectory)
{ }
public PersonContainer(int? approximateYears, string[] displayDirectoryAllFiles, string displayDirectoryName, PersonDirectory? personDirectory) :
public PersonContainer(int? approximateYears, ReadOnlyCollection<FilePath> displayDirectoryAllFiles, string displayDirectoryName, PersonDirectory? personDirectory) :
this(approximateYears, null, displayDirectoryAllFiles, displayDirectoryName, null, personDirectory)
{ }
public PersonContainer(int? approximateYears, PersonBirthday[]? birthdays, string[] displayDirectoryAllFiles, string displayDirectoryName, long? key) :
public PersonContainer(int? approximateYears, PersonBirthday[]? birthdays, ReadOnlyCollection<FilePath> displayDirectoryAllFiles, string displayDirectoryName, long? key) :
this(approximateYears, birthdays, displayDirectoryAllFiles, displayDirectoryName, key, null)
{ }

View File

@ -1,16 +0,0 @@
namespace View_by_Distance.Shared.Models.Properties;
public interface IFileHolder
{
public DateTime? CreationTime { get; }
public string? DirectoryName { get; }
public bool Exists { get; }
public string ExtensionLowered { get; }
public string FullName { get; }
public DateTime? LastWriteTime { get; }
public long? Length { get; }
public string Name { get; }
public string NameWithoutExtension { get; }
}

View File

@ -5,6 +5,7 @@ public interface IItem
public bool? FileSizeChanged { get; }
public List<Face> Faces { get; }
public FilePath FilePath { get; }
public FileHolder ImageFileHolder { get; }
public bool? IsNotUniqueAndNeedsReview { get; }
public bool IsUniqueFileName { get; }

View File

@ -4,6 +4,7 @@ public interface IMapping
{
public int? By { get; }
public FilePath FilePath { init; get; }
public MappingFromFilterPost MappingFromFilterPost { init; get; }
public MappingFromFilterPre MappingFromFilterPre { init; get; }
public MappingFromLocation? MappingFromLocation { init; get; }

View File

@ -1,3 +1,5 @@
using System.Collections.ObjectModel;
namespace View_by_Distance.Shared.Models.Properties;
public interface IPersonContainer
@ -5,7 +7,7 @@ public interface IPersonContainer
public int? ApproximateYears { init; get; }
public PersonBirthday[]? Birthdays { init; get; }
public string[] DisplayDirectoryAllFiles { init; get; }
public ReadOnlyCollection<FilePath> DisplayDirectoryAllFilePaths { init; get; }
public string DisplayDirectoryName { init; get; }
public long? Key { init; get; }
public bool? KeyIsMaxBirthday { init; get; }

View File

@ -6,6 +6,7 @@ public interface IPropertyConfiguration
public string DateGroup { init; get; }
public string[] IgnoreExtensions { init; get; }
public string[] IgnoreRulesKeyWords { init; get; }
public int IntMinValueLength { init; get; }
public string PersonBirthdayFormat { init; get; }
public bool PropertiesChangedForProperty { init; get; }
public string[] PropertyContentCollectionFiles { init; get; }

View File

@ -33,7 +33,7 @@ public class SaveContainer
{ }
public SaveContainer(string directory, string locationContainersFile) :
this(string.Empty, directory, null, null, null, false, new(locationContainersFile), Path.Combine(directory, $"{Path.GetFileName(locationContainersFile)}.lnk"))
this(string.Empty, directory, null, null, null, false, Stateless.Methods.IFileHolder.Get(locationContainersFile), Path.Combine(directory, $"{Path.GetFileName(locationContainersFile)}.lnk"))
{ }
public SaveContainer(string directory, FileHolder? faceFileHolder, FileHolder? resizedFileHolder, string shortcutFile) :

View File

@ -6,7 +6,7 @@ namespace View_by_Distance.Shared.Models.Stateless.Methods;
internal abstract class Container
{
private record FilePair(string Path, string? Directory, bool IsUnique, List<string> Collection, Models.Item Item) { }
private record FilePair(bool IsUnique, List<string> Collection, FilePath FilePath, Models.Item Item) { }
internal static DateTime[] GetContainerDateTimes(IEnumerable<Models.Item> items)
{
@ -45,15 +45,15 @@ internal abstract class Container
List<Models.FilePair>? filePairs = null;
ReadOnlyCollection<string[]>? jsonFilesCollection = null;
IReadOnlyDictionary<string, List<string>>? compareFileNamesToFiles = null;
IReadOnlyDictionary<string, List<string>> fileNamesToFiles = IDirectory.GetFilesKeyValuePairs(filesCollection);
IReadOnlyDictionary<string, List<string>> fileNamesToFiles = XDirectory.GetFilesKeyValuePairs(filesCollection);
for (int i = 0; i < int.MaxValue; i++)
{
renamed = 0;
jsonFilesCollection = IDirectory.GetFilesCollection(aPropertySingletonDirectory, directorySearchFilter, extension, useCeilingAverage);
compareFileNamesToFiles = IDirectory.GetFilesKeyValuePairs(jsonFilesCollection);
renamed += IDirectory.LookForAbandoned(jsonFilesCollection, fileNamesToFiles, extension);
filePairs = IDirectory.GetFiles(filesCollection, fileNamesToFiles, extension, compareFileNamesToFiles);
renamed += IDirectory.MaybeMove(propertyConfiguration.RootDirectory, propertyConfiguration.ResultAllInOne, propertyConfiguration.ResultAllInOneSubdirectoryLength, filePairs, aPropertySingletonDirectory, extension);
compareFileNamesToFiles = XDirectory.GetFilesKeyValuePairs(jsonFilesCollection);
renamed += XDirectory.LookForAbandoned(jsonFilesCollection, fileNamesToFiles, extension);
filePairs = XDirectory.GetFiles(filesCollection, fileNamesToFiles, extension, compareFileNamesToFiles);
renamed += XDirectory.MaybeMove(propertyConfiguration, filePairs, aPropertySingletonDirectory, extension);
if (renamed == 0)
break;
}
@ -80,33 +80,33 @@ internal abstract class Container
private static void ParallelFor(Properties.IPropertyConfiguration propertyConfiguration, string aPropertySingletonDirectory, string extension, int rootDirectoryLength, Models.FilePair filePair, List<FilePair> results)
{
string fileName;
bool abandoned = false;
Models.FileHolder sourceDirectoryFileHolder;
Models.Property? property = GetProperty(filePair);
Models.FileHolder imageFileInfo = new(filePair.Path);
bool? fileSizeChanged = property is not null ? property.FileSize != imageFileInfo.Length : null;
Models.FileHolder imageFileInfo = IFileHolder.Get(filePair.Path);
FilePath filePath = FilePath.Get(propertyConfiguration, imageFileInfo, index: null);
bool? fileSizeChanged = property is not null ? property.FileSize != filePath.Length : null;
bool isValidImageFormatExtension = propertyConfiguration.ValidImageFormatExtensions.Contains(filePath.ExtensionLowered);
string relativePath = IPath.GetRelativePath(filePair.Path, rootDirectoryLength, forceExtensionToLower: true);
bool isValidImageFormatExtension = propertyConfiguration.ValidImageFormatExtensions.Contains(imageFileInfo.ExtensionLowered);
bool? lastWriteTimeChanged = property is not null ? propertyConfiguration.PropertiesChangedForProperty || property.LastWriteTime != imageFileInfo.LastWriteTime : null;
bool? lastWriteTimeChanged = property is not null ? propertyConfiguration.PropertiesChangedForProperty || property.LastWriteTime.Ticks != filePath.LastWriteTicks : null;
if (filePair.Match is not null)
sourceDirectoryFileHolder = new(filePair.Match);
sourceDirectoryFileHolder = IFileHolder.Get(filePair.Match);
else if (!filePair.IsUnique)
sourceDirectoryFileHolder = new(Path.GetFullPath(string.Concat(aPropertySingletonDirectory, relativePath, extension)));
sourceDirectoryFileHolder = IFileHolder.Get(Path.GetFullPath(string.Concat(aPropertySingletonDirectory, relativePath, extension)));
else
{
fileName = Path.GetFileName(filePair.Path);
(string directoryName, _) = IPath.GetDirectoryNameAndIndex(propertyConfiguration.ResultAllInOneSubdirectoryLength, fileName);
sourceDirectoryFileHolder = new(Path.Combine(aPropertySingletonDirectory, propertyConfiguration.ResultAllInOne, directoryName, $"{fileName}{extension}"));
string fileName = Path.GetFileName(filePair.Path);
(string directoryName, _) = IPath.GetDirectoryNameAndIndex(propertyConfiguration, filePath);
sourceDirectoryFileHolder = IFileHolder.Get(Path.Combine(aPropertySingletonDirectory, directoryName, $"{fileName}{extension}"));
}
if (imageFileInfo.LastWriteTime is not null && sourceDirectoryFileHolder.CreationTime is not null && sourceDirectoryFileHolder.LastWriteTime is not null && imageFileInfo.LastWriteTime.Value != sourceDirectoryFileHolder.CreationTime.Value)
if (sourceDirectoryFileHolder.CreationTime is not null && sourceDirectoryFileHolder.LastWriteTime is not null && filePath.LastWriteTicks != sourceDirectoryFileHolder.CreationTime.Value.Ticks)
{
File.SetCreationTime(sourceDirectoryFileHolder.FullName, imageFileInfo.LastWriteTime.Value);
File.SetCreationTime(sourceDirectoryFileHolder.FullName, new(filePath.LastWriteTicks));
File.SetLastWriteTime(sourceDirectoryFileHolder.FullName, sourceDirectoryFileHolder.LastWriteTime.Value);
}
Models.Item item = new(sourceDirectoryFileHolder, relativePath, imageFileInfo, filePair.IsNotUniqueAndNeedsReview, filePair.IsUnique, isValidImageFormatExtension, property, abandoned, fileSizeChanged, lastWriteTimeChanged);
Models.Item item = new(filePath, sourceDirectoryFileHolder, relativePath, imageFileInfo, filePair.IsNotUniqueAndNeedsReview, filePair.IsUnique, isValidImageFormatExtension, property, abandoned, fileSizeChanged, lastWriteTimeChanged);
lock (results)
results.Add(new(filePair.Path, imageFileInfo.DirectoryName, filePair.IsUnique, filePair.Collection, item));
results.Add(new(filePair.IsUnique, filePair.Collection, filePath, item));
}
private static List<FilePair> GetFilePairs(Properties.IPropertyConfiguration propertyConfiguration, string aPropertySingletonDirectory, string filesCollectionDirectory, string extension, List<Models.FilePair> filePairs)
@ -148,12 +148,10 @@ internal abstract class Container
List<FilePair> collection = GetFilePairs(propertyConfiguration, aPropertySingletonDirectory, filesCollectionDirectory, extension, filePairs);
foreach (FilePair filePair in collection)
{
if (filePair.Directory is null)
continue;
if (!directoryToItems.TryGetValue(filePair.Directory, out items))
if (!directoryToItems.TryGetValue(filePair.FilePath.DirectoryName, out items))
{
directoryToItems.Add(filePair.Directory, []);
if (!directoryToItems.TryGetValue(filePair.Directory, out items))
directoryToItems.Add(filePair.FilePath.DirectoryName, []);
if (!directoryToItems.TryGetValue(filePair.FilePath.DirectoryName, out items))
throw new Exception();
}
items.Add(filePair.Item);

View File

@ -7,14 +7,14 @@ internal abstract class FileHolder
{
List<Models.FileHolder> results = [];
foreach ((string _, string[] files) in collection)
results.AddRange(files.Select(l => new Models.FileHolder(l)));
results.AddRange(files.Select(l => IFileHolder.Get(l)));
return results;
}
internal static IEnumerable<Models.FileHolder> GetFileHolders(IEnumerable<(string, string)> collection)
{
foreach ((string _, string file) in collection)
yield return new(file);
yield return IFileHolder.Get(file);
}
internal static IEnumerable<(string, string[])> GetFiles(string root, string searchPattern)

View File

@ -15,11 +15,6 @@ public interface IContainer
static Models.Item[] GetFilterItems(Properties.IPropertyConfiguration propertyConfiguration, Models.Container container) =>
Container.GetFilterItems(propertyConfiguration, container);
List<FilePair> TestStatic_GetFilePairs(Properties.IPropertyConfiguration propertyConfiguration, string directorySearchFilter, string extension, string aPropertySingletonDirectory, ReadOnlyCollection<string[]> filesCollection) =>
Container.GetFilePairs(propertyConfiguration, directorySearchFilter, extension, aPropertySingletonDirectory, filesCollection);
static List<FilePair> GetFilePairs(Properties.IPropertyConfiguration propertyConfiguration, string directorySearchFilter, string extension, string aPropertySingletonDirectory, ReadOnlyCollection<string[]> filesCollection) =>
Container.GetFilePairs(propertyConfiguration, directorySearchFilter, extension, aPropertySingletonDirectory, filesCollection);
(int, Models.Container[]) TestStatic_GetContainers(Properties.IPropertyConfiguration propertyConfiguration, string aPropertySingletonDirectory) =>
GetContainers(propertyConfiguration, aPropertySingletonDirectory);
static (int, Models.Container[]) GetContainers(Properties.IPropertyConfiguration propertyConfiguration, string aPropertySingletonDirectory) =>

View File

@ -5,11 +5,6 @@ namespace View_by_Distance.Shared.Models.Stateless.Methods;
public interface IDirectory
{
short TestStatic_GetSortOrderOnlyLengthIndex(int offset) =>
GetSortOrderOnlyLengthIndex(offset);
static short GetSortOrderOnlyLengthIndex(int offset) =>
(short)(offset.ToString().Length + 3);
char TestStatic_GetDirectory(string fileName) =>
GetDirectory(fileName);
static char GetDirectory(string fileName) =>
@ -20,77 +15,29 @@ public interface IDirectory
static int GetDirectory(char directory) =>
directory == '-' ? 10 : int.TryParse(directory.ToString(), out int value) ? value : 11;
string TestStatic_GetPaddedId(int intMinValueLength, int index, int id) =>
GetPaddedId(intMinValueLength, index, id);
static string GetPaddedId(int intMinValueLength, int index, int id) =>
id > -1 ? $"{index}070{id.ToString().PadLeft(intMinValueLength, '0')}" : $"{index}030{id.ToString()[1..].PadLeft(intMinValueLength, '0')}";
bool TestStatic_NameWithoutExtensionIsPaddedIdFormat(string fileNameWithoutExtension, short sortOrderOnlyLengthIndex) =>
NameWithoutExtensionIsPaddedIdFormat(fileNameWithoutExtension, sortOrderOnlyLengthIndex);
static bool NameWithoutExtensionIsPaddedIdFormat(string fileNameWithoutExtension, short sortOrderOnlyLengthIndex) =>
fileNameWithoutExtension.Length > sortOrderOnlyLengthIndex
&& fileNameWithoutExtension[sortOrderOnlyLengthIndex] == '0'
&& fileNameWithoutExtension[sortOrderOnlyLengthIndex - 3] == '0'
&& fileNameWithoutExtension.All(l => char.IsNumber(l));
bool TestStatic_NameWithoutExtensionIsPaddedIdFormat(Models.FileHolder fileHolder, short sortOrderOnlyLengthIndex) =>
NameWithoutExtensionIsPaddedIdFormat(fileHolder, sortOrderOnlyLengthIndex);
static bool NameWithoutExtensionIsPaddedIdFormat(Models.FileHolder fileHolder, short sortOrderOnlyLengthIndex) =>
NameWithoutExtensionIsPaddedIdFormat(fileHolder.NameWithoutExtension, sortOrderOnlyLengthIndex);
ReadOnlyCollection<string[]> TestStatic_GetFilesCollection(string directory, string directorySearchFilter, string fileSearchFilter, bool useCeilingAverage) =>
GetFilesCollection(directory, directorySearchFilter, fileSearchFilter, useCeilingAverage);
static ReadOnlyCollection<string[]> GetFilesCollection(string directory, string directorySearchFilter, string fileSearchFilter, bool useCeilingAverage) =>
XDirectory.GetFilesCollection(directory, directorySearchFilter, fileSearchFilter, useCeilingAverage);
IReadOnlyDictionary<string, List<string>> TestStatic_GetFilesKeyValuePairs(ReadOnlyCollection<string[]> filesCollection) =>
GetFilesKeyValuePairs(filesCollection);
static IReadOnlyDictionary<string, List<string>> GetFilesKeyValuePairs(ReadOnlyCollection<string[]> filesCollection) =>
XDirectory.GetFilesKeyValuePairs(filesCollection);
int TestStatic_LookForAbandoned(ReadOnlyCollection<string[]> jsonFilesCollection, IReadOnlyDictionary<string, List<string>> fileNamesToFiles, string extension) =>
LookForAbandoned(jsonFilesCollection, fileNamesToFiles, extension);
static int LookForAbandoned(ReadOnlyCollection<string[]> jsonFilesCollection, IReadOnlyDictionary<string, List<string>> fileNamesToFiles, string extension) =>
XDirectory.LookForAbandoned(jsonFilesCollection, fileNamesToFiles, extension);
int TestStatic_MaybeMove(string directory, string resultAllInOne, int resultAllInOneSubdirectoryLength, List<FilePair> filePairs, string jsonGroupDirectory, string extension) =>
MaybeMove(directory, resultAllInOne, resultAllInOneSubdirectoryLength, filePairs, jsonGroupDirectory, extension);
static int MaybeMove(string directory, string resultAllInOne, int resultAllInOneSubdirectoryLength, List<FilePair> filePairs, string jsonGroupDirectory, string extension) =>
XDirectory.MaybeMove(directory, resultAllInOne, resultAllInOneSubdirectoryLength, filePairs, jsonGroupDirectory, extension);
List<FilePair> TestStatic_GetFiles(ReadOnlyCollection<string[]> filesCollection, IReadOnlyDictionary<string, List<string>> fileNamesToFiles, string extension, IReadOnlyDictionary<string, List<string>> compareFileNamesToFiles) =>
GetFiles(filesCollection, fileNamesToFiles, extension, compareFileNamesToFiles);
static List<FilePair> GetFiles(ReadOnlyCollection<string[]> filesCollection, IReadOnlyDictionary<string, List<string>> fileNamesToFiles, string extension, IReadOnlyDictionary<string, List<string>> compareFileNamesToFiles) =>
XDirectory.GetFiles(filesCollection, fileNamesToFiles, extension, compareFileNamesToFiles);
void TestStatic_MoveFiles(List<string> files, string find, string replace) =>
MoveFiles(files, find, replace);
static void MoveFiles(List<string> files, string find, string replace) =>
XDirectory.MoveFiles(files, find, replace);
(string[], List<(Models.FileHolder, string?, string)>) TestStatic_GetToDoCollection(Properties.IPropertyConfiguration propertyConfiguration, ReadOnlyCollection<string[]> filesCollection, string[] directories, Action? tick) =>
(string[], List<(FilePath, string)>) TestStatic_GetToDoCollection(Properties.IPropertyConfiguration propertyConfiguration, ReadOnlyCollection<string[]> filesCollection, string[] directories, Action? tick) =>
GetToDoCollection(propertyConfiguration, filesCollection, directories, tick);
static (string[], List<(Models.FileHolder, string?, string)>) GetToDoCollection(Properties.IPropertyConfiguration propertyConfiguration, ReadOnlyCollection<string[]> filesCollection, string[] directories, Action? tick) =>
static (string[], List<(FilePath, string)>) GetToDoCollection(Properties.IPropertyConfiguration propertyConfiguration, ReadOnlyCollection<string[]> filesCollection, string[] directories, Action? tick) =>
XDirectory.GetToDoCollection(propertyConfiguration, copyDuplicates: false, ifCanUseId: true, filesCollection, directories, tick);
(string[], List<(Models.FileHolder, string?, string)>) TestStatic_GetToDoCollection(Properties.IPropertyConfiguration propertyConfiguration, bool copyDuplicates, bool ifCanUseId, ReadOnlyCollection<string[]> filesCollection, string[] directories, Action? tick) =>
(string[], List<(FilePath, string)>) TestStatic_GetToDoCollection(Properties.IPropertyConfiguration propertyConfiguration, bool copyDuplicates, bool ifCanUseId, ReadOnlyCollection<string[]> filesCollection, string[] directories, Action? tick) =>
GetToDoCollection(propertyConfiguration, copyDuplicates, ifCanUseId, filesCollection, directories, tick);
static (string[], List<(Models.FileHolder, string?, string)>) GetToDoCollection(Properties.IPropertyConfiguration propertyConfiguration, bool copyDuplicates, bool ifCanUseId, ReadOnlyCollection<string[]> filesCollection, string[] directories, Action? tick) =>
static (string[], List<(FilePath, string)>) GetToDoCollection(Properties.IPropertyConfiguration propertyConfiguration, bool copyDuplicates, bool ifCanUseId, ReadOnlyCollection<string[]> filesCollection, string[] directories, Action? tick) =>
XDirectory.GetToDoCollection(propertyConfiguration, copyDuplicates, ifCanUseId, filesCollection, directories, tick);
List<string> TestStatic_CopyOrMove(List<(Models.FileHolder, string?, string)> toDoCollection, bool move, bool moveBack, Action? tick) =>
List<string> TestStatic_CopyOrMove(List<(FilePath, string)> toDoCollection, bool move, bool moveBack, Action? tick) =>
CopyOrMove(toDoCollection, move, moveBack, tick);
static List<string> CopyOrMove(List<(Models.FileHolder, string?, string)> toDoCollection, bool move, bool moveBack, Action? tick) =>
static List<string> CopyOrMove(List<(FilePath, string)> toDoCollection, bool move, bool moveBack, Action? tick) =>
XDirectory.CopyOrMove(toDoCollection, move, moveBack, tick);
(bool, int?) TestStatic_GetId(short sortOrderOnlyLengthIndex, Models.FileHolder fileHolder) =>
GetId(sortOrderOnlyLengthIndex, fileHolder);
static (bool, int?) GetId(short sortOrderOnlyLengthIndex, Models.FileHolder fileHolder) =>
XDirectory.GetId(sortOrderOnlyLengthIndex, fileHolder);
(bool, int?) TestStatic_GetId(int offset, Models.FileHolder fileHolder) =>
GetId(offset, fileHolder);
static (bool, int?) GetId(int offset, Models.FileHolder fileHolder) =>
XDirectory.GetId(GetSortOrderOnlyLengthIndex(offset), fileHolder);
}

View File

@ -21,6 +21,24 @@ public interface IFileHolder
Models.FileHolder TestStatic_Refresh(Models.FileHolder fileHolder) =>
Refresh(fileHolder);
static Models.FileHolder Refresh(Models.FileHolder fileHolder) =>
new(fileHolder.FullName);
Get(fileHolder.FullName);
Models.FileHolder TestStatic_Get(string fileName) =>
Get(fileName);
static Models.FileHolder Get(string fileName) =>
Models.FileHolder.Get(new FileInfo(fileName));
Models.FileHolder TestStatic_Get(FilePath filePath) =>
Get(filePath);
static Models.FileHolder Get(FilePath filePath) =>
new(new(filePath.CreationTicks),
filePath.DirectoryName,
true,
filePath.ExtensionLowered,
filePath.FullName,
new(filePath.LastWriteTicks),
filePath.Length,
filePath.Name,
filePath.NameWithoutExtension);
}

View File

@ -0,0 +1,43 @@
namespace View_by_Distance.Shared.Models.Stateless.Methods;
public interface IId
{ // ...
string TestStatic_GetIntelligentId(Properties.IPropertyConfiguration propertyConfiguration, long id, bool ignore) =>
GetIntelligentId(propertyConfiguration, id, ignore);
static string GetIntelligentId(Properties.IPropertyConfiguration propertyConfiguration, long id, bool ignore) =>
Id.GetIntelligentId(propertyConfiguration, id, ignore);
int TestStatic_GetId(Properties.IPropertyConfiguration propertyConfiguration, string intelligentId) =>
GetId(propertyConfiguration, intelligentId);
static int GetId(Properties.IPropertyConfiguration propertyConfiguration, string intelligentId) =>
Id.GetId(propertyConfiguration, intelligentId);
string TestStatic_GetPaddedId(Properties.IPropertyConfiguration propertyConfiguration, int index, int id) =>
GetPaddedId(propertyConfiguration, index, id);
static string GetPaddedId(Properties.IPropertyConfiguration propertyConfiguration, int index, int id) =>
Id.GetPaddedId(propertyConfiguration, index, id);
bool TestStatic_NameWithoutExtensionIsIntelligentIdFormat(Properties.IPropertyConfiguration propertyConfiguration, string fileNameFirstSegment) =>
NameWithoutExtensionIsIntelligentIdFormat(propertyConfiguration, fileNameFirstSegment);
static bool NameWithoutExtensionIsIntelligentIdFormat(Properties.IPropertyConfiguration propertyConfiguration, string fileNameFirstSegment) =>
fileNameFirstSegment.Length - 1 == propertyConfiguration.IntMinValueLength && fileNameFirstSegment[^1] is '1' or '2' or '8' or '9' && fileNameFirstSegment.All(char.IsNumber);
bool TestStatic_NameWithoutExtensionIsPaddedIntelligentIdFormat(Properties.IPropertyConfiguration propertyConfiguration, int sortOrderOnlyLengthIndex, string fileNameFirstSegment) =>
NameWithoutExtensionIsPaddedIntelligentIdFormat(propertyConfiguration, sortOrderOnlyLengthIndex, fileNameFirstSegment);
static bool NameWithoutExtensionIsPaddedIntelligentIdFormat(Properties.IPropertyConfiguration propertyConfiguration, int sortOrderOnlyLengthIndex, string fileNameFirstSegment) =>
fileNameFirstSegment.Length == propertyConfiguration.IntMinValueLength + sortOrderOnlyLengthIndex + 1
&& fileNameFirstSegment[^1] is '1' or '2' or '8' or '9'
&& fileNameFirstSegment.All(char.IsNumber);
bool TestStatic_NameWithoutExtensionIsIdFormat(Properties.IPropertyConfiguration propertyConfiguration, Models.FileHolder fileHolder) =>
NameWithoutExtensionIsIdFormat(propertyConfiguration, fileHolder);
static bool NameWithoutExtensionIsIdFormat(Properties.IPropertyConfiguration propertyConfiguration, Models.FileHolder fileHolder) =>
Id.NameWithoutExtensionIsIdFormat(propertyConfiguration, fileHolder.NameWithoutExtension.Split('.')[0]);
int TestStatic_GetDeterministicHashCode(byte[] value) =>
GetDeterministicHashCode(value);
static int GetDeterministicHashCode(byte[] value) =>
Id.GetDeterministicHashCode(value);
}

View File

@ -3,11 +3,6 @@ namespace View_by_Distance.Shared.Models.Stateless.Methods;
public interface IMapping
{ // ...
(string?, string?, string?, bool?) TestStatic_GetSegments(string facesFileNameExtension, string fileName)
=> GetSegments(facesFileNameExtension, fileName);
static (string?, string?, string?, bool?) GetSegments(string facesFileNameExtension, string fileName)
=> Mapping.GetSegments(facesFileNameExtension, fileName);
int TestStatic_GetAreaPermyriad(int faceAreaPermyriad, int height, Models.Location location, int width)
=> GetAreaPermyriad(faceAreaPermyriad, height, location, width);
static int GetAreaPermyriad(int faceAreaPermyriad, int height, Models.Location location, int width)
@ -23,19 +18,19 @@ public interface IMapping
static int GetAreaPermyriad(int faceAreaPermyriad, Models.Location location, Models.OutputResolution outputResolution)
=> Mapping.GetAreaPermyriad(faceAreaPermyriad, location.Bottom, outputResolution.Height, location.Left, location.Right, location.Top, outputResolution.Width);
string TestStatic_GetDeterministicHashCodeKey(int id, Models.Location location, int locationDigits, Models.OutputResolution outputResolution)
=> GetDeterministicHashCodeKey(id, location, locationDigits, outputResolution);
static string GetDeterministicHashCodeKey(int id, Models.Location location, int locationDigits, Models.OutputResolution outputResolution)
=> $"{id}.{ILocation.GetLeftPadded(locationDigits, ILocation.GetWholePercentages(location, locationDigits, outputResolution))}";
string TestStatic_GetDeterministicHashCodeKey(FilePath filePath, Models.Location location, int locationDigits, Models.OutputResolution outputResolution)
=> GetDeterministicHashCodeKey(filePath, location, locationDigits, outputResolution);
static string GetDeterministicHashCodeKey(FilePath filePath, Models.Location location, int locationDigits, Models.OutputResolution outputResolution)
=> filePath.IsIntelligentIdFormat ? $"{filePath.FileNameFirstSegment}.{ILocation.GetLeftPadded(locationDigits, ILocation.GetWholePercentages(location, locationDigits, outputResolution))}" : throw new NotImplementedException();
string TestStatic_GetDeterministicHashCodeKey(int id, int locationDigits)
=> GetDeterministicHashCodeKey(id, locationDigits);
static string GetDeterministicHashCodeKey(int id, int locationDigits)
=> $"{id}.{ILocation.GetLeftPadded(locationDigits, ILocation.GetWholePercentages(locationDigits))}";
string TestStatic_GetDeterministicHashCodeKey(FilePath filePath, int locationDigits)
=> GetDeterministicHashCodeKey(filePath, locationDigits);
static string GetDeterministicHashCodeKey(FilePath filePath, int locationDigits)
=> filePath.IsIntelligentIdFormat ? $"{filePath.FileNameFirstSegment}.{ILocation.GetLeftPadded(locationDigits, ILocation.GetWholePercentages(locationDigits))}" : throw new NotImplementedException();
(int?, int?) TestStatic_GetConverted(string facesFileNameExtension, string file) =>
GetConverted(facesFileNameExtension, file);
static (int?, int?) GetConverted(string facesFileNameExtension, string file) =>
Mapping.GetConverted(facesFileNameExtension, file);
int? TestStatic_GetWholePercentages(string facesFileNameExtension, FilePath filePath) =>
GetWholePercentages(facesFileNameExtension, filePath);
static int? GetWholePercentages(string facesFileNameExtension, FilePath filePath) =>
Mapping.GetWholePercentages(facesFileNameExtension, filePath);
}

View File

@ -1,3 +1,4 @@
using System.Collections.ObjectModel;
using View_by_Distance.Shared.Models.Properties;
namespace View_by_Distance.Shared.Models.Stateless.Methods;
@ -61,14 +62,14 @@ public interface IPath
static string GetDirectory(string sourceDirectory, int level, string directoryName) =>
XPath.GetDirectory(sourceDirectory, level, directoryName);
(string, int) TestStatic_GetDirectoryNameAndIndex(int resultAllInOneSubdirectoryLength, string fileName) =>
GetDirectoryNameAndIndex(resultAllInOneSubdirectoryLength, fileName);
static (string, int) GetDirectoryNameAndIndex(int resultAllInOneSubdirectoryLength, string fileName) =>
XPath.GetDirectoryNameAndIndex(resultAllInOneSubdirectoryLength, fileName);
(string, int) TestStatic_GetDirectoryNameAndIndex(IPropertyConfiguration propertyConfiguration, FilePath filePath) =>
GetDirectoryNameAndIndex(propertyConfiguration, filePath);
static (string, int) GetDirectoryNameAndIndex(IPropertyConfiguration propertyConfiguration, FilePath filePath) =>
XPath.GetDirectoryNameAndIndex(propertyConfiguration, filePath);
Dictionary<string, string[]> TestStatic_GetKeyValuePairs(IPropertyConfiguration propertyConfiguration, string? resultsFullGroupDirectory, string[]? directories) =>
GetKeyValuePairs(propertyConfiguration, resultsFullGroupDirectory, directories);
static Dictionary<string, string[]> GetKeyValuePairs(IPropertyConfiguration propertyConfiguration, string? resultsFullGroupDirectory, string[]? directories) =>
XPath.GetKeyValuePairs(propertyConfiguration, resultsFullGroupDirectory, directories);
ReadOnlyDictionary<string, string[]> TestStatic_GetKeyValuePairs(IPropertyConfiguration propertyConfiguration, string? resultsFullGroupDirectory, string[]? jsonGroups) =>
GetKeyValuePairs(propertyConfiguration, resultsFullGroupDirectory, jsonGroups);
static ReadOnlyDictionary<string, string[]> GetKeyValuePairs(IPropertyConfiguration propertyConfiguration, string? resultsFullGroupDirectory, string[]? jsonGroups) =>
XPath.GetKeyValuePairs(propertyConfiguration, resultsFullGroupDirectory, jsonGroups);
}

View File

@ -10,10 +10,10 @@ public interface IPersonContainer
static List<long> GetPersonKeys(IEnumerable<Models.PersonContainer> personContainers) =>
PersonContainer.GetPersonKeys(personContainers);
List<Models.PersonContainer> TestStatic_GetPersonContainers(string a2PeopleSingletonDirectory, string personBirthdayFormat, char[] personCharacters, string facesFileNameExtension) =>
GetPersonContainers(a2PeopleSingletonDirectory, personBirthdayFormat, personCharacters, facesFileNameExtension);
static List<Models.PersonContainer> GetPersonContainers(string a2PeopleSingletonDirectory, string personBirthdayFormat, char[] personCharacters, string facesFileNameExtension) =>
PersonContainer.GetPersonContainers(a2PeopleSingletonDirectory, personBirthdayFormat, personCharacters, facesFileNameExtension);
List<Models.PersonContainer> TestStatic_GetPersonContainers(string a2PeopleSingletonDirectory, string personBirthdayFormat, char[] personCharacters, Properties.IPropertyConfiguration propertyConfiguration, string facesFileNameExtension) =>
GetPersonContainers(a2PeopleSingletonDirectory, personBirthdayFormat, personCharacters, propertyConfiguration, facesFileNameExtension);
static List<Models.PersonContainer> GetPersonContainers(string a2PeopleSingletonDirectory, string personBirthdayFormat, char[] personCharacters, Properties.IPropertyConfiguration propertyConfiguration, string facesFileNameExtension) =>
PersonContainer.GetPersonContainers(a2PeopleSingletonDirectory, personBirthdayFormat, personCharacters, propertyConfiguration, facesFileNameExtension);
string? TestStatic_VerifyAge(char numberSign, string personDisplayDirectory, string? minusOne, string personDisplayDirectoryName, int? approximateYears, List<(string PersonKeyFormatted, Models.PersonBirthday PersonBirthday)> collection) =>
VerifyAge(numberSign, personDisplayDirectory, minusOne, personDisplayDirectoryName, approximateYears, collection);

View File

@ -38,16 +38,6 @@ public interface IProperty
static (bool?, string[]) IsWrongYear(Models.FileHolder fileHolder, DateTime? dateTimeOriginal, List<DateTime> dateTimes) =>
Property.IsWrongYear(fileHolder, dateTimeOriginal, dateTimes);
bool TestStatic_NameWithoutExtensionIsIdFormat(string fileNameWithoutExtension) =>
NameWithoutExtensionIsIdFormat(fileNameWithoutExtension);
static bool NameWithoutExtensionIsIdFormat(string fileNameWithoutExtension) =>
Property.NameWithoutExtensionIsIdFormat(fileNameWithoutExtension);
bool TestStatic_NameWithoutExtensionIsIdFormat(Models.FileHolder fileHolder) =>
NameWithoutExtensionIsIdFormat(fileHolder);
static bool NameWithoutExtensionIsIdFormat(Models.FileHolder fileHolder) =>
NameWithoutExtensionIsIdFormat(fileHolder.NameWithoutExtension);
List<DateTime> TestStatic_GetDateTimes(Models.Property property) =>
GetDateTimes(property);
static List<DateTime> GetDateTimes(Models.Property property) =>

View File

@ -0,0 +1,95 @@
using System.Text;
namespace View_by_Distance.Shared.Models.Stateless.Methods;
internal abstract class Id
{
internal static bool NameWithoutExtensionIsIdFormat(Properties.IPropertyConfiguration propertyConfiguration, string fileNameWithoutExtension)
{
bool result;
if (fileNameWithoutExtension.Length < 5 || fileNameWithoutExtension.Length > propertyConfiguration.IntMinValueLength)
result = false;
else
{
bool skipOneAllAreNumbers = fileNameWithoutExtension[1..].All(char.IsNumber);
result = (skipOneAllAreNumbers && fileNameWithoutExtension[0] == '-') || (skipOneAllAreNumbers && char.IsNumber(fileNameWithoutExtension[0]));
}
return result;
}
internal static int GetId(Properties.IPropertyConfiguration propertyConfiguration, string intelligentId)
{
int result;
StringBuilder results = new();
if (propertyConfiguration.IntMinValueLength < (propertyConfiguration.ResultAllInOneSubdirectoryLength + 2))
throw new NotSupportedException();
for (int i = intelligentId.Length - (propertyConfiguration.ResultAllInOneSubdirectoryLength + 2); i > -1; i--)
_ = results.Append(intelligentId[i]);
_ = results.Append(intelligentId[^3]).Append(intelligentId[^2]);
result = int.Parse(results.ToString());
if (intelligentId[^1] is '1' or '2')
result *= -1;
else if (intelligentId[^1] is not '9' and not '8')
throw new NotSupportedException();
return result;
}
internal static string GetIntelligentId(Properties.IPropertyConfiguration propertyConfiguration, long id, bool ignore)
{
string result;
StringBuilder stringBuilder = new();
if (propertyConfiguration.IntMinValueLength < (propertyConfiguration.ResultAllInOneSubdirectoryLength + 2))
throw new NotSupportedException();
int key;
string value;
List<char> resultAllInOneSubdirectoryChars = [];
if (id > -1)
{
key = ignore ? 8 : 9;
value = id.ToString().PadLeft(propertyConfiguration.IntMinValueLength, '0');
}
else
{
key = ignore ? 2 : 1;
value = id.ToString()[1..].PadLeft(propertyConfiguration.IntMinValueLength, '0');
}
for (int i = value.Length - propertyConfiguration.ResultAllInOneSubdirectoryLength - 1; i > -1; i--)
_ = stringBuilder.Append(value[i]);
for (int i = value.Length - propertyConfiguration.ResultAllInOneSubdirectoryLength; i < value.Length; i++)
resultAllInOneSubdirectoryChars.Add(value[i]);
result = $"{stringBuilder}{string.Join(string.Empty, resultAllInOneSubdirectoryChars)}{key}";
return result;
}
internal static string GetPaddedId(Properties.IPropertyConfiguration propertyConfiguration, int index, int id)
{
string result;
string intelligentId = GetIntelligentId(propertyConfiguration, id, ignore: false);
int check = GetId(propertyConfiguration, intelligentId);
if (check != id)
throw new NotSupportedException();
result = $"{propertyConfiguration.Offset + index}{intelligentId}";
return result;
}
internal static int GetDeterministicHashCode(byte[] value)
{
int result;
unchecked
{
int hash1 = (5381 << 16) + 5381;
int hash2 = hash1;
for (int i = 0; i < value.Length; i += 2)
{
hash1 = ((hash1 << 5) + hash1) ^ value[i];
if (i == value.Length - 1)
break;
hash2 = ((hash2 << 5) + hash2) ^ value[i + 1];
}
result = hash1 + (hash2 * 1566083941);
}
return result;
}
}

View File

@ -3,66 +3,48 @@ namespace View_by_Distance.Shared.Models.Stateless.Methods;
internal abstract class Mapping
{
internal static (string?, string?, string?, bool?) GetSegments(string facesFileNameExtension, string fileName)
internal static (string?, string?, bool?) GetSegments(string facesFileNameExtension, FilePath filePath)
{
string[] segments = fileName.Split('.');
string? id;
string? extensionLowered;
string? wholePercentages;
bool? needsFacesFileNameExtension;
string[] segments = filePath.Name.Split('.');
if (segments.Length < 4 || $".{segments[3]}" != facesFileNameExtension)
{
id = null;
extensionLowered = null;
wholePercentages = null;
needsFacesFileNameExtension = null;
}
else
{
id = segments[0];
extensionLowered = $".{segments[2]}";
wholePercentages = segments[1];
needsFacesFileNameExtension = segments.Length == 3;
}
return new(id, wholePercentages, extensionLowered, needsFacesFileNameExtension);
return new(wholePercentages, extensionLowered, needsFacesFileNameExtension);
}
private static (int?, int?) GetConvertedFromSegments(string facesFileNameExtension, string fileName)
private static int? GetConvertedFromSegments(string facesFileNameExtension, FilePath filePath)
{
int? id;
int? wholePercentages;
(string? Id, string? WholePercentages, string? ExtensionLowered, bool? Check) segments = GetSegments(facesFileNameExtension, fileName);
if (string.IsNullOrEmpty(segments.Id) || string.IsNullOrEmpty(segments.WholePercentages) || string.IsNullOrEmpty(segments.ExtensionLowered) || segments.Check is null)
{
id = null;
wholePercentages = null;
}
else if (!int.TryParse(segments.Id, out int idValue) || !int.TryParse(segments.WholePercentages, out int wholePercentagesValue))
{
id = null;
wholePercentages = null;
}
int? result;
(string? WholePercentages, string? ExtensionLowered, bool? Check) segments = GetSegments(facesFileNameExtension, filePath);
if (string.IsNullOrEmpty(segments.WholePercentages) || string.IsNullOrEmpty(segments.ExtensionLowered) || segments.Check is null)
result = null;
else if (!int.TryParse(segments.WholePercentages, out int wholePercentages))
result = null;
else
{
id = idValue;
wholePercentages = wholePercentagesValue;
}
return new(id, wholePercentages);
result = wholePercentages;
return result;
}
internal static (int?, int?) GetConverted(string facesFileNameExtension, string file)
internal static int? GetWholePercentages(string facesFileNameExtension, FilePath filePath)
{
int? id;
int? wholePercentages;
string fileName = Path.GetFileName(file);
if (fileName.Length >= 2 && !fileName[1..].Contains('-'))
(id, wholePercentages) = GetConvertedFromSegments(facesFileNameExtension, fileName);
else
{
id = null;
if (filePath.Name.Length < 2 || filePath.Name[1..].Contains('-'))
wholePercentages = null;
}
return new(id, wholePercentages);
else
wholePercentages = GetConvertedFromSegments(facesFileNameExtension, filePath);
return wholePercentages;
}
internal static int GetAreaPermyriad(int faceAreaPermyriad, int bottom, int height, int left, int right, int top, int width)

View File

@ -3,17 +3,24 @@ namespace View_by_Distance.Shared.Models.Stateless.Methods;
internal abstract class PersonContainer
{
private static List<string> GetFiles(string personDisplayDirectory)
private static List<FilePath> GetFilePaths(Properties.IPropertyConfiguration propertyConfiguration, string personDisplayDirectory)
{
List<string> results = [];
List<FilePath> results = [];
string[] files;
string extension;
string checkFile;
FilePath filePath;
string directoryName;
List<string> distinct = [];
Models.FileHolder fileHolder;
string fileNameWithoutExtension;
string personDisplayDirectoryName = Path.GetFileName(personDisplayDirectory);
results.AddRange(Directory.GetFiles(personDisplayDirectory, "*", SearchOption.TopDirectoryOnly));
files = Directory.GetFiles(personDisplayDirectory, "*", SearchOption.TopDirectoryOnly);
foreach (string file in files)
{
fileHolder = IFileHolder.Get(file);
filePath = FilePath.Get(propertyConfiguration, fileHolder, index: null);
results.Add(filePath);
}
string[] directories = Directory.GetDirectories(personDisplayDirectory, "*", SearchOption.TopDirectoryOnly);
foreach (string directory in directories)
{
@ -21,10 +28,11 @@ internal abstract class PersonContainer
files = Directory.GetFiles(directory, "*", SearchOption.TopDirectoryOnly);
foreach (string file in files)
{
extension = Path.GetExtension(file);
if (extension is not ".json" and not ".pged")
fileHolder = IFileHolder.Get(file);
filePath = FilePath.Get(propertyConfiguration, fileHolder, index: null);
if (filePath.ExtensionLowered is not ".json" and not ".pged")
{
results.Add(file);
results.Add(filePath);
continue;
}
fileNameWithoutExtension = Path.GetFileNameWithoutExtension(file);
@ -38,11 +46,13 @@ internal abstract class PersonContainer
}
else if (fileNameWithoutExtension != directoryName)
{
checkFile = Path.Combine(directory, $"{fileNameWithoutExtension}{extension}");
checkFile = Path.Combine(directory, $"{fileNameWithoutExtension}{filePath.ExtensionLowered}");
if (!File.Exists(checkFile))
{
File.Move(file, checkFile);
results.Add(checkFile);
fileHolder = IFileHolder.Get(checkFile);
filePath = FilePath.Get(propertyConfiguration, fileHolder, index: null);
results.Add(filePath);
}
else
{
@ -53,26 +63,31 @@ internal abstract class PersonContainer
}
continue;
}
results.Add(file);
results.Add(filePath);
}
}
return results;
}
private static List<string> GetFiles(string facesFileNameExtension, string personDisplayDirectory)
private static List<FilePath> GetFilePaths(string facesFileNameExtension, Properties.IPropertyConfiguration propertyConfiguration, string personDisplayDirectory)
{
List<string> results;
int? id;
List<FilePath> results;
string checkFile;
FilePath filePath;
int? wholePercentages;
string? checkDirectory;
Models.FileHolder fileHolder;
string[] files = Directory.GetFiles(personDisplayDirectory, "*", SearchOption.TopDirectoryOnly);
foreach (string file in files)
{
if (file.EndsWith(".lnk"))
continue;
(id, wholePercentages) = IMapping.GetConverted(facesFileNameExtension, file);
if (id is not null && wholePercentages is not null)
fileHolder = IFileHolder.Get(file);
filePath = FilePath.Get(propertyConfiguration, fileHolder, index: null);
if (filePath.Id is null )
continue;
wholePercentages = IMapping.GetWholePercentages(facesFileNameExtension, filePath);
if (wholePercentages is null)
continue;
checkDirectory = Path.GetDirectoryName(file);
if (string.IsNullOrEmpty(checkDirectory))
@ -86,20 +101,22 @@ internal abstract class PersonContainer
else
File.Move(file, checkFile);
}
results = GetFiles(personDisplayDirectory);
results = GetFilePaths(propertyConfiguration, personDisplayDirectory);
return results;
}
private static List<Models.PersonContainer> GetPersonContainersCollections(string facesFileNameExtension, PersonDirectory personDirectory, char numberSign, string personDisplayDirectory, string personDisplayDirectoryName, int? approximateYears, List<(string PersonKeyFormatted, Models.PersonBirthday PersonBirthday)> collection)
private static List<Models.PersonContainer> GetPersonContainersCollections(string facesFileNameExtension, Properties.IPropertyConfiguration propertyConfiguration, PersonDirectory personDirectory, char numberSign, string personDisplayDirectory, string personDisplayDirectoryName, int? approximateYears, List<(string PersonKeyFormatted, Models.PersonBirthday PersonBirthday)> collection)
{
List<Models.PersonContainer> results = [];
long personKey;
string[] files;
FilePath filePath;
const int zero = 0;
string personKeyDirectory;
Models.FileHolder fileHolder;
Models.PersonContainer personContainer;
Models.PersonBirthday[] orderedPersonBirthdays;
List<string> personDisplayDirectoryAllFiles = GetFiles(facesFileNameExtension, personDisplayDirectory);
List<FilePath> personDisplayDirectoryAllFilePaths = GetFilePaths(facesFileNameExtension, propertyConfiguration, personDisplayDirectory);
foreach ((string personKeyFormatted, Models.PersonBirthday personBirthday) in collection)
{
orderedPersonBirthdays = (from l in collection where !l.PersonKeyFormatted.Contains(numberSign) orderby l.PersonBirthday.Value.Ticks descending select l.PersonBirthday).ToArray();
@ -115,8 +132,15 @@ internal abstract class PersonContainer
files = Directory.GetFiles(personKeyDirectory, "*", SearchOption.AllDirectories);
if (files.Length == 0)
continue;
personDisplayDirectoryAllFiles.AddRange(files.Where(l => l.EndsWith(".rel")));
personContainer = new(approximateYears, orderedPersonBirthdays, personDisplayDirectoryAllFiles.ToArray(), personDisplayDirectoryName, personKey, personDirectory);
foreach (string file in files)
{
if (!file.EndsWith(".rel"))
continue;
fileHolder = IFileHolder.Get(file);
filePath = FilePath.Get(propertyConfiguration, fileHolder, index: null);
personDisplayDirectoryAllFilePaths.Add(filePath);
}
personContainer = new(approximateYears, orderedPersonBirthdays, new(personDisplayDirectoryAllFilePaths), personDisplayDirectoryName, personKey, personDirectory);
results.Add(personContainer);
}
return results;
@ -153,7 +177,7 @@ internal abstract class PersonContainer
return result;
}
private static (List<string?>, List<Models.PersonContainer>) GetPersonContainersGroup(string personBirthdayFormat, string facesFileNameExtension, char[] personCharacters, PersonDirectory personDirectory, string[] personDisplayDirectories)
private static (List<string?>, List<Models.PersonContainer>) GetPersonContainersGroup(string personBirthdayFormat, string facesFileNameExtension, char[] personCharacters, Properties.IPropertyConfiguration propertyConfiguration, PersonDirectory personDirectory, string[] personDisplayDirectories)
{
List<Models.PersonContainer> results = [];
string? minusOne;
@ -163,9 +187,9 @@ internal abstract class PersonContainer
string[] personKeyDirectories;
string? personDisplayDirectoryName;
Models.PersonContainer personContainer;
List<string> personDisplayDirectoryAllFiles;
List<Models.PersonContainer> personContainers;
List<(string, Models.PersonBirthday)> collection;
List<FilePath> personDisplayDirectoryAllFilePaths;
foreach (string personDisplayDirectory in personDisplayDirectories)
{
personDisplayDirectoryName = Path.GetFileName(personDisplayDirectory);
@ -185,20 +209,20 @@ internal abstract class PersonContainer
continue;
if (collection.Count > 0)
{
personContainers = GetPersonContainersCollections(facesFileNameExtension, personDirectory, numberSign, personDisplayDirectory, personDisplayDirectoryName, approximateYears, collection);
personContainers = GetPersonContainersCollections(facesFileNameExtension, propertyConfiguration, personDirectory, numberSign, personDisplayDirectory, personDisplayDirectoryName, approximateYears, collection);
results.AddRange(personContainers);
}
else
{
personDisplayDirectoryAllFiles = GetFiles(facesFileNameExtension, personDisplayDirectory);
personContainer = new(approximateYears, personDisplayDirectoryAllFiles.ToArray(), personDisplayDirectoryName, personDirectory);
personDisplayDirectoryAllFilePaths = GetFilePaths(facesFileNameExtension, propertyConfiguration, personDisplayDirectory);
personContainer = new(approximateYears, new(personDisplayDirectoryAllFilePaths), personDisplayDirectoryName, personDirectory);
results.Add(personContainer);
}
}
return new(changes, results);
}
private static (List<string?>, List<Models.PersonContainer>) GetPersonContainersInnerGroups(string personBirthdayFormat, string facesFileNameExtension, char[] personCharacters, string groupDirectory, string groupDirectoryName)
private static (List<string?>, List<Models.PersonContainer>) GetPersonContainersInnerGroups(string personBirthdayFormat, string facesFileNameExtension, char[] personCharacters, Properties.IPropertyConfiguration propertyConfiguration, string groupDirectory, string groupDirectoryName)
{
List<Models.PersonContainer> results = [];
string[] segments;
@ -215,7 +239,7 @@ internal abstract class PersonContainer
if (@char == exclamationPoint)
{
personDirectory = new(@char, "Ignore", 'U', 'U', 'U');
(changes, collection) = GetPersonContainersGroup(personBirthdayFormat, facesFileNameExtension, personCharacters, personDirectory, innerGroupDirectories);
(changes, collection) = GetPersonContainersGroup(personBirthdayFormat, facesFileNameExtension, personCharacters, propertyConfiguration, personDirectory, innerGroupDirectories);
allChanges.AddRange(changes);
results.AddRange(collection);
}
@ -237,7 +261,7 @@ internal abstract class PersonContainer
continue;
personDirectory = new(@char, innerGroupDirectoryName, segments[zero][zero], segments[1][zero], segments[2][zero]);
personDisplayDirectories = Directory.GetDirectories(innerGroupDirectory, "*", SearchOption.TopDirectoryOnly);
(changes, collection) = GetPersonContainersGroup(personBirthdayFormat, facesFileNameExtension, personCharacters, personDirectory, personDisplayDirectories);
(changes, collection) = GetPersonContainersGroup(personBirthdayFormat, facesFileNameExtension, personCharacters, propertyConfiguration, personDirectory, personDisplayDirectories);
allChanges.AddRange(changes);
results.AddRange(collection);
}
@ -245,7 +269,7 @@ internal abstract class PersonContainer
return new(allChanges, results);
}
private static List<Models.PersonContainer> GetPersonContainersGroups(string personBirthdayFormat, string facesFileNameExtension, char[] personCharacters, string[] groupDirectories)
private static List<Models.PersonContainer> GetPersonContainersGroups(string personBirthdayFormat, string facesFileNameExtension, char[] personCharacters, Properties.IPropertyConfiguration propertyConfiguration, string[] groupDirectories)
{
List<Models.PersonContainer> results;
List<string?> changes;
@ -260,7 +284,7 @@ internal abstract class PersonContainer
groupDirectoryName = Path.GetFileName(groupDirectory);
if (personCharacters[i] != groupDirectoryName.First())
continue;
(changes, collection) = GetPersonContainersInnerGroups(personBirthdayFormat, facesFileNameExtension, personCharacters, groupDirectory, groupDirectoryName);
(changes, collection) = GetPersonContainersInnerGroups(personBirthdayFormat, facesFileNameExtension, personCharacters, propertyConfiguration, groupDirectory, groupDirectoryName);
allChanges.AddRange(changes);
personContainers.AddRange(collection);
}
@ -271,7 +295,7 @@ internal abstract class PersonContainer
return results;
}
internal static List<Models.PersonContainer> GetPersonContainers(string a2PeopleSingletonDirectory, string personBirthdayFormat, char[] personCharacters, string facesFileNameExtension)
internal static List<Models.PersonContainer> GetPersonContainers(string a2PeopleSingletonDirectory, string personBirthdayFormat, char[] personCharacters, Properties.IPropertyConfiguration propertyConfiguration, string facesFileNameExtension)
{
List<Models.PersonContainer> results;
if (!Directory.Exists(a2PeopleSingletonDirectory))
@ -287,7 +311,7 @@ internal abstract class PersonContainer
if (groupDirectories.Length == 0)
results = [];
else
results = GetPersonContainersGroups(personBirthdayFormat, facesFileNameExtension, personCharacters, groupDirectories);
results = GetPersonContainersGroups(personBirthdayFormat, facesFileNameExtension, personCharacters, propertyConfiguration, groupDirectories);
return results;
}

View File

@ -274,18 +274,4 @@ internal abstract class Property
return result;
}
internal static bool NameWithoutExtensionIsIdFormat(string fileNameWithoutExtension)
{
bool result;
int intMinValueLength = int.MinValue.ToString().Length;
if (fileNameWithoutExtension.Length < 5 || fileNameWithoutExtension.Length > intMinValueLength)
result = false;
else
{
bool skipOneAllAreNumbers = fileNameWithoutExtension[1..].All(l => char.IsNumber(l));
result = (skipOneAllAreNumbers && fileNameWithoutExtension[0] == '-') || (skipOneAllAreNumbers && char.IsNumber(fileNameWithoutExtension[0]));
}
return result;
}
}

View File

@ -5,8 +5,6 @@ namespace View_by_Distance.Shared.Models.Stateless.Methods;
internal abstract partial class XDirectory
{
private record SortedRecord(Models.FileHolder FileHolder, bool NameWithoutExtensionIsIdFormat, int? Id);
private static int GetCeilingAverage(List<string[]> fileCollection)
{
List<int> counts = [];
@ -39,6 +37,8 @@ internal abstract partial class XDirectory
fileSearchFilter = string.Concat('*', fileSearchFilter);
if (!directorySearchFilter.Contains('*'))
directorySearchFilter = string.Concat('*', directorySearchFilter);
if (!Directory.Exists(directory))
_ = Directory.CreateDirectory(directory);
results.Add(Directory.GetFiles(directory, fileSearchFilter, SearchOption.TopDirectoryOnly));
string[] directories = Directory.GetDirectories(directory, directorySearchFilter, SearchOption.TopDirectoryOnly);
foreach (string innerDirectory in directories)
@ -185,46 +185,28 @@ internal abstract partial class XDirectory
return results;
}
private static void IsUniqueLoop(string resultAllInOne, string resultAllInOneDirectory, int resultAllInOneSubdirectoryLength, FilePair item, List<(string, string)> rename)
private static void IsNotUniqueLoop(Properties.IPropertyConfiguration propertyConfiguration, string jsonGroupDirectory, string extension, FilePair filePair, List<(string, string)> rename)
{
string fileName;
string directoryName;
foreach (string path in item.Collection)
int length = propertyConfiguration.RootDirectory.Length;
foreach (string path in filePair.Collection)
{
if (path.Contains(resultAllInOne))
if (filePair.Match is null || path != filePair.Match)
continue;
fileName = Path.GetFileName(path);
(directoryName, _) = IPath.GetDirectoryNameAndIndex(resultAllInOneSubdirectoryLength, fileName);
rename.Add(new(path, Path.Combine(resultAllInOneDirectory, directoryName, fileName)));
rename.Add(new(path, string.Concat(jsonGroupDirectory, filePair.Path[length..], extension)));
}
}
private static void IsNotUniqueLoop(string directory, string resultAllInOne, string jsonGroupDirectory, string extension, FilePair item, List<(string, string)> rename)
{
int length = directory.Length;
foreach (string path in item.Collection)
{
if (!path.Contains(resultAllInOne))
continue;
if (item.Match is null || path != item.Match)
continue;
rename.Add(new(path, string.Concat(jsonGroupDirectory, item.Path[length..], extension)));
}
}
internal static int MaybeMove(string directory, string resultAllInOne, int resultAllInOneSubdirectoryLength, List<FilePair> filePairs, string jsonGroupDirectory, string extension)
internal static int MaybeMove(Properties.IPropertyConfiguration propertyConfiguration, List<FilePair> filePairs, string jsonGroupDirectory, string extension)
{
FileInfo? toFileInfo;
FileInfo fromFileInfo;
string checkDirectory;
List<(string, string)> rename = [];
string resultAllInOneDirectory = Path.Combine(jsonGroupDirectory, resultAllInOne);
foreach (FilePair item in filePairs)
foreach (FilePair filePair in filePairs)
{
if (item.IsUnique)
IsUniqueLoop(resultAllInOne, resultAllInOneDirectory, resultAllInOneSubdirectoryLength, item, rename);
else
IsNotUniqueLoop(directory, resultAllInOne, jsonGroupDirectory, extension, item, rename);
if (filePair.IsUnique)
continue;
IsNotUniqueLoop(propertyConfiguration, jsonGroupDirectory, extension, filePair, rename);
}
foreach ((string from, string to) in rename)
{
@ -283,153 +265,109 @@ internal abstract partial class XDirectory
}
}
internal static (bool, int?) GetId(short sortOrderOnlyLengthIndex, Models.FileHolder fileHolder)
private static FilePath[] GetSortedRecords(Properties.IPropertyConfiguration propertyConfiguration, ReadOnlyCollection<string[]> filesCollection)
{
int? id;
short? multiplier;
char negativeMarker;
int absoluteValueOfId;
bool nameWithoutExtensionIsIdFormat = IProperty.NameWithoutExtensionIsIdFormat(fileHolder);
bool nameWithoutExtensionIsPaddedIdFormat = IDirectory.NameWithoutExtensionIsPaddedIdFormat(fileHolder, sortOrderOnlyLengthIndex);
if (!nameWithoutExtensionIsIdFormat && !nameWithoutExtensionIsPaddedIdFormat)
id = null;
else if (nameWithoutExtensionIsIdFormat)
{
if (!int.TryParse(fileHolder.NameWithoutExtension, out absoluteValueOfId))
id = null;
else
id = absoluteValueOfId;
}
else
{
negativeMarker = fileHolder.NameWithoutExtension[sortOrderOnlyLengthIndex - 2];
if (negativeMarker == '7')
multiplier = 1;
else if (negativeMarker == '3')
multiplier = -1;
else
multiplier = null;
if (!int.TryParse(fileHolder.NameWithoutExtension[sortOrderOnlyLengthIndex..], out absoluteValueOfId))
id = null;
else
{
id = absoluteValueOfId * multiplier;
if (id is null || !fileHolder.NameWithoutExtension.EndsWith(id.Value.ToString()[1..]))
id = null;
}
}
return (nameWithoutExtensionIsIdFormat, id);
}
private static SortedRecord[] GetSortedRecords(int offset, ReadOnlyCollection<string[]> filesCollection)
{
List<SortedRecord> results = [];
int? id;
List<FilePath> results = [];
FilePath filePath;
Models.FileHolder fileHolder;
bool nameWithoutExtensionIsIdFormat;
short sortOrderOnlyLengthIndex = IDirectory.GetSortOrderOnlyLengthIndex(offset);
foreach (string[] files in filesCollection)
{
foreach (string file in files)
{
fileHolder = new(file);
(nameWithoutExtensionIsIdFormat, id) = GetId(sortOrderOnlyLengthIndex, fileHolder);
results.Add(new(fileHolder, nameWithoutExtensionIsIdFormat, id));
fileHolder = IFileHolder.Get(file);
filePath = FilePath.Get(propertyConfiguration, fileHolder, index: null);
results.Add(filePath);
}
}
return (from l in results orderby l.FileHolder.CreationTime, l.FileHolder.FullName.Length descending select l).ToArray();
return (from l in results orderby l.CreationTicks, l.FullName.Length descending select l).ToArray();
}
internal static (string[], List<(Models.FileHolder, string?, string)>) GetToDoCollection(Properties.IPropertyConfiguration propertyConfiguration, bool copyDuplicates, bool ifCanUseId, ReadOnlyCollection<string[]> filesCollection, string[] directories, Action? tick)
internal static (string[], List<(FilePath, string)>) GetToDoCollection(Properties.IPropertyConfiguration propertyConfiguration, bool copyDuplicates, bool ifCanUseId, ReadOnlyCollection<string[]> filesCollection, string[] directories, Action? tick)
{
List<(Models.FileHolder, string?, string)> results = [];
List<(FilePath, string)> results = [];
string paddedId;
string checkFile;
string directory;
FileInfo fileInfo;
FilePath filePath;
int directoryIndex;
bool ignore = false;
string paddedIdFile;
bool wrapped = false;
string directoryName;
string intelligentId;
bool paddedCheck = false;
string fileDirectoryName;
SortedRecord sortedRecord;
string? alternateCheckFile;
string? alternateDirectory;
Models.FileHolder fileHolder;
List<int> distinctIds = [];
List<string> distinct = [];
Models.FileHolder fileHolder;
List<string> distinctDirectories = [];
int intMinValueLength = int.MinValue.ToString().Length;
SortedRecord[] sortedRecords = GetSortedRecords(propertyConfiguration.Offset, filesCollection);
string? alternateResultAllInOne = !propertyConfiguration.ResultAllInOne.Contains(' ') ? null : propertyConfiguration.ResultAllInOne.Replace(' ', '-');
FilePath[] sortedRecords = GetSortedRecords(propertyConfiguration, filesCollection);
for (int i = 0; i < sortedRecords.Length; i++)
{
tick?.Invoke();
sortedRecord = sortedRecords[i];
fileHolder = sortedRecord.FileHolder;
if (fileHolder.Name.EndsWith("len") || fileHolder.ExtensionLowered == ".id" || fileHolder.ExtensionLowered == ".lsv" || fileHolder.DirectoryName is null)
filePath = sortedRecords[i];
if (filePath.Name.EndsWith("len") || filePath.ExtensionLowered == ".id" || filePath.ExtensionLowered == ".lsv" || filePath.DirectoryName is null)
continue;
(directoryName, directoryIndex) = IPath.GetDirectoryNameAndIndex(propertyConfiguration.ResultAllInOneSubdirectoryLength, fileHolder.NameWithoutExtension);
fileDirectoryName = Path.GetFileName(fileHolder.DirectoryName);
if (fileDirectoryName.Length < propertyConfiguration.ResultAllInOneSubdirectoryLength + 3 || !fileHolder.Name.StartsWith(fileDirectoryName))
(_, directoryIndex) = IPath.GetDirectoryNameAndIndex(propertyConfiguration, filePath);
fileDirectoryName = Path.GetFileName(filePath.DirectoryName);
if (fileDirectoryName.Length < propertyConfiguration.ResultAllInOneSubdirectoryLength + 3 || !filePath.Name.StartsWith(fileDirectoryName))
{
if (wrapped)
continue;
directory = directories[directoryIndex];
if (alternateResultAllInOne is null)
alternateDirectory = null;
else
alternateDirectory = Path.Combine(Path.GetDirectoryName(Path.GetDirectoryName(directory)) ?? directory, alternateResultAllInOne, directoryName);
}
else
{
if (!wrapped)
wrapped = true;
alternateDirectory = null;
directory = Path.Combine(directories[directoryIndex], fileDirectoryName);
}
if (ifCanUseId && sortedRecord.NameWithoutExtensionIsIdFormat && sortedRecord.Id is not null && fileHolder.DirectoryName is not null)
if (ifCanUseId && filePath.IsIntelligentIdFormat && filePath.Id is not null && filePath.DirectoryName is not null)
{
paddedId = IDirectory.GetPaddedId(intMinValueLength, propertyConfiguration.Offset + i, sortedRecord.Id.Value);
paddedIdFile = Path.Combine(fileHolder.DirectoryName, $"{paddedId}{fileHolder.ExtensionLowered}");
paddedId = IId.GetPaddedId(propertyConfiguration, i, filePath.Id.Value);
paddedIdFile = Path.Combine(filePath.DirectoryName, $"{paddedId}{filePath.ExtensionLowered}");
if (!File.Exists(paddedIdFile))
{
File.Move(fileHolder.FullName, paddedIdFile);
fileHolder = new(paddedIdFile);
File.Move(filePath.FullName, paddedIdFile);
fileInfo = new(paddedIdFile);
fileHolder = Models.FileHolder.Get(fileInfo);
filePath = FilePath.Get(propertyConfiguration, fileHolder, index: null);
if (!paddedCheck)
paddedCheck = true;
}
}
if (ifCanUseId)
checkFile = Path.Combine(directory, $"{sortedRecord.Id}{fileHolder.ExtensionLowered}");
if (filePath.IsIntelligentIdFormat || !ifCanUseId)
checkFile = Path.Combine(directory, $"{filePath.NameWithoutExtension}{filePath.ExtensionLowered}");
else
checkFile = Path.Combine(directory, $"{fileHolder.NameWithoutExtension}{fileHolder.ExtensionLowered}");
if ((sortedRecord.Id is not null && distinctIds.Contains(sortedRecord.Id.Value)) || distinct.Contains(checkFile))
{
if (string.IsNullOrEmpty(fileHolder.DirectoryName))
if (filePath.Id is null)
throw new NullReferenceException(nameof(filePath.Id));
intelligentId = IId.GetIntelligentId(propertyConfiguration, filePath.Id.Value, ignore);
checkFile = Path.Combine(directory, $"{intelligentId}{filePath.ExtensionLowered}");
}
if ((filePath.Id is not null && distinctIds.Contains(filePath.Id.Value)) || distinct.Contains(checkFile))
{
if (string.IsNullOrEmpty(filePath.DirectoryName))
continue;
if (!copyDuplicates)
continue;
alternateDirectory = null;
for (int j = 1; j < int.MaxValue; j++)
{
fileInfo = new(checkFile);
if (!fileInfo.Exists || fileHolder.Length == fileInfo.Length && fileHolder.LastWriteTime == fileInfo.LastWriteTime)
checkFile = Path.Combine(directory, $"{fileHolder.NameWithoutExtension}.{j}dup{fileHolder.ExtensionLowered}");
if (!fileInfo.Exists || filePath.Length == fileInfo.Length && filePath.LastWriteTicks == fileInfo.LastWriteTime.Ticks)
checkFile = Path.Combine(directory, $"{filePath.NameWithoutExtension}.{j}dup{filePath.ExtensionLowered}");
else
checkFile = Path.Combine(directory, $"{fileHolder.NameWithoutExtension}.{j}why{fileHolder.ExtensionLowered}");
if (sortedRecord.Id is not null)
checkFile = Path.Combine(directory, $"{filePath.NameWithoutExtension}.{j}why{filePath.ExtensionLowered}");
if (filePath.Id is not null)
{
if (distinctIds.Contains(sortedRecord.Id.Value))
if (distinctIds.Contains(filePath.Id.Value))
continue;
distinctIds.Add(sortedRecord.Id.Value);
distinctIds.Add(filePath.Id.Value);
}
if (distinct.Contains(checkFile))
continue;
alternateCheckFile = null;
distinct.Add(checkFile);
results.Add(new(fileHolder, alternateCheckFile, checkFile));
results.Add(new(filePath, checkFile));
if (!distinctDirectories.Contains(directory))
distinctDirectories.Add(directory);
break;
@ -437,17 +375,9 @@ internal abstract partial class XDirectory
continue;
}
distinct.Add(checkFile);
if (sortedRecord.Id is not null)
distinctIds.Add(sortedRecord.Id.Value);
if (string.IsNullOrEmpty(alternateDirectory))
alternateCheckFile = null;
else
{
alternateCheckFile = Path.Combine(alternateDirectory, $"{sortedRecord.Id}{fileHolder.ExtensionLowered}.tsv");
if (!distinctDirectories.Contains(alternateDirectory))
distinctDirectories.Add(alternateDirectory);
}
results.Add(new(fileHolder, alternateCheckFile, checkFile));
if (filePath.Id is not null)
distinctIds.Add(filePath.Id.Value);
results.Add(new(filePath, checkFile));
if (!distinctDirectories.Contains(directory))
distinctDirectories.Add(directory);
}
@ -456,30 +386,28 @@ internal abstract partial class XDirectory
return (distinctDirectories.ToArray(), results);
}
internal static List<string> CopyOrMove(List<(Models.FileHolder, string?, string)> toDoCollection, bool move, bool moveBack, Action? tick)
internal static List<string> CopyOrMove(List<(FilePath, string)> toDoCollection, bool move, bool moveBack, Action? tick)
{
List<string> results = [];
FileInfo fileInfo;
foreach ((Models.FileHolder fileHolder, string? alternateFile, string to) in toDoCollection)
foreach ((FilePath filePath, string to) in toDoCollection)
{
tick?.Invoke();
fileInfo = new(to);
if (!fileInfo.Exists && alternateFile is not null)
_ = XPath.WriteAllText(alternateFile, fileHolder.FullName, updateDateWhenMatches: false, compareBeforeWrite: true, updateToWhenMatches: null);
if (fileInfo.Exists)
{
if (fileHolder.Length != fileInfo.Length || fileHolder.LastWriteTime != fileInfo.LastWriteTime)
if (filePath.Length != fileInfo.Length || filePath.LastWriteTicks != fileInfo.LastWriteTime.Ticks)
fileInfo.Delete();
else
continue;
}
results.Add(fileHolder.NameWithoutExtension);
results.Add(filePath.NameWithoutExtension);
try
{
if (move || moveBack)
File.Move(fileHolder.FullName, to);
File.Move(filePath.FullName, to);
else
File.Copy(fileHolder.FullName, to);
File.Copy(filePath.FullName, to);
}
catch (Exception) { }
}

View File

@ -1,3 +1,4 @@
using System.Collections.ObjectModel;
using View_by_Distance.Shared.Models.Properties;
namespace View_by_Distance.Shared.Models.Stateless.Methods;
@ -283,24 +284,35 @@ internal abstract class XPath
return (result, converted);
}
internal static Dictionary<string, string[]> GetKeyValuePairs(IPropertyConfiguration propertyConfiguration, string? resultsFullGroupDirectory, string[]? directories)
internal static (string, int) GetDirectoryNameAndIndex(IPropertyConfiguration propertyConfiguration, FilePath filePath)
{
int converted;
string result;
if (filePath.Id is not null)
(result, converted) = GetDirectoryNameAndIndex(propertyConfiguration.ResultAllInOneSubdirectoryLength, filePath.Id.Value.ToString());
else
(result, converted) = GetDirectoryNameAndIndex(propertyConfiguration.ResultAllInOneSubdirectoryLength, filePath.FileNameFirstSegment);
return (result, converted);
}
internal static ReadOnlyDictionary<string, string[]> GetKeyValuePairs(IPropertyConfiguration propertyConfiguration, string? resultsFullGroupDirectory, string[]? jsonGroups)
{
Dictionary<string, string[]> results = [];
int converted = int.Parse($"1{new string('0', propertyConfiguration.ResultAllInOneSubdirectoryLength)}");
string directory;
string checkDirectory;
int converted = int.Parse($"1{new string('0', propertyConfiguration.ResultAllInOneSubdirectoryLength)}");
int plusOne = converted + 1;
List<string> collection = [];
if (directories is not null)
if (jsonGroups is not null)
{
foreach (string key in directories)
foreach (string jsonGroup in jsonGroups)
{
if (resultsFullGroupDirectory is null)
continue;
collection.Clear();
for (int i = 0; i < plusOne; i++)
{
if (string.IsNullOrEmpty(key))
if (string.IsNullOrEmpty(jsonGroup))
{
if (i == converted)
checkDirectory = Path.GetFullPath(Path.Combine(resultsFullGroupDirectory, new('-', propertyConfiguration.ResultAllInOneSubdirectoryLength)));
@ -309,7 +321,7 @@ internal abstract class XPath
}
else
{
directory = Path.Combine(resultsFullGroupDirectory, key, propertyConfiguration.ResultAllInOne);
directory = Path.Combine(resultsFullGroupDirectory, jsonGroup);
if (i == converted)
checkDirectory = Path.GetFullPath(Path.Combine(directory, new('-', propertyConfiguration.ResultAllInOneSubdirectoryLength)));
else
@ -319,13 +331,13 @@ internal abstract class XPath
_ = Directory.CreateDirectory(checkDirectory);
collection.Add(checkDirectory);
}
if (!string.IsNullOrEmpty(key))
results.Add(key, collection.ToArray());
if (!string.IsNullOrEmpty(jsonGroup))
results.Add(jsonGroup, collection.ToArray());
else
results.Add(propertyConfiguration.ResultAllInOne, collection.ToArray());
}
}
return results;
return new(results);
}
}

View File

@ -86,7 +86,7 @@ public partial class UnitTestHardCoded
[TestMethod]
public void TestMethodGetApproximateYears()
{
string personDisplayDirectory = "D:/1-Images-A/Images-dd514b88-Results/A2)People/dd514b88/{}/^/Sydney Dupray^9";
string personDisplayDirectory = "D:/1-Images-A/Images-4083e56a-Results/A2)People/4083e56a/{}/^/Sydney Dupray^9";
if (Directory.Exists(Directory.GetDirectoryRoot(personDisplayDirectory)) && Directory.Exists(personDisplayDirectory))
{
char numberSign = '#';
@ -189,7 +189,7 @@ public partial class UnitTestHardCoded
[TestMethod]
public void TestMethodRenameAbandoned()
{
string directory = "D:/1-Images-A/Images-dd514b88-Results/A2)People/dd514b88/{}/!/Abandoned";
string directory = "D:/1-Images-A/Images-4083e56a-Results/A2)People/4083e56a/{}/!/Abandoned";
if (Directory.Exists(Path.GetPathRoot(directory)) && Directory.Exists(directory))
{
string checkFile;
@ -209,7 +209,7 @@ public partial class UnitTestHardCoded
[TestMethod]
public void TestMethodRenameDelete()
{
string directory = "D:/1-Images-A/Images-dd514b88-Results/A)Property/dd514b88/{}";
string directory = "D:/1-Images-A/Images-4083e56a-Results/A)Property/4083e56a/{}";
if (Directory.Exists(Path.GetPathRoot(directory)) && Directory.Exists(directory))
{
string checkFile;
@ -229,7 +229,7 @@ public partial class UnitTestHardCoded
[TestMethod]
public void TestMethodRenameOld()
{
string directory = "D:/1-Images-A/Images-dd514b88-Results/E)Distance/dd514b88/()";
string directory = "D:/1-Images-A/Images-4083e56a-Results/E)Distance/4083e56a/()";
if (Directory.Exists(Path.GetPathRoot(directory)) && Directory.Exists(directory))
{
string checkFile;
@ -250,7 +250,7 @@ public partial class UnitTestHardCoded
public void TestMethodRenameDup()
{
string directory;
directory = "D:/1-Images-A/Images-dd514b88-Results/E)Distance/dd514b88/()";
directory = "D:/1-Images-A/Images-4083e56a-Results/E)Distance/4083e56a/()";
if (Directory.Exists(Path.GetPathRoot(directory)) && Directory.Exists(directory))
{
string checkFile;
@ -264,7 +264,7 @@ public partial class UnitTestHardCoded
}
Assert.IsTrue(true);
}
directory = "D:/1-Images-A/Images-dd514b88-Results/A2)People/dd514b88/{}/!";
directory = "D:/1-Images-A/Images-4083e56a-Results/A2)People/4083e56a/{}/!";
if (Directory.Exists(Path.GetPathRoot(directory)) && Directory.Exists(directory))
{
string checkFile;
@ -284,9 +284,9 @@ public partial class UnitTestHardCoded
[TestMethod]
public void TestMethodRename()
{
// string directory = "D:/2-Images-B/Not-Copy-Copy-dd514b88";
string directory = "D:/1-Images-A/Images-dd514b88";
// string directory = "D:/2-Images-B/Not-Copy-Copy-dd514b88";
// string directory = "D:/2-Images-B/Not-Copy-Copy-4083e56a";
string directory = "D:/1-Images-A/Images-4083e56a";
// string directory = "D:/2-Images-B/Not-Copy-Copy-4083e56a";
if (Directory.Exists(Path.GetPathRoot(directory)) && Directory.Exists(directory))
{
string[] directories = Directory.GetDirectories(directory, "*;*", SearchOption.AllDirectories);
@ -303,7 +303,7 @@ public partial class UnitTestHardCoded
[TestMethod]
public void TestMethodRenameForUnkown()
{
string directory = "D:/1-Images-A/Images-dd514b88-Results/E)Distance/dd514b88/(RectInt-2023-06-19-less-0.99)";
string directory = "D:/1-Images-A/Images-4083e56a-Results/E)Distance/4083e56a/(RectInt-2023-06-19-less-0.99)";
if (Directory.Exists(Path.GetPathRoot(directory)) && Directory.Exists(directory))
{
string[] files = Directory.GetFiles(directory, "*.unk", SearchOption.AllDirectories);
@ -316,7 +316,7 @@ public partial class UnitTestHardCoded
[TestMethod]
public void TestMethodRenameForTicks()
{
string directory = "D:/1-Images-A/Images-dd514b88-Results/A2)People/dd514b88/([])/ged";
string directory = "D:/1-Images-A/Images-4083e56a-Results/A2)People/4083e56a/([])/ged";
if (Directory.Exists(Path.GetPathRoot(directory)) && Directory.Exists(directory))
{
string checkName;

View File

@ -154,11 +154,11 @@ public class UnitTestResize
_ = resize.ToString();
bool isUniqueFileName = false;
bool? isNotUniqueAndNeedsReview = null;
FileHolder sourceDirectoryFileHolder = new(".json");
FileHolder sourceDirectoryFileHolder = IFileHolder.Get(".json");
string sourceDirectory = Path.GetFullPath(Path.Combine(_PropertyConfiguration.RootDirectory, sourceDirectoryName));
FileHolder fileHolder = new(Path.Combine(sourceDirectory, sourceFileName));
(_, int? id) = IDirectory.GetId(_PropertyConfiguration.Offset, fileHolder);
Assert.IsNotNull(id);
FileHolder fileHolder = IFileHolder.Get(Path.Combine(sourceDirectory, sourceFileName));
FilePath filePath = FilePath.Get(_PropertyConfiguration, fileHolder, index: null);
Assert.IsNotNull(filePath.Id);
string relativePath = IPath.GetRelativePath(fileHolder.FullName, length);
string propertyLogicSourceDirectory = Path.GetFullPath(Path.Combine(aPropertySingletonDirectory, sourceDirectoryName));
propertyLogic.SetAngleBracketCollection(aResultsFullGroupDirectory, propertyLogicSourceDirectory);
@ -166,7 +166,7 @@ public class UnitTestResize
resize.SetAngleBracketCollection(cResultsFullGroupDirectory, sourceDirectory);
resize.Update(cResultsFullGroupDirectory);
blurHasher.Update(cResultsFullGroupDirectory);
item = new(sourceDirectoryFileHolder, relativePath, fileHolder, isNotUniqueAndNeedsReview, isUniqueFileName, isValidImageFormatExtension, property, false, false, false);
item = new(filePath, sourceDirectoryFileHolder, relativePath, fileHolder, isNotUniqueAndNeedsReview, isUniqueFileName, isValidImageFormatExtension, property, false, false, false);
Assert.IsNotNull(item.ImageFileHolder);
if (item.Property is null)
{
@ -175,15 +175,15 @@ public class UnitTestResize
}
if (property is null || item.Property is null)
throw new NullReferenceException(nameof(property));
resizedFileHolder = resize.GetResizedFileHolder(cResultsFullGroupDirectory, item, outputResolutionHasNumber, id.Value);
resizedFileHolder = resize.GetResizedFileHolder(cResultsFullGroupDirectory, item, outputResolutionHasNumber, filePath.Id.Value);
item.SetResizedFileHolder(resize.FileNameExtension, resizedFileHolder);
MappingFromItem mappingFromItem = IMappingFromItem.GetMappingFromItem(item);
Dictionary<string, int[]> outputResolutionToResize = resize.GetResizeKeyValuePairs(_PropertyConfiguration, cResultsFullGroupDirectory, subFileTuples, parseExceptions, item.Property, mappingFromItem);
Dictionary<string, int[]> outputResolutionToResize = resize.GetResizeKeyValuePairs(_PropertyConfiguration, cResultsFullGroupDirectory, item.FilePath, subFileTuples, parseExceptions, item.Property, mappingFromItem);
Assert.IsNotNull(mappingFromItem.ResizedFileHolder);
resize.SaveResizedSubfile(_PropertyConfiguration, outputResolution, cResultsFullGroupDirectory, subFileTuples, item, item.Property, mappingFromItem, outputResolutionToResize);
string blurHash = blurHasher.Encode(resizedFileHolder);
Assert.IsNotNull(blurHash);
ReadOnlyDictionary<string, MetadataExtractorDirectory> metadataExtractorDirectories = metadata.GetMetadataCollection(subFileTuples, parseExceptions, changesFrom, mappingFromItem);
ReadOnlyDictionary<string, MetadataExtractorDirectory> metadataExtractorDirectories = metadata.GetMetadataCollection(item.FilePath, subFileTuples, parseExceptions, changesFrom, mappingFromItem);
string json = JsonSerializer.Serialize(metadataExtractorDirectories, ReadOnlyDictionaryStringMetadataExtractorDirectorySourceGenerationContext.Default.ReadOnlyDictionaryStringMetadataExtractorDirectory);
File.WriteAllText("../../../.json", json);
MetadataExtractor.GeoLocation? geoLocation = Metadata.Models.Stateless.Methods.IMetadata.GeoLocation(metadataExtractorDirectories);

View File

@ -227,11 +227,11 @@ public class UnitTestFace
_ = resize.ToString();
bool isUniqueFileName = false;
bool? isNotUniqueAndNeedsReview = null;
FileHolder sourceDirectoryFileHolder = new(".json");
FileHolder sourceDirectoryFileHolder = IFileHolder.Get(".json");
string sourceDirectory = Path.GetFullPath(Path.Combine(_PropertyConfiguration.RootDirectory, sourceDirectoryName));
FileHolder fileHolder = new(Path.Combine(sourceDirectory, sourceFileName));
(_, int? id) = IDirectory.GetId(_PropertyConfiguration.Offset, fileHolder);
Assert.IsNotNull(id);
FileHolder fileHolder = IFileHolder.Get(Path.Combine(sourceDirectory, sourceFileName));
FilePath filePath = FilePath.Get(_PropertyConfiguration, fileHolder, index: null);
Assert.IsNotNull(filePath.Id);
string relativePath = IPath.GetRelativePath(fileHolder.FullName, length);
string propertyLogicSourceDirectory = Path.GetFullPath(Path.Combine(aPropertySingletonDirectory, sourceDirectoryName));
propertyLogic.SetAngleBracketCollection(aResultsFullGroupDirectory, propertyLogicSourceDirectory);
@ -239,7 +239,7 @@ public class UnitTestFace
resize.SetAngleBracketCollection(cResultsFullGroupDirectory, sourceDirectory);
resize.Update(cResultsFullGroupDirectory);
blurHasher.Update(cResultsFullGroupDirectory);
item = new(sourceDirectoryFileHolder, relativePath, fileHolder, isNotUniqueAndNeedsReview, isUniqueFileName, isValidImageFormatExtension, property, false, false, false);
item = new(filePath, sourceDirectoryFileHolder, relativePath, fileHolder, isNotUniqueAndNeedsReview, isUniqueFileName, isValidImageFormatExtension, property, false, false, false);
Assert.IsNotNull(item.ImageFileHolder);
if (item.Property is null)
{
@ -248,16 +248,16 @@ public class UnitTestFace
}
if (property is null || item.Property is null)
throw new NullReferenceException(nameof(property));
resizedFileHolder = resize.GetResizedFileHolder(cResultsFullGroupDirectory, item, outputResolutionHasNumber, id.Value);
resizedFileHolder = resize.GetResizedFileHolder(cResultsFullGroupDirectory, item, outputResolutionHasNumber, filePath.Id.Value);
item.SetResizedFileHolder(resize.FileNameExtension, resizedFileHolder);
MappingFromItem mappingFromItem = IMappingFromItem.GetMappingFromItem(item);
IReadOnlyList<MetadataExtractor.Directory> directories = MetadataExtractor.ImageMetadataReader.ReadMetadata(resizedFileHolder.FullName);
Dictionary<string, int[]> outputResolutionToResize = resize.GetResizeKeyValuePairs(_PropertyConfiguration, cResultsFullGroupDirectory, subFileTuples, parseExceptions, item.Property, mappingFromItem);
Dictionary<string, int[]> outputResolutionToResize = resize.GetResizeKeyValuePairs(_PropertyConfiguration, cResultsFullGroupDirectory, item.FilePath, subFileTuples, parseExceptions, item.Property, mappingFromItem);
Assert.IsNotNull(mappingFromItem.ResizedFileHolder);
resize.SaveResizedSubfile(_PropertyConfiguration, outputResolution, cResultsFullGroupDirectory, subFileTuples, item, item.Property, mappingFromItem, outputResolutionToResize);
string blurHash = blurHasher.Encode(resizedFileHolder);
Assert.IsNotNull(blurHash);
ReadOnlyDictionary<string, MetadataExtractorDirectory>? metadataExtractorDirectories = metadata.GetMetadataCollection(subFileTuples, parseExceptions, changesFrom, mappingFromItem);
ReadOnlyDictionary<string, MetadataExtractorDirectory>? metadataExtractorDirectories = metadata.GetMetadataCollection(item.FilePath, subFileTuples, parseExceptions, changesFrom, mappingFromItem);
string json = JsonSerializer.Serialize(metadataExtractorDirectories, ReadOnlyDictionaryStringMetadataExtractorDirectorySourceGenerationContext.Default.ReadOnlyDictionaryStringMetadataExtractorDirectory);
File.WriteAllText("../../../.json", json);
Image image = FaceRecognition.LoadImageFile(mappingFromItem.ResizedFileHolder.FullName);