using Microsoft.Extensions.Configuration; using Phares.Shared; using Serilog; using ShellProgressBar; using System.Drawing; using System.Drawing.Imaging; using System.Reflection; using View_by_Distance.Offset.Date.Time.Original.Models; using View_by_Distance.Shared.Models.Methods; using View_by_Distance.Shared.Models.Stateless; namespace View_by_Distance.Offset.Date.Time.Original; public class OffsetDateTimeOriginal { private readonly AppSettings _AppSettings; private readonly string _WorkingDirectory; private readonly Configuration _Configuration; private readonly IsEnvironment _IsEnvironment; private readonly IConfigurationRoot _ConfigurationRoot; private readonly Property.Models.Configuration _PropertyConfiguration; public OffsetDateTimeOriginal(List args, IsEnvironment isEnvironment, IConfigurationRoot configurationRoot, AppSettings appSettings, string workingDirectory, bool isSilent, IConsole console) { if (isSilent) { } if (console is null) { } _AppSettings = appSettings; _IsEnvironment = isEnvironment; _WorkingDirectory = workingDirectory; _ConfigurationRoot = configurationRoot; ILogger? log = Log.ForContext(); Property.Models.Configuration propertyConfiguration = Property.Models.Binder.Configuration.Get(isEnvironment, configurationRoot); Configuration configuration = Models.Binder.Configuration.Get(isEnvironment, configurationRoot, propertyConfiguration); _PropertyConfiguration = propertyConfiguration; _Configuration = configuration; propertyConfiguration.Update(); log.Information(propertyConfiguration.RootDirectory); Verify(); List lines = OffsetDateTimeOriginalFilesInDirectories(log); if (!lines.Any()) File.WriteAllLines($"D:/Tmp/Phares/{DateTime.Now.Ticks}.tsv", lines); } private void Verify() { if (_AppSettings is null) { } if (_IsEnvironment is null) { } if (_Configuration is null) { } if (_ConfigurationRoot is null) { } if (_WorkingDirectory is null) { } if (_PropertyConfiguration is null) { } } private static List<(string, int, DateTime)> GetCollection(string checkDirectory, DateTime minimumDateTime, DateTime maximumDateTime, long ticks) { List<(string, int, DateTime)> results = new(); DateTime dateTime; Shared.Models.Property property; string[] files = Directory.GetFiles(checkDirectory, "*", SearchOption.TopDirectoryOnly); foreach (string file in files) { property = Property.Models.A_Property.GetImageProperty(file); if (property.Id is null || property.DateTimeOriginal is null) continue; dateTime = property.DateTimeOriginal.Value.AddTicks(ticks); if (dateTime < minimumDateTime) continue; if (dateTime > maximumDateTime) continue; results.Add((file, property.Id.Value, property.DateTimeOriginal.Value.AddTicks(ticks))); } if (files.Length != results.Count) throw new Exception(); return results; } #pragma warning disable CA1416 private static void DateFix(string sourceDirectory, string checkDirectory, DateTime minimumDateTime, DateTime maximumDateTime, long ticks) { Bitmap bitmap; short type = 2; string checkFile; PropertyItem? propertyItem; string? ticksDirectory = null; Shared.Models.Property property; int dateTimeOriginal = (int)IExif.Tags.DateTimeOriginal; for (int i = 0; i < int.MaxValue; i++) { ticksDirectory = Path.Combine(sourceDirectory, ticks.ToString()); if (!Directory.Exists(ticksDirectory)) { _ = Directory.CreateDirectory(ticksDirectory); break; } ticks++; } List<(string, int, DateTime)> collection = GetCollection(checkDirectory, minimumDateTime, maximumDateTime, ticks); ConstructorInfo? constructorInfo = typeof(PropertyItem).GetConstructor(BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Public, null, Array.Empty(), null) ?? throw new Exception(); string message = nameof(OffsetDateTimeOriginal); ProgressBarOptions options = new() { ProgressCharacter = '─', ProgressBarOnBottom = true, DisableBottomPercentage = true }; ProgressBar progressBar = new(collection.Count, message, options); foreach ((string file, int id, DateTime dateTime) in collection) { progressBar.Tick(); if (ticksDirectory is null) throw new Exception(); checkFile = Path.Combine(ticksDirectory, Path.GetFileName(file)); if (File.Exists(checkFile)) continue; propertyItem = Shared.Models.Stateless.Methods.IProperty.GetPropertyItem(constructorInfo, dateTimeOriginal, type, dateTime.ToString("yyyy:MM:dd HH:mm:ss")); bitmap = new(file); bitmap.SetPropertyItem(propertyItem); bitmap.Save(checkFile); bitmap.Dispose(); property = Property.Models.A_Property.GetImageProperty(checkFile); if (property.Id is null || property.Id.Value != id) throw new Exception(); } progressBar.Dispose(); } #pragma warning restore CA1416 private static void DateFix(ILogger log, string sourceDirectory) { string checkDirectory; long oneYearTicks = DateTime.MinValue.AddYears(1).Ticks; checkDirectory = Path.Combine(sourceDirectory, oneYearTicks.ToString()); if (Directory.Exists(checkDirectory)) DateFix(sourceDirectory, checkDirectory, DateTime.MinValue, DateTime.MaxValue, new TimeSpan(oneYearTicks - DateTime.MinValue.Ticks).Ticks); else { checkDirectory = Path.Combine(sourceDirectory, "1"); if (!Directory.Exists(checkDirectory)) log.Error($"<{checkDirectory}> doesn't exist!"); else { string badDirectory = Path.Combine(sourceDirectory, "Bad"); string targetDirectory = Path.Combine(sourceDirectory, "Target"); string[] minimumDirectory = Directory.GetDirectories(targetDirectory, "*", SearchOption.TopDirectoryOnly); if (minimumDirectory.Length != 1) log.Error($"<{checkDirectory}> doesn't exist!"); else { string format = "yyyy-MM-dd"; string[] maximumDirectory = Directory.GetDirectories(minimumDirectory.First(), "*", SearchOption.TopDirectoryOnly); string[] badFiles = !Directory.Exists(badDirectory) ? Array.Empty() : Directory.GetFiles(badDirectory, "*", SearchOption.TopDirectoryOnly); string[] targetFiles = !Directory.Exists(targetDirectory) ? Array.Empty() : Directory.GetFiles(targetDirectory, "*", SearchOption.TopDirectoryOnly); if (badFiles.Length != 1 || targetFiles.Length != 1 || maximumDirectory.Length != 1) log.Error("bad file(s) or target file(s) or maximum directory doesn't equal 1!"); else { DateTime minimumDateTime = DateTime.ParseExact(Path.GetFileName(minimumDirectory.First()), format, null, System.Globalization.DateTimeStyles.None); DateTime maximumDateTime = DateTime.ParseExact(Path.GetFileName(maximumDirectory.First()), format, null, System.Globalization.DateTimeStyles.None).AddHours(23); Shared.Models.Property badProperty = Property.Models.A_Property.GetImageProperty(badFiles.First()); Shared.Models.Property targetProperty = Property.Models.A_Property.GetImageProperty(targetFiles.First()); if (badProperty.DateTimeOriginal is null || targetProperty.DateTimeOriginal is null) log.Error("Date is null!"); else { TimeSpan timeSpan = new(targetProperty.DateTimeOriginal.Value.Ticks - badProperty.DateTimeOriginal.Value.Ticks); DateFix(sourceDirectory, checkDirectory, minimumDateTime, maximumDateTime, timeSpan.Ticks); } } } } } } private List OffsetDateTimeOriginalFilesInDirectories(ILogger log) { List results = new(); DateFix(log, _PropertyConfiguration.RootDirectory); return results; } }