using System.Collections.ObjectModel; using System.Text.Json; using View_by_Distance.Metadata.Models.Stateless; using View_by_Distance.Shared.Models; using View_by_Distance.Shared.Models.Stateless; namespace View_by_Distance.Metadata.Models; public class A_Metadata { private readonly ResultSettings _ResultSettings; private readonly MetadataSettings _MetadataSettings; private readonly ReadOnlyDictionary> _FileGroups; public A_Metadata(ResultSettings resultSettings, MetadataSettings metadataSettings) { _ResultSettings = resultSettings; _MetadataSettings = metadataSettings; string aResultsFullGroupDirectory = IResult.GetResultsFullGroupDirectory(resultSettings, nameof(A_Metadata), string.Empty, includeResizeGroup: false, includeModel: false, includePredictorModel: false); _FileGroups = IPath.GetKeyValuePairs(resultSettings, aResultsFullGroupDirectory, [resultSettings.ResultSingleton]); } private MinimumYearAndPathCombined GetMinimumYearAndPathCombined(ResultSettings resultSettings, FilePath filePath) { MinimumYearAndPathCombined result; (_, int directoryIndex) = IPath.GetDirectoryNameAndIndex(resultSettings, filePath); DateTime minimumDateTime = new(filePath.CreationTicks < filePath.LastWriteTicks ? filePath.CreationTicks : filePath.LastWriteTicks); int minimumYear = minimumDateTime.Year < resultSettings.EpicYear ? resultSettings.EpicYear : minimumDateTime.Year; result = new(minimumYear, Path.Combine(_FileGroups[minimumYear][_ResultSettings.ResultSingleton][directoryIndex], $"{filePath.NameWithoutExtension}{filePath.ExtensionLowered}.json")); return result; } private (int, string) GetJsonFile(ResultSettings resultSettings, FilePath filePath, ExifDirectory exifDirectory) { string? result; DateTime? dateTime; dateTime = IDate.GetDateTimeOriginal(exifDirectory); dateTime ??= IDate.GetMinimum(exifDirectory); (_, int directoryIndex) = IPath.GetDirectoryNameAndIndex(resultSettings, filePath); int exifYear = dateTime.Value.Year < resultSettings.EpicYear ? resultSettings.EpicYear : dateTime.Value.Year; result = Path.Combine(_FileGroups[exifYear][_ResultSettings.ResultSingleton][directoryIndex], $"{filePath.NameWithoutExtension}{filePath.ExtensionLowered}.json"); return new(exifYear, result); } private static (string, ExifDirectory?) Get(string jsonFile) { ExifDirectory? result; string json = File.ReadAllText(jsonFile); try { result = JsonSerializer.Deserialize(json, ExifDirectorySourceGenerationContext.Default.ExifDirectory); if (result is null) throw new Exception(); } catch (Exception) { result = null; } return new(json, result); } public (MinimumYearAndPathCombined, ExifDirectory) GetMetadataCollection(ResultSettings resultSettings, MetadataSettings metadataSettings, FilePath filePath) { ExifDirectory? result; MinimumYearAndPathCombined minimumYearAndPathCombined = GetMinimumYearAndPathCombined(resultSettings, filePath); FileInfo fileInfo = new(minimumYearAndPathCombined.PathCombined); if (_MetadataSettings.ForceMetadataLastWriteTimeToCreationTime && !fileInfo.Exists && File.Exists(Path.ChangeExtension(fileInfo.FullName, ".delete"))) { File.Move(Path.ChangeExtension(fileInfo.FullName, ".delete"), fileInfo.FullName); fileInfo.Refresh(); } if (_MetadataSettings.ForceMetadataLastWriteTimeToCreationTime && fileInfo.Exists && fileInfo.LastWriteTime != fileInfo.CreationTime) { File.SetLastWriteTime(fileInfo.FullName, fileInfo.CreationTime); fileInfo.Refresh(); } if (_MetadataSettings.PropertiesChangedForMetadata) result = null; else if (!fileInfo.Exists) result = null; else if (!fileInfo.FullName.EndsWith(".json") && !fileInfo.FullName.EndsWith(".old")) throw new ArgumentException("must be a *.json file"); else { string json = File.ReadAllText(fileInfo.FullName); try { result = JsonSerializer.Deserialize(json, ExifDirectorySourceGenerationContext.Default.ExifDirectory); if (result is null) throw new Exception(); } catch (Exception) { result = null; } } if (result is null) { string json; Stream stream = File.OpenRead(filePath.FullName); const PersonKeyFormattedAndKeyTicksAndDisplayDirectoryName? personKeyFormattedAndKeyTicksAndDisplayDirectoryName = null; result = Exif.GetExifDirectory(filePath, stream, personKeyFormattedAndKeyTicksAndDisplayDirectoryName); stream.Dispose(); (int exifYear, string jsonFile) = GetJsonFile(_ResultSettings, filePath, result); if (exifYear == minimumYearAndPathCombined.MinimumYear) json = JsonSerializer.Serialize(result, ExifDirectorySourceGenerationContext.Default.ExifDirectory); else { fileInfo = new(jsonFile); if (!File.Exists(jsonFile)) json = JsonSerializer.Serialize(result, ExifDirectorySourceGenerationContext.Default.ExifDirectory); else { (string checkJson, ExifDirectory? exifDirectory) = Get(jsonFile); if (exifDirectory is null) json = JsonSerializer.Serialize(result, ExifDirectorySourceGenerationContext.Default.ExifDirectory); else { json = checkJson; result = exifDirectory; } } } if (IPath.WriteAllText(fileInfo.FullName, json, updateDateWhenMatches: false, compareBeforeWrite: true, updateToWhenMatches: null) && _MetadataSettings.ForceMetadataLastWriteTimeToCreationTime) { File.SetLastWriteTime(fileInfo.FullName, fileInfo.CreationTime); fileInfo.Refresh(); } } return new(minimumYearAndPathCombined, result); } private static Stream GetStream(HttpClient httpClient, FilePath filePath) { Stream result; Task httpResponseMessage = httpClient.GetAsync(filePath.FullName); httpResponseMessage.Wait(); Task task = httpResponseMessage.Result.Content.LoadIntoBufferAsync(); task.Wait(); Task stream = httpResponseMessage.Result.Content.ReadAsStreamAsync(); stream.Wait(); result = stream.Result; return result; } public (MinimumYearAndPathCombined, ExifDirectory) GetMetadataCollection(ResultSettings resultSettings, MetadataSettings metadataSettings, HttpClient? httpClient, FilePath filePath) { ExifDirectory result; MinimumYearAndPathCombined minimumYearAndPathCombined; if (httpClient is null) (minimumYearAndPathCombined, result) = GetMetadataCollection(resultSettings, metadataSettings, filePath); else { Stream stream = GetStream(httpClient, filePath); minimumYearAndPathCombined = GetMinimumYearAndPathCombined(resultSettings, filePath); const PersonKeyFormattedAndKeyTicksAndDisplayDirectoryName? personKeyFormattedAndKeyTicksAndDisplayDirectoryName = null; result = Exif.GetExifDirectory(filePath, stream, personKeyFormattedAndKeyTicksAndDisplayDirectoryName); stream.Dispose(); } return new(minimumYearAndPathCombined, result); } }