FilePath ready to test

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

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);
}
}