Changed GetDimensions to handle a stream at the end and one exit Switched to using Action? over IDlibDotNet for Tick method Switched to using AsReadOnly over new() Moved Meta Base to Shared
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);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
} |