Ready to test DownloadFile

DirectoryDictionary

Add http file

.7-Question

JustMediaDate

CombinedEnumAndIndex
This commit is contained in:
2025-03-08 17:28:30 -07:00
parent ef4672aaf0
commit c15c854481
13 changed files with 464 additions and 251 deletions

View File

@ -176,7 +176,7 @@ public partial class Rename : IRename, IDisposable
JsonFile: minimumYearAndPathCombined.PathCombined);
toDoCollection.AddRange(GetSidecarFiles(appSettings, record, [], checkDirectory, paddedId));
}
_ = RenameFilesInDirectories(appSettings.RenameSettings, rename, new(toDoCollection));
_ = RenameFilesInDirectories(appSettings.RenameSettings, rename, toDoCollection.AsReadOnly());
string jsonFile = Path.Combine(checkDirectory, $"{paddedId}{checkFileExtension}.json");
File.Move(minimumYearAndPathCombined.PathCombined, jsonFile, overwrite: true);
if (appSettings.RenameSettings.InPlaceWithOriginalName && ids.Count > 0)
@ -189,12 +189,37 @@ public partial class Rename : IRename, IDisposable
}
}
private List<FirstPass> GetFirstPassCollection(ILogger<Program>? logger, AppSettings appSettings, IRename rename, long ticks, ReadOnlyCollection<int> ids, IEnumerable<string> files, A_Metadata metadata)
private void JustMediaDate(ILogger<Program>? logger, AppSettings appSettings, A_Metadata metadata, FilePath filePath)
{
ExifDirectory? exifDirectory;
MinimumYearAndPathCombined? minimumYearAndPathCombined;
try
{ (minimumYearAndPathCombined, exifDirectory) = metadata.GetMetadataCollection(appSettings.ResultSettings, appSettings.MetadataSettings, filePath); }
catch (Exception)
{
exifDirectory = null;
minimumYearAndPathCombined = null;
logger?.LogWarning("<{filePath}>", filePath.FullName);
}
if (exifDirectory is null || minimumYearAndPathCombined is null)
logger?.LogWarning("<{filePath}>", filePath.FullName);
else
{
DateTime? dateTime = IDate.GetDateTimeOriginal(exifDirectory);
if (dateTime is null)
logger?.LogWarning("<{filePath}>", filePath.FullName);
else
{
File.SetCreationTime(filePath.FullName, dateTime.Value);
Thread.Sleep(500);
File.SetLastWriteTime(filePath.FullName, dateTime.Value);
}
}
}
private void SetFirstPassCollection(ILogger<Program>? logger, AppSettings appSettings, IRename rename, ReadOnlyCollection<int> ids, A_Metadata metadata, int index, KeyValuePair<string, List<FileHolder>> keyValuePair, List<FirstPass> results)
{
List<FirstPass> results = [];
int index = -1;
FilePath filePath;
TimeSpan timeSpan;
FirstPass firstPass;
string directoryName;
ExifDirectory exifDirectory;
@ -204,7 +229,66 @@ public partial class Rename : IRename, IDisposable
MinimumYearAndPathCombined minimumYearAndPathCombined;
FilePath? fastForwardMovingPictureExpertsGroupFilePath;
ReadOnlyCollection<string>? fastForwardMovingPictureExpertsGroupFiles;
ReadOnlyDictionary<string, List<FileHolder>> keyValuePairs = IMetadata.GetKeyValuePairs(files);
foreach (FileHolder fileHolder in keyValuePair.Value)
{
if (appSettings.RenameSettings.SidecarExtensions.Contains(fileHolder.ExtensionLowered))
continue;
if (appSettings.RenameSettings.IgnoreExtensions.Contains(fileHolder.ExtensionLowered))
continue;
filePath = FilePath.Get(appSettings.ResultSettings, appSettings.MetadataSettings, fileHolder, index);
if (appSettings.RenameSettings.SkipIdFiles && filePath.Id is not null && (filePath.IsIntelligentIdFormat || filePath.SortOrder is not null))
continue;
if (!appSettings.RenameSettings.ForceNewId && filePath.Id is not null)
{
fastForwardMovingPictureExpertsGroupFiles = null;
deterministicHashCode = new(null, filePath.Id, null);
directoryName = Path.GetFileName(filePath.DirectoryFullPath);
if (appSettings.RenameSettings.InPlaceWithOriginalName || (appSettings.RenameSettings.InPlace && directoryName.EndsWith(filePath.Id.Value.ToString())))
continue;
}
else
{
fastForwardMovingPictureExpertsGroupFiles = rename.ConvertAndGetFastForwardMovingPictureExpertsGroupFiles(appSettings.RenameSettings, filePath);
fastForwardMovingPictureExpertsGroupFilePath = fastForwardMovingPictureExpertsGroupFiles.Count == 0 ? null : FilePath.Get(appSettings.ResultSettings, appSettings.MetadataSettings, FileHolder.Get(fastForwardMovingPictureExpertsGroupFiles[0]), index);
deterministicHashCode = fastForwardMovingPictureExpertsGroupFilePath is null ? rename.GetDeterministicHashCode(filePath) : rename.GetDeterministicHashCode(fastForwardMovingPictureExpertsGroupFilePath);
}
sidecarFiles = [];
filePath = FilePath.Get(filePath, deterministicHashCode);
for (int i = 0; i < keyValuePair.Value.Count; i++)
{
if (appSettings.RenameSettings.JustMediaDate && filePath.HasDateTimeOriginal is not null && filePath.HasDateTimeOriginal.Value)
JustMediaDate(logger, appSettings, metadata, filePath);
if (keyValuePair.Value[i].ExtensionLowered == fileHolder.ExtensionLowered)
continue;
sidecarFiles.Add(keyValuePair.Value[i]);
}
try
{ (minimumYearAndPathCombined, exifDirectory) = metadata.GetMetadataCollection(appSettings.ResultSettings, appSettings.MetadataSettings, filePath); }
catch (Exception)
{
logger?.LogWarning("<{filePath}>", filePath.FullName);
continue;
}
fastForwardMovingPictureExpertsGroupUsed = fastForwardMovingPictureExpertsGroupFiles is not null && fastForwardMovingPictureExpertsGroupFiles.Count > 0;
if (fastForwardMovingPictureExpertsGroupUsed && fastForwardMovingPictureExpertsGroupFiles is not null)
{
foreach (string fastForwardMovingPictureExpertsGroupFile in fastForwardMovingPictureExpertsGroupFiles)
File.Delete(fastForwardMovingPictureExpertsGroupFile);
}
if (appSettings.RenameSettings.InPlace || appSettings.RenameSettings.InPlaceWithOriginalName)
NonParallelismAndInPlace(appSettings, rename, ids, exifDirectory, minimumYearAndPathCombined, fastForwardMovingPictureExpertsGroupUsed, sidecarFiles.ToArray());
if (!fastForwardMovingPictureExpertsGroupUsed && appSettings.RenameSettings.InPlaceMoveDirectory && appSettings.RenameSettings.ValidVideoFormatExtensions.Contains(filePath.ExtensionLowered))
fastForwardMovingPictureExpertsGroupUsed = true;
firstPass = new(exifDirectory, fastForwardMovingPictureExpertsGroupUsed, minimumYearAndPathCombined, sidecarFiles.ToArray());
results.Add(firstPass);
}
}
private List<FirstPass> GetFirstPassCollection(ILogger<Program>? logger, AppSettings appSettings, IRename rename, long ticks, ReadOnlyCollection<int> ids, A_Metadata metadata, ReadOnlyDictionary<string, List<FileHolder>> keyValuePairs)
{
List<FirstPass> results = [];
int index = -1;
TimeSpan timeSpan;
foreach (KeyValuePair<string, List<FileHolder>> keyValuePair in keyValuePairs)
{
index += 1;
@ -217,57 +301,7 @@ public partial class Rename : IRename, IDisposable
}
if (keyValuePair.Value.Count > 2)
throw new NotSupportedException("Too many sidecar files!");
foreach (FileHolder fileHolder in keyValuePair.Value)
{
if (appSettings.RenameSettings.SidecarExtensions.Contains(fileHolder.ExtensionLowered))
continue;
if (appSettings.RenameSettings.IgnoreExtensions.Contains(fileHolder.ExtensionLowered))
continue;
filePath = FilePath.Get(appSettings.ResultSettings, appSettings.MetadataSettings, fileHolder, index);
if (appSettings.RenameSettings.SkipIdFiles && filePath.Id is not null && (filePath.IsIntelligentIdFormat || filePath.SortOrder is not null))
continue;
if (!appSettings.RenameSettings.ForceNewId && filePath.Id is not null)
{
fastForwardMovingPictureExpertsGroupFiles = null;
deterministicHashCode = new(null, filePath.Id, null);
directoryName = Path.GetFileName(filePath.DirectoryFullPath);
if (appSettings.RenameSettings.InPlaceWithOriginalName || (appSettings.RenameSettings.InPlace && directoryName.EndsWith(filePath.Id.Value.ToString())))
continue;
}
else
{
fastForwardMovingPictureExpertsGroupFiles = rename.ConvertAndGetFastForwardMovingPictureExpertsGroupFiles(appSettings.RenameSettings, filePath);
fastForwardMovingPictureExpertsGroupFilePath = fastForwardMovingPictureExpertsGroupFiles.Count == 0 ? null : FilePath.Get(appSettings.ResultSettings, appSettings.MetadataSettings, FileHolder.Get(fastForwardMovingPictureExpertsGroupFiles[0]), index);
deterministicHashCode = fastForwardMovingPictureExpertsGroupFilePath is null ? rename.GetDeterministicHashCode(filePath) : rename.GetDeterministicHashCode(fastForwardMovingPictureExpertsGroupFilePath);
}
sidecarFiles = [];
filePath = FilePath.Get(filePath, deterministicHashCode);
for (int i = 0; i < keyValuePair.Value.Count; i++)
{
if (keyValuePair.Value[i].ExtensionLowered == fileHolder.ExtensionLowered)
continue;
sidecarFiles.Add(keyValuePair.Value[i]);
}
try
{ (minimumYearAndPathCombined, exifDirectory) = metadata.GetMetadataCollection(appSettings.ResultSettings, appSettings.MetadataSettings, filePath); }
catch (Exception)
{
logger?.LogWarning("<{filePath}>", filePath.FullName);
continue;
}
fastForwardMovingPictureExpertsGroupUsed = fastForwardMovingPictureExpertsGroupFiles is not null && fastForwardMovingPictureExpertsGroupFiles.Count > 0;
if (fastForwardMovingPictureExpertsGroupUsed && fastForwardMovingPictureExpertsGroupFiles is not null)
{
foreach (string fastForwardMovingPictureExpertsGroupFile in fastForwardMovingPictureExpertsGroupFiles)
File.Delete(fastForwardMovingPictureExpertsGroupFile);
}
if (appSettings.RenameSettings.InPlace || appSettings.RenameSettings.InPlaceWithOriginalName)
NonParallelismAndInPlace(appSettings, rename, ids, exifDirectory, minimumYearAndPathCombined, fastForwardMovingPictureExpertsGroupUsed, sidecarFiles.ToArray());
if (!fastForwardMovingPictureExpertsGroupUsed && appSettings.RenameSettings.InPlaceMoveDirectory && appSettings.RenameSettings.ValidVideoFormatExtensions.Contains(filePath.ExtensionLowered))
fastForwardMovingPictureExpertsGroupUsed = true;
firstPass = new(exifDirectory, fastForwardMovingPictureExpertsGroupUsed, minimumYearAndPathCombined, sidecarFiles.ToArray());
results.Add(firstPass);
}
SetFirstPassCollection(logger, appSettings, rename, ids, metadata, index, keyValuePair, results);
timeSpan = new(DateTime.Now.Ticks - ticks);
if (timeSpan.TotalMilliseconds > appSettings.RenameSettings.MaxMilliSecondsPerCall)
break;
@ -302,49 +336,61 @@ public partial class Rename : IRename, IDisposable
return results.AsReadOnly();
}
private List<FirstPass> GetRecordCollection(ILogger<Program>? logger, AppSettings appSettings, IRename rename, long ticks, ReadOnlyCollection<int> ids, string sourceDirectory, ReadOnlyCollection<string> files, string? checkFile)
{
List<FirstPass> results;
FirstPass firstPass;
A_Metadata metadata = new(appSettings.ResultSettings, appSettings.MetadataSettings);
int appSettingsMaxDegreeOfParallelism = appSettings.RenameSettings.MaxDegreeOfParallelism;
int filesCount = appSettingsMaxDegreeOfParallelism == 1 ? files.Count : 123000;
rename.ConstructProgressBar(filesCount, "EnumerateFiles load");
if (appSettingsMaxDegreeOfParallelism == 1)
{
ReadOnlyDictionary<string, List<FileHolder>> keyValuePairs = IMetadata.GetKeyValuePairs(files);
results = GetFirstPassCollection(logger, appSettings, rename, ticks, ids, metadata, keyValuePairs);
}
else
{
results = [];
List<string> distinct = [];
List<MetadataGroup> metadataGroups = [];
ParallelOptions parallelOptions = new() { MaxDegreeOfParallelism = appSettingsMaxDegreeOfParallelism };
files.AsParallel().ForAll(IMetadata.SetExifDirectoryCollection(rename, appSettings.ResultSettings, appSettings.MetadataSettings, appSettings.RenameSettings, metadata, distinct, metadataGroups));
Thread.Sleep(500);
foreach (MetadataGroup metadataGroup in metadataGroups)
{
if (metadataGroup.FastForwardMovingPictureExpertsGroupUsed || !appSettings.RenameSettings.InPlaceMoveDirectory || !appSettings.RenameSettings.ValidVideoFormatExtensions.Contains(metadataGroup.FilePath.ExtensionLowered))
firstPass = new(metadataGroup.ExifDirectory, metadataGroup.FastForwardMovingPictureExpertsGroupUsed, metadataGroup.MinimumYearAndPathCombined, metadataGroup.SidecarFiles.ToArray());
else
firstPass = new(metadataGroup.ExifDirectory, FastForwardMovingPictureExpertsGroupUsed: true, metadataGroup.MinimumYearAndPathCombined, metadataGroup.SidecarFiles.ToArray());
results.Add(firstPass);
}
}
if (!string.IsNullOrEmpty(checkFile))
{
string json = JsonSerializer.Serialize(results, FirstPassCollectionSourceGenerationContext.Default.ListFirstPass);
File.WriteAllText(Path.Combine(sourceDirectory, $"{ticks}.json"), json);
}
return results;
}
private ReadOnlyCollection<Record> GetRecordCollection(ILogger<Program>? logger, AppSettings appSettings, IRename rename, long ticks, ReadOnlyCollection<int> ids, string sourceDirectory, ReadOnlyCollection<string> files)
{
ReadOnlyCollection<Record> results;
FirstPass firstPass;
List<FirstPass> collection;
string? checkFile = string.IsNullOrEmpty(appSettings.RenameSettings.FirstPassFile) ? null : Path.Combine(sourceDirectory, appSettings.RenameSettings.FirstPassFile);
if (!string.IsNullOrEmpty(checkFile) && File.Exists(checkFile))
if (string.IsNullOrEmpty(checkFile) || !File.Exists(checkFile))
collection = GetRecordCollection(logger, appSettings, rename, ticks, ids, sourceDirectory, files, checkFile);
else
{
string json = File.ReadAllText(checkFile);
collection = JsonSerializer.Deserialize(json, FirstPassCollectionSourceGenerationContext.Default.ListFirstPass) ?? throw new Exception();
}
if (appSettings.RenameSettings.JustMediaDate)
results = new([]);
else
{
collection = [];
A_Metadata metadata = new(appSettings.ResultSettings, appSettings.MetadataSettings);
int appSettingsMaxDegreeOfParallelism = appSettings.RenameSettings.MaxDegreeOfParallelism;
int filesCount = appSettingsMaxDegreeOfParallelism == 1 ? files.Count : 123000;
rename.ConstructProgressBar(filesCount, "EnumerateFiles load");
if (appSettingsMaxDegreeOfParallelism == 1)
collection.AddRange(GetFirstPassCollection(logger, appSettings, rename, ticks, ids, files, metadata));
else
{
List<string> distinct = [];
List<MetadataGroup> metadataGroups = [];
ParallelOptions parallelOptions = new() { MaxDegreeOfParallelism = appSettingsMaxDegreeOfParallelism };
files.AsParallel().ForAll(IMetadata.SetExifDirectoryCollection(rename, appSettings.ResultSettings, appSettings.MetadataSettings, appSettings.RenameSettings, metadata, distinct, metadataGroups));
Thread.Sleep(500);
foreach (MetadataGroup metadataGroup in metadataGroups)
{
if (metadataGroup.FastForwardMovingPictureExpertsGroupUsed || !appSettings.RenameSettings.InPlaceMoveDirectory || !appSettings.RenameSettings.ValidVideoFormatExtensions.Contains(metadataGroup.FilePath.ExtensionLowered))
firstPass = new(metadataGroup.ExifDirectory, metadataGroup.FastForwardMovingPictureExpertsGroupUsed, metadataGroup.MinimumYearAndPathCombined, metadataGroup.SidecarFiles.ToArray());
else
firstPass = new(metadataGroup.ExifDirectory, FastForwardMovingPictureExpertsGroupUsed: true, metadataGroup.MinimumYearAndPathCombined, metadataGroup.SidecarFiles.ToArray());
collection.Add(firstPass);
}
}
if (!string.IsNullOrEmpty(checkFile))
{
string json = JsonSerializer.Serialize(collection, FirstPassCollectionSourceGenerationContext.Default.ListFirstPass);
File.WriteAllText(Path.Combine(sourceDirectory, $"{ticks}.json"), json);
}
}
results = GetRecordCollection(appSettings, collection);
results = GetRecordCollection(appSettings, collection);
return results;
}
@ -381,6 +427,7 @@ public partial class Rename : IRename, IDisposable
{
if (record.ExifDirectory.FilePath.FullName[..2] != directoryInfo.FullName[..2])
isWrongYear = null;
string directoryName;
string tfw = GetTFW(record, isWrongYear);
string? maker = IMetadata.GetMaker(record.ExifDirectory);
string rootDirectory = appSettings.ResultSettings.RootDirectory;
@ -389,7 +436,14 @@ public partial class Rename : IRename, IDisposable
string? splat = checkDirectoryName.Length > 3 && checkDirectoryName[^3..][1] == '!' ? checkDirectoryName[^3..] : null;
string contains = record.ExifDirectory.FilePath.Id is null || ids.Contains(record.ExifDirectory.FilePath.Id.Value) ? "_ Exists _" : "_ New-Destination _";
string makerSplit = string.IsNullOrEmpty(maker) ? string.IsNullOrEmpty(appSettings.RenameSettings.DefaultMaker) ? string.Empty : appSettings.RenameSettings.DefaultMaker : $" {maker.Split(' ')[0]}";
string directoryName = GetDirectoryName(year, tfw, segments[0], splat, seasonValue, seasonName, makerSplit);
if (!string.IsNullOrEmpty(splat) || isWrongYear is null || isWrongYear.Value || appSettings.RenameSettings.DirectoryDictionary.Count < 2)
directoryName = GetDirectoryName(year, tfw, segments[0], splat, seasonValue, seasonName, makerSplit);
else
{
directoryName = record.DateTime.ToString("yyyy-MM-dd");
if (appSettings.RenameSettings.DirectoryDictionary.TryGetValue(directoryName, out string? value) && !string.IsNullOrEmpty(value))
directoryName = value;
}
result = Path.GetFullPath(Path.Combine(rootDirectory, contains, directoryName));
}
}
@ -460,9 +514,9 @@ public partial class Rename : IRename, IDisposable
string checkFile;
FilePath filePath;
FileInfo[] matches;
string directoryName;
FileHolder fileHolder;
string? checkDirectory;
CombinedEnumAndIndex cei;
const string jpg = ".jpg";
string checkFileExtension;
List<string> distinct = [];
@ -493,8 +547,8 @@ public partial class Rename : IRename, IDisposable
if (File.Exists(checkFile))
continue;
}
(directoryName, _) = IPath.GetDirectoryNameAndIndex(appSettings.ResultSettings, record.ExifDirectory.FilePath);
jsonFile = Path.Combine(jsonFileSubDirectory, directoryName, $"{record.ExifDirectory.FilePath.Id.Value}{checkFileExtension}.json");
cei = IPath.GetCombinedEnumAndIndex(appSettings.ResultSettings, record.ExifDirectory.FilePath);
jsonFile = Path.Combine(jsonFileSubDirectory, cei.Combined, $"{record.ExifDirectory.FilePath.Id.Value}{checkFileExtension}.json");
if (record.JsonFile != jsonFile)
{
fileHolder = FileHolder.Get(record.JsonFile);