540 lines
30 KiB
C#
540 lines
30 KiB
C#
using System.Collections.ObjectModel;
|
|
using System.Text.Json;
|
|
using View_by_Distance.Shared.Models;
|
|
using View_by_Distance.Shared.Models.Properties;
|
|
using View_by_Distance.Shared.Models.Stateless.Methods;
|
|
|
|
namespace View_by_Distance.Container.Models.Stateless.Methods;
|
|
|
|
internal abstract class Container
|
|
{
|
|
|
|
private record Record(string From, string To, char A);
|
|
|
|
private record FilePair(bool IsUnique,
|
|
ReadOnlyCollection<FilePath> Collection,
|
|
FilePath FilePath,
|
|
Item Item);
|
|
|
|
internal static ReadOnlyCollection<Item> GetValidImageItems(IPropertyConfiguration propertyConfiguration, Models.Container container)
|
|
{
|
|
List<Item> results = [];
|
|
foreach (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();
|
|
}
|
|
|
|
internal static DateTime[] GetContainerDateTimes(ReadOnlyCollection<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 List<int> GetFilteredDistinctIds(IPropertyConfiguration propertyConfiguration, ReadOnlyCollection<Models.Container> readOnlyContainers)
|
|
{
|
|
List<int> results = [];
|
|
ReadOnlyCollection<Item> filteredItems;
|
|
foreach (Models.Container container in readOnlyContainers)
|
|
{
|
|
if (container.Items.Count == 0)
|
|
continue;
|
|
filteredItems = GetValidImageItems(propertyConfiguration, container);
|
|
if (filteredItems.Count == 0)
|
|
continue;
|
|
foreach (Item item in filteredItems)
|
|
{
|
|
if (item.ExifDirectory?.FilePath?.Id is null || item.ResizedFileHolder is null)
|
|
continue;
|
|
if (results.Contains(item.ExifDirectory.FilePath.Id.Value))
|
|
continue;
|
|
results.Add(item.ExifDirectory.FilePath.Id.Value);
|
|
}
|
|
}
|
|
return results;
|
|
}
|
|
|
|
internal static (int, Models.Container[]) GetContainers(IPropertyConfiguration propertyConfiguration, ReadOnlyDictionary<int, Identifier>? splatNineIdentifiers)
|
|
{
|
|
int count;
|
|
Models.Container[] results;
|
|
bool useIgnoreExtensions = true;
|
|
const bool useCeilingAverage = true;
|
|
const string fileSearchFilter = "*";
|
|
IDlibDotNet dlibDotNet = GetDlibDotNet();
|
|
const string directorySearchFilter = "*";
|
|
ReadOnlyDictionary<int, ExifDirectory> exifDirectoriesById = new(new Dictionary<int, ExifDirectory>());
|
|
ReadOnlyCollection<string[]> filesCollection = IDirectory.GetFilesCollection(propertyConfiguration.RootDirectory, directorySearchFilter, fileSearchFilter, useCeilingAverage);
|
|
ReadOnlyCollection<ReadOnlyCollection<FilePath>> filePathsCollection = IDirectory.GetFilePathCollections(propertyConfiguration, filesCollection, useIgnoreExtensions);
|
|
ReadOnlyDictionary<int, ReadOnlyCollection<FilePath>> idToFilePaths = FilePath.GetKeyValuePairs(filePathsCollection);
|
|
(count, results) = GetContainers(dlibDotNet, propertyConfiguration, propertyConfiguration.RootDirectory, idToFilePaths, splatNineIdentifiers, filePathsCollection, exifDirectoriesById, directorySearchFilter);
|
|
return (count, results);
|
|
}
|
|
|
|
private static IDlibDotNet GetDlibDotNet() =>
|
|
throw new NotImplementedException(nameof(IDlibDotNet));
|
|
|
|
private static (int, Models.Container[]) GetContainers(IDlibDotNet dlibDotNet, IPropertyConfiguration propertyConfiguration, string filesCollectionDirectory, ReadOnlyDictionary<int, ReadOnlyCollection<FilePath>> idToFilePaths, ReadOnlyDictionary<int, Identifier>? splatNineIdentifiers, ReadOnlyCollection<ReadOnlyCollection<FilePath>> filePathsCollection, ReadOnlyDictionary<int, ExifDirectory> exifDirectoriesById, string directorySearchFilter)
|
|
{
|
|
List<Models.Container> results = [];
|
|
string directory;
|
|
List<Item>? items;
|
|
Models.Container container;
|
|
List<string> directories = [];
|
|
Dictionary<string, List<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();
|
|
}
|
|
}
|
|
ReadOnlyCollection<FilePair> filePairs = GetFilePairs(dlibDotNet, propertyConfiguration, filesCollectionDirectory, idToFilePaths, splatNineIdentifiers, filePathsCollection, exifDirectoriesById, 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<Item>> keyValuePair in directoryToItems)
|
|
{
|
|
if (keyValuePair.Value.Count == 0)
|
|
continue;
|
|
container = new(keyValuePair.Key, keyValuePair.Value.AsReadOnly());
|
|
results.Add(container);
|
|
}
|
|
return (filePairs.Count, results.ToArray());
|
|
}
|
|
|
|
private static ReadOnlyCollection<FilePair> GetFilePairs(IDlibDotNet dlibDotNet, IPropertyConfiguration propertyConfiguration, string filesCollectionDirectory, ReadOnlyDictionary<int, ReadOnlyCollection<FilePath>> idToFilePaths, ReadOnlyDictionary<int, Identifier>? splatNineIdentifiers, ReadOnlyCollection<ReadOnlyCollection<FilePath>> filePathsCollection, ReadOnlyDictionary<int, ExifDirectory> exifDirectoriesById, string directorySearchFilter)
|
|
{
|
|
ReadOnlyCollection<FilePair> results;
|
|
const string extension = ".json";
|
|
Dictionary<int, ExifDirectory> keyValuePairs = [];
|
|
ReadOnlyCollection<Shared.Models.FilePair> filePairs;
|
|
int maxDegreeOfParallelism = Environment.ProcessorCount;
|
|
int filesCollectionDirectoryLength = filesCollectionDirectory.Length;
|
|
ParallelOptions parallelOptions = new() { MaxDegreeOfParallelism = maxDegreeOfParallelism };
|
|
(_, string bResultsFullGroupDirectory) = dlibDotNet.GetResultsFullGroupDirectories();
|
|
string jsonGroupDirectory = Path.Combine(bResultsFullGroupDirectory, propertyConfiguration.ResultSingleton);
|
|
if (!Directory.Exists(jsonGroupDirectory))
|
|
_ = Directory.CreateDirectory(jsonGroupDirectory);
|
|
filePairs = IFilePair.GetFilePairs(propertyConfiguration, directorySearchFilter, extension, jsonGroupDirectory, filePathsCollection);
|
|
string message;
|
|
message = $") {nameof(Container)} - Preloading ExifDirectory Dictionary - {(int)Math.Floor(new TimeSpan(DateTime.Now.Ticks - dlibDotNet.Ticks).TotalSeconds)} total second(s)";
|
|
dlibDotNet.ConstructProgressBar(filePairs.Count, message);
|
|
_ = Parallel.For(0, filePairs.Count, parallelOptions, (i, state) =>
|
|
ParallelFor(exifDirectoriesById, filePairs[i], keyValuePairs, dlibDotNet.Tick));
|
|
results = GetFilePairs(propertyConfiguration, idToFilePaths, splatNineIdentifiers, exifDirectoriesById, extension, keyValuePairs, filePairs, jsonGroupDirectory, filesCollectionDirectoryLength);
|
|
return results;
|
|
}
|
|
|
|
private static ReadOnlyCollection<FilePair> GetFilePairs(IPropertyConfiguration propertyConfiguration, ReadOnlyDictionary<int, ReadOnlyCollection<FilePath>> idToFilePaths, ReadOnlyDictionary<int, Identifier>? splatNineIdentifiers, ReadOnlyDictionary<int, ExifDirectory> exifDirectoriesById, string extension, Dictionary<int, ExifDirectory> keyValuePairs, ReadOnlyCollection<Shared.Models.FilePair> filePairs, string jsonGroupDirectory, int rootDirectoryLength)
|
|
{
|
|
List<FilePair> results = [];
|
|
Item item;
|
|
string json;
|
|
char? change;
|
|
bool abandoned;
|
|
bool? isArchive;
|
|
string fileName;
|
|
string directory;
|
|
FileInfo fileInfo;
|
|
bool? shouldIgnore;
|
|
DateTime? dateTime;
|
|
string fullFileName;
|
|
string jsonFileName;
|
|
string relativePath;
|
|
bool? fileSizeChanged;
|
|
char hasIgnoreKeyword;
|
|
char hasDateTimeOriginal;
|
|
CombinedEnumAndIndex cei;
|
|
List<Record> records = [];
|
|
bool? lastWriteTimeChanged;
|
|
char missingDateTimeOriginal;
|
|
ExifDirectory? exifDirectory;
|
|
bool isValidImageFormatExtension;
|
|
ReadOnlyCollection<string> keywords;
|
|
FileHolder sourceDirectoryFileHolder;
|
|
ReadOnlyCollection<FilePath>? filePaths;
|
|
foreach (Shared.Models.FilePair filePair in filePairs)
|
|
{
|
|
abandoned = false;
|
|
if (filePair.FilePath.Id is null || (!exifDirectoriesById.TryGetValue(filePair.FilePath.Id.Value, out exifDirectory) && !keyValuePairs.TryGetValue(filePair.FilePath.Id.Value, out exifDirectory)))
|
|
exifDirectory = Metadata.Models.Stateless.Methods.IMetadata.GetExifDirectory(filePair.FilePath);
|
|
keywords = IMetaBase.GetKeywords(exifDirectory?.ExifBaseDirectories);
|
|
shouldIgnore = propertyConfiguration.IgnoreRulesKeyWords.Any(keywords.Contains);
|
|
fileSizeChanged = exifDirectory?.FilePath is not null ? exifDirectory.FilePath.Length != filePair.FilePath.Length : null;
|
|
isValidImageFormatExtension = propertyConfiguration.ValidImageFormatExtensions.Contains(filePair.FilePath.ExtensionLowered);
|
|
isArchive = filePair.FilePath.Id is null || splatNineIdentifiers is null ? null : splatNineIdentifiers.TryGetValue(filePair.FilePath.Id.Value, out Identifier? identifier);
|
|
if (exifDirectory is not null && filePair.FilePath.Id is not null && filePair.FilePath.HasIgnoreKeyword is not null && filePair.FilePath.HasDateTimeOriginal is not null)
|
|
{
|
|
filePaths = null;
|
|
dateTime = IDate.GetDateTimeOriginal(exifDirectory);
|
|
hasIgnoreKeyword = IId.GetHasIgnoreKeyword(filePair.FilePath).ToString()[0];
|
|
hasDateTimeOriginal = IId.GetHasDateTimeOriginal(propertyConfiguration, filePair.FilePath).ToString()[0];
|
|
missingDateTimeOriginal = IId.GetMissingDateTimeOriginal(propertyConfiguration, filePair.FilePath).ToString()[0];
|
|
if (shouldIgnore is not null && shouldIgnore.Value)
|
|
{
|
|
if (filePair.FilePath.FileNameFirstSegment[^1] == hasIgnoreKeyword)
|
|
change = null;
|
|
else
|
|
{
|
|
change = hasIgnoreKeyword;
|
|
if (!idToFilePaths.TryGetValue(filePair.FilePath.Id.Value, out filePaths) || filePaths is null)
|
|
throw new NotSupportedException($"Rename File! <{filePair.FilePath.FileNameFirstSegment}>");
|
|
}
|
|
}
|
|
else if ((shouldIgnore is null || !shouldIgnore.Value) && dateTime is null)
|
|
{
|
|
if (filePair.FilePath.FileNameFirstSegment[^1] == missingDateTimeOriginal)
|
|
change = null;
|
|
else
|
|
{
|
|
change = missingDateTimeOriginal;
|
|
if (!idToFilePaths.TryGetValue(filePair.FilePath.Id.Value, out filePaths) || filePaths is null)
|
|
throw new NotSupportedException($"Rename File! <{filePair.FilePath.FileNameFirstSegment}>");
|
|
}
|
|
}
|
|
else if (filePair.FilePath.FileNameFirstSegment[^1] != hasDateTimeOriginal)
|
|
{
|
|
change = hasDateTimeOriginal;
|
|
if (!idToFilePaths.TryGetValue(filePair.FilePath.Id.Value, out filePaths) || filePaths is null)
|
|
throw new NotSupportedException($"Rename File! <{filePair.FilePath.FileNameFirstSegment}>");
|
|
}
|
|
else
|
|
change = null;
|
|
if (filePaths is not null && change is not null)
|
|
RenameFile(filePair, filePair.FilePath, change.Value, filePaths);
|
|
}
|
|
relativePath = Shared.Models.Stateless.Methods.IPath.GetRelativePath(filePair.FilePath.FullName, rootDirectoryLength, forceExtensionToLower: true);
|
|
lastWriteTimeChanged = exifDirectory?.FilePath is not null ? propertyConfiguration.PropertiesChangedForProperty || exifDirectory.FilePath.LastWriteTicks != filePair.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(jsonGroupDirectory, relativePath, extension)));
|
|
else
|
|
{
|
|
fileName = Path.GetFileName(filePair.FilePath.FullName);
|
|
cei = Shared.Models.Stateless.Methods.IPath.GetCombinedEnumAndIndex(propertyConfiguration, filePair.FilePath);
|
|
directory = Path.Combine(jsonGroupDirectory, cei.Combined);
|
|
jsonFileName = $"{fileName}{extension}";
|
|
fullFileName = Path.Combine(directory, jsonFileName);
|
|
MoveIf(jsonFileName, cei, directory, fullFileName);
|
|
fileInfo = new(fullFileName);
|
|
if (exifDirectory is not null && !fileInfo.Exists)
|
|
{
|
|
json = JsonSerializer.Serialize(exifDirectory, ExifDirectorySourceGenerationContext.Default.ExifDirectory);
|
|
_ = Shared.Models.Stateless.Methods.IPath.WriteAllText(fileInfo.FullName, json, updateDateWhenMatches: false, compareBeforeWrite: true, updateToWhenMatches: null);
|
|
fileInfo.Refresh();
|
|
}
|
|
sourceDirectoryFileHolder = IFileHolder.Get(fileInfo);
|
|
}
|
|
if (sourceDirectoryFileHolder.CreationTime is not null && sourceDirectoryFileHolder.LastWriteTime is not null && filePair.FilePath.LastWriteTicks != sourceDirectoryFileHolder.CreationTime.Value.Ticks)
|
|
{
|
|
File.SetCreationTime(sourceDirectoryFileHolder.FullName, new(filePair.FilePath.LastWriteTicks));
|
|
File.SetLastWriteTime(sourceDirectoryFileHolder.FullName, sourceDirectoryFileHolder.LastWriteTime.Value);
|
|
}
|
|
item = Item.Get(filePair.FilePath, sourceDirectoryFileHolder, relativePath, isArchive, filePair.IsNotUniqueAndNeedsReview, filePair.IsUnique, isValidImageFormatExtension, exifDirectory, abandoned, fileSizeChanged, lastWriteTimeChanged);
|
|
results.Add(new(filePair.IsUnique, filePair.Collection, filePair.FilePath, item));
|
|
}
|
|
return results.AsReadOnly();
|
|
}
|
|
|
|
private static void ParallelFor(ReadOnlyDictionary<int, ExifDirectory> exifDirectoriesById, Shared.Models.FilePair filePair, Dictionary<int, ExifDirectory> keyValuePairs, Action? tick)
|
|
{
|
|
tick?.Invoke();
|
|
if (filePair.FilePath.Id is not null && (!exifDirectoriesById.TryGetValue(filePair.FilePath.Id.Value, out ExifDirectory? exifDirectory) || exifDirectory.FilePath?.Id is null))
|
|
{
|
|
exifDirectory = Metadata.Models.Stateless.Methods.IMetadata.GetExifDirectory(filePair.FilePath);
|
|
lock (keyValuePairs)
|
|
{
|
|
if (!keyValuePairs.ContainsKey(filePair.FilePath.Id.Value))
|
|
keyValuePairs.Add(filePair.FilePath.Id.Value, exifDirectory);
|
|
}
|
|
}
|
|
}
|
|
|
|
private static void RenameFile(Shared.Models.FilePair filePair, FilePath filePath, char change, ReadOnlyCollection<FilePath> filePaths)
|
|
{
|
|
string checkFile;
|
|
if (filePath.DirectoryFullPath.Contains("Results") && filePath.DirectoryFullPath.Contains("Resize"))
|
|
File.Delete(filePath.FullName);
|
|
if (filePair.Match is not null)
|
|
{
|
|
string fileNameWithoutExtensionSecond = Path.GetFileNameWithoutExtension(filePair.Match.NameWithoutExtension);
|
|
string extensionSecond = Path.GetExtension(filePair.Match.Name);
|
|
checkFile = Path.Combine(filePair.Match.DirectoryFullPath, $"{fileNameWithoutExtensionSecond[..^1]}{change}{extensionSecond}{filePair.Match.ExtensionLowered}");
|
|
if (!File.Exists(checkFile) && File.Exists(filePair.Match.FullName))
|
|
File.Move(filePair.Match.FullName, checkFile);
|
|
}
|
|
foreach (FilePath f in filePaths)
|
|
{
|
|
checkFile = Path.Combine(f.DirectoryFullPath, $"{f.NameWithoutExtension[..^1]}{change}{f.ExtensionLowered}");
|
|
if (File.Exists(checkFile) || !File.Exists(f.FullName))
|
|
continue;
|
|
File.Move(f.FullName, checkFile);
|
|
}
|
|
}
|
|
|
|
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);
|
|
}
|
|
}
|
|
|
|
internal static List<string> GetFilteredDistinctFileNameFirstSegments(IPropertyConfiguration propertyConfiguration, ReadOnlyCollection<Models.Container> readOnlyContainers)
|
|
{
|
|
List<string> results = [];
|
|
ReadOnlyCollection<Item> filteredItems;
|
|
foreach (Models.Container container in readOnlyContainers)
|
|
{
|
|
if (container.Items.Count == 0)
|
|
continue;
|
|
filteredItems = GetValidImageItems(propertyConfiguration, container);
|
|
if (filteredItems.Count == 0)
|
|
continue;
|
|
foreach (Item item in filteredItems)
|
|
{
|
|
if (item.ExifDirectory?.FilePath?.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<Item> GetValidImageItems(IPropertyConfiguration propertyConfiguration, ReadOnlyCollection<Models.Container> containers, bool distinctItems, bool filterItems)
|
|
{
|
|
List<Item> results = [];
|
|
List<int> distinct = [];
|
|
ReadOnlyCollection<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 (Item item in filteredItems)
|
|
{
|
|
if (item.ExifDirectory?.FilePath?.Id is null || item.ResizedFileHolder is null)
|
|
continue;
|
|
if (distinctItems)
|
|
{
|
|
if (distinct.Contains(item.ExifDirectory.FilePath.Id.Value))
|
|
continue;
|
|
distinct.Add(item.ExifDirectory.FilePath.Id.Value);
|
|
}
|
|
results.Add(item);
|
|
}
|
|
}
|
|
return results.AsReadOnly();
|
|
}
|
|
|
|
internal static ReadOnlyCollection<Models.Container> GetContainers(IDlibDotNet dlibDotNet, IPropertyConfiguration propertyConfiguration, string facesFileNameExtension, string facesHiddenFileNameExtension, string eDistanceContentDirectory, string filesCollectionDirectory, ReadOnlyDictionary<int, Identifier>? splatNineIdentifiers, ReadOnlyCollection<ReadOnlyCollection<FilePath>> filePathsCollection, ReadOnlyDictionary<int, ExifDirectory> exifDirectoriesById)
|
|
{
|
|
Models.Container[] results;
|
|
const string directorySearchFilter = "*";
|
|
ReadOnlyDictionary<int, ReadOnlyCollection<FilePath>> idToFilePaths = FilePath.GetKeyValuePairs(filePathsCollection);
|
|
(_, results) = GetContainers(dlibDotNet, propertyConfiguration, filesCollectionDirectory, idToFilePaths, splatNineIdentifiers, filePathsCollection, exifDirectoriesById, directorySearchFilter);
|
|
AnyMoved(dlibDotNet, propertyConfiguration, facesFileNameExtension, facesHiddenFileNameExtension, eDistanceContentDirectory, filePathsCollection, idToFilePaths, directorySearchFilter);
|
|
return results.AsReadOnly();
|
|
}
|
|
|
|
private static void AnyMoved(IDlibDotNet dlibDotNet, IPropertyConfiguration propertyConfiguration, string facesFileNameExtension, string facesHiddenFileNameExtension, string eDistanceContentDirectory, ReadOnlyCollection<ReadOnlyCollection<FilePath>> filePathsCollection, ReadOnlyDictionary<int, ReadOnlyCollection<FilePath>> idToFilePaths, string directorySearchFilter)
|
|
{
|
|
const string extension = ".json";
|
|
(_, string bResultsFullGroupDirectory) = dlibDotNet.GetResultsFullGroupDirectories();
|
|
string bMetaSingletonDirectory = Path.Combine(bResultsFullGroupDirectory, propertyConfiguration.ResultSingleton);
|
|
if (!Directory.Exists(bMetaSingletonDirectory))
|
|
_ = Directory.CreateDirectory(bMetaSingletonDirectory);
|
|
_ = IFilePair.GetFilePairs(propertyConfiguration, directorySearchFilter, extension, bMetaSingletonDirectory, filePathsCollection);
|
|
(string cResultsFullGroupDirectory, _, string dResultsFullGroupDirectory, _) = dlibDotNet.GetResultsFullGroupDirectories("Original");
|
|
string cResizeSingletonDirectory = Path.Combine(cResultsFullGroupDirectory, propertyConfiguration.ResultSingleton);
|
|
if (!Directory.Exists(cResizeSingletonDirectory))
|
|
_ = Directory.CreateDirectory(cResizeSingletonDirectory);
|
|
_ = IFilePair.GetFilePairs(propertyConfiguration, directorySearchFilter, extension, cResizeSingletonDirectory, filePathsCollection);
|
|
string dFaceCollectionDirectory = Path.Combine(dResultsFullGroupDirectory, propertyConfiguration.ResultCollection);
|
|
if (!Directory.Exists(dFaceCollectionDirectory))
|
|
_ = Directory.CreateDirectory(dFaceCollectionDirectory);
|
|
_ = IFilePair.GetFilePairs(propertyConfiguration, directorySearchFilter, extension, dFaceCollectionDirectory, filePathsCollection);
|
|
string dFaceContentDirectory = Path.Combine(dResultsFullGroupDirectory, propertyConfiguration.ResultContent);
|
|
if (!Directory.Exists(dFaceContentDirectory))
|
|
_ = Directory.CreateDirectory(dFaceContentDirectory);
|
|
AnyMovedFace(propertyConfiguration, facesFileNameExtension, facesHiddenFileNameExtension, idToFilePaths, dFaceContentDirectory);
|
|
AnyMovedDistance(propertyConfiguration, facesFileNameExtension, idToFilePaths, eDistanceContentDirectory);
|
|
}
|
|
|
|
private static void AnyMovedFace(IPropertyConfiguration propertyConfiguration, string extension, string hiddenExtension, ReadOnlyDictionary<int, ReadOnlyCollection<FilePath>> idToFilePaths, string jsonGroupDirectory)
|
|
{
|
|
string directory;
|
|
string checkFile;
|
|
string directoryName;
|
|
List<string> files = [];
|
|
string[] fileNameSegments;
|
|
List<string> directories = [];
|
|
files.AddRange(Directory.GetFiles(jsonGroupDirectory, $"*{extension}", SearchOption.AllDirectories));
|
|
files.AddRange(Directory.GetFiles(jsonGroupDirectory, $"*{hiddenExtension}", SearchOption.AllDirectories));
|
|
foreach (string file in files)
|
|
{
|
|
directory = Path.GetDirectoryName(file) ?? throw new Exception();
|
|
if (!directories.Contains(directory))
|
|
directories.Add(directory);
|
|
directoryName = Path.GetFileName(directory);
|
|
fileNameSegments = Path.GetFileName(file).Split('.');
|
|
if (fileNameSegments[0] != directoryName)
|
|
{
|
|
fileNameSegments[0] = string.Empty;
|
|
checkFile = Path.Combine(directory, $"{directoryName}{string.Join('.', fileNameSegments)}");
|
|
if (!File.Exists(checkFile))
|
|
File.Move(file, checkFile);
|
|
else
|
|
{
|
|
if (new FileInfo(file).LastWriteTime > new FileInfo(checkFile).LastWriteTime)
|
|
File.Delete(file);
|
|
else
|
|
File.Move(file, checkFile, true);
|
|
}
|
|
}
|
|
}
|
|
if (directories.Count > 0)
|
|
AnyMovedFace(propertyConfiguration, idToFilePaths, directories);
|
|
}
|
|
|
|
private static void AnyMovedFace(IPropertyConfiguration propertyConfiguration, IReadOnlyDictionary<int, ReadOnlyCollection<FilePath>> fileNamesToFiles, List<string> directories)
|
|
{
|
|
bool result = false;
|
|
string checkFile;
|
|
FilePath? filePath;
|
|
string subDirectory;
|
|
string directoryName;
|
|
string checkDirectory;
|
|
FileHolder fileHolder;
|
|
string directoryNameWith;
|
|
List<string> directoryNames = [];
|
|
ReadOnlyCollection<FilePath>? collection;
|
|
foreach (string directory in directories)
|
|
{
|
|
fileHolder = IFileHolder.Get(Path.GetFileName(directory));
|
|
filePath = FilePath.GetNullSafe(propertyConfiguration, fileHolder, index: null);
|
|
if (filePath?.Id is null)
|
|
continue;
|
|
if (!fileNamesToFiles.TryGetValue(filePath.Id.Value, out collection))
|
|
throw new Exception();
|
|
directoryNames.Clear();
|
|
foreach (FilePath f in collection)
|
|
directoryNames.Add(Path.GetFileName(f.DirectoryFullPath) ?? throw new Exception());
|
|
if (directoryNames.Count == 0 || directoryNames.Distinct().Count() != 1)
|
|
continue;
|
|
directoryName = Path.GetFileName(Path.GetDirectoryName(directory)) ?? throw new Exception();
|
|
if (directoryName != directoryNames[0])
|
|
{
|
|
subDirectory = Path.GetDirectoryName(Path.GetDirectoryName(directory)) ?? throw new Exception();
|
|
checkDirectory = Path.Combine(subDirectory, directoryNames[0]);
|
|
if (!Directory.Exists(checkDirectory))
|
|
_ = Directory.CreateDirectory(checkDirectory);
|
|
directoryNameWith = collection.Count > 1 ? directoryName : $"{collection[0].NameWithoutExtension}";
|
|
checkFile = Path.Combine(checkDirectory, directoryNameWith);
|
|
if (!result)
|
|
result = true;
|
|
if (!Directory.Exists(checkFile))
|
|
Directory.Move(directory, checkFile);
|
|
else
|
|
{
|
|
if (new DirectoryInfo(directory).LastWriteTime > new DirectoryInfo(checkFile).LastWriteTime)
|
|
Directory.Delete(directory, recursive: true);
|
|
else
|
|
{
|
|
Directory.Delete(checkFile, recursive: true);
|
|
Directory.Move(directory, checkFile);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
private static void AnyMovedDistance(IPropertyConfiguration propertyConfiguration, string extension, ReadOnlyDictionary<int, ReadOnlyCollection<FilePath>> idToFilePaths, string jsonGroupDirectory)
|
|
{
|
|
bool result = false;
|
|
string checkFile;
|
|
string directory;
|
|
FilePath filePath;
|
|
FileHolder fileHolder;
|
|
string[] fileNameSegments;
|
|
List<string> fileNames = [];
|
|
ReadOnlyCollection<FilePath>? collection;
|
|
string[] files = Directory.GetFiles(jsonGroupDirectory, $"*{extension}", SearchOption.AllDirectories);
|
|
foreach (string file in files)
|
|
{
|
|
fileHolder = IFileHolder.Get(file);
|
|
if (!fileHolder.Exists)
|
|
continue;
|
|
filePath = FilePath.Get(propertyConfiguration, fileHolder, index: null);
|
|
if (filePath.Id is null)
|
|
continue;
|
|
fileNameSegments = filePath.Name.Split('.');
|
|
if (!idToFilePaths.TryGetValue(filePath.Id.Value, out collection))
|
|
continue;
|
|
fileNames.Clear();
|
|
foreach (FilePath f in collection)
|
|
fileNames.Add(f.NameWithoutExtension ?? throw new Exception());
|
|
if (fileNames.Count == 0 || fileNames.Distinct().Count() != 1)
|
|
continue;
|
|
if (filePath.FileNameFirstSegment != fileNames[0])
|
|
{
|
|
fileNameSegments[0] = string.Empty;
|
|
directory = Path.GetDirectoryName(file) ?? throw new Exception();
|
|
checkFile = Path.Combine(directory, $"{fileNames[0]}{string.Join('.', fileNameSegments)}");
|
|
if (!result)
|
|
result = true;
|
|
if (!File.Exists(checkFile))
|
|
File.Move(file, checkFile);
|
|
else
|
|
{
|
|
if (new FileInfo(file).LastWriteTime > new FileInfo(checkFile).LastWriteTime)
|
|
File.Delete(file);
|
|
else
|
|
File.Move(file, checkFile, true);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
} |