Mostly Sorting

Video Merge as 4, 5, and 6
This commit is contained in:
2025-03-22 16:50:47 -07:00
parent d5fa108f81
commit 130e3b6528
24 changed files with 6223 additions and 6119 deletions

View File

@ -5,59 +5,70 @@ namespace View_by_Distance.Shared.Models.Stateless.Methods;
public interface IDirectory
{
char TestStatic_GetDirectory(string fileName) =>
GetDirectory(fileName);
static char GetDirectory(string fileName) =>
fileName.Split('-').Length > 2 ? '-' : fileName.Split('.')[0][^1];
int TestStatic_GetDirectory(char directory) =>
GetDirectory(directory);
static int GetDirectory(char directory) =>
public static int GetDirectory(char directory) =>
directory == '-' ? 10 : int.TryParse(directory.ToString(), out int value) ? value : 11;
ReadOnlyCollection<string[]> TestStatic_GetFilesCollection(string directory, string directorySearchFilter, string fileSearchFilter, bool useCeilingAverage) =>
GetFilesCollection(directory, directorySearchFilter, fileSearchFilter, useCeilingAverage);
static ReadOnlyCollection<string[]> GetFilesCollection(string directory, string directorySearchFilter, string fileSearchFilter, bool useCeilingAverage) =>
XDirectory.GetFilesCollection(directory, directorySearchFilter, fileSearchFilter, useCeilingAverage);
public static char GetDirectory(string fileName) =>
fileName.Split('-').Length > 2 ? '-' : fileName.Split('.')[0][^1];
ReadOnlyCollection<ReadOnlyCollection<FilePath>> TestStatic_GetFilePathCollections(Properties.IPropertyConfiguration propertyConfiguration, string directorySearchFilter, string fileSearchFilter, string directory, bool useCeilingAverage) =>
GetFilePathCollections(propertyConfiguration, directorySearchFilter, fileSearchFilter, directory, useCeilingAverage);
static ReadOnlyCollection<ReadOnlyCollection<FilePath>> GetFilePathCollections(Properties.IPropertyConfiguration propertyConfiguration, string directorySearchFilter, string fileSearchFilter, string directory, bool useCeilingAverage) =>
XDirectory.GetFilePathCollections(propertyConfiguration, directorySearchFilter, fileSearchFilter, directory, 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<ReadOnlyCollection<FilePath>> filePathsCollection, IReadOnlyDictionary<string, ReadOnlyDictionary<byte, ReadOnlyCollection<string>>> fileGroups, Action? tick) =>
GetToDoCollection(propertyConfiguration, filePathsCollection, fileGroups, tick);
static (string[], List<(FilePath, string)>) GetToDoCollection(Properties.IPropertyConfiguration propertyConfiguration, ReadOnlyCollection<ReadOnlyCollection<FilePath>> filePathsCollection, IReadOnlyDictionary<string, ReadOnlyDictionary<byte, ReadOnlyCollection<string>>> fileGroups, Action? tick) =>
XDirectory.GetToDoCollection(propertyConfiguration, copyDuplicates: false, ifCanUseId: true, filePathsCollection, fileGroups, tick);
(string[], List<(FilePath, string)>) TestStatic_GetToDoCollection(Properties.IPropertyConfiguration propertyConfiguration, bool copyDuplicates, bool ifCanUseId, ReadOnlyCollection<ReadOnlyCollection<FilePath>> filePathsCollection, IReadOnlyDictionary<string, ReadOnlyDictionary<byte, ReadOnlyCollection<string>>> fileGroups, Action? tick) =>
GetToDoCollection(propertyConfiguration, copyDuplicates, ifCanUseId, filePathsCollection, fileGroups, tick);
static (string[], List<(FilePath, string)>) GetToDoCollection(Properties.IPropertyConfiguration propertyConfiguration, bool copyDuplicates, bool ifCanUseId, ReadOnlyCollection<ReadOnlyCollection<FilePath>> filePathsCollection, IReadOnlyDictionary<string, ReadOnlyDictionary<byte, ReadOnlyCollection<string>>> fileGroups, Action? tick) =>
public static (string[], List<(FilePath, string)>) GetToDoCollection(Properties.IPropertyConfiguration propertyConfiguration, bool copyDuplicates, bool ifCanUseId, ReadOnlyCollection<ReadOnlyCollection<FilePath>> filePathsCollection, IReadOnlyDictionary<string, ReadOnlyDictionary<byte, ReadOnlyCollection<string>>> fileGroups, Action? tick) =>
XDirectory.GetToDoCollection(propertyConfiguration, copyDuplicates, ifCanUseId, filePathsCollection, fileGroups, 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) =>
public static void MoveFiles(List<string> files, string find, string replace) =>
XDirectory.MoveFiles(files, find, replace);
public 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);
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) =>
public static int MaybeMove(Properties.IPropertyConfiguration propertyConfiguration, List<FilePair> filePairs, string jsonGroupDirectory, string extension) =>
XDirectory.MaybeMove(propertyConfiguration, filePairs, jsonGroupDirectory, extension);
public static ReadOnlyCollection<string[]> GetFilesCollection(string directory, string directorySearchFilter, string fileSearchFilter, bool useCeilingAverage) =>
XDirectory.GetFilesCollection(directory, directorySearchFilter, fileSearchFilter, useCeilingAverage);
public static ReadOnlyCollection<ReadOnlyCollection<FilePath>> GetFilePathCollections(Properties.IPropertyConfiguration propertyConfiguration, ReadOnlyCollection<string[]> filesCollection) =>
XDirectory.GetFilePathCollections(propertyConfiguration, filesCollection);
public static ReadOnlyCollection<ReadOnlyCollection<FilePath>> GetFilePathCollections(Properties.IPropertyConfiguration propertyConfiguration, string directorySearchFilter, string fileSearchFilter, string directory, bool useCeilingAverage) =>
XDirectory.GetFilePathCollections(propertyConfiguration, directorySearchFilter, fileSearchFilter, directory, useCeilingAverage);
public 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);
public static (string[], List<(FilePath, string)>) GetToDoCollection(Properties.IPropertyConfiguration propertyConfiguration, ReadOnlyCollection<ReadOnlyCollection<FilePath>> filePathsCollection, IReadOnlyDictionary<string, ReadOnlyDictionary<byte, ReadOnlyCollection<string>>> fileGroups, Action? tick) =>
XDirectory.GetToDoCollection(propertyConfiguration, copyDuplicates: false, ifCanUseId: true, filePathsCollection, fileGroups, tick);
internal int TestStatic_GetDirectory(char directory) =>
GetDirectory(directory);
internal char TestStatic_GetDirectory(string fileName) =>
GetDirectory(fileName);
internal void TestStatic_MoveFiles(List<string> files, string find, string replace) =>
MoveFiles(files, find, replace);
internal List<string> TestStatic_CopyOrMove(List<(FilePath, string)> toDoCollection, bool move, bool moveBack, Action? tick) =>
CopyOrMove(toDoCollection, move, moveBack, tick);
internal int TestStatic_MaybeMove(Properties.IPropertyConfiguration propertyConfiguration, List<FilePair> filePairs, string jsonGroupDirectory, string extension) =>
MaybeMove(propertyConfiguration, filePairs, jsonGroupDirectory, extension);
internal ReadOnlyCollection<string[]> TestStatic_GetFilesCollection(string directory, string directorySearchFilter, string fileSearchFilter, bool useCeilingAverage) =>
GetFilesCollection(directory, directorySearchFilter, fileSearchFilter, useCeilingAverage);
internal ReadOnlyCollection<ReadOnlyCollection<FilePath>> TestStatic_GetFilePathCollections(Properties.IPropertyConfiguration propertyConfiguration, ReadOnlyCollection<string[]> filesCollection) =>
GetFilePathCollections(propertyConfiguration, filesCollection);
internal ReadOnlyCollection<ReadOnlyCollection<FilePath>> TestStatic_GetFilePathCollections(Properties.IPropertyConfiguration propertyConfiguration, string directorySearchFilter, string fileSearchFilter, string directory, bool useCeilingAverage) =>
GetFilePathCollections(propertyConfiguration, directorySearchFilter, fileSearchFilter, directory, useCeilingAverage);
internal 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);
internal (string[], List<(FilePath, string)>) TestStatic_GetToDoCollection(Properties.IPropertyConfiguration propertyConfiguration, ReadOnlyCollection<ReadOnlyCollection<FilePath>> filePathsCollection, IReadOnlyDictionary<string, ReadOnlyDictionary<byte, ReadOnlyCollection<string>>> fileGroups, Action? tick) =>
GetToDoCollection(propertyConfiguration, filePathsCollection, fileGroups, tick);
internal (string[], List<(FilePath, string)>) TestStatic_GetToDoCollection(Properties.IPropertyConfiguration propertyConfiguration, bool copyDuplicates, bool ifCanUseId, ReadOnlyCollection<ReadOnlyCollection<FilePath>> filePathsCollection, IReadOnlyDictionary<string, ReadOnlyDictionary<byte, ReadOnlyCollection<string>>> fileGroups, Action? tick) =>
GetToDoCollection(propertyConfiguration, copyDuplicates, ifCanUseId, filePathsCollection, fileGroups, tick);
}

