added-numbers-to-distinguish-has-ignore-keyword-and-has-date-time-original
moved-container-to-new-project-to-prepare-to-remove-property-file added-logic-to-rename-to-3-and-7-like-should-ignore-for-missing-date-time-original
This commit is contained in:
@ -1,302 +0,0 @@
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Text.Json;
|
||||
|
||||
namespace View_by_Distance.Shared.Models.Stateless.Methods;
|
||||
|
||||
internal abstract class Container
|
||||
{
|
||||
|
||||
private record FilePair(bool IsUnique, List<string> Collection, FilePath FilePath, Models.Item Item) { }
|
||||
|
||||
internal static DateTime[] GetContainerDateTimes(ReadOnlyCollection<Models.Item> items)
|
||||
{
|
||||
DateTime[] results;
|
||||
long containerMinimumTicks = (from l in items select l.FilePath.LastWriteTicks).Min();
|
||||
long containerMaximumTicks = (from l in items select l.FilePath.LastWriteTicks).Max();
|
||||
results = [new(containerMinimumTicks), new(containerMaximumTicks)];
|
||||
return results;
|
||||
}
|
||||
|
||||
internal static ReadOnlyCollection<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))
|
||||
continue;
|
||||
results.Add(item);
|
||||
}
|
||||
return container.Items.Count == results.Count ? container.Items : results.AsReadOnly();
|
||||
}
|
||||
|
||||
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(filePathsCollection);
|
||||
for (int i = 0; i < short.MaxValue; i++)
|
||||
{
|
||||
renamed = 0;
|
||||
jsonFilesCollection = IDirectory.GetFilesCollection(aPropertySingletonDirectory, directorySearchFilter, extension, useCeilingAverage);
|
||||
compareFileNamesToFiles = XDirectory.GetFilesKeyValuePairs(jsonFilesCollection);
|
||||
renamed += XDirectory.LookForAbandoned(jsonFilesCollection, fileNamesToFiles, extension);
|
||||
filePairs = XDirectory.GetFiles(propertyConfiguration, filePathsCollection, fileNamesToFiles, extension, compareFileNamesToFiles);
|
||||
renamed += XDirectory.MaybeMove(propertyConfiguration, filePairs, aPropertySingletonDirectory, extension);
|
||||
if (renamed == 0)
|
||||
break;
|
||||
if (i > 10)
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
if (filePairs is null || jsonFilesCollection is null || compareFileNamesToFiles is null)
|
||||
throw new NullReferenceException(nameof(filePairs));
|
||||
return filePairs;
|
||||
}
|
||||
|
||||
private static Models.Property? GetProperty(Models.FilePair filePair)
|
||||
{
|
||||
Models.Property? result;
|
||||
if (filePair.Match is null)
|
||||
result = null;
|
||||
else
|
||||
{
|
||||
string json = File.ReadAllText(filePair.Match);
|
||||
if (string.IsNullOrEmpty(json))
|
||||
result = null;
|
||||
else
|
||||
result = JsonSerializer.Deserialize(json, PropertyGenerationContext.Default.Property);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private static void MoveIf(string fileName, CombinedEnumAndIndex cei, string directory, string fullFileName)
|
||||
{
|
||||
string[] segments = directory.Split(cei.Combined);
|
||||
string? checkDirectory = segments.Length == 1 ?
|
||||
Path.Combine(segments[0], $"{cei.Combined[2..]}") :
|
||||
segments.Length == 2 ?
|
||||
$"{segments[0]}{cei.Combined[2..]}{segments[1]}" :
|
||||
null;
|
||||
if (checkDirectory is not null && Directory.Exists(checkDirectory))
|
||||
{
|
||||
string checkFile = Path.Combine(checkDirectory, fileName);
|
||||
if (File.Exists(checkFile))
|
||||
File.Move(checkFile, fullFileName);
|
||||
}
|
||||
}
|
||||
|
||||
private static void ParallelFor(IDlibDotNet? dlibDotNet, Properties.IPropertyConfiguration propertyConfiguration, string aPropertySingletonDirectory, string extension, int rootDirectoryLength, ReadOnlyDictionary<int, Identifier>? splatNineIdentifiers, Models.FilePair filePair, List<FilePair> results)
|
||||
{
|
||||
dlibDotNet?.Tick();
|
||||
bool abandoned = false;
|
||||
Models.FileHolder sourceDirectoryFileHolder;
|
||||
Models.Property? property = GetProperty(filePair);
|
||||
Models.FileHolder imageFileHolder = IFileHolder.Get(filePair.Path);
|
||||
FilePath filePath = FilePath.Get(propertyConfiguration, imageFileHolder, index: null);
|
||||
bool? fileSizeChanged = property is not null ? property.FileSize != filePath.Length : null;
|
||||
bool isValidImageFormatExtension = propertyConfiguration.ValidImageFormatExtensions.Contains(filePath.ExtensionLowered);
|
||||
bool? shouldIgnore = property is null || property.Keywords is null ? null : propertyConfiguration.IgnoreRulesKeyWords.Any(l => property.Keywords.Contains(l));
|
||||
bool? isArchive = filePath.Id is null || splatNineIdentifiers is null ? null : splatNineIdentifiers.TryGetValue(filePath.Id.Value, out Identifier? identifier);
|
||||
if (shouldIgnore is not null)
|
||||
{
|
||||
if (shouldIgnore.Value)
|
||||
{
|
||||
FileInfo fileInfo = new(filePath.FullName);
|
||||
if (!fileInfo.Attributes.HasFlag(FileAttributes.Hidden))
|
||||
File.SetAttributes(imageFileHolder.FullName, FileAttributes.Hidden);
|
||||
}
|
||||
if (filePath.HasIgnoreKeyword is not null && filePath.HasIgnoreKeyword.Value != shouldIgnore.Value)
|
||||
{
|
||||
if (filePath.DirectoryFullPath.Contains("Results") && filePath.DirectoryFullPath.Contains("Resize"))
|
||||
File.Delete(filePath.FullName);
|
||||
else
|
||||
throw new NotSupportedException($"Rename File! <{filePath.FileNameFirstSegment}>");
|
||||
}
|
||||
}
|
||||
string relativePath = IPath.GetRelativePath(filePair.Path, rootDirectoryLength, forceExtensionToLower: true);
|
||||
bool? lastWriteTimeChanged = property is not null ? propertyConfiguration.PropertiesChangedForProperty || property.LastWriteTime.Ticks != filePath.LastWriteTicks : null;
|
||||
if (filePair.Match is not null)
|
||||
sourceDirectoryFileHolder = IFileHolder.Get(filePair.Match);
|
||||
else if (!filePair.IsUnique)
|
||||
sourceDirectoryFileHolder = IFileHolder.Get(Path.GetFullPath(string.Concat(aPropertySingletonDirectory, relativePath, extension)));
|
||||
else
|
||||
{
|
||||
string fileName = Path.GetFileName(filePair.Path);
|
||||
CombinedEnumAndIndex cei = IPath.GetCombinedEnumAndIndex(propertyConfiguration, filePath);
|
||||
string directory = Path.Combine(aPropertySingletonDirectory, cei.Combined);
|
||||
string jsonFileName = $"{fileName}{extension}";
|
||||
string fullFileName = Path.Combine(directory, jsonFileName);
|
||||
MoveIf(jsonFileName, cei, directory, fullFileName);
|
||||
sourceDirectoryFileHolder = IFileHolder.Get(fullFileName);
|
||||
}
|
||||
if (sourceDirectoryFileHolder.CreationTime is not null && sourceDirectoryFileHolder.LastWriteTime is not null && filePath.LastWriteTicks != sourceDirectoryFileHolder.CreationTime.Value.Ticks)
|
||||
{
|
||||
File.SetCreationTime(sourceDirectoryFileHolder.FullName, new(filePath.LastWriteTicks));
|
||||
File.SetLastWriteTime(sourceDirectoryFileHolder.FullName, sourceDirectoryFileHolder.LastWriteTime.Value);
|
||||
}
|
||||
Models.Item item = Models.Item.Get(filePath, sourceDirectoryFileHolder, relativePath, isArchive, filePair.IsNotUniqueAndNeedsReview, filePair.IsUnique, isValidImageFormatExtension, property, abandoned, fileSizeChanged, lastWriteTimeChanged);
|
||||
lock (results)
|
||||
results.Add(new(filePair.IsUnique, filePair.Collection, filePath, item));
|
||||
}
|
||||
|
||||
private static List<FilePair> GetFilePairs(IDlibDotNet? dlibDotNet, Properties.IPropertyConfiguration propertyConfiguration, string aPropertySingletonDirectory, string filesCollectionDirectory, ReadOnlyDictionary<int, Identifier>? splatNineIdentifiers, 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, filePathsCollection);
|
||||
_ = Parallel.For(0, filePairs.Count, parallelOptions, (i, state) => ParallelFor(dlibDotNet, propertyConfiguration, aPropertySingletonDirectory, extension, filesCollectionDirectoryLength, splatNineIdentifiers, filePairs[i], results));
|
||||
return results;
|
||||
}
|
||||
|
||||
private static (int, Models.Container[]) GetContainers(IDlibDotNet? dlibDotNet, Properties.IPropertyConfiguration propertyConfiguration, string aPropertySingletonDirectory, string filesCollectionDirectory, ReadOnlyDictionary<int, Identifier>? splatNineIdentifiers, ReadOnlyCollection<ReadOnlyCollection<FilePath>> filePathsCollection, string directorySearchFilter)
|
||||
{
|
||||
List<Models.Container> results = [];
|
||||
string directory;
|
||||
List<Models.Item>? items;
|
||||
Models.Container container;
|
||||
List<string> directories = [];
|
||||
Dictionary<string, List<Models.Item>> directoryToItems = [];
|
||||
foreach (ReadOnlyCollection<FilePath> filePaths in filePathsCollection)
|
||||
{
|
||||
if (filePaths.Count == 0)
|
||||
continue;
|
||||
directory = filePaths[0].DirectoryFullPath;
|
||||
if (directory is null)
|
||||
continue;
|
||||
if (!directories.Contains(directory))
|
||||
directories.Add(directory);
|
||||
if (!directoryToItems.TryGetValue(directory, out items))
|
||||
{
|
||||
directoryToItems.Add(directory, []);
|
||||
if (!directoryToItems.TryGetValue(directory, out items))
|
||||
throw new Exception();
|
||||
}
|
||||
}
|
||||
List<FilePair> filePairs = GetFilePairs(dlibDotNet, propertyConfiguration, aPropertySingletonDirectory, filesCollectionDirectory, splatNineIdentifiers, filePathsCollection, directorySearchFilter);
|
||||
foreach (FilePair filePair in filePairs)
|
||||
{
|
||||
if (!directoryToItems.TryGetValue(filePair.FilePath.DirectoryFullPath, out items))
|
||||
{
|
||||
directoryToItems.Add(filePair.FilePath.DirectoryFullPath, []);
|
||||
if (!directoryToItems.TryGetValue(filePair.FilePath.DirectoryFullPath, out items))
|
||||
throw new Exception();
|
||||
}
|
||||
items.Add(filePair.Item);
|
||||
}
|
||||
foreach (KeyValuePair<string, List<Models.Item>> keyValuePair in directoryToItems)
|
||||
{
|
||||
if (keyValuePair.Value.Count == 0)
|
||||
continue;
|
||||
container = new(keyValuePair.Key, new(keyValuePair.Value));
|
||||
results.Add(container);
|
||||
}
|
||||
return (filePairs.Count, results.ToArray());
|
||||
}
|
||||
|
||||
internal static ReadOnlyCollection<Models.Container> GetContainers(IDlibDotNet dlibDotNet, Properties.IPropertyConfiguration propertyConfiguration, string aPropertySingletonDirectory, string filesCollectionDirectory, ReadOnlyDictionary<int, Identifier>? splatNineIdentifiers, ReadOnlyCollection<ReadOnlyCollection<FilePath>> filePathsCollection)
|
||||
{
|
||||
Models.Container[] results;
|
||||
const string directorySearchFilter = "*";
|
||||
(_, results) = GetContainers(dlibDotNet, propertyConfiguration, aPropertySingletonDirectory, filesCollectionDirectory, splatNineIdentifiers, filePathsCollection, directorySearchFilter);
|
||||
return results.AsReadOnly();
|
||||
}
|
||||
|
||||
internal static (int, Models.Container[]) GetContainers(Properties.IPropertyConfiguration propertyConfiguration, ReadOnlyDictionary<int, Identifier>? splatNineIdentifiers, 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);
|
||||
ReadOnlyCollection<ReadOnlyCollection<FilePath>> filePathsCollection = IDirectory.GetFilePathCollections(propertyConfiguration, filesCollection);
|
||||
(count, results) = GetContainers(dlibDotNet, propertyConfiguration, aPropertySingletonDirectory, propertyConfiguration.RootDirectory, splatNineIdentifiers, filePathsCollection, directorySearchFilter);
|
||||
return (count, results);
|
||||
}
|
||||
|
||||
internal static List<int> GetFilteredDistinctIds(Properties.IPropertyConfiguration propertyConfiguration, ReadOnlyCollection<Models.Container> readOnlyContainers)
|
||||
{
|
||||
List<int> 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.Property.Id.Value))
|
||||
continue;
|
||||
results.Add(item.Property.Id.Value);
|
||||
}
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
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 = [];
|
||||
ReadOnlyCollection<Models.Item> filteredItems;
|
||||
foreach (Models.Container container in containers)
|
||||
{
|
||||
if (container.Items.Count == 0)
|
||||
continue;
|
||||
if (!filterItems)
|
||||
filteredItems = container.Items;
|
||||
else
|
||||
{
|
||||
filteredItems = GetValidImageItems(propertyConfiguration, container);
|
||||
if (filteredItems.Count == 0)
|
||||
continue;
|
||||
}
|
||||
foreach (Models.Item item in filteredItems)
|
||||
{
|
||||
if (item.Property?.Id is null || item.ResizedFileHolder is null)
|
||||
continue;
|
||||
if (distinctItems)
|
||||
{
|
||||
if (distinct.Contains(item.Property.Id.Value))
|
||||
continue;
|
||||
distinct.Add(item.Property.Id.Value);
|
||||
}
|
||||
results.Add(item);
|
||||
}
|
||||
}
|
||||
return results.AsReadOnly();
|
||||
}
|
||||
|
||||
}
|
@ -1,48 +0,0 @@
|
||||
using System.Collections.ObjectModel;
|
||||
|
||||
namespace View_by_Distance.Shared.Models.Stateless.Methods;
|
||||
|
||||
public interface IContainer
|
||||
{
|
||||
|
||||
DateTime[] TestStatic_GetContainerDateTimes(ReadOnlyCollection<Models.Item> items) =>
|
||||
GetContainerDateTimes(items);
|
||||
static DateTime[] GetContainerDateTimes(ReadOnlyCollection<Models.Item> items) =>
|
||||
Container.GetContainerDateTimes(items);
|
||||
|
||||
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) =>
|
||||
GetContainers(propertyConfiguration, null, aPropertySingletonDirectory);
|
||||
|
||||
(int, Models.Container[]) TestStatic_GetContainers(Properties.IPropertyConfiguration propertyConfiguration, ReadOnlyDictionary<int, Identifier>? splatNineIdentifiers, string aPropertySingletonDirectory) =>
|
||||
GetContainers(propertyConfiguration, splatNineIdentifiers, aPropertySingletonDirectory);
|
||||
static (int, Models.Container[]) GetContainers(Properties.IPropertyConfiguration propertyConfiguration, ReadOnlyDictionary<int, Identifier>? splatNineIdentifiers, string aPropertySingletonDirectory) =>
|
||||
Container.GetContainers(propertyConfiguration, splatNineIdentifiers, aPropertySingletonDirectory);
|
||||
|
||||
ReadOnlyCollection<Models.Container> TestStatic_GetContainers(IDlibDotNet dlibDotNet, Properties.IPropertyConfiguration propertyConfiguration, string aPropertySingletonDirectory, string filesCollectionDirectory, ReadOnlyDictionary<int, Identifier>? splatNineIdentifiers, ReadOnlyCollection<ReadOnlyCollection<FilePath>> filePathsCollection) =>
|
||||
GetContainers(dlibDotNet, propertyConfiguration, aPropertySingletonDirectory, filesCollectionDirectory, splatNineIdentifiers, filePathsCollection);
|
||||
static ReadOnlyCollection<Models.Container> GetContainers(IDlibDotNet dlibDotNet, Properties.IPropertyConfiguration propertyConfiguration, string aPropertySingletonDirectory, string filesCollectionDirectory, ReadOnlyDictionary<int, Identifier>? splatNineIdentifiers, ReadOnlyCollection<ReadOnlyCollection<FilePath>> filePathsCollection) =>
|
||||
Container.GetContainers(dlibDotNet, propertyConfiguration, aPropertySingletonDirectory, filesCollectionDirectory, splatNineIdentifiers, 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);
|
||||
|
||||
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);
|
||||
|
||||
}
|
@ -50,4 +50,14 @@ public interface IDirectory
|
||||
static ReadOnlyCollection<ReadOnlyCollection<FilePath>> GetFilePathCollections(Properties.IPropertyConfiguration propertyConfiguration, ReadOnlyCollection<string[]> filesCollection) =>
|
||||
XDirectory.GetFilePathCollections(propertyConfiguration, filesCollection);
|
||||
|
||||
List<FilePair> TestStatic_GetFiles(Properties.IPropertyConfiguration propertyConfiguration, ReadOnlyCollection<ReadOnlyCollection<FilePath>> filePathsCollection, IReadOnlyDictionary<string, List<string>> fileNamesToFiles, IReadOnlyDictionary<string, List<string>> compareFileNamesToFiles) =>
|
||||
GetFiles(propertyConfiguration, filePathsCollection, fileNamesToFiles, compareFileNamesToFiles);
|
||||
static List<FilePair> GetFiles(Properties.IPropertyConfiguration propertyConfiguration, ReadOnlyCollection<ReadOnlyCollection<FilePath>> filePathsCollection, IReadOnlyDictionary<string, List<string>> fileNamesToFiles, IReadOnlyDictionary<string, List<string>> compareFileNamesToFiles) =>
|
||||
XDirectory.GetFiles(propertyConfiguration, filePathsCollection, fileNamesToFiles, compareFileNamesToFiles);
|
||||
|
||||
int TestStatic_MaybeMove(Properties.IPropertyConfiguration propertyConfiguration, List<FilePair> filePairs, string jsonGroupDirectory, string extension) =>
|
||||
MaybeMove(propertyConfiguration, filePairs, jsonGroupDirectory, extension);
|
||||
static int MaybeMove(Properties.IPropertyConfiguration propertyConfiguration, List<FilePair> filePairs, string jsonGroupDirectory, string extension) =>
|
||||
XDirectory.MaybeMove(propertyConfiguration, filePairs, jsonGroupDirectory, extension);
|
||||
|
||||
}
|
@ -4,5 +4,7 @@ public interface IDlibDotNet
|
||||
{
|
||||
|
||||
void Tick();
|
||||
(string, string) GetResultsFullGroupDirectories();
|
||||
(string, string, string, string) GetResultsFullGroupDirectories(string outputResolution);
|
||||
|
||||
}
|
@ -23,29 +23,16 @@ public interface IId
|
||||
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);
|
||||
static string GetIgnoreFullPath(FilePath filePath, Models.FileHolder fileHolder) =>
|
||||
fileHolder.DirectoryFullPath is null ?
|
||||
throw new NotSupportedException() :
|
||||
filePath.Id > -1 ?
|
||||
fileHolder.NameWithoutExtension[^1] == '9' ?
|
||||
Path.Combine(fileHolder.DirectoryFullPath, $"{fileHolder.NameWithoutExtension[..^1]}8{fileHolder.ExtensionLowered}") :
|
||||
throw new NotSupportedException("High") :
|
||||
fileHolder.NameWithoutExtension[^1] == '1' ?
|
||||
Path.Combine(fileHolder.DirectoryFullPath, $"{fileHolder.NameWithoutExtension[..^1]}2{fileHolder.ExtensionLowered}") :
|
||||
throw new NotSupportedException("Low");
|
||||
|
||||
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);
|
||||
fileNameFirstSegment.Length - 1 == propertyConfiguration.IntMinValueLength && fileNameFirstSegment[^1] is '1' or '2' or '3' or '7' 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[^1] is '1' or '2' or '3' or '7' or '8' or '9'
|
||||
&& fileNameFirstSegment.All(char.IsNumber);
|
||||
|
||||
bool TestStatic_NameWithoutExtensionIsIdFormat(Properties.IPropertyConfiguration propertyConfiguration, Models.FileHolder fileHolder) =>
|
||||
@ -58,4 +45,19 @@ public interface IId
|
||||
static int GetDeterministicHashCode(byte[] value) =>
|
||||
Id.GetDeterministicHashCode(value);
|
||||
|
||||
int TestStatic_GetHasIgnoreKeyword(FilePath filePath) =>
|
||||
GetHasIgnoreKeyword(filePath);
|
||||
static int GetHasIgnoreKeyword(FilePath filePath) =>
|
||||
Id.GetHasIgnoreKeyword(filePath);
|
||||
|
||||
int TestStatic_GetMissingDateTimeOriginal(FilePath filePath) =>
|
||||
GetMissingDateTimeOriginal(filePath);
|
||||
static int GetMissingDateTimeOriginal(FilePath filePath) =>
|
||||
Id.GetMissingDateTimeOriginal(filePath);
|
||||
|
||||
int TestStatic_GetHasDateTimeOriginal(FilePath filePath) =>
|
||||
GetHasDateTimeOriginal(filePath);
|
||||
static int GetHasDateTimeOriginal(FilePath filePath) =>
|
||||
Id.GetHasDateTimeOriginal(filePath);
|
||||
|
||||
}
|
@ -72,4 +72,9 @@ public interface IPath
|
||||
static ReadOnlyDictionary<string, ReadOnlyDictionary<byte, ReadOnlyCollection<string>>> GetKeyValuePairs(IPropertyConfiguration propertyConfiguration, string? resultsFullGroupDirectory, string[]? jsonGroups) =>
|
||||
XPath.GetKeyValuePairs(propertyConfiguration, resultsFullGroupDirectory, jsonGroups);
|
||||
|
||||
byte TestStatic_GetEnum(FilePath filePath) =>
|
||||
GetEnum(filePath);
|
||||
static byte GetEnum(FilePath filePath) =>
|
||||
XPath.GetEnum(filePath);
|
||||
|
||||
}
|
@ -23,11 +23,6 @@ public interface IProperty
|
||||
static string GetDiffRootDirectory(string diffPropertyDirectory) =>
|
||||
Property.GetDiffRootDirectory(diffPropertyDirectory);
|
||||
|
||||
bool TestStatic_Any(Models.Container[] propertyHolderCollections) =>
|
||||
Any(propertyHolderCollections);
|
||||
static bool Any(Models.Container[] propertyHolderCollections) =>
|
||||
Property.Any(propertyHolderCollections);
|
||||
|
||||
(bool?, string[]) TestStatic_IsWrongYear(string[] segments, string year) =>
|
||||
IsWrongYear(segments, year);
|
||||
static (bool?, string[]) IsWrongYear(string[] segments, string year) =>
|
||||
@ -43,21 +38,6 @@ 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(List<long> values, double average) =>
|
||||
GetStandardDeviation(values, average);
|
||||
static double GetStandardDeviation(List<long> values, double average) =>
|
||||
Property.GetStandardDeviation(values, average);
|
||||
|
||||
TimeSpan TestStatic_GetThreeStandardDeviationHigh(int minimum, Models.Container container) =>
|
||||
GetThreeStandardDeviationHigh(minimum, container);
|
||||
static TimeSpan GetThreeStandardDeviationHigh(int minimum, Models.Container container) =>
|
||||
Property.GetThreeStandardDeviationHigh(minimum, container);
|
||||
|
||||
(int, List<DateTime>, List<Models.Item>) TestStatic_Get(Models.Container container, TimeSpan threeStandardDeviationHigh, int i) =>
|
||||
Get(container, threeStandardDeviationHigh, i);
|
||||
static (int, List<DateTime>, List<Models.Item>) Get(Models.Container container, TimeSpan threeStandardDeviationHigh, int i) =>
|
||||
Property.Get(container, threeStandardDeviationHigh, i);
|
||||
|
||||
List<DateTime> TestStatic_GetDateTimes(DateTime creationTime, DateTime lastWriteTime, DateTime? dateTime, DateTime? dateTimeDigitized, DateTime? dateTimeFromName, DateTime? dateTimeOriginal, DateTime? gpsDateStamp) =>
|
||||
GetDateTimes(creationTime, lastWriteTime, dateTime, dateTimeDigitized, dateTimeFromName, dateTimeOriginal, gpsDateStamp);
|
||||
static List<DateTime> GetDateTimes(DateTime creationTime, DateTime lastWriteTime, DateTime? dateTime, DateTime? dateTimeDigitized, DateTime? dateTimeFromName, DateTime? dateTimeOriginal, DateTime? gpsDateStamp) =>
|
||||
|
@ -28,13 +28,22 @@ internal abstract class Id
|
||||
_ = results.Append(intelligentId[i]);
|
||||
_ = results.Append(intelligentId[^3]).Append(intelligentId[^2]);
|
||||
result = int.Parse(results.ToString());
|
||||
if (intelligentId[^1] is '1' or '2')
|
||||
if (intelligentId[^1] is '1' or '2' or '3')
|
||||
result *= -1;
|
||||
else if (intelligentId[^1] is not '9' and not '8')
|
||||
else if (intelligentId[^1] is not '9' and not '8' and not '7')
|
||||
throw new NotSupportedException();
|
||||
return result;
|
||||
}
|
||||
|
||||
internal static int GetHasIgnoreKeyword(FilePath filePath) =>
|
||||
filePath.Id > -1 ? 8 : 2;
|
||||
|
||||
internal static int GetMissingDateTimeOriginal(FilePath filePath) =>
|
||||
filePath.Id > -1 ? 7 : 3;
|
||||
|
||||
internal static int GetHasDateTimeOriginal(FilePath filePath) =>
|
||||
filePath.Id > -1 ? 9 : 1;
|
||||
|
||||
internal static string GetIntelligentId(Properties.IPropertyConfiguration propertyConfiguration, long id, bool? hasIgnoreKeyword, bool? hasDateTimeOriginal)
|
||||
{
|
||||
string result;
|
||||
@ -48,12 +57,12 @@ internal abstract class Id
|
||||
List<char> resultAllInOneSubdirectoryChars = [];
|
||||
if (id > -1)
|
||||
{
|
||||
key = hasIgnoreKeyword is not null && hasIgnoreKeyword.Value ? 8 : 9;
|
||||
key = hasIgnoreKeyword is not null && hasIgnoreKeyword.Value ? 8 : hasDateTimeOriginal is not null && hasDateTimeOriginal.Value ? 9 : 7;
|
||||
value = id.ToString().PadLeft(propertyConfiguration.IntMinValueLength, '0');
|
||||
}
|
||||
else
|
||||
{
|
||||
key = hasIgnoreKeyword is not null && hasIgnoreKeyword.Value ? 2 : 1;
|
||||
key = hasIgnoreKeyword is not null && hasIgnoreKeyword.Value ? 2 : hasDateTimeOriginal is not null && hasDateTimeOriginal.Value ? 1 : 3;
|
||||
value = id.ToString()[1..].PadLeft(propertyConfiguration.IntMinValueLength, '0');
|
||||
}
|
||||
for (int i = value.Length - propertyConfiguration.ResultAllInOneSubdirectoryLength - 1; i > -1; i--)
|
||||
|
@ -171,112 +171,4 @@ internal abstract class Property
|
||||
return result;
|
||||
}
|
||||
|
||||
internal static double GetStandardDeviation(List<long> values, double average)
|
||||
{
|
||||
double result = 0;
|
||||
if (values.Count == 0)
|
||||
throw new Exception("Collection must have at least one value!");
|
||||
double sum = values.Sum(l => (l - average) * (l - average));
|
||||
result = Math.Sqrt(sum / values.Count);
|
||||
return result;
|
||||
}
|
||||
|
||||
private static long GetThreeStandardDeviationHigh(ref List<long> ticksCollection, long min)
|
||||
{
|
||||
long result;
|
||||
ticksCollection = (from l in ticksCollection select l - min).ToList();
|
||||
double sum = ticksCollection.Sum();
|
||||
double average = sum / ticksCollection.Count;
|
||||
double standardDeviation = GetStandardDeviation(ticksCollection, average);
|
||||
result = (long)Math.Ceiling(average + min + (standardDeviation * 3));
|
||||
return result;
|
||||
}
|
||||
|
||||
internal static TimeSpan GetThreeStandardDeviationHigh(int minimum, Models.Container container)
|
||||
{
|
||||
TimeSpan result;
|
||||
DateTime? minimumDateTime;
|
||||
List<long> ticksCollection = [];
|
||||
foreach (Models.Item item in container.Items)
|
||||
{
|
||||
if (item.Property is null)
|
||||
continue;
|
||||
minimumDateTime = GetMinimumDateTime(item.Property);
|
||||
if (minimumDateTime is null)
|
||||
continue;
|
||||
ticksCollection.Add(minimumDateTime.Value.Ticks);
|
||||
}
|
||||
long threeStandardDeviationHigh;
|
||||
long min;
|
||||
if (ticksCollection.Count == 0)
|
||||
min = 0;
|
||||
else
|
||||
min = ticksCollection.Min();
|
||||
if (ticksCollection.Count < minimum)
|
||||
threeStandardDeviationHigh = long.MaxValue;
|
||||
else
|
||||
threeStandardDeviationHigh = GetThreeStandardDeviationHigh(ref ticksCollection, min);
|
||||
result = new TimeSpan(threeStandardDeviationHigh - min);
|
||||
return result;
|
||||
}
|
||||
|
||||
internal static (int, List<DateTime>, List<Models.Item>) Get(Models.Container container, TimeSpan threeStandardDeviationHigh, int i)
|
||||
{
|
||||
List<Models.Item> results = [];
|
||||
int j = i;
|
||||
long? ticks;
|
||||
Models.Item item;
|
||||
TimeSpan timeSpan;
|
||||
Models.Item nextItem;
|
||||
DateTime? minimumDateTime;
|
||||
DateTime? nextMinimumDateTime;
|
||||
List<DateTime> dateTimes = [];
|
||||
for (; j < container.Items.Count; j++)
|
||||
{
|
||||
ticks = null;
|
||||
item = container.Items[j];
|
||||
if (item.Property is null)
|
||||
continue;
|
||||
minimumDateTime = GetMinimumDateTime(item.Property);
|
||||
if (minimumDateTime is null)
|
||||
continue;
|
||||
for (int k = j + 1; k < container.Items.Count; k++)
|
||||
{
|
||||
nextItem = container.Items[k];
|
||||
if (nextItem.Property is null)
|
||||
continue;
|
||||
nextMinimumDateTime = GetMinimumDateTime(nextItem.Property);
|
||||
if (nextMinimumDateTime is null)
|
||||
continue;
|
||||
ticks = nextMinimumDateTime.Value.Ticks;
|
||||
break;
|
||||
}
|
||||
results.Add(item);
|
||||
dateTimes.Add(minimumDateTime.Value);
|
||||
if (ticks.HasValue)
|
||||
{
|
||||
timeSpan = new(ticks.Value - minimumDateTime.Value.Ticks);
|
||||
if (timeSpan > threeStandardDeviationHigh)
|
||||
break;
|
||||
}
|
||||
}
|
||||
return new(j, dateTimes, results);
|
||||
}
|
||||
|
||||
internal static bool Any(Models.Container[] containers)
|
||||
{
|
||||
bool result = false;
|
||||
foreach (Models.Container container in containers)
|
||||
{
|
||||
if (container.Items.Count == 0)
|
||||
continue;
|
||||
if ((from l in container.Items where l.Any() select true).Any())
|
||||
{
|
||||
result = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
@ -33,6 +33,7 @@ internal abstract partial class XDirectory
|
||||
internal static ReadOnlyCollection<string[]> GetFilesCollection(string directory, string directorySearchFilter, string fileSearchFilter, bool useCeilingAverage)
|
||||
{
|
||||
List<string[]> results = [];
|
||||
string[] files;
|
||||
if (!fileSearchFilter.Contains('*'))
|
||||
fileSearchFilter = string.Concat('*', fileSearchFilter);
|
||||
if (!directorySearchFilter.Contains('*'))
|
||||
@ -44,7 +45,12 @@ internal abstract partial class XDirectory
|
||||
foreach (string innerDirectory in directories)
|
||||
{
|
||||
try
|
||||
{ results.Add(Directory.GetFiles(innerDirectory, fileSearchFilter, SearchOption.AllDirectories)); }
|
||||
{
|
||||
files = Directory.GetFiles(innerDirectory, fileSearchFilter, SearchOption.AllDirectories);
|
||||
if (files.Length == 0)
|
||||
continue;
|
||||
results.Add(files);
|
||||
}
|
||||
catch (UnauthorizedAccessException)
|
||||
{ continue; }
|
||||
}
|
||||
@ -62,77 +68,6 @@ internal abstract partial class XDirectory
|
||||
return results;
|
||||
}
|
||||
|
||||
internal static IReadOnlyDictionary<string, List<string>> GetFilesKeyValuePairs(ReadOnlyCollection<string[]> filesCollection)
|
||||
{
|
||||
Dictionary<string, List<string>> results = [];
|
||||
string fileName;
|
||||
List<string>? collection;
|
||||
foreach (string[] files in filesCollection)
|
||||
{
|
||||
foreach (string file in files)
|
||||
{
|
||||
fileName = Path.GetFileName(file);
|
||||
if (!results.TryGetValue(fileName, out collection))
|
||||
{
|
||||
results.Add(fileName, []);
|
||||
if (!results.TryGetValue(fileName, out collection))
|
||||
throw new Exception();
|
||||
}
|
||||
collection.Add(file);
|
||||
}
|
||||
}
|
||||
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;
|
||||
string fileNameWith;
|
||||
List<string>? collection;
|
||||
string fileNameUpperExtension;
|
||||
int length = extension.Length;
|
||||
List<string> renameCollection = [];
|
||||
foreach (string[] files in jsonFilesCollection)
|
||||
{
|
||||
foreach (string file in files)
|
||||
{
|
||||
fileNameWith = Path.GetFileName(file);
|
||||
if (fileNameWith.Length < length || !fileNameWith.EndsWith(extension))
|
||||
throw new Exception();
|
||||
fileName = fileNameWith[..^length];
|
||||
if (!fileNamesToFiles.TryGetValue(fileName, out collection))
|
||||
{
|
||||
fileNameUpperExtension = string.Concat(Path.GetFileNameWithoutExtension(fileName), Path.GetExtension(fileName).ToUpper());
|
||||
if (fileName == fileNameUpperExtension || !fileNamesToFiles.TryGetValue(fileNameUpperExtension, out collection))
|
||||
renameCollection.Add(file);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (renameCollection.Count > 0)
|
||||
IDirectory.MoveFiles(renameCollection, "{}", "{abd}");
|
||||
return renameCollection.Count;
|
||||
}
|
||||
|
||||
private static bool GetIsNotUniqueAndNeedsReview(string file, List<string> collection)
|
||||
{
|
||||
bool result = false;
|
||||
@ -175,13 +110,15 @@ internal abstract partial class XDirectory
|
||||
return result;
|
||||
}
|
||||
|
||||
internal static List<FilePair> GetFiles(Properties.IPropertyConfiguration propertyConfiguration, ReadOnlyCollection<ReadOnlyCollection<FilePath>> filePathsCollection, 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, IReadOnlyDictionary<string, List<string>> compareFileNamesToFiles)
|
||||
{
|
||||
List<FilePair> results = [];
|
||||
string? match;
|
||||
FilePair filePair;
|
||||
bool uniqueFileName;
|
||||
List<string>? collection;
|
||||
bool? isNotUniqueAndNeedsReview;
|
||||
string fileNameWithoutExtensionMinusOne;
|
||||
foreach (ReadOnlyCollection<FilePath> filePaths in filePathsCollection)
|
||||
{
|
||||
foreach (FilePath filePath in filePaths)
|
||||
@ -189,25 +126,43 @@ internal abstract partial class XDirectory
|
||||
isNotUniqueAndNeedsReview = null;
|
||||
if (propertyConfiguration.IgnoreExtensions.Contains(filePath.ExtensionLowered))
|
||||
continue;
|
||||
if (!fileNamesToFiles.TryGetValue(filePath.Name, out collection))
|
||||
fileNameWithoutExtensionMinusOne = filePath.NameWithoutExtension[..^1];
|
||||
if (!fileNamesToFiles.TryGetValue(fileNameWithoutExtensionMinusOne, out collection))
|
||||
throw new Exception();
|
||||
uniqueFileName = collection.Count == 1;
|
||||
if (!uniqueFileName)
|
||||
isNotUniqueAndNeedsReview = GetIsNotUniqueAndNeedsReview(filePath.FullName, collection);
|
||||
if (!compareFileNamesToFiles.TryGetValue(string.Concat(filePath.Name, extension), out collection))
|
||||
results.Add(new(filePath.FullName, uniqueFileName, isNotUniqueAndNeedsReview, [], null));
|
||||
if (!compareFileNamesToFiles.TryGetValue(fileNameWithoutExtensionMinusOne, out collection))
|
||||
filePair = new(Path: filePath.FullName,
|
||||
IsUnique: uniqueFileName,
|
||||
IsNotUniqueAndNeedsReview: isNotUniqueAndNeedsReview,
|
||||
Collection: [],
|
||||
Match: null);
|
||||
else
|
||||
{
|
||||
if (collection.Count == 0)
|
||||
results.Add(new(filePath.FullName, uniqueFileName, isNotUniqueAndNeedsReview, collection, null));
|
||||
filePair = new(Path: filePath.FullName,
|
||||
IsUnique: uniqueFileName,
|
||||
IsNotUniqueAndNeedsReview: isNotUniqueAndNeedsReview,
|
||||
Collection: collection,
|
||||
Match: null);
|
||||
else if (uniqueFileName && collection.Count == 1)
|
||||
results.Add(new(filePath.FullName, uniqueFileName, isNotUniqueAndNeedsReview, collection, collection.First()));
|
||||
filePair = new(Path: filePath.FullName,
|
||||
IsUnique: uniqueFileName,
|
||||
IsNotUniqueAndNeedsReview: isNotUniqueAndNeedsReview,
|
||||
Collection: collection,
|
||||
Match: collection.First());
|
||||
else
|
||||
{
|
||||
match = GetMatch(filePath.FullName, collection);
|
||||
results.Add(new(filePath.FullName, uniqueFileName, isNotUniqueAndNeedsReview, collection, match));
|
||||
filePair = new(Path: filePath.FullName,
|
||||
IsUnique: uniqueFileName,
|
||||
IsNotUniqueAndNeedsReview: isNotUniqueAndNeedsReview,
|
||||
Collection: collection,
|
||||
Match: match);
|
||||
}
|
||||
}
|
||||
results.Add(filePair);
|
||||
}
|
||||
}
|
||||
return results;
|
||||
@ -458,6 +413,7 @@ internal abstract partial class XDirectory
|
||||
{
|
||||
List<string> results = [];
|
||||
FileInfo fileInfo;
|
||||
List<string> distinctExtensions = [];
|
||||
foreach ((FilePath filePath, string to) in toDoCollection)
|
||||
{
|
||||
tick?.Invoke();
|
||||
@ -471,6 +427,8 @@ internal abstract partial class XDirectory
|
||||
results.Add(filePath.NameWithoutExtension);
|
||||
try
|
||||
{
|
||||
if (!distinctExtensions.Contains(filePath.ExtensionLowered))
|
||||
distinctExtensions.Add(filePath.ExtensionLowered);
|
||||
if (move || moveBack)
|
||||
File.Move(filePath.FullName, to);
|
||||
else
|
||||
|
@ -292,6 +292,9 @@ internal abstract class XPath
|
||||
return result;
|
||||
}
|
||||
|
||||
internal static byte GetEnum(FilePath filePath) =>
|
||||
GetEnum(filePath.HasIgnoreKeyword, filePath.HasDateTimeOriginal);
|
||||
|
||||
internal static CombinedEnumAndIndex GetCombinedEnumAndIndex(int resultAllInOneSubdirectoryLength, FilePath filePath, string fileName)
|
||||
{
|
||||
CombinedEnumAndIndex result;
|
||||
|
Reference in New Issue
Block a user