Runs but broken

This commit is contained in:
2024-08-31 08:32:06 -07:00
parent f458af776a
commit 326e579d5c
43 changed files with 1763 additions and 654 deletions

View File

@ -1,8 +1,9 @@
using System.Collections.ObjectModel;
using System.Text.Json;
namespace View_by_Distance.Shared.Models;
public record Container(string SourceDirectory, List<Item> Items)
public record Container(string SourceDirectory, ReadOnlyCollection<Item> Items)
{
public override string ToString()

View File

@ -20,33 +20,30 @@ public record FileHolder(DateTime? CreationTime,
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;
}
private static FileHolder GetExisting(FileInfo fileInfo) =>
new(fileInfo.CreationTime,
fileInfo.DirectoryName,
fileInfo.Exists,
fileInfo.Extension.ToLower(),
fileInfo.FullName,
fileInfo.LastWriteTime,
fileInfo.Length,
fileInfo.Name,
Path.GetFileNameWithoutExtension(fileInfo.FullName));
private static FileHolder GetNonExisting(FileInfo fileInfo) =>
new(null,
fileInfo.DirectoryName,
fileInfo.Exists,
fileInfo.Extension.ToLower(),
fileInfo.FullName,
null,
null,
fileInfo.Name,
Path.GetFileNameWithoutExtension(fileInfo.FullName));
public static FileHolder Get(FileInfo fileInfo) =>
fileInfo.Exists ? GetExisting(fileInfo) : GetNonExisting(fileInfo);
public static FileHolder Get(FilePath filePath)
{

View File

@ -10,7 +10,8 @@ public record FilePath(long CreationTicks,
string FileNameFirstSegment,
string FullName,
int? Id,
bool? IsIgnore,
bool? HasIgnoreKeyword,
bool? HasDateTimeOriginal,
bool IsIntelligentIdFormat,
long LastWriteTicks,
long Length,
@ -42,7 +43,8 @@ public record FilePath(long CreationTicks,
bool isIntelligentIdFormat = IId.NameWithoutExtensionIsIntelligentIdFormat(propertyConfiguration, fileNameFirstSegment);
bool isPaddedIntelligentIdFormat = IId.NameWithoutExtensionIsPaddedIntelligentIdFormat(propertyConfiguration, sortOrderOnlyLengthIndex, fileNameFirstSegment);
bool fileNameFirstSegmentIsIdFormat = !isPaddedIntelligentIdFormat && !isIntelligentIdFormat && IId.NameWithoutExtensionIsIdFormat(propertyConfiguration, fileHolder);
bool? isIgnore = !isIntelligentIdFormat && !isPaddedIntelligentIdFormat ? null : fileNameFirstSegment[^1] is '2' or '8';
bool? hasIgnoreKeyword = !isIntelligentIdFormat && !isPaddedIntelligentIdFormat ? null : fileNameFirstSegment[^1] is '2' or '8';
bool? hasDateTimeOriginal = !isIntelligentIdFormat && !isPaddedIntelligentIdFormat ? null : fileNameFirstSegment[^1] is '1' or '9';
if (!fileNameFirstSegmentIsIdFormat && !isIntelligentIdFormat && !isPaddedIntelligentIdFormat)
(id, sortOder) = (null, null);
else if (isIntelligentIdFormat)
@ -70,7 +72,8 @@ public record FilePath(long CreationTicks,
fileNameFirstSegment,
fileHolder.FullName,
id,
isIgnore,
hasIgnoreKeyword,
hasDateTimeOriginal,
isIntelligentIdFormat,
fileHolder.LastWriteTime.Value.Ticks,
fileHolder.Length.Value,

View File

@ -5,11 +5,57 @@ namespace View_by_Distance.Shared.Models;
public record LocationContainer(DateOnly CreationDateOnly,
ExifDirectory? ExifDirectory,
int? DirectoryNumber,
string DisplayDirectoryName,
string? DisplayDirectoryName,
object? Encoding,
FaceFile? FaceFile,
FilePath FilePath,
bool FromDistanceContent,
int Id,
Location? Location,
long PersonKey,
int? LengthPermyriad,
FilePath? LengthSource,
long? PersonKey,
RectangleF? Rectangle,
int WholePercentages);
int WholePercentages)
{
public static LocationContainer Get(LocationContainer locationContainer, object? encoding, bool keepExifDirectory)
{
LocationContainer result;
result = new(locationContainer.CreationDateOnly,
keepExifDirectory ? locationContainer.ExifDirectory : null,
locationContainer.DirectoryNumber,
locationContainer.DisplayDirectoryName,
encoding,
locationContainer.FaceFile,
locationContainer.FilePath,
locationContainer.FromDistanceContent,
locationContainer.Id,
locationContainer.LengthPermyriad,
locationContainer.LengthSource,
locationContainer.PersonKey,
locationContainer.Rectangle,
locationContainer.WholePercentages);
return result;
}
public static LocationContainer Get(LocationContainer source, LocationContainer locationContainer, int lengthPermyriad, bool keepExifDirectory, bool keepEncoding)
{
LocationContainer result;
result = new(locationContainer.CreationDateOnly,
keepExifDirectory ? locationContainer.ExifDirectory : null,
locationContainer.DirectoryNumber,
locationContainer.DisplayDirectoryName,
keepEncoding ? locationContainer.Encoding : null,
locationContainer.FaceFile,
locationContainer.FilePath,
locationContainer.FromDistanceContent,
locationContainer.Id,
lengthPermyriad,
source.FilePath,
locationContainer.PersonKey,
locationContainer.Rectangle,
locationContainer.WholePercentages);
return result;
}
}

View File

@ -5,6 +5,6 @@ namespace View_by_Distance.Shared.Models.Methods;
public interface IDistance
{
ReadOnlyCollection<RelationContainer> GetRelationContainers(int faceDistancePermyriad, int locationContainerDistanceTake, float locationContainerDistanceTolerance, ReadOnlyCollection<LocationContainer> locationContainers);
ReadOnlyCollection<RelationContainer> GetRelationContainers(IDistanceLimits distanceLimits, int faceDistancePermyriad, int locationContainerDistanceTake, float locationContainerDistanceTolerance, ReadOnlyCollection<LocationContainer> locationContainers);
}

View File

@ -9,6 +9,7 @@ public interface IDistanceLimits
public double FaceDistancePermyriad { init; get; }
public int SortingMaximumPerFaceShouldBeHigh { init; get; }
public bool RangeDaysDeltaTargetLessThenUpper { init; get; }
public double RangeDistanceToleranceUpperLimit { init; get; }
string GetCounts();
void AddCounts(int days, int distance);

View File

@ -8,7 +8,7 @@ internal abstract class Container
private record FilePair(bool IsUnique, List<string> Collection, FilePath FilePath, Models.Item Item) { }
internal static DateTime[] GetContainerDateTimes(IEnumerable<Models.Item> items)
internal static DateTime[] GetContainerDateTimes(ReadOnlyCollection<Models.Item> items)
{
DateTime[] results;
long containerMinimumTicks = (from l in items select l.FilePath.LastWriteTicks).Min();
@ -17,36 +17,38 @@ internal abstract class Container
return results;
}
internal static Models.Item[] GetFilterItems(Properties.IPropertyConfiguration propertyConfiguration, Models.Container container)
internal static ReadOnlyCollection<Models.Item> GetValidImageItems(Properties.IPropertyConfiguration propertyConfiguration, Models.Container container)
{
List<Models.Item> results = [];
foreach (Models.Item item in container.Items)
{
if (item.IsValidImageFormatExtension
&& !propertyConfiguration.IgnoreExtensions.Contains(item.FilePath.ExtensionLowered))
results.Add(item);
if (!item.IsValidImageFormatExtension || propertyConfiguration.IgnoreExtensions.Contains(item.FilePath.ExtensionLowered))
continue;
results.Add(item);
}
return results.ToArray();
return container.Items.Count == results.Count ? container.Items : new(results);
}
internal static List<Models.FilePair> GetFilePairs(Properties.IPropertyConfiguration propertyConfiguration, string directorySearchFilter, string extension, string aPropertySingletonDirectory, ReadOnlyCollection<string[]> filesCollection)
private static List<Models.FilePair> GetFilePairs(Properties.IPropertyConfiguration propertyConfiguration, string directorySearchFilter, string extension, string aPropertySingletonDirectory, ReadOnlyCollection<ReadOnlyCollection<FilePath>> filePathsCollection)
{
int renamed;
const bool useCeilingAverage = true;
List<Models.FilePair>? filePairs = null;
ReadOnlyCollection<string[]>? jsonFilesCollection = null;
IReadOnlyDictionary<string, List<string>>? compareFileNamesToFiles = null;
IReadOnlyDictionary<string, List<string>> fileNamesToFiles = XDirectory.GetFilesKeyValuePairs(filesCollection);
for (int i = 0; i < int.MaxValue; i++)
IReadOnlyDictionary<string, List<string>> fileNamesToFiles = XDirectory.GetFilesKeyValuePairs(filePathsCollection);
for (int i = 0; i < short.MaxValue; i++)
{
renamed = 0;
jsonFilesCollection = IDirectory.GetFilesCollection(aPropertySingletonDirectory, directorySearchFilter, extension, useCeilingAverage);
compareFileNamesToFiles = XDirectory.GetFilesKeyValuePairs(jsonFilesCollection);
renamed += XDirectory.LookForAbandoned(jsonFilesCollection, fileNamesToFiles, extension);
filePairs = XDirectory.GetFiles(filesCollection, fileNamesToFiles, extension, compareFileNamesToFiles);
filePairs = XDirectory.GetFiles(propertyConfiguration, filePathsCollection, fileNamesToFiles, extension, compareFileNamesToFiles);
renamed += XDirectory.MaybeMove(propertyConfiguration, filePairs, aPropertySingletonDirectory, extension);
if (renamed == 0)
break;
if (i > 10)
throw new NotImplementedException();
}
if (filePairs is null || jsonFilesCollection is null || compareFileNamesToFiles is null)
throw new NullReferenceException(nameof(filePairs));
@ -69,26 +71,26 @@ internal abstract class Container
return result;
}
private static void ParallelFor(Properties.IPropertyConfiguration propertyConfiguration, string aPropertySingletonDirectory, string extension, int rootDirectoryLength, Models.FilePair filePair, List<FilePair> results)
private static void ParallelFor(IDlibDotNet? dlibDotNet, Properties.IPropertyConfiguration propertyConfiguration, string aPropertySingletonDirectory, string extension, int rootDirectoryLength, Models.FilePair filePair, List<FilePair> results)
{
dlibDotNet?.Tick();
bool abandoned = false;
Models.FileHolder sourceDirectoryFileHolder;
Models.Property? property = GetProperty(filePair);
Models.FileHolder imageFileInfo = IFileHolder.Get(filePair.Path);
FilePath filePath = FilePath.Get(propertyConfiguration, imageFileInfo, index: null);
Models.FileHolder imageFileHolder = IFileHolder.Get(filePair.Path);
FilePath filePath = FilePath.Get(propertyConfiguration, imageFileHolder, index: null);
bool? fileSizeChanged = property is not null ? property.FileSize != filePath.Length : null;
bool isValidImageFormatExtension = propertyConfiguration.ValidImageFormatExtensions.Contains(filePath.ExtensionLowered);
if (property is not null && property.Keywords is not null)
bool? shouldIgnore = property is null || property.Keywords is null ? null : propertyConfiguration.IgnoreRulesKeyWords.Any(l => property.Keywords.Contains(l));
if (shouldIgnore is not null)
{
if (filePath.IsIgnore is null)
throw new NullReferenceException();
bool shouldIgnore = propertyConfiguration.IgnoreRulesKeyWords.Any(l => property.Keywords.Contains(l));
if (shouldIgnore)
if (shouldIgnore.Value)
{
if (shouldIgnore)
{ }
FileInfo fileInfo = new(filePath.FullName);
if (!fileInfo.Attributes.HasFlag(FileAttributes.Hidden))
File.SetAttributes(imageFileHolder.FullName, FileAttributes.Hidden);
}
if (filePath.IsIgnore.Value != shouldIgnore)
if (filePath.HasIgnoreKeyword is not null && filePath.HasIgnoreKeyword.Value != shouldIgnore.Value)
{
if (filePath.DirectoryName.Contains("Results") && filePath.DirectoryName.Contains("Resize"))
File.Delete(filePath.FullName);
@ -118,31 +120,31 @@ internal abstract class Container
results.Add(new(filePair.IsUnique, filePair.Collection, filePath, item));
}
private static List<FilePair> GetFilePairs(Properties.IPropertyConfiguration propertyConfiguration, string aPropertySingletonDirectory, string filesCollectionDirectory, ReadOnlyCollection<string[]> filesCollection, string directorySearchFilter)
private static List<FilePair> GetFilePairs(IDlibDotNet? dlibDotNet, Properties.IPropertyConfiguration propertyConfiguration, string aPropertySingletonDirectory, string filesCollectionDirectory, ReadOnlyCollection<ReadOnlyCollection<FilePath>> filePathsCollection, string directorySearchFilter)
{
List<FilePair> results = [];
const string extension = ".json";
int maxDegreeOfParallelism = Environment.ProcessorCount;
int filesCollectionDirectoryLength = filesCollectionDirectory.Length;
ParallelOptions parallelOptions = new() { MaxDegreeOfParallelism = maxDegreeOfParallelism };
List<Models.FilePair> filePairs = GetFilePairs(propertyConfiguration, directorySearchFilter, extension, aPropertySingletonDirectory, filesCollection);
_ = Parallel.For(0, filePairs.Count, parallelOptions, (i, state) => ParallelFor(propertyConfiguration, aPropertySingletonDirectory, extension, filesCollectionDirectoryLength, filePairs[i], results));
List<Models.FilePair> filePairs = GetFilePairs(propertyConfiguration, directorySearchFilter, extension, aPropertySingletonDirectory, filePathsCollection);
_ = Parallel.For(0, filePairs.Count, parallelOptions, (i, state) => ParallelFor(dlibDotNet, propertyConfiguration, aPropertySingletonDirectory, extension, filesCollectionDirectoryLength, filePairs[i], results));
return results;
}
private static (int, Models.Container[]) GetContainers(Properties.IPropertyConfiguration propertyConfiguration, string aPropertySingletonDirectory, string filesCollectionDirectory, ReadOnlyCollection<string[]> filesCollection, string directorySearchFilter)
private static (int, Models.Container[]) GetContainers(IDlibDotNet? dlibDotNet, Properties.IPropertyConfiguration propertyConfiguration, string aPropertySingletonDirectory, string filesCollectionDirectory, ReadOnlyCollection<ReadOnlyCollection<FilePath>> filePathsCollection, string directorySearchFilter)
{
List<Models.Container> results = [];
string? directory;
string directory;
List<Models.Item>? items;
Models.Container container;
List<string> directories = [];
Dictionary<string, List<Models.Item>> directoryToItems = [];
foreach (string[] files in filesCollection)
foreach (ReadOnlyCollection<FilePath> filePaths in filePathsCollection)
{
if (files.Length == 0)
if (filePaths.Count == 0)
continue;
directory = Path.GetDirectoryName(files.First());
directory = filePaths[0].DirectoryName;
if (directory is null)
continue;
if (!directories.Contains(directory))
@ -154,7 +156,7 @@ internal abstract class Container
throw new Exception();
}
}
List<FilePair> filePairs = GetFilePairs(propertyConfiguration, aPropertySingletonDirectory, filesCollectionDirectory, filesCollection, directorySearchFilter);
List<FilePair> filePairs = GetFilePairs(dlibDotNet, propertyConfiguration, aPropertySingletonDirectory, filesCollectionDirectory, filePathsCollection, directorySearchFilter);
foreach (FilePair filePair in filePairs)
{
if (!directoryToItems.TryGetValue(filePair.FilePath.DirectoryName, out items))
@ -169,43 +171,44 @@ internal abstract class Container
{
if (keyValuePair.Value.Count == 0)
continue;
container = new(keyValuePair.Key, keyValuePair.Value);
container = new(keyValuePair.Key, new(keyValuePair.Value));
results.Add(container);
}
return (filePairs.Count, results.ToArray());
}
internal static (int, Models.Container[]) GetContainers(Properties.IPropertyConfiguration propertyConfiguration, string aPropertySingletonDirectory, string filesCollectionDirectory, ReadOnlyCollection<string[]> filesCollection)
internal static ReadOnlyCollection<Models.Container> GetContainers(IDlibDotNet dlibDotNet, Properties.IPropertyConfiguration propertyConfiguration, string aPropertySingletonDirectory, string filesCollectionDirectory, ReadOnlyCollection<ReadOnlyCollection<FilePath>> filePathsCollection)
{
int count;
Models.Container[] results;
const string directorySearchFilter = "*";
(count, results) = GetContainers(propertyConfiguration, aPropertySingletonDirectory, filesCollectionDirectory, filesCollection, directorySearchFilter);
return (count, results);
(_, results) = GetContainers(dlibDotNet, propertyConfiguration, aPropertySingletonDirectory, filesCollectionDirectory, filePathsCollection, directorySearchFilter);
return new(results);
}
internal static (int, Models.Container[]) GetContainers(Properties.IPropertyConfiguration propertyConfiguration, string aPropertySingletonDirectory)
{
int count;
Models.Container[] results;
IDlibDotNet? dlibDotNet = null;
const bool useCeilingAverage = true;
const string fileSearchFilter = "*";
const string directorySearchFilter = "*";
ReadOnlyCollection<string[]> filesCollection = IDirectory.GetFilesCollection(propertyConfiguration.RootDirectory, directorySearchFilter, fileSearchFilter, useCeilingAverage);
(count, results) = GetContainers(propertyConfiguration, aPropertySingletonDirectory, propertyConfiguration.RootDirectory, filesCollection, directorySearchFilter);
ReadOnlyCollection<ReadOnlyCollection<FilePath>> filePathsCollection = IDirectory.GetFilePathCollections(propertyConfiguration, filesCollection);
(count, results) = GetContainers(dlibDotNet, propertyConfiguration, aPropertySingletonDirectory, propertyConfiguration.RootDirectory, filePathsCollection, directorySearchFilter);
return (count, results);
}
internal static List<int> GetFilteredDistinctIds(Properties.IPropertyConfiguration propertyConfiguration, ReadOnlyCollection<Models.Container> readOnlyContainers)
{
List<int> results = [];
Models.Item[] filteredItems;
ReadOnlyCollection<Models.Item> filteredItems;
foreach (Models.Container container in readOnlyContainers)
{
if (container.Items.Count == 0)
continue;
filteredItems = GetFilterItems(propertyConfiguration, container);
if (filteredItems.Length == 0)
filteredItems = GetValidImageItems(propertyConfiguration, container);
if (filteredItems.Count == 0)
continue;
foreach (Models.Item item in filteredItems)
{
@ -219,11 +222,34 @@ internal abstract class Container
return results;
}
internal static ReadOnlyCollection<Models.Item> GetItems(Properties.IPropertyConfiguration propertyConfiguration, ReadOnlyCollection<Models.Container> containers, bool distinctItems, bool filterItems)
internal static List<string> GetFilteredDistinctFileNameFirstSegments(Properties.IPropertyConfiguration propertyConfiguration, ReadOnlyCollection<Models.Container> readOnlyContainers)
{
List<string> results = [];
ReadOnlyCollection<Models.Item> filteredItems;
foreach (Models.Container container in readOnlyContainers)
{
if (container.Items.Count == 0)
continue;
filteredItems = GetValidImageItems(propertyConfiguration, container);
if (filteredItems.Count == 0)
continue;
foreach (Models.Item item in filteredItems)
{
if (item.Property?.Id is null || item.ResizedFileHolder is null)
continue;
if (results.Contains(item.FilePath.FileNameFirstSegment))
continue;
results.Add(item.FilePath.FileNameFirstSegment);
}
}
return results;
}
internal static ReadOnlyCollection<Models.Item> GetValidImageItems(Properties.IPropertyConfiguration propertyConfiguration, ReadOnlyCollection<Models.Container> containers, bool distinctItems, bool filterItems)
{
List<Models.Item> results = [];
List<int> distinct = [];
IEnumerable<Models.Item> filteredItems;
ReadOnlyCollection<Models.Item> filteredItems;
foreach (Models.Container container in containers)
{
if (container.Items.Count == 0)
@ -232,8 +258,8 @@ internal abstract class Container
filteredItems = container.Items;
else
{
filteredItems = GetFilterItems(propertyConfiguration, container);
if (!filteredItems.Any())
filteredItems = GetValidImageItems(propertyConfiguration, container);
if (filteredItems.Count == 0)
continue;
}
foreach (Models.Item item in filteredItems)

View File

@ -5,34 +5,39 @@ namespace View_by_Distance.Shared.Models.Stateless.Methods;
public interface IContainer
{
DateTime[] TestStatic_GetContainerDateTimes(IEnumerable<Models.Item> items) =>
DateTime[] TestStatic_GetContainerDateTimes(ReadOnlyCollection<Models.Item> items) =>
GetContainerDateTimes(items);
static DateTime[] GetContainerDateTimes(IEnumerable<Models.Item> items) =>
static DateTime[] GetContainerDateTimes(ReadOnlyCollection<Models.Item> items) =>
Container.GetContainerDateTimes(items);
Models.Item[] TestStatic_GetFilterItems(Properties.IPropertyConfiguration propertyConfiguration, Models.Container container) =>
GetFilterItems(propertyConfiguration, container);
static Models.Item[] GetFilterItems(Properties.IPropertyConfiguration propertyConfiguration, Models.Container container) =>
Container.GetFilterItems(propertyConfiguration, container);
ReadOnlyCollection<Models.Item> TestStatic_GetValidImageItems(Properties.IPropertyConfiguration propertyConfiguration, Models.Container container) =>
GetValidImageItems(propertyConfiguration, container);
static ReadOnlyCollection<Models.Item> GetValidImageItems(Properties.IPropertyConfiguration propertyConfiguration, Models.Container container) =>
Container.GetValidImageItems(propertyConfiguration, container);
(int, Models.Container[]) TestStatic_GetContainers(Properties.IPropertyConfiguration propertyConfiguration, string aPropertySingletonDirectory) =>
GetContainers(propertyConfiguration, aPropertySingletonDirectory);
static (int, Models.Container[]) GetContainers(Properties.IPropertyConfiguration propertyConfiguration, string aPropertySingletonDirectory) =>
Container.GetContainers(propertyConfiguration, aPropertySingletonDirectory);
(int, Models.Container[]) TestStatic_GetContainers(Properties.IPropertyConfiguration propertyConfiguration, string aPropertySingletonDirectory, string filesCollectionDirectory, ReadOnlyCollection<string[]> filesCollection) =>
GetContainers(propertyConfiguration, aPropertySingletonDirectory, filesCollectionDirectory, filesCollection);
static (int, Models.Container[]) GetContainers(Properties.IPropertyConfiguration propertyConfiguration, string aPropertySingletonDirectory, string filesCollectionDirectory, ReadOnlyCollection<string[]> filesCollection) =>
Container.GetContainers(propertyConfiguration, aPropertySingletonDirectory, filesCollectionDirectory, filesCollection);
ReadOnlyCollection<Models.Container> TestStatic_GetContainers(IDlibDotNet dlibDotNet, Properties.IPropertyConfiguration propertyConfiguration, string aPropertySingletonDirectory, string filesCollectionDirectory, ReadOnlyCollection<ReadOnlyCollection<FilePath>> filePathsCollection) =>
GetContainers(dlibDotNet, propertyConfiguration, aPropertySingletonDirectory, filesCollectionDirectory, filePathsCollection);
static ReadOnlyCollection<Models.Container> GetContainers(IDlibDotNet dlibDotNet, Properties.IPropertyConfiguration propertyConfiguration, string aPropertySingletonDirectory, string filesCollectionDirectory, ReadOnlyCollection<ReadOnlyCollection<FilePath>> filePathsCollection) =>
Container.GetContainers(dlibDotNet, propertyConfiguration, aPropertySingletonDirectory, filesCollectionDirectory, filePathsCollection);
List<int> TestStatic_GetFilteredDistinctIds(Properties.IPropertyConfiguration propertyConfiguration, ReadOnlyCollection<Models.Container> readOnlyContainers) =>
GetFilteredDistinctIds(propertyConfiguration, readOnlyContainers);
static List<int> GetFilteredDistinctIds(Properties.IPropertyConfiguration propertyConfiguration, ReadOnlyCollection<Models.Container> readOnlyContainers) =>
Container.GetFilteredDistinctIds(propertyConfiguration, readOnlyContainers);
ReadOnlyCollection<Models.Item> TestStatic_GetItems(Properties.IPropertyConfiguration propertyConfiguration, ReadOnlyCollection<Models.Container> containers, bool distinctItems, bool filterItems) =>
GetItems(propertyConfiguration, containers, distinctItems, filterItems);
static ReadOnlyCollection<Models.Item> GetItems(Properties.IPropertyConfiguration propertyConfiguration, ReadOnlyCollection<Models.Container> containers, bool distinctItems, bool filterItems) =>
Container.GetItems(propertyConfiguration, containers, distinctItems, filterItems);
List<string> TestStatic_GetFilteredDistinctFileNameFirstSegments(Properties.IPropertyConfiguration propertyConfiguration, ReadOnlyCollection<Models.Container> readOnlyContainers) =>
GetFilteredDistinctFileNameFirstSegments(propertyConfiguration, readOnlyContainers);
static List<string> GetFilteredDistinctFileNameFirstSegments(Properties.IPropertyConfiguration propertyConfiguration, ReadOnlyCollection<Models.Container> readOnlyContainers) =>
Container.GetFilteredDistinctFileNameFirstSegments(propertyConfiguration, readOnlyContainers);
ReadOnlyCollection<Models.Item> TestStatic_GetValidImageItems(Properties.IPropertyConfiguration propertyConfiguration, ReadOnlyCollection<Models.Container> containers, bool distinctItems, bool filterItems) =>
GetValidImageItems(propertyConfiguration, containers, distinctItems, filterItems);
static ReadOnlyCollection<Models.Item> GetValidImageItems(Properties.IPropertyConfiguration propertyConfiguration, ReadOnlyCollection<Models.Container> containers, bool distinctItems, bool filterItems) =>
Container.GetValidImageItems(propertyConfiguration, containers, distinctItems, filterItems);
}

View File

@ -20,24 +20,34 @@ public interface IDirectory
static ReadOnlyCollection<string[]> GetFilesCollection(string directory, string directorySearchFilter, string fileSearchFilter, bool useCeilingAverage) =>
XDirectory.GetFilesCollection(directory, directorySearchFilter, fileSearchFilter, useCeilingAverage);
ReadOnlyCollection<ReadOnlyCollection<FilePath>> TestStatic_GetFilePathCollections(Properties.IPropertyConfiguration propertyConfiguration, string directory, string directorySearchFilter, string fileSearchFilter, bool useCeilingAverage) =>
GetFilePathCollections(propertyConfiguration, directory, directorySearchFilter, fileSearchFilter, useCeilingAverage);
static ReadOnlyCollection<ReadOnlyCollection<FilePath>> GetFilePathCollections(Properties.IPropertyConfiguration propertyConfiguration, string directory, string directorySearchFilter, string fileSearchFilter, bool useCeilingAverage) =>
XDirectory.GetFilePathCollections(propertyConfiguration, directory, directorySearchFilter, fileSearchFilter, useCeilingAverage);
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<(FilePath, string)>) TestStatic_GetToDoCollection(Properties.IPropertyConfiguration propertyConfiguration, ReadOnlyCollection<string[]> filesCollection, string[] directories, Action? tick) =>
GetToDoCollection(propertyConfiguration, filesCollection, directories, 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<(FilePath, string)>) TestStatic_GetToDoCollection(Properties.IPropertyConfiguration propertyConfiguration, ReadOnlyCollection<ReadOnlyCollection<FilePath>> filePathsCollection, string[] directories, Action? tick) =>
GetToDoCollection(propertyConfiguration, filePathsCollection, directories, tick);
static (string[], List<(FilePath, string)>) GetToDoCollection(Properties.IPropertyConfiguration propertyConfiguration, ReadOnlyCollection<ReadOnlyCollection<FilePath>> filePathsCollection, string[] directories, Action? tick) =>
XDirectory.GetToDoCollection(propertyConfiguration, copyDuplicates: false, ifCanUseId: true, filePathsCollection, directories, 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<(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);
(string[], List<(FilePath, string)>) TestStatic_GetToDoCollection(Properties.IPropertyConfiguration propertyConfiguration, bool copyDuplicates, bool ifCanUseId, ReadOnlyCollection<ReadOnlyCollection<FilePath>> filePathsCollection, string[] directories, Action? tick) =>
GetToDoCollection(propertyConfiguration, copyDuplicates, ifCanUseId, filePathsCollection, directories, tick);
static (string[], List<(FilePath, string)>) GetToDoCollection(Properties.IPropertyConfiguration propertyConfiguration, bool copyDuplicates, bool ifCanUseId, ReadOnlyCollection<ReadOnlyCollection<FilePath>> filePathsCollection, string[] directories, Action? tick) =>
XDirectory.GetToDoCollection(propertyConfiguration, copyDuplicates, ifCanUseId, filePathsCollection, directories, 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<(FilePath, string)> toDoCollection, bool move, bool moveBack, Action? tick) =>
XDirectory.CopyOrMove(toDoCollection, move, moveBack, tick);
ReadOnlyCollection<ReadOnlyCollection<FilePath>> TestStatic_GetFilePathCollections(Properties.IPropertyConfiguration propertyConfiguration, ReadOnlyCollection<string[]> filesCollection) =>
GetFilePathCollections(propertyConfiguration, filesCollection);
static ReadOnlyCollection<ReadOnlyCollection<FilePath>> GetFilePathCollections(Properties.IPropertyConfiguration propertyConfiguration, ReadOnlyCollection<string[]> filesCollection) =>
XDirectory.GetFilePathCollections(propertyConfiguration, filesCollection);
}

View File

@ -0,0 +1,8 @@
namespace View_by_Distance.Shared.Models.Stateless.Methods;
public interface IDlibDotNet
{
void Tick();
}

View File

@ -0,0 +1,9 @@
namespace View_by_Distance.Shared.Models.Stateless.Methods;
public interface IFaceD
{
public string FileNameExtension { get; }
void ReSaveFace(ExifDirectory exifDirectory, FilePath filePath, Models.Face face, bool mappedFile);
}

View File

@ -28,6 +28,11 @@ public interface IFileHolder
static Models.FileHolder Get(string fileName) =>
Models.FileHolder.Get(new FileInfo(fileName));
Models.FileHolder TestStatic_Get(FileInfo fileInfo) =>
Get(fileInfo);
static Models.FileHolder Get(FileInfo fileInfo) =>
Models.FileHolder.Get(fileInfo);
Models.FileHolder TestStatic_Get(FilePath filePath) =>
Get(filePath);
static Models.FileHolder Get(FilePath filePath) =>

View File

@ -3,20 +3,25 @@ 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);
const int DeterministicHashCode = 9876543;
static bool IsOffsetDeterministicHashCode(Properties.IPropertyConfiguration propertyConfiguration) =>
propertyConfiguration.Offset == DeterministicHashCode;
string TestStatic_GetIntelligentId(Properties.IPropertyConfiguration propertyConfiguration, long id, bool? hasIgnoreKeyword, bool? hasDateTimeOriginal) =>
GetIntelligentId(propertyConfiguration, id, hasIgnoreKeyword, hasDateTimeOriginal);
static string GetIntelligentId(Properties.IPropertyConfiguration propertyConfiguration, long id, bool? hasIgnoreKeyword, bool? hasDateTimeOriginal) =>
Id.GetIntelligentId(propertyConfiguration, id, hasIgnoreKeyword, hasDateTimeOriginal);
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 id, bool? ignore, int? index) =>
GetPaddedId(propertyConfiguration, id, ignore, index);
static string GetPaddedId(Properties.IPropertyConfiguration propertyConfiguration, int id, bool? ignore, int? index) =>
Id.GetPaddedId(propertyConfiguration, id, ignore, index);
string TestStatic_GetPaddedId(Properties.IPropertyConfiguration propertyConfiguration, int id, bool? hasIgnoreKeyword, bool? hasDateTimeOriginal, int? index) =>
GetPaddedId(propertyConfiguration, id, hasIgnoreKeyword, hasDateTimeOriginal, index);
static string GetPaddedId(Properties.IPropertyConfiguration propertyConfiguration, int id, bool? hasIgnoreKeyword, bool? hasDateTimeOriginal, int? index) =>
Id.GetPaddedId(propertyConfiguration, id, hasIgnoreKeyword, hasDateTimeOriginal, index);
string TestStatic_GetIgnoreFullPath(FilePath filePath, Models.FileHolder fileHolder) =>
GetIgnoreFullPath(filePath, fileHolder);

View File

@ -10,9 +10,9 @@ public interface ILocation
static Models.Location? GetLocation(int height, Rectangle rectangle, int width) =>
Location.GetLocation(height, rectangle, width);
List<Models.Face> TestStatic_FilterByIntersect(Models.Face[] faces, float rectangleIntersectMinimum, int wholePercentages) =>
List<Models.Face> TestStatic_FilterByIntersect(List<Models.Face> faces, float rectangleIntersectMinimum, int wholePercentages) =>
FilterByIntersect(faces, rectangleIntersectMinimum, wholePercentages);
static List<Models.Face> FilterByIntersect(Models.Face[] faces, float rectangleIntersectMinimum, int wholePercentages) =>
static List<Models.Face> FilterByIntersect(List<Models.Face> faces, float rectangleIntersectMinimum, int wholePercentages) =>
Location.FilterByIntersect(faces, rectangleIntersectMinimum, wholePercentages);
RectangleF? TestStatic_GetPercentagesRectangle(DatabaseFile databaseFile, Marker marker, Models.OutputResolution outputResolution) =>
@ -25,10 +25,10 @@ public interface ILocation
static Models.Location? GetLocation(DatabaseFile databaseFile, Marker marker, Models.OutputResolution outputResolution) =>
Location.GetLocation(databaseFile, marker, outputResolution);
List<Models.Location> TestStatic_GetLocations(List<LocationContainer> locationContainers, List<Models.Face> faces, List<MappingFromPhotoPrism> mappingFromPhotoPrismCollection, float rectangleIntersectMinimum) =>
GetLocations(locationContainers, faces, mappingFromPhotoPrismCollection, rectangleIntersectMinimum);
static List<Models.Location> GetLocations(List<LocationContainer> locationContainers, List<Models.Face> faces, List<MappingFromPhotoPrism> mappingFromPhotoPrismCollection, float rectangleIntersectMinimum) =>
Location.GetLocations(locationContainers, faces, mappingFromPhotoPrismCollection, rectangleIntersectMinimum);
List<Models.Location> TestStatic_GetLocations(List<Models.Face> faces, List<MappingFromPhotoPrism> mappingFromPhotoPrismCollection, float rectangleIntersectMinimum) =>
GetLocations(faces, mappingFromPhotoPrismCollection, rectangleIntersectMinimum);
static List<Models.Location> GetLocations(List<Models.Face> faces, List<MappingFromPhotoPrism> mappingFromPhotoPrismCollection, float rectangleIntersectMinimum) =>
Location.GetLocations(faces, mappingFromPhotoPrismCollection, rectangleIntersectMinimum);
RectangleF? TestStatic_GetPercentagesRectangle(int locationDigits, int wholePercentages) =>
GetPercentagesRectangle(locationDigits, wholePercentages);

View File

@ -1,3 +1,5 @@
using System.Collections.ObjectModel;
namespace View_by_Distance.Shared.Models.Stateless.Methods;
public interface IPersonContainer
@ -5,9 +7,9 @@ public interface IPersonContainer
// ...
List<long> TestStatic_GetPersonKeys(IEnumerable<Models.PersonContainer> personContainers) =>
List<long> TestStatic_GetPersonKeys(ReadOnlyCollection<Models.PersonContainer> personContainers) =>
GetPersonKeys(personContainers);
static List<long> GetPersonKeys(IEnumerable<Models.PersonContainer> personContainers) =>
static List<long> GetPersonKeys(ReadOnlyCollection<Models.PersonContainer> personContainers) =>
PersonContainer.GetPersonKeys(personContainers);
List<Models.PersonContainer> TestStatic_GetPersonContainers(string a2PeopleSingletonDirectory, string personBirthdayFormat, char[] personCharacters, Properties.IPropertyConfiguration propertyConfiguration, string facesFileNameExtension) =>

View File

@ -43,9 +43,9 @@ public interface IProperty
static List<DateTime> GetDateTimes(Models.Property property) =>
Property.GetDateTimes(property.CreationTime, property.LastWriteTime, property.DateTime, property.DateTimeDigitized, property.DateTimeFromName, property.DateTimeOriginal, property.GPSDateStamp);
double TestStatic_GetStandardDeviation(IEnumerable<long> values, double average) =>
double TestStatic_GetStandardDeviation(List<long> values, double average) =>
GetStandardDeviation(values, average);
static double GetStandardDeviation(IEnumerable<long> values, double average) =>
static double GetStandardDeviation(List<long> values, double average) =>
Property.GetStandardDeviation(values, average);
TimeSpan TestStatic_GetThreeStandardDeviationHigh(int minimum, Models.Container container) =>

View File

@ -35,23 +35,25 @@ internal abstract class Id
return result;
}
internal static string GetIntelligentId(Properties.IPropertyConfiguration propertyConfiguration, long id, bool? ignore)
internal static string GetIntelligentId(Properties.IPropertyConfiguration propertyConfiguration, long id, bool? hasIgnoreKeyword, bool? hasDateTimeOriginal)
{
string result;
StringBuilder stringBuilder = new();
if (propertyConfiguration.IntMinValueLength < (propertyConfiguration.ResultAllInOneSubdirectoryLength + 2))
throw new NotSupportedException();
if (hasDateTimeOriginal is null)
{ }
int key;
string value;
List<char> resultAllInOneSubdirectoryChars = [];
if (id > -1)
{
key = ignore is not null && ignore.Value ? 8 : 9;
key = hasIgnoreKeyword is not null && hasIgnoreKeyword.Value ? 8 : 9;
value = id.ToString().PadLeft(propertyConfiguration.IntMinValueLength, '0');
}
else
{
key = ignore is not null && ignore.Value ? 2 : 1;
key = hasIgnoreKeyword is not null && hasIgnoreKeyword.Value ? 2 : 1;
value = id.ToString()[1..].PadLeft(propertyConfiguration.IntMinValueLength, '0');
}
for (int i = value.Length - propertyConfiguration.ResultAllInOneSubdirectoryLength - 1; i > -1; i--)
@ -62,18 +64,18 @@ internal abstract class Id
return result;
}
internal static string GetPaddedId(Properties.IPropertyConfiguration propertyConfiguration, int id, bool? ignore, int? index)
internal static string GetPaddedId(Properties.IPropertyConfiguration propertyConfiguration, int id, bool? hasIgnoreKeyword, bool? hasDateTimeOriginal, int? index)
{
string result;
if (propertyConfiguration.Offset < 0)
result = Guid.NewGuid().ToString();
else
{
string intelligentId = GetIntelligentId(propertyConfiguration, id, ignore);
string intelligentId = GetIntelligentId(propertyConfiguration, id, hasIgnoreKeyword, hasDateTimeOriginal);
int check = GetId(propertyConfiguration, intelligentId);
if (check != id)
throw new NotSupportedException();
result = index is null || propertyConfiguration.Offset == 9876543 ? intelligentId : $"{propertyConfiguration.Offset + index}{intelligentId}";
result = index is null || propertyConfiguration.Offset == IId.DeterministicHashCode ? intelligentId : $"{propertyConfiguration.Offset + index}{intelligentId}";
}
return result;
}

View File

@ -245,7 +245,7 @@ internal abstract class Location
return result;
}
internal static List<Models.Location> GetLocations(List<LocationContainer> locationContainers, List<Models.Face> faces, List<MappingFromPhotoPrism> mappingFromPhotoPrismCollection, float rectangleIntersectMinimum)
internal static List<Models.Location> GetLocations(List<Models.Face> faces, List<MappingFromPhotoPrism> mappingFromPhotoPrismCollection, float rectangleIntersectMinimum)
{
List<Models.Location> results = [];
bool any;
@ -266,12 +266,6 @@ internal abstract class Location
outputResolution ??= face.OutputResolution;
}
int before = results.Count;
foreach (LocationContainer locationContainer in locationContainers)
{
if (locationContainer.Location is null)
continue;
results.Add(locationContainer.Location);
}
foreach (MappingFromPhotoPrism mappingFromPhotoPrism in mappingFromPhotoPrismCollection)
{
if (outputResolution is null)
@ -289,19 +283,6 @@ internal abstract class Location
location = GetLocation(mappingFromPhotoPrism.DatabaseFile, marker, prismRectangle.Value);
if (location is null)
break;
foreach (LocationContainer locationContainer in locationContainers)
{
if (any)
continue;
if (locationContainer.Rectangle is null)
continue;
percent = GetIntersectPercent(prismRectangle.Value, prismArea, locationContainer.Rectangle.Value);
if (percent is null || percent < rectangleIntersectMinimum)
continue;
if (!any)
any = true;
break;
}
foreach (Models.Face face in faces)
{
if (any)
@ -329,7 +310,7 @@ internal abstract class Location
return results;
}
internal static List<Models.Face> FilterByIntersect(Models.Face[] faces, float rectangleIntersectMinimum, int wholePercentages)
internal static List<Models.Face> FilterByIntersect(List<Models.Face> faces, float rectangleIntersectMinimum, int wholePercentages)
{
List<Models.Face> results = [];
float? percent;

View File

@ -1,3 +1,5 @@
using System.Collections.ObjectModel;
namespace View_by_Distance.Shared.Models.Stateless.Methods;
internal abstract class PersonContainer
@ -313,7 +315,7 @@ internal abstract class PersonContainer
return results;
}
internal static List<long> GetPersonKeys(IEnumerable<Models.PersonContainer> personContainers)
internal static List<long> GetPersonKeys(ReadOnlyCollection<Models.PersonContainer> personContainers)
{
List<long> results = [];
long personKey;

View File

@ -166,13 +166,13 @@ internal abstract class Property
return result;
}
internal static double GetStandardDeviation(IEnumerable<long> values, double average)
internal static double GetStandardDeviation(List<long> values, double average)
{
double result = 0;
if (!values.Any())
if (values.Count == 0)
throw new Exception("Collection must have at least one value!");
double sum = values.Sum(l => (l - average) * (l - average));
result = Math.Sqrt(sum / values.Count());
result = Math.Sqrt(sum / values.Count);
return result;
}

View File

@ -54,6 +54,14 @@ internal abstract partial class XDirectory
return new(results);
}
internal static ReadOnlyCollection<ReadOnlyCollection<FilePath>> GetFilePathCollections(Properties.IPropertyConfiguration propertyConfiguration, string directory, string directorySearchFilter, string fileSearchFilter, bool useCeilingAverage)
{
ReadOnlyCollection<ReadOnlyCollection<FilePath>> results;
ReadOnlyCollection<string[]> filesCollection = GetFilesCollection(directory, directorySearchFilter, fileSearchFilter, useCeilingAverage);
results = IDirectory.GetFilePathCollections(propertyConfiguration, filesCollection);
return results;
}
internal static IReadOnlyDictionary<string, List<string>> GetFilesKeyValuePairs(ReadOnlyCollection<string[]> filesCollection)
{
Dictionary<string, List<string>> results = [];
@ -76,6 +84,26 @@ internal abstract partial class XDirectory
return results;
}
internal static IReadOnlyDictionary<string, List<string>> GetFilesKeyValuePairs(ReadOnlyCollection<ReadOnlyCollection<FilePath>> filePathsCollection)
{
Dictionary<string, List<string>> results = [];
List<string>? collection;
foreach (ReadOnlyCollection<FilePath> filePaths in filePathsCollection)
{
foreach (FilePath filePath in filePaths)
{
if (!results.TryGetValue(filePath.Name, out collection))
{
results.Add(filePath.Name, []);
if (!results.TryGetValue(filePath.Name, out collection))
throw new Exception();
}
collection.Add(filePath.FullName);
}
}
return results;
}
internal static int LookForAbandoned(ReadOnlyCollection<string[]> jsonFilesCollection, IReadOnlyDictionary<string, List<string>> fileNamesToFiles, string extension)
{
string fileName;
@ -147,37 +175,37 @@ internal abstract partial class XDirectory
return result;
}
internal static List<FilePair> GetFiles(ReadOnlyCollection<string[]> filesCollection, IReadOnlyDictionary<string, List<string>> fileNamesToFiles, string extension, IReadOnlyDictionary<string, List<string>> compareFileNamesToFiles)
internal static List<FilePair> GetFiles(Properties.IPropertyConfiguration propertyConfiguration, ReadOnlyCollection<ReadOnlyCollection<FilePath>> filePathsCollection, IReadOnlyDictionary<string, List<string>> fileNamesToFiles, string extension, IReadOnlyDictionary<string, List<string>> compareFileNamesToFiles)
{
List<FilePair> results = [];
string? match;
string fileName;
bool uniqueFileName;
List<string>? collection;
bool? isNotUniqueAndNeedsReview;
foreach (string[] files in filesCollection)
foreach (ReadOnlyCollection<FilePath> filePaths in filePathsCollection)
{
foreach (string file in files)
foreach (FilePath filePath in filePaths)
{
isNotUniqueAndNeedsReview = null;
fileName = Path.GetFileName(file);
if (!fileNamesToFiles.TryGetValue(fileName, out collection))
if (propertyConfiguration.IgnoreExtensions.Contains(filePath.ExtensionLowered))
continue;
if (!fileNamesToFiles.TryGetValue(filePath.Name, out collection))
throw new Exception();
uniqueFileName = collection.Count == 1;
if (!uniqueFileName)
isNotUniqueAndNeedsReview = GetIsNotUniqueAndNeedsReview(file, collection);
if (!compareFileNamesToFiles.TryGetValue(string.Concat(fileName, extension), out collection))
results.Add(new(file, uniqueFileName, isNotUniqueAndNeedsReview, [], null));
isNotUniqueAndNeedsReview = GetIsNotUniqueAndNeedsReview(filePath.FullName, collection);
if (!compareFileNamesToFiles.TryGetValue(string.Concat(filePath.Name, extension), out collection))
results.Add(new(filePath.FullName, uniqueFileName, isNotUniqueAndNeedsReview, [], null));
else
{
if (collection.Count == 0)
results.Add(new(file, uniqueFileName, isNotUniqueAndNeedsReview, collection, null));
results.Add(new(filePath.FullName, uniqueFileName, isNotUniqueAndNeedsReview, collection, null));
else if (uniqueFileName && collection.Count == 1)
results.Add(new(file, uniqueFileName, isNotUniqueAndNeedsReview, collection, collection.First()));
results.Add(new(filePath.FullName, uniqueFileName, isNotUniqueAndNeedsReview, collection, collection.First()));
else
{
match = GetMatch(file, collection);
results.Add(new(file, uniqueFileName, isNotUniqueAndNeedsReview, collection, match));
match = GetMatch(filePath.FullName, collection);
results.Add(new(filePath.FullName, uniqueFileName, isNotUniqueAndNeedsReview, collection, match));
}
}
}
@ -260,29 +288,46 @@ internal abstract partial class XDirectory
continue;
checkFile = file.Replace(find, replace);
if (File.Exists(checkFile))
{
File.Delete(checkFile);
continue;
}
File.Move(file, checkFile);
}
}
private static FilePath[] GetSortedRecords(Properties.IPropertyConfiguration propertyConfiguration, ReadOnlyCollection<string[]> filesCollection)
private static FilePath[] GetSortedRecords(ReadOnlyCollection<ReadOnlyCollection<FilePath>> filePathsCollection)
{
List<FilePath> results = [];
FilePath filePath;
Models.FileHolder fileHolder;
foreach (string[] files in filesCollection)
foreach (ReadOnlyCollection<FilePath> filePaths in filePathsCollection)
{
foreach (string file in files)
{
fileHolder = IFileHolder.Get(file);
filePath = FilePath.Get(propertyConfiguration, fileHolder, index: null);
foreach (FilePath filePath in filePaths)
results.Add(filePath);
}
}
return (from l in results orderby l.CreationTicks, l.FullName.Length descending select l).ToArray();
}
internal static (string[], List<(FilePath, string)>) GetToDoCollection(Properties.IPropertyConfiguration propertyConfiguration, bool copyDuplicates, bool ifCanUseId, ReadOnlyCollection<string[]> filesCollection, string[] directories, Action? tick)
internal static ReadOnlyCollection<ReadOnlyCollection<FilePath>> GetFilePathCollections(Properties.IPropertyConfiguration propertyConfiguration, ReadOnlyCollection<string[]> filesCollection)
{
List<ReadOnlyCollection<FilePath>> results = [];
FilePath filePath;
List<FilePath> filePaths;
Models.FileHolder fileHolder;
foreach (string[] files in filesCollection)
{
filePaths = [];
foreach (string file in files)
{
fileHolder = IFileHolder.Get(file);
filePath = FilePath.Get(propertyConfiguration, fileHolder, index: null);
filePaths.Add(filePath);
}
results.Add(new(filePaths));
}
return new(results);
}
internal static (string[], List<(FilePath, string)>) GetToDoCollection(Properties.IPropertyConfiguration propertyConfiguration, bool copyDuplicates, bool ifCanUseId, ReadOnlyCollection<ReadOnlyCollection<FilePath>> filePathsCollection, string[] directories, Action? tick)
{
List<(FilePath, string)> results = [];
string paddedId;
@ -300,7 +345,8 @@ internal abstract partial class XDirectory
List<string> distinct = [];
Models.FileHolder fileHolder;
List<string> distinctDirectories = [];
FilePath[] sortedRecords = GetSortedRecords(propertyConfiguration, filesCollection);
FilePath[] sortedRecords = GetSortedRecords(filePathsCollection);
bool isOffsetDeterministicHashCode = IId.IsOffsetDeterministicHashCode(propertyConfiguration);
for (int i = 0; i < sortedRecords.Length; i++)
{
tick?.Invoke();
@ -323,7 +369,7 @@ internal abstract partial class XDirectory
}
if (ifCanUseId && filePath.IsIntelligentIdFormat && filePath.Id is not null && filePath.DirectoryName is not null)
{
paddedId = IId.GetPaddedId(propertyConfiguration, filePath.Id.Value, filePath.IsIgnore, i);
paddedId = IId.GetPaddedId(propertyConfiguration, filePath.Id.Value, filePath.HasIgnoreKeyword, filePath.HasDateTimeOriginal, i);
paddedIdFile = Path.Combine(filePath.DirectoryName, $"{paddedId}{filePath.ExtensionLowered}");
if (!File.Exists(paddedIdFile))
{
@ -341,8 +387,22 @@ internal abstract partial class XDirectory
{
if (filePath.Id is null)
throw new NullReferenceException(nameof(filePath.Id));
intelligentId = IId.GetIntelligentId(propertyConfiguration, filePath.Id.Value, filePath.IsIgnore);
checkFile = Path.Combine(directory, $"{intelligentId}{filePath.ExtensionLowered}");
intelligentId = IId.GetIntelligentId(propertyConfiguration, filePath.Id.Value, filePath.HasIgnoreKeyword, filePath.HasDateTimeOriginal);
if (!isOffsetDeterministicHashCode)
checkFile = Path.Combine(directory, $"{intelligentId}{filePath.ExtensionLowered}");
else
{
if (filePath.DirectoryName is null)
continue;
paddedId = IId.GetPaddedId(propertyConfiguration, filePath.Id.Value, filePath.HasIgnoreKeyword, filePath.HasDateTimeOriginal, i);
paddedIdFile = Path.Combine(filePath.DirectoryName, $"{paddedId}{filePath.ExtensionLowered}");
if (File.Exists(paddedIdFile))
continue;
File.Move(filePath.FullName, paddedIdFile);
if (!paddedCheck)
paddedCheck = true;
continue;
}
}
if ((filePath.Id is not null && distinctIds.Contains(filePath.Id.Value)) || distinct.Contains(checkFile))
{
@ -380,6 +440,8 @@ internal abstract partial class XDirectory
if (!distinctDirectories.Contains(directory))
distinctDirectories.Add(directory);
}
if (!isOffsetDeterministicHashCode)
throw new Exception("Change Configuration Offset after creating iso file with images sorted!");
if (paddedCheck)
throw new Exception("Maybe need to restart application!");
return (distinctDirectories.ToArray(), results);