View File

@ -1,63 +1,75 @@
using View_by_Distance.Shared.Models.Properties;
namespace View_by_Distance.Shared.Models.Stateless.Methods;
public interface IId
{ // ...
{
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? 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);
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 '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 '3' or '7' or '8' or '9'
&& fileNameFirstSegment.All(char.IsNumber);
bool TestStatic_NameWithoutExtensionIsIdFormat(Properties.IPropertyConfiguration propertyConfiguration, Models.FileHolder fileHolder) =>
NameWithoutExtensionIsIdFormat(propertyConfiguration, fileHolder);
static bool NameWithoutExtensionIsIdFormat(Properties.IPropertyConfiguration propertyConfiguration, Models.FileHolder fileHolder) =>
Id.NameWithoutExtensionIsIdFormat(propertyConfiguration, fileHolder.NameWithoutExtension.Split('.')[0]);
int TestStatic_GetDeterministicHashCode(byte[] value) =>
GetDeterministicHashCode(value);
static int GetDeterministicHashCode(byte[] value) =>
public static int GetDeterministicHashCode(byte[] value) =>
Id.GetDeterministicHashCode(value);
int TestStatic_GetHasIgnoreKeyword(FilePath filePath) =>
GetHasIgnoreKeyword(filePath);
static int GetHasIgnoreKeyword(FilePath filePath) =>
public static byte GetHasIgnoreKeyword(FilePath filePath) =>
Id.GetHasIgnoreKeyword(filePath);
int TestStatic_GetMissingDateTimeOriginal(FilePath filePath) =>
GetMissingDateTimeOriginal(filePath);
static int GetMissingDateTimeOriginal(FilePath filePath) =>
Id.GetMissingDateTimeOriginal(filePath);
public static int GetId(IPropertyConfiguration propertyConfiguration, string intelligentId) =>
Id.GetId(propertyConfiguration, intelligentId);
int TestStatic_GetHasDateTimeOriginal(FilePath filePath) =>
GetHasDateTimeOriginal(filePath);
static int GetHasDateTimeOriginal(FilePath filePath) =>
Id.GetHasDateTimeOriginal(filePath);
public static bool IsOffsetDeterministicHashCode(IPropertyConfiguration propertyConfiguration) =>
propertyConfiguration.Offset == DeterministicHashCode;
public static byte GetHasDateTimeOriginal(IPropertyConfiguration propertyConfiguration, FilePath filePath) =>
Id.GetHasDateTimeOriginal(propertyConfiguration, filePath);
public static byte GetMissingDateTimeOriginal(IPropertyConfiguration propertyConfiguration, FilePath filePath) =>
Id.GetMissingDateTimeOriginal(propertyConfiguration, filePath);
public static bool NameWithoutExtensionIsIdFormat(IPropertyConfiguration propertyConfiguration, Models.FileHolder fileHolder) =>
Id.NameWithoutExtensionIsIdFormat(propertyConfiguration, fileHolder.NameWithoutExtension.Split('.')[0]);
public static bool NameWithoutExtensionIsIntelligentIdFormat(IPropertyConfiguration propertyConfiguration, string fileNameFirstSegment) =>
fileNameFirstSegment.Length - 1 == propertyConfiguration.IntMinValueLength && fileNameFirstSegment[^1] is '1' or '2' or '3' or '4' or '5' or '6' or '7' or '8' or '9' && fileNameFirstSegment.All(char.IsNumber);
public static string GetIntelligentId(IPropertyConfiguration propertyConfiguration, long id, bool? hasIgnoreKeyword, bool? hasDateTimeOriginal) =>
Id.GetIntelligentId(propertyConfiguration, id, hasIgnoreKeyword, hasDateTimeOriginal);
public static string GetPaddedId(IPropertyConfiguration propertyConfiguration, int id, bool? hasIgnoreKeyword, bool? hasDateTimeOriginal, int? index) =>
Id.GetPaddedId(propertyConfiguration, id, hasIgnoreKeyword, hasDateTimeOriginal, index);
public static bool NameWithoutExtensionIsPaddedIntelligentIdFormat(IPropertyConfiguration propertyConfiguration, int sortOrderOnlyLengthIndex, string fileNameFirstSegment) =>
fileNameFirstSegment.Length == propertyConfiguration.IntMinValueLength + sortOrderOnlyLengthIndex + 1
&& fileNameFirstSegment[^1] is '1' or '2' or '3' or '4' or '5' or '6' or '7' or '8' or '9'
&& fileNameFirstSegment.All(char.IsNumber);
internal int TestStatic_GetDeterministicHashCode(byte[] value) =>
GetDeterministicHashCode(value);
internal byte TestStatic_GetHasIgnoreKeyword(FilePath filePath) =>
GetHasIgnoreKeyword(filePath);
internal int TestStatic_GetId(IPropertyConfiguration propertyConfiguration, string intelligentId) =>
GetId(propertyConfiguration, intelligentId);
internal byte TestStatic_GetHasDateTimeOriginal(IPropertyConfiguration propertyConfiguration, FilePath filePath) =>
GetHasDateTimeOriginal(propertyConfiguration, filePath);
internal byte TestStatic_GetMissingDateTimeOriginal(IPropertyConfiguration propertyConfiguration, FilePath filePath) =>
GetMissingDateTimeOriginal(propertyConfiguration, filePath);
internal bool TestStatic_NameWithoutExtensionIsIdFormat(IPropertyConfiguration propertyConfiguration, Models.FileHolder fileHolder) =>
NameWithoutExtensionIsIdFormat(propertyConfiguration, fileHolder);
internal bool TestStatic_NameWithoutExtensionIsIntelligentIdFormat(IPropertyConfiguration propertyConfiguration, string fileNameFirstSegment) =>
NameWithoutExtensionIsIntelligentIdFormat(propertyConfiguration, fileNameFirstSegment);
internal string TestStatic_GetIntelligentId(IPropertyConfiguration propertyConfiguration, long id, bool? hasIgnoreKeyword, bool? hasDateTimeOriginal) =>
GetIntelligentId(propertyConfiguration, id, hasIgnoreKeyword, hasDateTimeOriginal);
internal string TestStatic_GetPaddedId(IPropertyConfiguration propertyConfiguration, int id, bool? hasIgnoreKeyword, bool? hasDateTimeOriginal, int? index) =>
GetPaddedId(propertyConfiguration, id, hasIgnoreKeyword, hasDateTimeOriginal, index);
internal bool TestStatic_NameWithoutExtensionIsPaddedIntelligentIdFormat(IPropertyConfiguration propertyConfiguration, int sortOrderOnlyLengthIndex, string fileNameFirstSegment) =>
NameWithoutExtensionIsPaddedIntelligentIdFormat(propertyConfiguration, sortOrderOnlyLengthIndex, fileNameFirstSegment);
}

