From a9275dd5d15726e89d425a9b96d33277d9a15961 Mon Sep 17 00:00:00 2001 From: Mike Phares Date: Mon, 17 Jun 2024 21:01:57 -0700 Subject: [PATCH] Pending changes --- Rename/Models/Binder/AppSettings.cs | 4 +- Rename/Models/RenameConfiguration.cs | 1 + Rename/Rename.cs | 106 ++++++++++++++++----------- 3 files changed, 69 insertions(+), 42 deletions(-) diff --git a/Rename/Models/Binder/AppSettings.cs b/Rename/Models/Binder/AppSettings.cs index a4451ba..eb4a6cf 100644 --- a/Rename/Models/Binder/AppSettings.cs +++ b/Rename/Models/Binder/AppSettings.cs @@ -39,8 +39,10 @@ public class AppSettings private static void Verify(Models.AppSettings appSettings) { - if (appSettings.MaxDegreeOfParallelism > 1 && appSettings.RenameConfiguration.InPlace) + if (appSettings.MaxDegreeOfParallelism > 1 && (appSettings.RenameConfiguration.InPlaceWithOriginalName || appSettings.RenameConfiguration.InPlace)) throw new NotSupportedException($"Change configuration: {nameof(appSettings.RenameConfiguration.InPlace)} or {nameof(appSettings.MaxDegreeOfParallelism)}"); + if (appSettings.RenameConfiguration.InPlaceWithOriginalName && appSettings.RenameConfiguration.InPlace) + throw new NotSupportedException($"Change configuration: {nameof(appSettings.RenameConfiguration.InPlace)} or {nameof(appSettings.RenameConfiguration.InPlaceWithOriginalName)}"); } private static Models.AppSettings Get(AppSettings? appSettings, RenameConfiguration renameConfiguration) diff --git a/Rename/Models/RenameConfiguration.cs b/Rename/Models/RenameConfiguration.cs index f0b86a3..df5b0cb 100644 --- a/Rename/Models/RenameConfiguration.cs +++ b/Rename/Models/RenameConfiguration.cs @@ -9,6 +9,7 @@ public record RenameConfiguration(Shared.Models.MetadataConfiguration MetadataCo bool ForceNewId, string[] IgnoreExtensions, bool InPlace, + bool InPlaceWithOriginalName, bool OnlySaveIdentifiersToDisk, string RelativePropertyCollectionFile, string[] SidecarExtensions, diff --git a/Rename/Rename.cs b/Rename/Rename.cs index dc95bab..b938049 100644 --- a/Rename/Rename.cs +++ b/Rename/Rename.cs @@ -117,7 +117,7 @@ public partial class Rename : IRename, IDisposable #pragma warning restore CA1416 - private void NonParallelismAndInPlace(MetadataConfiguration metadataConfiguration, ExifDirectory exifDirectory, FileInfo fileInfo, FilePath filePath, ReadOnlyCollection sidecarFiles) + private void NonParallelismAndInPlace(RenameConfiguration renameConfiguration, ReadOnlyCollection ids, ExifDirectory exifDirectory, FileInfo fileInfo, FilePath filePath, ReadOnlyCollection sidecarFiles) { if (exifDirectory.Id is null) throw new NotImplementedException(); @@ -127,32 +127,44 @@ public partial class Rename : IRename, IDisposable const string jpeg = ".jpeg"; List toDoCollection = []; ReadOnlyCollection keywords = IMetadata.GetKeywords(exifDirectory); + MetadataConfiguration metadataConfiguration = renameConfiguration.MetadataConfiguration; bool hasIgnoreKeyword = metadataConfiguration.IgnoreRulesKeyWords.Any(keywords.Contains); - string checkDirectory = Path.Combine(filePath.DirectoryName, filePath.FileNameFirstSegment); string checkFileExtension = filePath.ExtensionLowered == jpeg ? jpg : filePath.ExtensionLowered; string paddedId = IId.GetPaddedId(metadataConfiguration, exifDirectory.Id.Value, hasIgnoreKeyword, i); + string checkDirectory = renameConfiguration.InPlaceWithOriginalName ? Path.Combine(filePath.DirectoryName, filePath.FileNameFirstSegment) : filePath.DirectoryName; string checkFile = Path.Combine(checkDirectory, $"{paddedId}{checkFileExtension}"); - if (File.Exists(checkFile)) + if (checkFile != filePath.FullName) { - checkFile = string.Concat(checkFile, ".del"); if (File.Exists(checkFile)) - throw new NotImplementedException(); + { + checkFile = string.Concat(checkFile, ".del"); + if (File.Exists(checkFile)) + throw new NotImplementedException(); + } + toDoCollection.Add(new(checkDirectory, filePath, checkFile, JsonFile: false)); + if (sidecarFiles.Count != 0) + { + if (renameConfiguration.InPlace) + throw new NotSupportedException($"Must use {nameof(renameConfiguration.InPlaceWithOriginalName)} when sidecar file(s) are present!"); + dateTime = IDate.GetDateTimeOriginal(exifDirectory); + bool hasDateTimeOriginal = dateTime is not null; + dateTime ??= IDate.GetMinimum(exifDirectory); + RecordB recordB = new(dateTime.Value, exifDirectory, filePath, sidecarFiles, hasDateTimeOriginal, hasIgnoreKeyword, fileInfo.FullName); + toDoCollection.AddRange(GetSidecarFiles(metadataConfiguration, recordB, [], checkDirectory, paddedId)); + } + _ = RenameFilesInDirectories(renameConfiguration, new(toDoCollection)); + string jsonFile = Path.Combine(checkDirectory, $"{paddedId}{checkFileExtension}.json"); + File.Move(fileInfo.FullName, jsonFile, overwrite: true); + if (renameConfiguration.InPlaceWithOriginalName && ids.Count > 0) + { + string idCheck = Path.Combine(checkDirectory, ids.Contains(exifDirectory.Id.Value) ? "_ Exists _" : "_ New _"); + if (!Directory.Exists(idCheck)) + _ = Directory.CreateDirectory(idCheck); + } } - toDoCollection.Add(new(checkDirectory, filePath, checkFile, JsonFile: false)); - if (sidecarFiles.Count != 0) - { - dateTime = IDate.GetDateTimeOriginal(exifDirectory); - bool hasDateTimeOriginal = dateTime is not null; - dateTime ??= IDate.GetMinimum(exifDirectory); - RecordB recordB = new(dateTime.Value, exifDirectory, filePath, sidecarFiles, hasDateTimeOriginal, hasIgnoreKeyword, fileInfo.FullName); - toDoCollection.AddRange(GetSidecarFiles(metadataConfiguration, recordB, [], checkDirectory, paddedId)); - } - _ = RenameFilesInDirectories(new(toDoCollection)); - string jsonFile = Path.Combine(checkDirectory, $"{paddedId}{checkFileExtension}.json"); - File.Move(fileInfo.FullName, jsonFile); } - private List GetRecordACollection(ILogger? logger, RenameConfiguration renameConfiguration, IRename rename, IEnumerable files, A_Metadata metadata) + private List GetRecordACollection(ILogger? logger, RenameConfiguration renameConfiguration, IRename rename, ReadOnlyCollection ids, IEnumerable files, A_Metadata metadata) { List results = []; int index = -1; @@ -185,7 +197,7 @@ public partial class Rename : IRename, IDisposable { ffmpegFiles = null; deterministicHashCode = new(null, filePath.Id, null); - if (renameConfiguration.InPlace) + if (renameConfiguration.InPlaceWithOriginalName || (renameConfiguration.InPlace && filePath.DirectoryName.EndsWith(filePath.Id.Value.ToString()))) continue; } else @@ -213,8 +225,8 @@ public partial class Rename : IRename, IDisposable foreach (string ffmpegFile in ffmpegFiles) File.Delete(ffmpegFile); } - if (renameConfiguration.InPlace) - NonParallelismAndInPlace(renameConfiguration.MetadataConfiguration, exifDirectory, fileInfo, filePath, new(sidecarFiles)); + if (renameConfiguration.InPlace || renameConfiguration.InPlaceWithOriginalName) + NonParallelismAndInPlace(renameConfiguration, ids, exifDirectory, fileInfo, filePath, new(sidecarFiles)); results.Add(new(exifDirectory, fileInfo, filePath, new(sidecarFiles))); } } @@ -240,7 +252,7 @@ public partial class Rename : IRename, IDisposable return new(results); } - private ReadOnlyCollection GetRecordBCollection(ILogger? logger, AppSettings appSettings, IRename rename, DirectoryInfo directoryInfo) + private ReadOnlyCollection GetRecordBCollection(ILogger? logger, AppSettings appSettings, IRename rename, ReadOnlyCollection ids, DirectoryInfo directoryInfo) { ReadOnlyCollection results; List recordACollection = []; @@ -251,7 +263,7 @@ public partial class Rename : IRename, IDisposable int filesCount = appSettingsMaxDegreeOfParallelism == 1 ? files.Count() : 123000; _ProgressBar = new(filesCount, "EnumerateFiles load", new ProgressBarOptions() { ProgressCharacter = '─', ProgressBarOnBottom = true, DisableBottomPercentage = true }); if (appSettingsMaxDegreeOfParallelism == 1) - recordACollection.AddRange(GetRecordACollection(logger, renameConfiguration, rename, files, metadata)); + recordACollection.AddRange(GetRecordACollection(logger, renameConfiguration, rename, ids, files, metadata)); else { List distinct = []; @@ -295,7 +307,7 @@ public partial class Rename : IRename, IDisposable string splat = filePath.DirectoryName[^3..][1] == '!' ? filePath.DirectoryName[^3..] : string.Empty; string makerSplit = string.IsNullOrEmpty(maker) ? string.IsNullOrEmpty(renameConfiguration.DefaultMaker) ? string.Empty : renameConfiguration.DefaultMaker : $" {maker.Split(' ')[0]}"; string directoryName = $"{year}.{seasonValue} {seasonName}{makerSplit}{splat}"; - result = Path.Combine(renameConfiguration.MetadataConfiguration.ResultConfiguration.RootDirectory, record.ExifDirectory.Id is null || !ids.Contains(record.ExifDirectory.Id.Value) ? "_ Destination _" : "_ Exists _", record.HasDateTimeOriginal ? "Has" : "Not", directoryName); + result = Path.Combine(renameConfiguration.MetadataConfiguration.ResultConfiguration.RootDirectory, record.ExifDirectory.Id is null || ids.Contains(record.ExifDirectory.Id.Value) ? "_ Exists _" : "_ New-Destination _", record.HasDateTimeOriginal ? "Has" : "Not", directoryName); } return result; } @@ -346,7 +358,7 @@ public partial class Rename : IRename, IDisposable return result; } - private static ReadOnlyCollection GetToDoCollection(RenameConfiguration renameConfiguration, Identifier[]? identifiers, ReadOnlyCollection recordBCollection) + private static ReadOnlyCollection GetToDoCollection(RenameConfiguration renameConfiguration, ReadOnlyCollection ids, ReadOnlyCollection recordBCollection) { List results = []; RecordB record; @@ -366,7 +378,6 @@ public partial class Rename : IRename, IDisposable MetadataConfiguration metadataConfiguration = renameConfiguration.MetadataConfiguration; VerifyIntMinValueLength(metadataConfiguration, recordBCollection); bool multipleDirectoriesWithFiles = directoryCheck is not null && directoryCheck.Value; - ReadOnlyCollection ids = identifiers is null ? new([]) : new((from l in identifiers select l.Id).ToArray()); ReadOnlyCollection sorted = new((from l in recordBCollection orderby l.DateTime select l).ToArray()); for (int i = 0; i < sorted.Count; i++) { @@ -422,14 +433,17 @@ public partial class Rename : IRename, IDisposable } } - private ReadOnlyCollection RenameFilesInDirectories(ReadOnlyCollection toDoCollection) + private ReadOnlyCollection RenameFilesInDirectories(RenameConfiguration renameConfiguration, ReadOnlyCollection toDoCollection) { List results = []; VerifyDirectories(toDoCollection); - _ProgressBar = new(toDoCollection.Count, "Move Files", new ProgressBarOptions() { ProgressCharacter = '─', ProgressBarOnBottom = true, DisableBottomPercentage = true }); + bool useProgressBar = !renameConfiguration.InPlace && !renameConfiguration.InPlaceWithOriginalName; + if (useProgressBar) + _ProgressBar = new(toDoCollection.Count, "Move Files", new ProgressBarOptions() { ProgressCharacter = '─', ProgressBarOnBottom = true, DisableBottomPercentage = true }); foreach (ToDo toDo in toDoCollection) { - _ProgressBar.Tick(); + if (useProgressBar) + _ProgressBar?.Tick(); if (toDo.JsonFile) { if (File.Exists(toDo.File)) @@ -449,14 +463,17 @@ public partial class Rename : IRename, IDisposable results.Add($"{toDo.FilePath.FullName}\t{toDo.File}"); } } - _ProgressBar.Dispose(); + if (useProgressBar) + _ProgressBar?.Dispose(); return new(results); } - private static void SaveIdentifiersToDisk(long ticks, RenameConfiguration renameConfiguration, string aMetadataCollectionDirectory, ReadOnlyCollection recordBCollection) + private static void SaveIdentifiersToDisk(long ticks, RenameConfiguration renameConfiguration, ReadOnlyCollection recordBCollection) { string paddedId; List identifiers = []; + MetadataConfiguration metadataConfiguration = renameConfiguration.MetadataConfiguration; + string aMetadataCollectionDirectory = IResult.GetResultsDateGroupDirectory(metadataConfiguration.ResultConfiguration, nameof(A_Metadata), metadataConfiguration.ResultConfiguration.ResultCollection); foreach (RecordB record in recordBCollection) { if (record.ExifDirectory.Id is null) @@ -468,21 +485,28 @@ public partial class Rename : IRename, IDisposable _ = IPath.WriteAllText(Path.Combine(aMetadataCollectionDirectory, $"{ticks}.json"), json, updateDateWhenMatches: false, compareBeforeWrite: true, updateToWhenMatches: null); } - private void RenameWork(ILogger? logger, AppSettings appSettings, IRename rename, long ticks) + private static ReadOnlyCollection GetIds(RenameConfiguration renameConfiguration) { - RenameConfiguration renameConfiguration = appSettings.RenameConfiguration; - MetadataConfiguration metadataConfiguration = renameConfiguration.MetadataConfiguration; - string aMetadataCollectionDirectory = IResult.GetResultsDateGroupDirectory(metadataConfiguration.ResultConfiguration, nameof(A_Metadata), metadataConfiguration.ResultConfiguration.ResultCollection); - string? propertyCollectionFile = string.IsNullOrEmpty(renameConfiguration.RelativePropertyCollectionFile) ? null : Path.GetFullPath(Path.Combine(aMetadataCollectionDirectory, renameConfiguration.RelativePropertyCollectionFile)); + ReadOnlyCollection results; + string? propertyCollectionFile = string.IsNullOrEmpty(renameConfiguration.RelativePropertyCollectionFile) ? null : renameConfiguration.RelativePropertyCollectionFile; string? json = !File.Exists(propertyCollectionFile) ? null : File.ReadAllText(propertyCollectionFile); Identifier[]? identifiers = json is null ? null : JsonSerializer.Deserialize(json, IdentifierCollectionSourceGenerationContext.Default.IdentifierArray); if (identifiers is null && !string.IsNullOrEmpty(renameConfiguration.RelativePropertyCollectionFile)) throw new Exception($"Invalid {nameof(renameConfiguration.RelativePropertyCollectionFile)}"); + results = identifiers is null ? new([]) : new((from l in identifiers select l.Id).ToArray()); + return results; + } + + private void RenameWork(ILogger? logger, AppSettings appSettings, IRename rename, long ticks) + { + ReadOnlyCollection ids = GetIds(appSettings.RenameConfiguration); + RenameConfiguration renameConfiguration = appSettings.RenameConfiguration; + MetadataConfiguration metadataConfiguration = renameConfiguration.MetadataConfiguration; DirectoryInfo directoryInfo = new(Path.GetFullPath(metadataConfiguration.ResultConfiguration.RootDirectory)); logger?.LogInformation("{Ticks} {RootDirectory}", ticks, directoryInfo.FullName); - ReadOnlyCollection recordBCollection = GetRecordBCollection(logger, appSettings, rename, directoryInfo); - SaveIdentifiersToDisk(ticks, renameConfiguration, aMetadataCollectionDirectory, recordBCollection); - if (renameConfiguration.InPlace) + ReadOnlyCollection recordBCollection = GetRecordBCollection(logger, appSettings, rename, ids, directoryInfo); + SaveIdentifiersToDisk(ticks, renameConfiguration, recordBCollection); + if (renameConfiguration.InPlace || renameConfiguration.InPlaceWithOriginalName) { if (recordBCollection.Count > 0) recordBCollection = new([]); @@ -491,8 +515,8 @@ public partial class Rename : IRename, IDisposable } if (!renameConfiguration.OnlySaveIdentifiersToDisk) { - ReadOnlyCollection toDoCollection = GetToDoCollection(renameConfiguration, identifiers, recordBCollection); - ReadOnlyCollection lines = RenameFilesInDirectories(toDoCollection); + ReadOnlyCollection toDoCollection = GetToDoCollection(renameConfiguration, ids, recordBCollection); + ReadOnlyCollection lines = RenameFilesInDirectories(renameConfiguration, toDoCollection); if (lines.Count != 0) { File.WriteAllLines($"D:/Tmp/Phares/{DateTime.Now.Ticks}.tsv", lines);