Changed GetDimensions to handle a stream at the end and one exit Switched to using Action? over IDlibDotNet for Tick method Switched to using AsReadOnly over new() Moved Meta Base to Shared
252 lines
10 KiB
C#
252 lines
10 KiB
C#
using System.Collections.ObjectModel;
|
|
using System.Globalization;
|
|
using System.Text;
|
|
|
|
namespace View_by_Distance.Shared.Models.Stateless.Methods;
|
|
|
|
internal abstract class XDate
|
|
{
|
|
|
|
internal static ReadOnlyCollection<DateTime> GetDateTimes(ExifDirectory exifDirectory)
|
|
{
|
|
List<DateTime> results = [];
|
|
foreach (ExifDirectoryBase exifDirectoryBase in exifDirectory.ExifBaseDirectories)
|
|
{
|
|
if (exifDirectoryBase.DateTimeOriginal is not null)
|
|
results.Add(exifDirectoryBase.DateTimeOriginal.Value);
|
|
}
|
|
foreach (AviDirectory aviDirectory in exifDirectory.AviDirectories)
|
|
{
|
|
if (aviDirectory.DateTimeOriginal is not null)
|
|
results.Add(aviDirectory.DateTimeOriginal.Value);
|
|
}
|
|
foreach (QuickTimeMovieHeaderDirectory quickTimeMovieHeaderDirectory in exifDirectory.QuickTimeMovieHeaderDirectories)
|
|
{
|
|
if (quickTimeMovieHeaderDirectory.Created is not null)
|
|
{
|
|
if (quickTimeMovieHeaderDirectory.Created.Value.Year == 1904 && quickTimeMovieHeaderDirectory.Created.Value.Month == 1 && quickTimeMovieHeaderDirectory.Created.Value.Day == 1)
|
|
continue;
|
|
results.Add(quickTimeMovieHeaderDirectory.Created.Value);
|
|
}
|
|
}
|
|
foreach (QuickTimeTrackHeaderDirectory quickTimeTrackHeaderDirectory in exifDirectory.QuickTimeTrackHeaderDirectories)
|
|
{
|
|
if (quickTimeTrackHeaderDirectory.Created is not null)
|
|
{
|
|
if ((quickTimeTrackHeaderDirectory.Created.Value.Year is 1904 or 1970) && quickTimeTrackHeaderDirectory.Created.Value.Month == 1 && quickTimeTrackHeaderDirectory.Created.Value.Day == 1)
|
|
continue;
|
|
results.Add(quickTimeTrackHeaderDirectory.Created.Value);
|
|
}
|
|
}
|
|
if (results.Count == 0)
|
|
{
|
|
string? fileNameWithoutExtension = exifDirectory.FilePath is null ? null : Path.GetFileNameWithoutExtension(exifDirectory.FilePath.Name);
|
|
DateTime? dateTime = fileNameWithoutExtension is null ? null : GetDateTimeFromName(fileNameWithoutExtension);
|
|
if (dateTime is not null)
|
|
results.Add(dateTime.Value);
|
|
foreach (ExifDirectoryBase exifDirectoryBase in exifDirectory.ExifBaseDirectories)
|
|
{
|
|
if (exifDirectoryBase.DateTime is not null)
|
|
results.Add(exifDirectoryBase.DateTime.Value);
|
|
if (exifDirectoryBase.DateTimeDigitized is not null)
|
|
results.Add(exifDirectoryBase.DateTimeDigitized.Value);
|
|
}
|
|
}
|
|
if (results.Count == 0)
|
|
{
|
|
foreach (FileMetadataDirectory fileMetadataDirectory in exifDirectory.FileMetadataDirectories)
|
|
{
|
|
if (fileMetadataDirectory.FileModifiedDate is not null)
|
|
results.Add(fileMetadataDirectory.FileModifiedDate.Value);
|
|
}
|
|
}
|
|
return results.AsReadOnly();
|
|
}
|
|
|
|
private static DateTime? GetDateTimeFromName(string fileNameWithoutExtension)
|
|
{
|
|
DateTime? result = null;
|
|
int length;
|
|
string format;
|
|
string fullFormat;
|
|
StringBuilder value = new();
|
|
const string ticksExample = "##################";
|
|
string[][] dateFormats =
|
|
[
|
|
[string.Empty, "yyyyMMdd_HHmmss", string.Empty],
|
|
[string.Empty, "yyyyMMddHHmmssfff", string.Empty],
|
|
[string.Empty, "yyyyMMdd_", ticksExample],
|
|
[string.Empty, "yyyy-MM-dd_", ticksExample],
|
|
[string.Empty, "yyyy-MM-dd.", ticksExample],
|
|
// [string.Empty, "yyyy-MM-dd.", $"{ticksExample}.{fileHolder.Length}"],
|
|
[string.Empty, "yyyy-MM-dd HH.mm.ss", string.Empty],
|
|
[string.Empty, "yyyyMMdd_HHmmss", "_LLS"],
|
|
[string.Empty, "yyyyMMdd_HHmmss", "_HDR"],
|
|
["WIN_", "yyyyMMdd_HH_mm_ss", "_Pro"],
|
|
["IMG_", "yyyyMMdd_HHmmss", string.Empty],
|
|
["IMG#####-", "yyyyMMdd-HHmm", string.Empty],
|
|
["CameraZOOM-", "yyyyMMddHHmmss", string.Empty],
|
|
["VideoCapture_", "yyyyMMdd-HHmmss ", string.Empty]
|
|
];
|
|
foreach (string[] dateFormat in dateFormats)
|
|
{
|
|
_ = value.Clear();
|
|
if (dateFormat.Length != 3)
|
|
throw new Exception();
|
|
fullFormat = string.Join(string.Empty, dateFormat);
|
|
if (fileNameWithoutExtension.Length != fullFormat.Length)
|
|
continue;
|
|
format = dateFormat[1];
|
|
length = dateFormat[0].Length + dateFormat[1].Length;
|
|
for (int i = dateFormat[0].Length; i < length; i++)
|
|
_ = value.Append(fileNameWithoutExtension[i]);
|
|
if (value.Length != format.Length)
|
|
continue;
|
|
if (DateTime.TryParseExact(value.ToString(), format, CultureInfo.InvariantCulture, DateTimeStyles.None, out DateTime checkDateTime))
|
|
{
|
|
if (fileNameWithoutExtension.Length < ticksExample.Length || !long.TryParse(fileNameWithoutExtension[^ticksExample.Length..], out long ticks))
|
|
result = checkDateTime;
|
|
else
|
|
result = new DateTime(ticks);
|
|
break;
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
|
|
internal static DateTime GetMinimum(ExifDirectory exifDirectory)
|
|
{
|
|
DateTime result;
|
|
ReadOnlyCollection<DateTime> results = GetDateTimes(exifDirectory);
|
|
result = results.Count == 0 ? DateTime.MinValue : results.Min();
|
|
return result;
|
|
}
|
|
|
|
internal static (int Season, string seasonName) GetSeason(int dayOfYear)
|
|
{
|
|
(int Season, string seasonName) result = dayOfYear switch
|
|
{
|
|
< 78 => new(0, "Winter"),
|
|
< 124 => new(1, "Spring"),
|
|
< 171 => new(2, "Spring"),
|
|
< 217 => new(3, "Summer"),
|
|
< 264 => new(4, "Summer"),
|
|
< 309 => new(5, "Fall"),
|
|
< 354 => new(6, "Fall"),
|
|
_ => new(7, "Winter")
|
|
};
|
|
return result;
|
|
}
|
|
|
|
internal static DateTime? GetDateTimeOriginal(ExifDirectory exifDirectory)
|
|
{
|
|
DateTime? result;
|
|
List<DateTime> results = [];
|
|
foreach (ExifDirectoryBase exifDirectoryBase in exifDirectory.ExifBaseDirectories)
|
|
{
|
|
if (exifDirectoryBase.DateTimeOriginal is not null)
|
|
results.Add(exifDirectoryBase.DateTimeOriginal.Value);
|
|
}
|
|
foreach (AviDirectory aviDirectory in exifDirectory.AviDirectories)
|
|
{
|
|
if (aviDirectory.DateTimeOriginal is not null)
|
|
results.Add(aviDirectory.DateTimeOriginal.Value);
|
|
}
|
|
foreach (QuickTimeMovieHeaderDirectory quickTimeMovieHeaderDirectory in exifDirectory.QuickTimeMovieHeaderDirectories)
|
|
{
|
|
if (quickTimeMovieHeaderDirectory.Created is not null)
|
|
{
|
|
if (quickTimeMovieHeaderDirectory.Created.Value.Year == 1904 && quickTimeMovieHeaderDirectory.Created.Value.Month == 1 && quickTimeMovieHeaderDirectory.Created.Value.Day == 1)
|
|
continue;
|
|
results.Add(quickTimeMovieHeaderDirectory.Created.Value);
|
|
}
|
|
}
|
|
foreach (QuickTimeTrackHeaderDirectory quickTimeTrackHeaderDirectory in exifDirectory.QuickTimeTrackHeaderDirectories)
|
|
{
|
|
if (quickTimeTrackHeaderDirectory.Created is not null)
|
|
{
|
|
if ((quickTimeTrackHeaderDirectory.Created.Value.Year is 1904 or 1970) && quickTimeTrackHeaderDirectory.Created.Value.Month == 1 && quickTimeTrackHeaderDirectory.Created.Value.Day == 1)
|
|
continue;
|
|
results.Add(quickTimeTrackHeaderDirectory.Created.Value);
|
|
}
|
|
}
|
|
result = results.Count == 0 ? null : results.Min();
|
|
return result;
|
|
}
|
|
|
|
internal static (bool?, string[]) IsWrongYear(DirectoryInfo directoryInfo, FilePath filePath, ExifDirectory exifDirectory)
|
|
{
|
|
string[] results = [];
|
|
bool? result = null;
|
|
string year;
|
|
string directoryName;
|
|
string[] directorySegments;
|
|
List<DateTime> collection = [];
|
|
string? check = Path.GetFullPath(filePath.FullName);
|
|
DateTime? dateTimeOriginal = GetDateTimeOriginal(exifDirectory);
|
|
if (dateTimeOriginal is not null)
|
|
collection.Add(dateTimeOriginal.Value);
|
|
else
|
|
{
|
|
ReadOnlyCollection<DateTime> dateTimes = GetDateTimes(exifDirectory);
|
|
foreach (DateTime dateTime in dateTimes)
|
|
collection.Add(dateTime);
|
|
}
|
|
foreach (DateTime dateTime in collection)
|
|
{
|
|
year = dateTime.ToString("yyyy");
|
|
for (int i = 0; i < int.MaxValue; i++)
|
|
{
|
|
check = Path.GetDirectoryName(check);
|
|
if (string.IsNullOrEmpty(check))
|
|
break;
|
|
directoryName = Path.GetFileName(check);
|
|
directorySegments = directoryName.Split(' ');
|
|
(result, results) = IsWrongYear(directorySegments, year);
|
|
if (result is not null)
|
|
break;
|
|
if (check == directoryInfo.FullName)
|
|
break;
|
|
}
|
|
if (result is not null && !result.Value)
|
|
break;
|
|
}
|
|
return new(result, results);
|
|
}
|
|
|
|
private static Record IsWrongYear(string[] segments, string year)
|
|
{
|
|
Record result;
|
|
bool? check;
|
|
string[] results = (
|
|
from l
|
|
in segments
|
|
where l?.Length > 2
|
|
&& (
|
|
l[..2] is "18" or "19" or "20"
|
|
|| (l.Length == 5 && l.Substring(1, 2) is "18" or "19" or "20" && (l[0] is '~' or '=' or '-' or '^' or '#'))
|
|
|| (l.Length == 6 && l[..2] is "18" or "19" or "20" && l[4] == '.')
|
|
|| (l.Length == 7 && l.Substring(1, 2) is "18" or "19" or "20" && l[5] == '.')
|
|
)
|
|
select l
|
|
).ToArray();
|
|
string[] matches = (
|
|
from l
|
|
in results
|
|
where l == year
|
|
|| (l.Length == 5 && l.Substring(1, 4) == year && (l[0] is '~' or '=' or '-' or '^' or '#'))
|
|
|| (l.Length == 6 && l[..4] == year && l[4] == '.')
|
|
|| (l.Length == 7 && l.Substring(1, 4) == year && l[5] == '.')
|
|
select l
|
|
).ToArray();
|
|
if (results.Length == 0)
|
|
check = null;
|
|
else
|
|
check = matches.Length == 0;
|
|
result = new(check, results);
|
|
return result;
|
|
}
|
|
|
|
private record Record(bool? IsWrongYear, string[] Years);
|
|
|
|
} |