View File

@ -4,77 +4,89 @@ using View_by_Distance.Shared.Models.Properties;
namespace View_by_Distance.Shared.Models.Stateless.Methods;
public interface IPath
{ // ...
{
string TestStatic_GetRelativePath(string path, int length) =>
GetRelativePath(path, length);
static string GetRelativePath(string path, int length) =>
XPath.GetRelativePath(path, length, forceExtensionToLower: false);
bool TestStatic_DeleteEmptyDirectories(string rootDirectory) =>
DeleteEmptyDirectories(rootDirectory);
static bool DeleteEmptyDirectories(string rootDirectory) =>
XPath.DeleteEmptyDirectories(rootDirectory);
void TestStatic_ChangeDateForEmptyDirectories(string rootDirectory, long ticks) =>
ChangeDateForEmptyDirectories(rootDirectory, ticks);
static void ChangeDateForEmptyDirectories(string rootDirectory, long ticks) =>
XPath.ChangeDateForEmptyDirectories(rootDirectory, ticks);
void TestStatic_MakeHiddenIfAllItemsAreHidden(string rootDirectory) =>
MakeHiddenIfAllItemsAreHidden(rootDirectory);
static void MakeHiddenIfAllItemsAreHidden(string rootDirectory) =>
XPath.MakeHiddenIfAllItemsAreHidden(rootDirectory);
void TestStatic_DeleteEmptyDirectories(string rootDirectory, List<string> deletedDirectories) =>
DeleteEmptyDirectories(rootDirectory, deletedDirectories);
static void DeleteEmptyDirectories(string rootDirectory, List<string> deletedDirectories) =>
XPath.DeleteEmptyDirectories(rootDirectory, deletedDirectories);
// $dirs = gci "" -directory -recurse | Where { (gci $_.fullName).count -eq 0 } | select -expandproperty FullName $dirs | Foreach-Object { Remove-Item $_ }
string[] TestStatic_GetDirectoryNames(string directory) =>
GetDirectoryNames(directory);
static string[] GetDirectoryNames(string directory) =>
XPath.GetDirectoryNames(directory).ToArray();
string[] TestStatic_GetDirectories(string directory) =>
GetDirectories(directory);
static string[] GetDirectories(string directory) =>
XPath.GetDirectories(directory).ToArray();
string TestStatic_GetRelativePath(string path, int length, bool forceExtensionToLower) =>
GetRelativePath(path, length, forceExtensionToLower);
static string GetRelativePath(string path, int length, bool forceExtensionToLower) =>
XPath.GetRelativePath(path, length, forceExtensionToLower);
bool TestStatic_WriteAllText(string path, string contents, bool updateDateWhenMatches, bool compareBeforeWrite, DateTime? updateToWhenMatches = null) =>
WriteAllText(path, contents, updateDateWhenMatches, compareBeforeWrite, updateToWhenMatches);
static bool WriteAllText(string path, string contents, bool updateDateWhenMatches, bool compareBeforeWrite, DateTime? updateToWhenMatches = null) =>
XPath.WriteAllText(path, contents, updateDateWhenMatches, compareBeforeWrite, updateToWhenMatches);
(int level, List<string> directories) TestStatic_Get(string rootDirectory, string sourceDirectory) =>
Get(rootDirectory, sourceDirectory);
static (int level, List<string> directories) Get(string rootDirectory, string sourceDirectory) =>
XPath.Get(rootDirectory, sourceDirectory);
string TestStatic_GetDirectory(string sourceDirectory, int level, string directoryName) =>
GetDirectory(sourceDirectory, level, directoryName);
static string GetDirectory(string sourceDirectory, int level, string directoryName) =>
XPath.GetDirectory(sourceDirectory, level, directoryName);
CombinedEnumAndIndex TestStatic_GetCombinedEnumAndIndex(IPropertyConfiguration propertyConfiguration, FilePath filePath) =>
GetCombinedEnumAndIndex(propertyConfiguration, filePath);
static CombinedEnumAndIndex GetCombinedEnumAndIndex(IPropertyConfiguration propertyConfiguration, FilePath filePath) =>
XPath.GetCombinedEnumAndIndex(propertyConfiguration, filePath);
ReadOnlyDictionary<string, ReadOnlyDictionary<byte, ReadOnlyCollection<string>>> TestStatic_GetKeyValuePairs(IPropertyConfiguration propertyConfiguration, string? resultsFullGroupDirectory, string[]? jsonGroups) =>
GetKeyValuePairs(propertyConfiguration, resultsFullGroupDirectory, jsonGroups);
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) =>
public static byte GetEnum(FilePath filePath) =>
XPath.GetEnum(filePath);
public static string[] GetDirectories(string directory) =>
XPath.GetDirectories(directory).ToArray();
public static string[] GetDirectoryNames(string directory) =>
XPath.GetDirectoryNames(directory).ToArray();
public static string GetRelativePath(string path, int length) =>
XPath.GetRelativePath(path, length, forceExtensionToLower: false);
public static bool DeleteEmptyDirectories(string rootDirectory) =>
XPath.DeleteEmptyDirectories(rootDirectory);
public static void MakeHiddenIfAllItemsAreHidden(string rootDirectory) =>
XPath.MakeHiddenIfAllItemsAreHidden(rootDirectory);
public static void ChangeDateForEmptyDirectories(string rootDirectory, long ticks) =>
XPath.ChangeDateForEmptyDirectories(rootDirectory, ticks);
public static string GetRelativePath(string path, int length, bool forceExtensionToLower) =>
XPath.GetRelativePath(path, length, forceExtensionToLower);
public static string GetDirectory(string sourceDirectory, int level, string directoryName) =>
XPath.GetDirectory(sourceDirectory, level, directoryName);
public static void DeleteEmptyDirectories(string rootDirectory, List<string> deletedDirectories) =>
XPath.DeleteEmptyDirectories(rootDirectory, deletedDirectories);
public static (int level, List<string> directories) Get(string rootDirectory, string sourceDirectory) =>
XPath.Get(rootDirectory, sourceDirectory);
public static CombinedEnumAndIndex GetCombinedEnumAndIndex(IPropertyConfiguration propertyConfiguration, FilePath filePath) =>
XPath.GetCombinedEnumAndIndex(propertyConfiguration, filePath);
public static bool WriteAllText(string path, string contents, bool updateDateWhenMatches, bool compareBeforeWrite, DateTime? updateToWhenMatches = null) =>
XPath.WriteAllText(path, contents, updateDateWhenMatches, compareBeforeWrite, updateToWhenMatches);
public static ReadOnlyDictionary<string, ReadOnlyDictionary<byte, ReadOnlyCollection<string>>> GetKeyValuePairs(IPropertyConfiguration propertyConfiguration, string? resultsFullGroupDirectory, string[]? jsonGroups) =>
XPath.GetKeyValuePairs(propertyConfiguration, resultsFullGroupDirectory, jsonGroups);
internal byte TestStatic_GetEnum(FilePath filePath) =>
GetEnum(filePath);
internal string[] TestStatic_GetDirectories(string directory) =>
GetDirectories(directory);
internal string[] TestStatic_GetDirectoryNames(string directory) =>
GetDirectoryNames(directory);
internal string TestStatic_GetRelativePath(string path, int length) =>
GetRelativePath(path, length);
internal bool TestStatic_DeleteEmptyDirectories(string rootDirectory) =>
DeleteEmptyDirectories(rootDirectory);
internal void TestStatic_MakeHiddenIfAllItemsAreHidden(string rootDirectory) =>
MakeHiddenIfAllItemsAreHidden(rootDirectory);
internal void TestStatic_ChangeDateForEmptyDirectories(string rootDirectory, long ticks) =>
ChangeDateForEmptyDirectories(rootDirectory, ticks);
internal string TestStatic_GetRelativePath(string path, int length, bool forceExtensionToLower) =>
GetRelativePath(path, length, forceExtensionToLower);
internal string TestStatic_GetDirectory(string sourceDirectory, int level, string directoryName) =>
GetDirectory(sourceDirectory, level, directoryName);
internal void TestStatic_DeleteEmptyDirectories(string rootDirectory, List<string> deletedDirectories) =>
DeleteEmptyDirectories(rootDirectory, deletedDirectories);
internal (int level, List<string> directories) TestStatic_Get(string rootDirectory, string sourceDirectory) =>
Get(rootDirectory, sourceDirectory);
internal CombinedEnumAndIndex TestStatic_GetCombinedEnumAndIndex(IPropertyConfiguration propertyConfiguration, FilePath filePath) =>
GetCombinedEnumAndIndex(propertyConfiguration, filePath);
internal bool TestStatic_WriteAllText(string path, string contents, bool updateDateWhenMatches, bool compareBeforeWrite, DateTime? updateToWhenMatches = null) =>
WriteAllText(path, contents, updateDateWhenMatches, compareBeforeWrite, updateToWhenMatches);
internal ReadOnlyDictionary<string, ReadOnlyDictionary<byte, ReadOnlyCollection<string>>> TestStatic_GetKeyValuePairs(IPropertyConfiguration propertyConfiguration, string? resultsFullGroupDirectory, string[]? jsonGroups) =>
GetKeyValuePairs(propertyConfiguration, resultsFullGroupDirectory, jsonGroups);
}

