Merge Kristy Files
This commit is contained in:
206
Rename/Rename.cs
206
Rename/Rename.cs
@ -12,6 +12,15 @@ namespace View_by_Distance.Rename;
|
||||
public class Rename
|
||||
{
|
||||
|
||||
private record Record(int Index,
|
||||
bool IsIgnoreExtension,
|
||||
bool IsValidImageFormatExtension,
|
||||
List<FileHolder> FileHolders,
|
||||
bool FfmpegFilesPresent,
|
||||
DateTime? DateTimeOriginal,
|
||||
DateTime?[] DateTimes,
|
||||
int? Id);
|
||||
|
||||
private readonly AppSettings _AppSettings;
|
||||
private readonly string _WorkingDirectory;
|
||||
private readonly Configuration _Configuration;
|
||||
@ -90,44 +99,27 @@ public class Rename
|
||||
return results;
|
||||
}
|
||||
|
||||
private List<(FileHolder, string, string)> GetToDoCollection(ProgressBar progressBar, string[] files, bool nefPresent)
|
||||
private List<Record> GetRecords(int offset, ProgressBar progressBar, string[] files)
|
||||
{
|
||||
List<(FileHolder, string, string)> results = new();
|
||||
List<Record> results = new();
|
||||
int? id;
|
||||
int season;
|
||||
string? message;
|
||||
string checkFile;
|
||||
DateTime dateTime;
|
||||
bool? isWrongYear;
|
||||
string seasonName;
|
||||
string? directory;
|
||||
TimeSpan? timeSpan;
|
||||
string directoryName;
|
||||
DateTime?[] dateTimes;
|
||||
FileHolder fileHolder;
|
||||
string[]? ffmpegFiles;
|
||||
bool isIgnoreExtension;
|
||||
string? seasonDirectory;
|
||||
const string jpg = ".jpg";
|
||||
DateTime? minimumDateTime;
|
||||
string checkFileExtension;
|
||||
DateTime? dateTimeFromName;
|
||||
DateTime? dateTimeOriginal;
|
||||
const string jpeg = ".jpeg";
|
||||
DateTime?[] metadataDateTimes;
|
||||
List<string> distinct = new();
|
||||
string[] directoryNameSegments;
|
||||
bool isValidImageFormatExtension;
|
||||
DateTime? metadataDateTimeOriginal;
|
||||
bool nameWithoutExtensionIsIdFormat;
|
||||
IReadOnlyList<MetadataExtractor.Directory> directories;
|
||||
foreach (string file in files)
|
||||
for (int i = 0; i < files.Length; i++)
|
||||
{
|
||||
progressBar.Tick();
|
||||
fileHolder = new(file);
|
||||
fileHolder = new(files[i]);
|
||||
if (!fileHolder.Exists)
|
||||
continue;
|
||||
directory = Path.GetDirectoryName(file);
|
||||
directory = Path.GetDirectoryName(files[i]);
|
||||
if (string.IsNullOrEmpty(directory))
|
||||
continue;
|
||||
if (fileHolder.ExtensionLowered == ".id" || fileHolder.ExtensionLowered == ".lsv" || fileHolder.DirectoryName is null)
|
||||
@ -137,7 +129,6 @@ public class Rename
|
||||
nameWithoutExtensionIsIdFormat = Shared.Models.Stateless.Methods.IProperty.NameWithoutExtensionIsIdFormat(fileHolder);
|
||||
if (nameWithoutExtensionIsIdFormat)
|
||||
continue;
|
||||
dateTimeFromName = Shared.Models.Stateless.Methods.IProperty.GetDateTimeFromName(fileHolder);
|
||||
isValidImageFormatExtension = _PropertyConfiguration.ValidImageFormatExtensions.Contains(fileHolder.ExtensionLowered);
|
||||
isIgnoreExtension = isValidImageFormatExtension && _PropertyConfiguration.IgnoreExtensions.Contains(fileHolder.ExtensionLowered);
|
||||
if (!isIgnoreExtension && isValidImageFormatExtension)
|
||||
@ -145,11 +136,11 @@ public class Rename
|
||||
else
|
||||
{
|
||||
try
|
||||
{ directories = MetadataExtractor.ImageMetadataReader.ReadMetadata(file); }
|
||||
{ directories = MetadataExtractor.ImageMetadataReader.ReadMetadata(files[i]); }
|
||||
catch (Exception) { continue; }
|
||||
CommandTask<CommandResult> result = Cli.Wrap("ffmpeg.exe")
|
||||
// .WithArguments(new[] { "-ss", "00:00:00", "-t", "00:00:00", "-i", file, "-qscale:v", "2", "-r", "0.01", $"{fileHolder.Name}-%4d.jpg" })
|
||||
.WithArguments(new[] { "-i", file, "-vframes", "1", $"{fileHolder.Name}-%4d.jpg" })
|
||||
// .WithArguments(new[] { "-ss", "00:00:00", "-t", "00:00:00", "-i", files[i], "-qscale:v", "2", "-r", "0.01", $"{fileHolder.Name}-%4d.jpg" })
|
||||
.WithArguments(new[] { "-i", files[i], "-vframes", "1", $"{fileHolder.Name}-%4d.jpg" })
|
||||
.WithWorkingDirectory(fileHolder.DirectoryName)
|
||||
.ExecuteAsync();
|
||||
result.Task.Wait();
|
||||
@ -166,9 +157,57 @@ public class Rename
|
||||
if (fileHolder.DirectoryName is null)
|
||||
continue;
|
||||
}
|
||||
(dateTimeOriginal, dateTimes, id, message) = Shared.Models.Stateless.Methods.IProperty.Get(fileHolder, isIgnoreExtension, isValidImageFormatExtension, _PropertyConfiguration.PopulatePropertyId);
|
||||
if (ffmpegFiles is not null)
|
||||
{
|
||||
fileHolder = new(files[i]);
|
||||
foreach (string ffmpegFile in ffmpegFiles)
|
||||
File.Delete(ffmpegFile);
|
||||
}
|
||||
if (message is not null)
|
||||
throw new Exception(message);
|
||||
results.Add(new(i + offset, isIgnoreExtension, isValidImageFormatExtension, new() { fileHolder }, ffmpegFiles is null, dateTimeOriginal, dateTimes, id));
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
private List<(FileHolder, string, string)> GetToDoCollection(ProgressBar progressBar, bool nefPresent, List<Record> records, int length)
|
||||
{
|
||||
List<(FileHolder, string, string)> results = new();
|
||||
string id;
|
||||
int season;
|
||||
string checkFile;
|
||||
bool? isWrongYear;
|
||||
DateTime dateTime;
|
||||
string seasonName;
|
||||
TimeSpan? timeSpan;
|
||||
string directoryName;
|
||||
FileHolder fileHolder;
|
||||
string? seasonDirectory;
|
||||
const string jpg = ".jpg";
|
||||
DateTime? minimumDateTime;
|
||||
string checkFileExtension;
|
||||
DateTime? dateTimeFromName;
|
||||
const string jpeg = ".jpeg";
|
||||
DateTime?[] metadataDateTimes;
|
||||
List<string> distinct = new();
|
||||
string[] directoryNameSegments;
|
||||
DateTime? dateTimeOriginalByLogic;
|
||||
DateTime? metadataDateTimeOriginal;
|
||||
IReadOnlyList<MetadataExtractor.Directory> directories;
|
||||
foreach (Record record in records)
|
||||
{
|
||||
progressBar.Tick();
|
||||
if (record.FileHolders.Count != 1)
|
||||
continue;
|
||||
fileHolder = record.FileHolders.First();
|
||||
if (!fileHolder.Exists)
|
||||
continue;
|
||||
if (string.IsNullOrEmpty(fileHolder.DirectoryName))
|
||||
continue;
|
||||
if (fileHolder.ExtensionLowered == jpeg)
|
||||
{
|
||||
if (!isIgnoreExtension && isValidImageFormatExtension)
|
||||
if (!record.IsIgnoreExtension && record.IsValidImageFormatExtension)
|
||||
{
|
||||
if (File.Exists($"{fileHolder.FullName}.id"))
|
||||
{
|
||||
@ -178,7 +217,7 @@ public class Rename
|
||||
if (distinct.Contains(checkFile))
|
||||
continue;
|
||||
distinct.Add(checkFile);
|
||||
results.Add(new(new($"{fileHolder.FullName}.id"), directory, checkFile));
|
||||
results.Add(new(new($"{fileHolder.FullName}.id"), fileHolder.DirectoryName, checkFile));
|
||||
}
|
||||
checkFile = Path.Combine(fileHolder.DirectoryName, $"{fileHolder.NameWithoutExtension}{jpg}");
|
||||
if (File.Exists(checkFile))
|
||||
@ -186,11 +225,11 @@ public class Rename
|
||||
if (distinct.Contains(checkFile))
|
||||
continue;
|
||||
distinct.Add(checkFile);
|
||||
results.Add(new(fileHolder, directory, checkFile));
|
||||
results.Add(new(fileHolder, fileHolder.DirectoryName, checkFile));
|
||||
if (nefPresent)
|
||||
results.Add(new(new($"{fileHolder.FullName[..^4]}.tif"), directory, $"{checkFile[..^4]}.tif"));
|
||||
results.Add(new(new($"{fileHolder.FullName[..^4]}.tif"), fileHolder.DirectoryName, $"{checkFile[..^4]}.tif"));
|
||||
if (nefPresent)
|
||||
results.Add(new(new($"{fileHolder.FullName[..^4]}.nef"), directory, $"{checkFile[..^4]}.nef"));
|
||||
results.Add(new(new($"{fileHolder.FullName[..^4]}.nef"), fileHolder.DirectoryName, $"{checkFile[..^4]}.nef"));
|
||||
if (File.Exists(checkFile))
|
||||
continue;
|
||||
File.Move(fileHolder.FullName, checkFile);
|
||||
@ -199,24 +238,16 @@ public class Rename
|
||||
continue;
|
||||
}
|
||||
}
|
||||
(dateTimeOriginal, dateTimes, id, message) = Shared.Models.Stateless.Methods.IProperty.Get(fileHolder, isIgnoreExtension, isValidImageFormatExtension, _PropertyConfiguration.PopulatePropertyId);
|
||||
if (ffmpegFiles is not null)
|
||||
{
|
||||
fileHolder = new(file);
|
||||
foreach (string ffmpegFile in ffmpegFiles)
|
||||
File.Delete(ffmpegFile);
|
||||
}
|
||||
if (fileHolder.DirectoryName is null)
|
||||
continue;
|
||||
minimumDateTime = dateTimes.Min();
|
||||
dateTimeFromName = Shared.Models.Stateless.Methods.IProperty.GetDateTimeFromName(fileHolder);
|
||||
minimumDateTime = record.DateTimes.Min();
|
||||
if (minimumDateTime is null)
|
||||
throw new NotSupportedException();
|
||||
if (dateTimeOriginal is null)
|
||||
if (record.DateTimeOriginal is null)
|
||||
timeSpan = null;
|
||||
else
|
||||
timeSpan = new(Math.Abs(minimumDateTime.Value.Ticks - dateTimeOriginal.Value.Ticks));
|
||||
timeSpan = new(Math.Abs(minimumDateTime.Value.Ticks - record.DateTimeOriginal.Value.Ticks));
|
||||
if (timeSpan is not null && timeSpan.Value.TotalMinutes < _AppSettings.MaxMinutesDelta)
|
||||
(metadataDateTimeOriginal, metadataDateTimes) = (null, Array.Empty<DateTime?>());
|
||||
(dateTimeOriginalByLogic, metadataDateTimeOriginal, metadataDateTimes) = (record.DateTimeOriginal, null, Array.Empty<DateTime?>());
|
||||
else
|
||||
{
|
||||
if (_PropertyConfiguration.IgnoreExtensions.Contains(fileHolder.ExtensionLowered))
|
||||
@ -225,16 +256,21 @@ public class Rename
|
||||
{ directories = MetadataExtractor.ImageMetadataReader.ReadMetadata(fileHolder.FullName); }
|
||||
catch (Exception) { continue; }
|
||||
(metadataDateTimeOriginal, metadataDateTimes) = Metadata.Models.Stateless.Methods.IMetadata.GetDateTimes(fileHolder, directories);
|
||||
dateTimeOriginal ??= metadataDateTimeOriginal;
|
||||
if (ffmpegFiles is not null && dateTimeOriginal is not null)
|
||||
minimumDateTime = dateTimeOriginal.Value;
|
||||
if (dateTimeOriginal is null)
|
||||
dateTimeOriginalByLogic = record.DateTimeOriginal is not null ? record.DateTimeOriginal : metadataDateTimeOriginal;
|
||||
if (record.FfmpegFilesPresent && dateTimeOriginalByLogic is not null)
|
||||
minimumDateTime = dateTimeOriginalByLogic.Value;
|
||||
if (dateTimeOriginalByLogic is null)
|
||||
timeSpan = null;
|
||||
else
|
||||
timeSpan = new(Math.Abs(minimumDateTime.Value.Ticks - dateTimeOriginal.Value.Ticks));
|
||||
timeSpan = new(Math.Abs(minimumDateTime.Value.Ticks - dateTimeOriginalByLogic.Value.Ticks));
|
||||
}
|
||||
if (timeSpan is null || timeSpan.Value.TotalMinutes > _AppSettings.MaxMinutesDelta)
|
||||
(isWrongYear, seasonDirectory) = (null, !_AppSettings.ForceIdName ? null : Path.Combine(fileHolder.DirectoryName, "Unknown"));
|
||||
{
|
||||
if (string.IsNullOrEmpty(_AppSettings.DefaultUnknownDirectoryName))
|
||||
(isWrongYear, seasonDirectory) = (null, !_AppSettings.ForceIdName ? null : fileHolder.DirectoryName);
|
||||
else
|
||||
(isWrongYear, seasonDirectory) = (null, !_AppSettings.ForceIdName ? null : Path.Combine(fileHolder.DirectoryName, _AppSettings.DefaultUnknownDirectoryName));
|
||||
}
|
||||
else
|
||||
{
|
||||
directoryName = Path.GetFileName(fileHolder.DirectoryName);
|
||||
@ -251,12 +287,10 @@ public class Rename
|
||||
{
|
||||
if (dateTimeFromName is not null && isWrongYear is not null && isWrongYear.Value)
|
||||
minimumDateTime = dateTimeFromName.Value;
|
||||
else if (dateTimeOriginal is not null)
|
||||
minimumDateTime = dateTimeOriginal.Value;
|
||||
else if (metadataDateTimeOriginal is not null)
|
||||
minimumDateTime = metadataDateTimeOriginal.Value;
|
||||
else if (dateTimeOriginalByLogic is not null)
|
||||
minimumDateTime = dateTimeOriginalByLogic.Value;
|
||||
else
|
||||
minimumDateTime = new DateTime?[] { dateTimes.Where(l => l is not null).Min(), metadataDateTimes.Where(l => l is not null).Min() }.Min();
|
||||
minimumDateTime = new DateTime?[] { record.DateTimes.Where(l => l is not null).Min(), metadataDateTimes.Where(l => l is not null).Min() }.Min();
|
||||
if (minimumDateTime is null)
|
||||
continue;
|
||||
checkFileExtension = fileHolder.ExtensionLowered == jpeg ? jpg : fileHolder.ExtensionLowered;
|
||||
@ -266,18 +300,19 @@ public class Rename
|
||||
if (distinct.Contains(checkFile))
|
||||
continue;
|
||||
distinct.Add(checkFile);
|
||||
results.Add(new(fileHolder, directory, checkFile));
|
||||
results.Add(new(fileHolder, fileHolder.DirectoryName, checkFile));
|
||||
if (nefPresent)
|
||||
results.Add(new(new($"{fileHolder.FullName[..^4]}.tif"), directory, $"{checkFile[..^4]}.tif"));
|
||||
results.Add(new(new($"{fileHolder.FullName[..^4]}.tif"), fileHolder.DirectoryName, $"{checkFile[..^4]}.tif"));
|
||||
if (nefPresent)
|
||||
results.Add(new(new($"{fileHolder.FullName[..^4]}.nef"), directory, $"{checkFile[..^4]}.nef"));
|
||||
results.Add(new(new($"{fileHolder.FullName[..^4]}.nef"), fileHolder.DirectoryName, $"{checkFile[..^4]}.nef"));
|
||||
}
|
||||
else
|
||||
{
|
||||
if (id is null)
|
||||
if (record.Id is null)
|
||||
continue;
|
||||
id = Shared.Models.Stateless.Methods.IDirectory.GetPaddedId(length, record.Index, record.Id.Value);
|
||||
checkFileExtension = fileHolder.ExtensionLowered == jpeg ? jpg : fileHolder.ExtensionLowered;
|
||||
checkFile = Path.Combine(seasonDirectory, $"{id.Value}{checkFileExtension}");
|
||||
checkFile = Path.Combine(seasonDirectory, $"{id}{checkFileExtension}");
|
||||
if (checkFile == fileHolder.FullName)
|
||||
continue;
|
||||
if (File.Exists(checkFile))
|
||||
@ -317,13 +352,16 @@ public class Rename
|
||||
{
|
||||
List<string> results = new();
|
||||
string message;
|
||||
bool nefPresent;
|
||||
bool nefPresentCheck;
|
||||
bool nefPresent = false;
|
||||
ProgressBar progressBar;
|
||||
List<Record> records = new();
|
||||
const string fileSearchFilter = "*";
|
||||
const string directorySearchFilter = "*";
|
||||
List<string> distinctDirectories = new();
|
||||
List<(FileHolder, string)> verifiedToDoCollection = new();
|
||||
List<(FileHolder, string, string)> toDoCollection = new();
|
||||
int offset = Shared.Models.Stateless.Methods.IDirectory.GetOffset();
|
||||
ProgressBarOptions options = new() { ProgressCharacter = '─', ProgressBarOnBottom = true, DisableBottomPercentage = true };
|
||||
List<string[]> filesCollection = Shared.Models.Stateless.Methods.IDirectory.GetFilesCollection(_PropertyConfiguration.RootDirectory, directorySearchFilter, fileSearchFilter);
|
||||
int count = filesCollection.Select(l => l.Length).Sum();
|
||||
@ -331,28 +369,52 @@ public class Rename
|
||||
{
|
||||
if (!files.Any())
|
||||
continue;
|
||||
// foreach (string file in files)
|
||||
// foreach (string files[i] in files)
|
||||
// {
|
||||
// if (!file.EndsWith(".del"))
|
||||
// if (!files[i].EndsWith(".del"))
|
||||
// continue;
|
||||
// File.Move(file, file[..^4]);
|
||||
// File.Move(files[i], files[i][..^4]);
|
||||
// }
|
||||
// continue;
|
||||
distinctDirectories.Clear();
|
||||
message = $") Renaming files for <{files.FirstOrDefault()}>";
|
||||
progressBar = new(files.Length, message, options);
|
||||
if (_AppSettings.RenameUndo)
|
||||
{
|
||||
message = $") Undo renaming files for <{files.FirstOrDefault()}>";
|
||||
progressBar = new(files.Length, message, options);
|
||||
toDoCollection.AddRange(GetRenameUndoToDoCollection(progressBar, files));
|
||||
}
|
||||
else
|
||||
{
|
||||
nefPresent = files.Any(l => l.EndsWith(".NEF"));
|
||||
if (!nefPresent)
|
||||
toDoCollection.AddRange(GetToDoCollection(progressBar, files, nefPresent));
|
||||
message = $"{records.Count:00000}) Gathering records for files next to <{files.FirstOrDefault()}>";
|
||||
progressBar = new(files.Length, message, options);
|
||||
nefPresentCheck = files.Any(l => l.EndsWith(".NEF"));
|
||||
if (!nefPresentCheck)
|
||||
records.AddRange(GetRecords(offset + records.Count, progressBar, files));
|
||||
else
|
||||
toDoCollection.AddRange(GetToDoCollection(progressBar, (from l in files where l.EndsWith(".JPG") select l).ToArray(), nefPresent));
|
||||
{
|
||||
if (!nefPresent)
|
||||
nefPresent = true;
|
||||
records.AddRange(GetRecords(offset + records.Count, progressBar, (from l in files where l.EndsWith(".JPG") select l).ToArray()));
|
||||
}
|
||||
}
|
||||
progressBar.Dispose();
|
||||
}
|
||||
if (records.Any())
|
||||
{
|
||||
int length = 0;
|
||||
foreach (Record record in records)
|
||||
{
|
||||
if (record.Id is null)
|
||||
continue;
|
||||
if (length > record.Id.Value.ToString().Length)
|
||||
continue;
|
||||
length = record.Id.Value.ToString().Length;
|
||||
}
|
||||
message = $"{length}) comparing records";
|
||||
progressBar = new(records.Count, message, options);
|
||||
toDoCollection.AddRange(GetToDoCollection(progressBar, nefPresent, records, length));
|
||||
progressBar.Dispose();
|
||||
}
|
||||
foreach ((FileHolder fileHolder, string directory, string to) in toDoCollection)
|
||||
{
|
||||
if (distinctDirectories.Contains(directory))
|
||||
@ -372,10 +434,10 @@ public class Rename
|
||||
File.WriteAllText($"{to}.id", $"{to}{Environment.NewLine}{fileHolder.FullName}");
|
||||
}
|
||||
ConsoleKey? consoleKey = null;
|
||||
log.Information($"Ready to Move {verifiedToDoCollection.Count} file(s)?");
|
||||
log.Information($"Ready to Move {verifiedToDoCollection.Count} files[i](s)?");
|
||||
for (int y = 0; y < int.MaxValue; y++)
|
||||
{
|
||||
log.Information("Press \"Y\" key to move file(s), \"N\" key to log file(s) or close console to not move files");
|
||||
log.Information("Press \"Y\" key to move files[i](s), \"N\" key to log files[i](s) or close console to not move files");
|
||||
consoleKey = System.Console.ReadKey().Key;
|
||||
if (consoleKey is ConsoleKey.Y or ConsoleKey.N)
|
||||
break;
|
||||
|
Reference in New Issue
Block a user