View File

@ -5,6 +5,51 @@ namespace View_by_Distance.Shared.Models.Stateless.Methods;
internal abstract class Id
{
internal static int GetDeterministicHashCode(byte[] value)
{
int result;
unchecked
{
int hash1 = (5381 << 16) + 5381;
int hash2 = hash1;
for (int i = 0; i < value.Length; i += 2)
{
hash1 = ((hash1 << 5) + hash1) ^ value[i];
if (i == value.Length - 1)
break;
hash2 = ((hash2 << 5) + hash2) ^ value[i + 1];
}
result = hash1 + (hash2 * 1566083941);
}
return result;
}
internal static byte GetHasIgnoreKeyword(FilePath filePath) =>
(byte)(filePath.Id > -1 ? 8 : 2);
internal static int GetId(Properties.IPropertyConfiguration propertyConfiguration, string intelligentId)
{
int result;
StringBuilder results = new();
if (propertyConfiguration.IntMinValueLength < (propertyConfiguration.ResultAllInOneSubdirectoryLength + 2))
throw new NotSupportedException();
for (int i = intelligentId.Length - (propertyConfiguration.ResultAllInOneSubdirectoryLength + 2); i > -1; i--)
_ = results.Append(intelligentId[i]);
_ = results.Append(intelligentId[^3]).Append(intelligentId[^2]);
result = int.Parse(results.ToString());
if (intelligentId[^1] is '1' or '2' or '3' or '4')
result *= -1;
else if (intelligentId[^1] is not '9' and not '8' and not '7' and not '6' and not '5')
throw new NotSupportedException();
return result;
}
internal static byte GetHasDateTimeOriginal(Properties.IPropertyConfiguration propertyConfiguration, FilePath filePath) =>
(byte)(!propertyConfiguration.ValidVideoFormatExtensions.Contains(filePath.ExtensionLowered) ? filePath.Id > -1 ? 9 : 1 : filePath.Id > -1 ? 6 : 4);
internal static byte GetMissingDateTimeOriginal(Properties.IPropertyConfiguration propertyConfiguration, FilePath filePath) =>
(byte)(!propertyConfiguration.ValidVideoFormatExtensions.Contains(filePath.ExtensionLowered) ? filePath.Id > -1 ? 7 : 3 : 5);
internal static bool NameWithoutExtensionIsIdFormat(Properties.IPropertyConfiguration propertyConfiguration, string fileNameWithoutExtension)
{
bool result;
@ -18,32 +63,6 @@ internal abstract class Id
return result;
}
internal static int GetId(Properties.IPropertyConfiguration propertyConfiguration, string intelligentId)
{
int result;
StringBuilder results = new();
if (propertyConfiguration.IntMinValueLength < (propertyConfiguration.ResultAllInOneSubdirectoryLength + 2))
throw new NotSupportedException();
for (int i = intelligentId.Length - (propertyConfiguration.ResultAllInOneSubdirectoryLength + 2); i > -1; i--)
_ = results.Append(intelligentId[i]);
_ = results.Append(intelligentId[^3]).Append(intelligentId[^2]);
result = int.Parse(results.ToString());
if (intelligentId[^1] is '1' or '2' or '3')
result *= -1;
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;
@ -89,23 +108,4 @@ internal abstract class Id
return result;
}
internal static int GetDeterministicHashCode(byte[] value)
{
int result;
unchecked
{
int hash1 = (5381 << 16) + 5381;
int hash2 = hash1;
for (int i = 0; i < value.Length; i += 2)
{
hash1 = ((hash1 << 5) + hash1) ^ value[i];
if (i == value.Length - 1)
break;
hash2 = ((hash2 << 5) + hash2) ^ value[i + 1];
}
result = hash1 + (hash2 * 1566083941);
}
return result;
}
}

View File

@ -5,31 +5,119 @@ namespace View_by_Distance.Shared.Models.Stateless.Methods;
internal abstract partial class XDirectory
{
private static int GetCeilingAverage(List<string[]> fileCollection)
internal static void MoveFiles(List<string> files, string find, string replace)
{
List<int> counts = [];
foreach (string[] files in fileCollection)
counts.Add(files.Length);
int average = (int)Math.Ceiling(counts.Average());
return average;
string checkFile;
string? checkDirectory;
List<string> directories = [];
foreach (string file in files)
{
checkDirectory = Path.GetDirectoryName(file.Replace(find, replace));
if (string.IsNullOrEmpty(checkDirectory) || directories.Contains(checkDirectory))
continue;
directories.Add(checkDirectory);
}
foreach (string directory in directories)
{
if (Directory.Exists(directory))
continue;
_ = Directory.CreateDirectory(directory);
}
foreach (string file in files)
{
if (!File.Exists(file))
continue;
checkFile = file.Replace(find, replace);
if (File.Exists(checkFile))
{
File.Delete(checkFile);
continue;
}
File.Move(file, checkFile);
}
}
private static List<string[]> GetFilesCollection(List<string[]> fileCollection, int ceilingAverage)
internal static List<string> CopyOrMove(List<(FilePath, string)> toDoCollection, bool move, bool moveBack, Action? tick)
{
List<string[]> results = [];
foreach (string[] files in fileCollection)
List<string> results = [];
FileInfo fileInfo;
List<string> distinctExtensions = [];
foreach ((FilePath filePath, string to) in toDoCollection)
{
if (files.Length < ceilingAverage)
results.Add(files);
}
foreach (string[] files in fileCollection)
{
if (files.Length >= ceilingAverage)
results.Add(files);
tick?.Invoke();
fileInfo = new(to);
if (fileInfo.Exists)
{
if (filePath.Length == fileInfo.Length && filePath.LastWriteTicks == fileInfo.LastWriteTime.Ticks)
continue;
fileInfo.Delete();
}
results.Add(filePath.NameWithoutExtension);
try
{
if (!distinctExtensions.Contains(filePath.ExtensionLowered))
distinctExtensions.Add(filePath.ExtensionLowered);
if (move || moveBack)
File.Move(filePath.FullName, to);
else
File.Copy(filePath.FullName, to);
}
catch (Exception) { }
}
return results;
}
internal static int MaybeMove(Properties.IPropertyConfiguration propertyConfiguration, List<FilePair> filePairs, string jsonGroupDirectory, string extension)
{
FileInfo? toFileInfo;
FileInfo fromFileInfo;
string checkDirectory;
List<(string, string)> rename = [];
foreach (FilePair filePair in filePairs)
{
if (filePair.IsUnique)
continue;
IsNotUniqueLoop(propertyConfiguration, jsonGroupDirectory, extension, filePair, rename);
}
foreach ((string from, string to) in rename)
{
toFileInfo = null;
checkDirectory = to;
fromFileInfo = new(from);
if (!fromFileInfo.Exists)
continue;
for (int i = 0; i < int.MaxValue; i++)
{
toFileInfo = new(checkDirectory);
if (toFileInfo.Directory is null)
continue;
if (!toFileInfo.Directory.Exists)
_ = Directory.CreateDirectory(toFileInfo.Directory.FullName);
if (checkDirectory.Length > 199)
throw new Exception();
if (!toFileInfo.Exists)
break;
else if (fromFileInfo.Length == toFileInfo.Length && fromFileInfo.LastWriteTime == toFileInfo.LastWriteTime)
checkDirectory = string.Concat(checkDirectory, ".del");
else
checkDirectory = string.Concat(checkDirectory, ".j");
}
File.Move(from, checkDirectory);
}
return rename.Count;
}
private static void IsNotUniqueLoop(Properties.IPropertyConfiguration propertyConfiguration, string jsonGroupDirectory, string extension, FilePair filePair, List<(string, string)> rename)
{
int length = propertyConfiguration.RootDirectory.Length;
foreach (string path in filePair.Collection)
{
if (filePair.Match is null || path != filePair.Match)
continue;
rename.Add(new(path, string.Concat(jsonGroupDirectory, filePair.Path[length..], extension)));
}
}
internal static ReadOnlyCollection<string[]> GetFilesCollection(string directory, string directorySearchFilter, string fileSearchFilter, bool useCeilingAverage)
{
List<string[]> results = [];
@ -60,6 +148,53 @@ internal abstract partial class XDirectory
return results.AsReadOnly();
}
private static int GetCeilingAverage(List<string[]> fileCollection)
{
List<int> counts = [];
foreach (string[] files in fileCollection)
counts.Add(files.Length);
int average = (int)Math.Ceiling(counts.Average());
return average;
}
private static List<string[]> GetFilesCollection(List<string[]> fileCollection, int ceilingAverage)
{
List<string[]> results = [];
foreach (string[] files in fileCollection)
{
if (files.Length < ceilingAverage)
results.Add(files);
}
foreach (string[] files in fileCollection)
{
if (files.Length >= ceilingAverage)
results.Add(files);
}
return results;
}
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);
if (propertyConfiguration.IgnoreExtensions.Contains(fileHolder.ExtensionLowered))
continue;
filePath = FilePath.Get(propertyConfiguration, fileHolder, index: null);
filePaths.Add(filePath);
}
results.Add(new(filePaths));
}
return results.AsReadOnly();
}
internal static ReadOnlyCollection<ReadOnlyCollection<FilePath>> GetFilePathCollections(Properties.IPropertyConfiguration propertyConfiguration, string directorySearchFilter, string fileSearchFilter, string directory, bool useCeilingAverage)
{
ReadOnlyCollection<ReadOnlyCollection<FilePath>> results;
@ -68,48 +203,6 @@ internal abstract partial class XDirectory
return results;
}
private static bool GetIsNotUniqueAndNeedsReview(string file, List<string> collection)
{
bool result = false;
FileInfo possibleFileInfo;
FileInfo fileInfo = new(file);
foreach (string possible in collection)
{
if (possible == file)
continue;
possibleFileInfo = new(possible);
if (possibleFileInfo.LastWriteTime != fileInfo.LastWriteTime)
File.SetLastWriteTime(file, new DateTime[] { possibleFileInfo.LastWriteTime, fileInfo.LastWriteTime }.Max());
if (possibleFileInfo.LastWriteTime == fileInfo.LastWriteTime && possibleFileInfo.Length == fileInfo.Length)
continue;
if (!result)
result = true;
}
return result;
}
private static string? GetMatch(string file, List<string> collection)
{
string? result = null;
FileInfo possibleFileInfo;
List<long> lengths = [];
List<string> matches = [];
FileInfo fileInfo = new(file);
List<DateTime> creationTimes = [];
foreach (string possible in collection)
{
possibleFileInfo = new(possible);
lengths.Add(possibleFileInfo.Length);
creationTimes.Add(possibleFileInfo.CreationTime);
if (possibleFileInfo.CreationTime != fileInfo.LastWriteTime)
continue;
matches.Add(possible);
}
if (matches.Count == 1 || (matches.Count > 0 && lengths.Distinct().Count() == 1 && creationTimes.Distinct().Count() == 1))
result = matches.First();
return result;
}
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 = [];
@ -168,126 +261,51 @@ internal abstract partial class XDirectory
return results;
}
private static void IsNotUniqueLoop(Properties.IPropertyConfiguration propertyConfiguration, string jsonGroupDirectory, string extension, FilePair filePair, List<(string, string)> rename)
private static bool GetIsNotUniqueAndNeedsReview(string file, List<string> collection)
{
int length = propertyConfiguration.RootDirectory.Length;
foreach (string path in filePair.Collection)
bool result = false;
FileInfo possibleFileInfo;
FileInfo fileInfo = new(file);
foreach (string possible in collection)
{
if (filePair.Match is null || path != filePair.Match)
if (possible == file)
continue;
rename.Add(new(path, string.Concat(jsonGroupDirectory, filePair.Path[length..], extension)));
possibleFileInfo = new(possible);
if (possibleFileInfo.LastWriteTime != fileInfo.LastWriteTime)
File.SetLastWriteTime(file, new DateTime[] { possibleFileInfo.LastWriteTime, fileInfo.LastWriteTime }.Max());
if (possibleFileInfo.LastWriteTime == fileInfo.LastWriteTime && possibleFileInfo.Length == fileInfo.Length)
continue;
if (!result)
result = true;
}
return result;
}
internal static int MaybeMove(Properties.IPropertyConfiguration propertyConfiguration, List<FilePair> filePairs, string jsonGroupDirectory, string extension)
private static string? GetMatch(string file, List<string> collection)
{
FileInfo? toFileInfo;
FileInfo fromFileInfo;
string checkDirectory;
List<(string, string)> rename = [];
foreach (FilePair filePair in filePairs)
string? result = null;
FileInfo possibleFileInfo;
List<long> lengths = [];
List<string> matches = [];
FileInfo fileInfo = new(file);
List<DateTime> creationTimes = [];
foreach (string possible in collection)
{
if (filePair.IsUnique)
possibleFileInfo = new(possible);
lengths.Add(possibleFileInfo.Length);
creationTimes.Add(possibleFileInfo.CreationTime);
if (possibleFileInfo.CreationTime != fileInfo.LastWriteTime)
continue;
IsNotUniqueLoop(propertyConfiguration, jsonGroupDirectory, extension, filePair, rename);
matches.Add(possible);
}
foreach ((string from, string to) in rename)
{
toFileInfo = null;
checkDirectory = to;
fromFileInfo = new(from);
if (!fromFileInfo.Exists)
continue;
for (int i = 0; i < int.MaxValue; i++)
{
toFileInfo = new(checkDirectory);
if (toFileInfo.Directory is null)
continue;
if (!toFileInfo.Directory.Exists)
_ = Directory.CreateDirectory(toFileInfo.Directory.FullName);
if (checkDirectory.Length > 199)
throw new Exception();
if (!toFileInfo.Exists)
break;
else if (fromFileInfo.Length == toFileInfo.Length && fromFileInfo.LastWriteTime == toFileInfo.LastWriteTime)
checkDirectory = string.Concat(checkDirectory, ".del");
else
checkDirectory = string.Concat(checkDirectory, ".j");
}
File.Move(from, checkDirectory);
}
return rename.Count;
}
internal static void MoveFiles(List<string> files, string find, string replace)
{
string checkFile;
string? checkDirectory;
List<string> directories = [];
foreach (string file in files)
{
checkDirectory = Path.GetDirectoryName(file.Replace(find, replace));
if (string.IsNullOrEmpty(checkDirectory) || directories.Contains(checkDirectory))
continue;
directories.Add(checkDirectory);
}
foreach (string directory in directories)
{
if (Directory.Exists(directory))
continue;
_ = Directory.CreateDirectory(directory);
}
foreach (string file in files)
{
if (!File.Exists(file))
continue;
checkFile = file.Replace(find, replace);
if (File.Exists(checkFile))
{
File.Delete(checkFile);
continue;
}
File.Move(file, checkFile);
}
}
private static FilePath[] GetSortedRecords(ReadOnlyCollection<ReadOnlyCollection<FilePath>> filePathsCollection)
{
List<FilePath> results = [];
foreach (ReadOnlyCollection<FilePath> filePaths in filePathsCollection)
{
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 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);
if (propertyConfiguration.IgnoreExtensions.Contains(fileHolder.ExtensionLowered))
continue;
filePath = FilePath.Get(propertyConfiguration, fileHolder, index: null);
filePaths.Add(filePath);
}
results.Add(new(filePaths));
}
return results.AsReadOnly();
if (matches.Count == 1 || (matches.Count > 0 && lengths.Distinct().Count() == 1 && creationTimes.Distinct().Count() == 1))
result = matches.First();
return result;
}
internal static (string[], List<(FilePath, string)>) GetToDoCollection(Properties.IPropertyConfiguration propertyConfiguration, bool copyDuplicates, bool ifCanUseId, ReadOnlyCollection<ReadOnlyCollection<FilePath>> filePathsCollection, IReadOnlyDictionary<string, ReadOnlyDictionary<byte, ReadOnlyCollection<string>>> fileGroups, Action? tick)
{
List<(FilePath, string)> results = [];
string key;
string paddedId;
string checkFile;
string directory;
@ -305,6 +323,8 @@ internal abstract partial class XDirectory
List<string> distinctDirectories = [];
FilePath[] sortedRecords = GetSortedRecords(filePathsCollection);
ReadOnlyDictionary<byte, ReadOnlyCollection<string>>? keyValuePairs;
if (!fileGroups.TryGetValue(propertyConfiguration.ResultContent, out keyValuePairs))
throw new NotImplementedException();
bool isOffsetDeterministicHashCode = IId.IsOffsetDeterministicHashCode(propertyConfiguration);
for (int i = 0; i < sortedRecords.Length; i++)
{
@ -312,11 +332,8 @@ internal abstract partial class XDirectory
filePath = sortedRecords[i];
if (filePath.Name.EndsWith("len") || filePath.ExtensionLowered == ".id" || filePath.ExtensionLowered == ".lsv" || filePath.DirectoryFullPath is null)
continue;
key = propertyConfiguration.ValidVideoFormatExtensions.Contains(filePath.ExtensionLowered) ? propertyConfiguration.ResultContentCollection : propertyConfiguration.ResultContent;
if (!fileGroups.TryGetValue(key, out keyValuePairs))
continue;
cei = IPath.GetCombinedEnumAndIndex(propertyConfiguration, filePath);
fileDirectoryName = Path.GetFileName(filePath.DirectoryFullPath);
cei = IPath.GetCombinedEnumAndIndex(propertyConfiguration, filePath);
if (fileDirectoryName.Length < propertyConfiguration.ResultAllInOneSubdirectoryLength + 3 || !filePath.Name.StartsWith(fileDirectoryName))
{
if (wrapped)
@ -409,34 +426,15 @@ internal abstract partial class XDirectory
return (distinctDirectories.ToArray(), results);
}
internal static List<string> CopyOrMove(List<(FilePath, string)> toDoCollection, bool move, bool moveBack, Action? tick)
private static FilePath[] GetSortedRecords(ReadOnlyCollection<ReadOnlyCollection<FilePath>> filePathsCollection)
{
List<string> results = [];
FileInfo fileInfo;
List<string> distinctExtensions = [];
foreach ((FilePath filePath, string to) in toDoCollection)
List<FilePath> results = [];
foreach (ReadOnlyCollection<FilePath> filePaths in filePathsCollection)
{
tick?.Invoke();
fileInfo = new(to);
if (fileInfo.Exists)
{
if (filePath.Length == fileInfo.Length && filePath.LastWriteTicks == fileInfo.LastWriteTime.Ticks)
continue;
fileInfo.Delete();
}
results.Add(filePath.NameWithoutExtension);
try
{
if (!distinctExtensions.Contains(filePath.ExtensionLowered))
distinctExtensions.Add(filePath.ExtensionLowered);
if (move || moveBack)
File.Move(filePath.FullName, to);
else
File.Copy(filePath.FullName, to);
}
catch (Exception) { }
foreach (FilePath filePath in filePaths)
results.Add(filePath);
}
return results;
return (from l in results orderby l.CreationTicks, l.FullName.Length descending select l).ToArray();
}
}

View File

@ -6,35 +6,21 @@ namespace View_by_Distance.Shared.Models.Stateless.Methods;
internal abstract class XPath
{
internal static string GetRelativePath(string path, int length, bool forceExtensionToLower)
private static ReadOnlyDictionary<byte, ReadOnlyCollection<string>> Convert(List<CombinedEnumAndIndex> collection)
{
string result;
if (forceExtensionToLower)
Dictionary<byte, List<string>> results = [];
List<string>? c;
foreach (CombinedEnumAndIndex cei in collection)
{
string extension = Path.GetExtension(path);
string extensionLowered = Path.GetExtension(path).ToLower();
if (extension != extensionLowered)
if (!results.TryGetValue(cei.Enum, out c))
{
string? directoryName = Path.GetDirectoryName(path);
if (string.IsNullOrEmpty(directoryName))
throw new NullReferenceException(directoryName);
string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(path);
if (string.IsNullOrEmpty(fileNameWithoutExtension))
throw new NullReferenceException(fileNameWithoutExtension);
path = Path.Combine(directoryName, $"{fileNameWithoutExtension}{extensionLowered}");
results.Add(cei.Enum, []);
if (!results.TryGetValue(cei.Enum, out c))
throw new Exception();
}
c.Add(cei.Combined);
}
result = path[length..].Replace(@"\", "/");
return result;
}
internal static bool DeleteEmptyDirectories(string rootDirectory)
{
bool result;
List<string> results = [];
DeleteEmptyDirectories(rootDirectory, results);
result = results.Count > 0;
return result;
return Convert(results);
}
internal static void DeleteEmptyDirectories(string rootDirectory, List<string> deletedDirectories)
@ -72,45 +58,79 @@ internal abstract class XPath
}
}
internal static bool WriteAllText(string path, string contents, bool updateDateWhenMatches, bool compareBeforeWrite, DateTime? updateToWhenMatches)
internal static CombinedEnumAndIndex GetCombinedEnumAndIndex(IPropertyConfiguration propertyConfiguration, FilePath filePath, string fileNameFirstSegment)
{
bool result;
string text;
if (!compareBeforeWrite)
result = true;
CombinedEnumAndIndex result;
int converted;
string combined;
byte @enum = GetEnum(filePath.HasIgnoreKeyword, filePath.HasDateTimeOriginal);
string check = fileNameFirstSegment.Length < propertyConfiguration.ResultAllInOneSubdirectoryLength ?
new('-', propertyConfiguration.ResultAllInOneSubdirectoryLength) :
fileNameFirstSegment.Split('.')[0][^propertyConfiguration.ResultAllInOneSubdirectoryLength..];
if (check.Any(l => !char.IsNumber(l)))
{
combined = $"{@enum}{new('-', propertyConfiguration.ResultAllInOneSubdirectoryLength)}";
converted = int.Parse($"1{new string('0', propertyConfiguration.ResultAllInOneSubdirectoryLength)}");
}
else
{
if (!File.Exists(path))
text = string.Empty;
else
text = File.ReadAllText(path);
result = text != contents;
if (!result && updateDateWhenMatches)
{
if (updateToWhenMatches is null)
File.SetLastWriteTime(path, DateTime.Now);
else
File.SetLastWriteTime(path, updateToWhenMatches.Value);
}
}
if (result)
{
if (path.Contains("()"))
File.WriteAllText(path, contents);
else if (path.Contains("{}") && !path.EndsWith(".json"))
File.WriteAllText(path, contents);
else if (path.Contains("[]") && !path.EndsWith(".json"))
File.WriteAllText(path, contents);
else if (path.Contains("{}") && path.EndsWith(".json") && contents[0] == '{')
File.WriteAllText(path, contents);
else if (path.Contains("[]") && path.EndsWith(".json") && contents[0] == '[')
File.WriteAllText(path, contents);
else
File.WriteAllText(path, contents);
combined = $"{@enum}{check}";
converted = int.Parse(check);
}
result = new(combined, @enum, converted);
return result;
}
private static byte GetEnum(bool? ik, bool? dto)
{
byte result;
if (ik is not null && ik.Value && dto is not null && dto.Value)
result = 11;
else if (ik is not null && ik.Value && dto is not null && !dto.Value)
result = 15;
else if (ik is not null && ik.Value && dto is null)
result = 19;
else if (ik is not null && !ik.Value && dto is not null && dto.Value)
result = 51;
else if (ik is not null && !ik.Value && dto is not null && !dto.Value)
result = 55;
else if (ik is not null && !ik.Value && dto is null)
result = 59;
else if (ik is null && dto is not null && dto.Value)
result = 91;
else if (ik is null && dto is not null && !dto.Value)
result = 95;
else if (ik is null && dto is null)
result = 99;
else
throw new Exception();
return result;
}
internal static byte GetEnum(FilePath filePath) =>
GetEnum(filePath.HasIgnoreKeyword, filePath.HasDateTimeOriginal);
internal static List<string> GetDirectories(string directory)
{
List<string> results = [];
string? checkDirectory = directory;
string? pathRoot = Path.GetPathRoot(directory);
if (string.IsNullOrEmpty(pathRoot))
throw new NullReferenceException(nameof(pathRoot));
if (Directory.Exists(directory))
results.Add(directory);
for (int i = 0; i < int.MaxValue; i++)
{
checkDirectory = Path.GetDirectoryName(checkDirectory);
if (string.IsNullOrEmpty(checkDirectory) || checkDirectory == pathRoot)
break;
results.Add(checkDirectory);
}
results.Add(pathRoot);
results.Reverse();
return results;
}
internal static List<string> GetDirectoryNames(string directory)
{
List<string> results = [];
@ -147,83 +167,15 @@ internal abstract class XPath
return results;
}
internal static List<string> GetDirectories(string directory)
internal static bool DeleteEmptyDirectories(string rootDirectory)
{
bool result;
List<string> results = [];
string? checkDirectory = directory;
string? pathRoot = Path.GetPathRoot(directory);
if (string.IsNullOrEmpty(pathRoot))
throw new NullReferenceException(nameof(pathRoot));
if (Directory.Exists(directory))
results.Add(directory);
for (int i = 0; i < int.MaxValue; i++)
{
checkDirectory = Path.GetDirectoryName(checkDirectory);
if (string.IsNullOrEmpty(checkDirectory) || checkDirectory == pathRoot)
break;
results.Add(checkDirectory);
}
results.Add(pathRoot);
results.Reverse();
return results;
}
internal static (int level, List<string> directories) Get(string rootDirectory, string sourceDirectory)
{
int result = 0;
string? directory;
string? checkDirectory;
List<string> results = [];
checkDirectory = sourceDirectory;
for (int i = 0; i < int.MaxValue; i++)
{
result += 1;
directory = Path.GetFileName(checkDirectory);
if (string.IsNullOrEmpty(directory))
break;
results.Add(directory);
checkDirectory = Path.GetDirectoryName(checkDirectory);
if (checkDirectory == rootDirectory)
break;
}
results.Reverse();
return new(result, results);
}
internal static string GetDirectory(string sourceDirectory, int level, string directoryName)
{
string result;
string? checkDirectory;
checkDirectory = Path.GetDirectoryName(sourceDirectory);
for (int i = 0; i < level; i++)
checkDirectory = Path.GetDirectoryName(checkDirectory);
if (string.IsNullOrEmpty(checkDirectory))
throw new Exception();
checkDirectory = Path.Combine(checkDirectory, directoryName);
if (!Directory.Exists(checkDirectory))
_ = Directory.CreateDirectory(checkDirectory);
result = checkDirectory;
DeleteEmptyDirectories(rootDirectory, results);
result = results.Count > 0;
return result;
}
internal static void ChangeDateForEmptyDirectories(string rootDirectory, long ticks)
{
DateTime dateTime = new(ticks);
IEnumerable<string> fileSystemEntries;
string[] directories;
if (!Directory.Exists(rootDirectory))
directories = [];
else
directories = Directory.GetDirectories(rootDirectory, "*", SearchOption.AllDirectories);
foreach (string directory in directories)
{
fileSystemEntries = Directory.EnumerateFileSystemEntries(directory, "*", SearchOption.TopDirectoryOnly);
if (fileSystemEntries.Any())
continue;
Directory.SetLastWriteTime(directory, dateTime);
}
}
internal static void MakeHiddenIfAllItemsAreHidden(string rootDirectory)
{
bool check;
@ -266,104 +218,131 @@ internal abstract class XPath
}
}
private static byte GetEnum(bool? ik, bool? dto)
internal static void ChangeDateForEmptyDirectories(string rootDirectory, long ticks)
{
byte result;
if (ik is not null && ik.Value && dto is not null && dto.Value)
result = 11;
else if (ik is not null && ik.Value && dto is not null && !dto.Value)
result = 15;
else if (ik is not null && ik.Value && dto is null)
result = 19;
else if (ik is not null && !ik.Value && dto is not null && dto.Value)
result = 51;
else if (ik is not null && !ik.Value && dto is not null && !dto.Value)
result = 55;
else if (ik is not null && !ik.Value && dto is null)
result = 59;
else if (ik is null && dto is not null && dto.Value)
result = 91;
else if (ik is null && dto is not null && !dto.Value)
result = 95;
else if (ik is null && dto is null)
result = 99;
DateTime dateTime = new(ticks);
IEnumerable<string> fileSystemEntries;
string[] directories;
if (!Directory.Exists(rootDirectory))
directories = [];
else
throw new Exception();
directories = Directory.GetDirectories(rootDirectory, "*", SearchOption.AllDirectories);
foreach (string directory in directories)
{
fileSystemEntries = Directory.EnumerateFileSystemEntries(directory, "*", SearchOption.TopDirectoryOnly);
if (fileSystemEntries.Any())
continue;
Directory.SetLastWriteTime(directory, dateTime);
}
}
internal static string GetRelativePath(string path, int length, bool forceExtensionToLower)
{
string result;
if (forceExtensionToLower)
{
string extension = Path.GetExtension(path);
string extensionLowered = Path.GetExtension(path).ToLower();
if (extension != extensionLowered)
{
string? directoryName = Path.GetDirectoryName(path);
if (string.IsNullOrEmpty(directoryName))
throw new NullReferenceException(directoryName);
string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(path);
if (string.IsNullOrEmpty(fileNameWithoutExtension))
throw new NullReferenceException(fileNameWithoutExtension);
path = Path.Combine(directoryName, $"{fileNameWithoutExtension}{extensionLowered}");
}
}
result = path[length..].Replace(@"\", "/");
return result;
}
internal static byte GetEnum(FilePath filePath) =>
GetEnum(filePath.HasIgnoreKeyword, filePath.HasDateTimeOriginal);
internal static CombinedEnumAndIndex GetCombinedEnumAndIndex(int resultAllInOneSubdirectoryLength, FilePath filePath, string fileName)
internal static string GetDirectory(string sourceDirectory, int level, string directoryName)
{
CombinedEnumAndIndex result;
int converted;
string combined;
byte @enum = GetEnum(filePath.HasIgnoreKeyword, filePath.HasDateTimeOriginal);
string check = fileName.Length < resultAllInOneSubdirectoryLength ?
new('-', resultAllInOneSubdirectoryLength) :
fileName.Split('.')[0][^resultAllInOneSubdirectoryLength..];
if (check.Any(l => !char.IsNumber(l)))
{
combined = $"{@enum}{new('-', resultAllInOneSubdirectoryLength)}";
converted = int.Parse($"1{new string('0', resultAllInOneSubdirectoryLength)}");
}
else
{
combined = $"{@enum}{check}";
converted = int.Parse(check);
}
result = new(combined, @enum, converted);
string result;
string? checkDirectory;
checkDirectory = Path.GetDirectoryName(sourceDirectory);
for (int i = 0; i < level; i++)
checkDirectory = Path.GetDirectoryName(checkDirectory);
if (string.IsNullOrEmpty(checkDirectory))
throw new Exception();
checkDirectory = Path.Combine(checkDirectory, directoryName);
if (!Directory.Exists(checkDirectory))
_ = Directory.CreateDirectory(checkDirectory);
result = checkDirectory;
return result;
}
internal static (int level, List<string> directories) Get(string rootDirectory, string sourceDirectory)
{
int result = 0;
string? directory;
string? checkDirectory;
List<string> results = [];
checkDirectory = sourceDirectory;
for (int i = 0; i < int.MaxValue; i++)
{
result += 1;
directory = Path.GetFileName(checkDirectory);
if (string.IsNullOrEmpty(directory))
break;
results.Add(directory);
checkDirectory = Path.GetDirectoryName(checkDirectory);
if (checkDirectory == rootDirectory)
break;
}
results.Reverse();
return new(result, results);
}
internal static CombinedEnumAndIndex GetCombinedEnumAndIndex(IPropertyConfiguration propertyConfiguration, FilePath filePath)
{
CombinedEnumAndIndex result;
if (filePath.Id is not null)
result = GetCombinedEnumAndIndex(propertyConfiguration.ResultAllInOneSubdirectoryLength, filePath, filePath.Id.Value.ToString());
result = GetCombinedEnumAndIndex(propertyConfiguration, filePath, filePath.Id.Value.ToString());
else
result = GetCombinedEnumAndIndex(propertyConfiguration.ResultAllInOneSubdirectoryLength, filePath, filePath.FileNameFirstSegment);
result = GetCombinedEnumAndIndex(propertyConfiguration, filePath, filePath.FileNameFirstSegment);
return result;
}
private static byte[] GetBytes() =>
[
11,
15,
19,
51,
55,
59,
91,
95,
99
];
private static ReadOnlyDictionary<byte, ReadOnlyCollection<string>> Convert(Dictionary<byte, List<string>> keyValuePairs)
internal static bool WriteAllText(string path, string contents, bool updateDateWhenMatches, bool compareBeforeWrite, DateTime? updateToWhenMatches)
{
Dictionary<byte, ReadOnlyCollection<string>> results = [];
foreach (KeyValuePair<byte, List<string>> keyValuePair in keyValuePairs)
results.Add(keyValuePair.Key, new(keyValuePair.Value));
return results.AsReadOnly();
}
private static ReadOnlyDictionary<byte, ReadOnlyCollection<string>> Convert(List<CombinedEnumAndIndex> collection)
{
Dictionary<byte, List<string>> results = [];
List<string>? c;
foreach (CombinedEnumAndIndex cei in collection)
bool result;
string text;
if (!compareBeforeWrite)
result = true;
else
{
if (!results.TryGetValue(cei.Enum, out c))
if (!File.Exists(path))
text = string.Empty;
else
text = File.ReadAllText(path);
result = text != contents;
if (!result && updateDateWhenMatches)
{
results.Add(cei.Enum, []);
if (!results.TryGetValue(cei.Enum, out c))
throw new Exception();
if (updateToWhenMatches is null)
File.SetLastWriteTime(path, DateTime.Now);
else
File.SetLastWriteTime(path, updateToWhenMatches.Value);
}
c.Add(cei.Combined);
}
return Convert(results);
if (result)
{
if (path.Contains("()"))
File.WriteAllText(path, contents);
else if (path.Contains("{}") && !path.EndsWith(".json"))
File.WriteAllText(path, contents);
else if (path.Contains("[]") && !path.EndsWith(".json"))
File.WriteAllText(path, contents);
else if (path.Contains("{}") && path.EndsWith(".json") && contents[0] == '{')
File.WriteAllText(path, contents);
else if (path.Contains("[]") && path.EndsWith(".json") && contents[0] == '[')
File.WriteAllText(path, contents);
else
File.WriteAllText(path, contents);
}
return result;
}
internal static ReadOnlyDictionary<string, ReadOnlyDictionary<byte, ReadOnlyCollection<string>>> GetKeyValuePairs(IPropertyConfiguration propertyConfiguration, string? resultsFullGroupDirectory, string[]? jsonGroups)
@ -420,4 +399,25 @@ internal abstract class XPath
return results.AsReadOnly();
}
private static byte[] GetBytes() =>
[
11,
15,
19,
51,
55,
59,
91,
95,
99
];
private static ReadOnlyDictionary<byte, ReadOnlyCollection<string>> Convert(Dictionary<byte, List<string>> keyValuePairs)
{
Dictionary<byte, ReadOnlyCollection<string>> results = [];
foreach (KeyValuePair<byte, List<string>> keyValuePair in keyValuePairs)
results.Add(keyValuePair.Key, new(keyValuePair.Value));
return results.AsReadOnly();
}
}