Rename files to padded number string
This commit is contained in:
@ -29,15 +29,12 @@ taskTemplate: '^+^_${overdue ? ''^R'' : ''''}${name}^: ${relations ? (''\n^-^/^g
|
||||
- [determine-if-location-container-collection-is-needed-in-get-faces](tasks/determine-if-location-container-collection-is-needed-in-get-faces.md)
|
||||
- [import-know-faces-into-db](tasks/import-know-faces-into-db.md)
|
||||
- [skip-metadata-load-after-first-each-day](tasks/skip-metadata-load-after-first-each-day.md)
|
||||
- [use-eyes-to-find-orientation](tasks/use-eyes-to-find-orientation.md)
|
||||
- [find-incorrectly-mapped-faces](tasks/find-incorrectly-mapped-faces.md)
|
||||
- [nef-support](tasks/nef-support.md)
|
||||
|
||||
## In Progress
|
||||
|
||||
- [find-incorrectly-mapped-faces](tasks/find-incorrectly-mapped-faces.md)
|
||||
- [nef-support](tasks/nef-support.md)
|
||||
- [use-eyes-to-find-orientation](tasks/use-eyes-to-find-orientation.md)
|
||||
- [merge-kristy-files](tasks/merge-kristy-files.md)
|
||||
- [set-date-taken-when-missing](tasks/set-date-taken-when-missing.md)
|
||||
- [rename-files-to-padded-number-string](tasks/rename-files-to-padded-number-string.md)
|
||||
|
||||
## Done
|
||||
|
||||
@ -45,3 +42,6 @@ taskTemplate: '^+^_${overdue ? ''^R'' : ''''}${name}^: ${relations ? (''\n^-^/^g
|
||||
- [run-scan-originals](tasks/run-scan-originals.md)
|
||||
- [shrink-percent](tasks/shrink-percent.md)
|
||||
- [setup-photo-prism-again-in-wsl-docker](tasks/setup-photo-prism-again-in-wsl-docker.md)
|
||||
- [set-date-taken-when-missing](tasks/set-date-taken-when-missing.md)
|
||||
- [rename-files-to-padded-number-string](tasks/rename-files-to-padded-number-string.md)
|
||||
- [merge-kristy-files](tasks/merge-kristy-files.md)
|
||||
|
@ -1,10 +1,10 @@
|
||||
---
|
||||
created: 2023-06-18T20:29:10.288Z
|
||||
updated: 2023-07-08T21:21:04.820Z
|
||||
updated: 2023-07-09T23:00:08.674Z
|
||||
assigned: ""
|
||||
progress: 0
|
||||
tags: []
|
||||
status: "3-In Progress"
|
||||
status: '3-In Progress'
|
||||
type: kanbn
|
||||
---
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
---
|
||||
created: 2023-06-25T16:35:28.627Z
|
||||
updated: 2023-07-08T21:44:14.665Z
|
||||
updated: 2023-07-09T22:16:11.849Z
|
||||
assigned: ""
|
||||
progress: 0
|
||||
tags: []
|
||||
@ -23,4 +23,6 @@ return new(result, (from l in results orderby l.FileHolder.DirectoryName?.EndsWi
|
||||
- [ ] Copy to each backup from question
|
||||
- [x] Rotate the .jpg only
|
||||
- [x] Use Rename console app to rename for storage
|
||||
- [x] Set created date
|
||||
- [ ] Verify
|
||||
- [ ] Move to production ...
|
||||
|
@ -1,10 +1,10 @@
|
||||
---
|
||||
created: 2023-06-24T02:13:16.426Z
|
||||
updated: 2023-07-08T21:21:06.222Z
|
||||
updated: 2023-07-09T23:00:05.524Z
|
||||
assigned: ""
|
||||
progress: 0
|
||||
tags: []
|
||||
status: "3-In Progress"
|
||||
status: '3-In Progress'
|
||||
type: kanbn
|
||||
---
|
||||
|
||||
|
@ -1,12 +1,13 @@
|
||||
---
|
||||
created: 2023-07-08T21:26:25.403Z
|
||||
updated: 2023-07-08T21:26:25.399Z
|
||||
updated: 2023-07-10T06:35:46.076Z
|
||||
assigned: ""
|
||||
progress: 0
|
||||
tags: []
|
||||
type: note
|
||||
---
|
||||
|
||||
# Photoview in docker for a viewer only
|
||||
# Photoview in Docker for a Viewer Only
|
||||
|
||||
## Sub-Tasks
|
||||
|
||||
|
@ -1,17 +1,22 @@
|
||||
---
|
||||
created: 2023-07-08T21:25:25.925Z
|
||||
updated: 2023-07-08T21:45:42.263Z
|
||||
updated: 2023-07-10T05:03:00.856Z
|
||||
assigned: ""
|
||||
progress: 0
|
||||
tags: []
|
||||
started: 2023-07-08T21:45:42.263Z
|
||||
type: note
|
||||
---
|
||||
|
||||
# Rename files to padded number string
|
||||
# Rename Files to Padded Number String
|
||||
|
||||
## Sub-tasks
|
||||
|
||||
- [ ] ~~Go Back to Index for Sort~~
|
||||
- [ ] New file for index to to id
|
||||
- [ ] Count backwards
|
||||
- [ ] Maybe skip some for scan images
|
||||
- [ ] ~~New file for index to to id~~
|
||||
- [ ] ~~Count backwards~~
|
||||
- [ ] ~~Maybe skip some for scan images~~
|
||||
- [Set Date Taken When Missing](set-date-taken-when-missing.md)
|
||||
- [x] Rename production with padding names starting with one directory
|
||||
- [x] Need equivalent to NameWithoutExtensionIsIdFormat method
|
||||
- [x] Verify nothing broke (run from resize original now ... ?)
|
||||
|
@ -1,6 +1,6 @@
|
||||
---
|
||||
created: 2023-07-05T22:17:38.271Z
|
||||
updated: 2023-07-08T21:47:12.461Z
|
||||
updated: 2023-07-10T00:16:19.096Z
|
||||
status: 2-Todo
|
||||
type: kanbn
|
||||
started: 2023-07-08T21:47:12.461Z
|
||||
@ -8,6 +8,15 @@ started: 2023-07-08T21:47:12.461Z
|
||||
|
||||
# Set Date Taken When Missing
|
||||
|
||||
```c#
|
||||
records = (from l in unordered orderby l.DateTime, l.FileHolder.Name.Length, l.FileHolder.Name select l).ToArray();
|
||||
return new(result, (from l in results orderby l.FileHolder.CreationTime, l.FileHolder.FullName.Length descending select l).ToArray());
|
||||
```
|
||||
|
||||
## Sub-tasks
|
||||
|
||||
- [ ] [ ]
|
||||
- [x] Set just one directory with no original and re-run Instance to verify it doesn't break anything
|
||||
- [x] Set just one directory with all original and re-run Instance to verify it doesn't break anything
|
||||
- [?] Set just one directory with mixed original and re-run Instance to verify it doesn't break anything
|
||||
- [x] Set all and re-run Instance to verify it doesn't break anything
|
||||
- [ ] Review above lines
|
||||
|
@ -1,10 +1,10 @@
|
||||
---
|
||||
created: 2023-06-23T13:56:11.956Z
|
||||
updated: 2023-07-08T21:21:06.224Z
|
||||
updated: 2023-07-09T23:00:03.100Z
|
||||
assigned: ""
|
||||
progress: 0
|
||||
tags: []
|
||||
status: "3-In Progress"
|
||||
status: '3-In Progress'
|
||||
type: kanbn
|
||||
---
|
||||
|
||||
|
@ -88,7 +88,6 @@
|
||||
"PopulatePropertyId": true,
|
||||
"PropertiesChangedForProperty": false,
|
||||
"RootDirectory": "C:/Tmp/Phares/Compare/Images-dd514b88",
|
||||
"WriteBitmapDataBytes": false,
|
||||
"IgnoreExtensions": [
|
||||
".gif",
|
||||
".GIF",
|
||||
@ -120,36 +119,6 @@
|
||||
".tif",
|
||||
".TIF"
|
||||
],
|
||||
"ValidMetadataExtensions": [
|
||||
".3gp",
|
||||
".3GP",
|
||||
".avi",
|
||||
".AVI",
|
||||
".bmp",
|
||||
".BMP",
|
||||
".gif",
|
||||
".GIF",
|
||||
".ico",
|
||||
".ICO",
|
||||
".jpeg",
|
||||
".JPEG",
|
||||
".jpg",
|
||||
".JPG",
|
||||
".m4v",
|
||||
".M4V",
|
||||
".mov",
|
||||
".MOV",
|
||||
".mp4",
|
||||
".MP4",
|
||||
".mta",
|
||||
".MTA",
|
||||
".png",
|
||||
".PNG",
|
||||
".tiff",
|
||||
".TIFF",
|
||||
".tif",
|
||||
".TIF"
|
||||
],
|
||||
"VerifyToSeason": [
|
||||
". 2000",
|
||||
". 2001",
|
||||
|
@ -122,34 +122,6 @@
|
||||
".tif",
|
||||
".TIF"
|
||||
],
|
||||
"ValidMetadataExtensions": [
|
||||
".3gp",
|
||||
".3GP",
|
||||
".avi",
|
||||
".AVI",
|
||||
".bmp",
|
||||
".BMP",
|
||||
".gif",
|
||||
".GIF",
|
||||
".ico",
|
||||
".ICO",
|
||||
".jpeg",
|
||||
".JPEG",
|
||||
".jpg",
|
||||
".JPG",
|
||||
".m4v",
|
||||
".M4V",
|
||||
".mov",
|
||||
".MOV",
|
||||
".mp4",
|
||||
".MP4",
|
||||
".mta",
|
||||
".MTA",
|
||||
".png",
|
||||
".PNG",
|
||||
".tiff",
|
||||
".TIFF"
|
||||
],
|
||||
"VerifyToSeason": [
|
||||
". 2000",
|
||||
". 2001",
|
||||
|
@ -70,7 +70,6 @@
|
||||
"ResultContent": "()",
|
||||
"ResultSingleton": "{}",
|
||||
"RootDirectory": "D:/Images",
|
||||
"WriteBitmapDataBytes": false,
|
||||
"IgnoreExtensions": [
|
||||
".gif",
|
||||
".GIF",
|
||||
@ -94,36 +93,6 @@
|
||||
".TIFF",
|
||||
".tif",
|
||||
".TIF"
|
||||
],
|
||||
"ValidMetadataExtensions": [
|
||||
".3gp",
|
||||
".3GP",
|
||||
".avi",
|
||||
".AVI",
|
||||
".bmp",
|
||||
".BMP",
|
||||
".gif",
|
||||
".GIF",
|
||||
".ico",
|
||||
".ICO",
|
||||
".jpeg",
|
||||
".JPEG",
|
||||
".jpg",
|
||||
".JPG",
|
||||
".m4v",
|
||||
".M4V",
|
||||
".mov",
|
||||
".MOV",
|
||||
".mp4",
|
||||
".MP4",
|
||||
".mta",
|
||||
".MTA",
|
||||
".png",
|
||||
".PNG",
|
||||
".tiff",
|
||||
".TIFF",
|
||||
".tif",
|
||||
".TIF"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
@ -51,6 +51,7 @@
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Shared\View-by-Distance.Shared.csproj" />
|
||||
<ProjectReference Include="..\Metadata\Metadata.csproj" />
|
||||
<ProjectReference Include="..\Property\Property.csproj" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
|
@ -45,6 +45,7 @@ public class DateGroup
|
||||
if (!_IsEnvironment.Development)
|
||||
throw new Exception("This program only allows development environments!");
|
||||
long ticks = DateTime.Now.Ticks;
|
||||
Metadata.Models.B_Metadata metadata = new(propertyConfiguration);
|
||||
string[] dbFiles = Directory.GetFiles(propertyConfiguration.RootDirectory, "*.db", SearchOption.AllDirectories);
|
||||
foreach (string dbFile in dbFiles)
|
||||
File.Delete(dbFile);
|
||||
@ -65,7 +66,7 @@ public class DateGroup
|
||||
throw new Exception();
|
||||
if (propertyConfiguration.PopulatePropertyId && (configuration.ByCreateDateShortcut || configuration.ByHash) && Shared.Models.Stateless.Methods.IProperty.Any(containers))
|
||||
{
|
||||
propertyLogic.SavePropertyParallelWork(ticks, t, containers);
|
||||
propertyLogic.SavePropertyParallelWork(ticks, metadata, t, containers);
|
||||
if (appSettings.MaxDegreeOfParallelism < 2)
|
||||
ticks = LogDelta(ticks, nameof(A_Property.SavePropertyParallelWork));
|
||||
if (propertyLogic.ExceptionsDirectories.Any())
|
||||
|
@ -69,7 +69,6 @@
|
||||
"ResultContent": "()",
|
||||
"ResultSingleton": "{}",
|
||||
"RootDirectory": "C:/Tmp/phares/Pictures",
|
||||
"WriteBitmapDataBytes": false,
|
||||
"IgnoreExtensions": [
|
||||
".gif",
|
||||
".GIF",
|
||||
@ -95,36 +94,6 @@
|
||||
".tif",
|
||||
".TIF"
|
||||
],
|
||||
"ValidMetadataExtensions": [
|
||||
".3gp",
|
||||
".3GP",
|
||||
".avi",
|
||||
".AVI",
|
||||
".bmp",
|
||||
".BMP",
|
||||
".gif",
|
||||
".GIF",
|
||||
".ico",
|
||||
".ICO",
|
||||
".jpeg",
|
||||
".JPEG",
|
||||
".jpg",
|
||||
".JPG",
|
||||
".m4v",
|
||||
".M4V",
|
||||
".mov",
|
||||
".MOV",
|
||||
".mp4",
|
||||
".MP4",
|
||||
".mta",
|
||||
".MTA",
|
||||
".png",
|
||||
".PNG",
|
||||
".tiff",
|
||||
".TIFF",
|
||||
".tif",
|
||||
".TIF"
|
||||
],
|
||||
"VerifyToSeason": [
|
||||
". 2000",
|
||||
". 2001",
|
||||
|
@ -71,7 +71,6 @@
|
||||
"ResultContent": "()",
|
||||
"ResultSingleton": "{}",
|
||||
"RootDirectory": "C:/Tmp/Phares/Compare/Images-dd514b88",
|
||||
"WriteBitmapDataBytes": false,
|
||||
"IgnoreExtensions": [
|
||||
".gif",
|
||||
".GIF",
|
||||
@ -95,36 +94,6 @@
|
||||
".TIFF",
|
||||
".tif",
|
||||
".TIF"
|
||||
],
|
||||
"ValidMetadataExtensions": [
|
||||
".3gp",
|
||||
".3GP",
|
||||
".avi",
|
||||
".AVI",
|
||||
".bmp",
|
||||
".BMP",
|
||||
".gif",
|
||||
".GIF",
|
||||
".ico",
|
||||
".ICO",
|
||||
".jpeg",
|
||||
".JPEG",
|
||||
".jpg",
|
||||
".JPG",
|
||||
".m4v",
|
||||
".M4V",
|
||||
".mov",
|
||||
".MOV",
|
||||
".mp4",
|
||||
".MP4",
|
||||
".mta",
|
||||
".MTA",
|
||||
".png",
|
||||
".PNG",
|
||||
".tiff",
|
||||
".TIFF",
|
||||
".tif",
|
||||
".TIF"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
@ -66,7 +66,6 @@
|
||||
"ResultContent": "()",
|
||||
"ResultSingleton": "{}",
|
||||
"RootDirectory": "C:/Tmp/Phares/Compare/Images-dd514b88",
|
||||
"WriteBitmapDataBytes": false,
|
||||
"IgnoreExtensions": [
|
||||
".gif",
|
||||
".GIF",
|
||||
@ -90,36 +89,6 @@
|
||||
".TIFF",
|
||||
".tif",
|
||||
".TIF"
|
||||
],
|
||||
"ValidMetadataExtensions": [
|
||||
".3gp",
|
||||
".3GP",
|
||||
".avi",
|
||||
".AVI",
|
||||
".bmp",
|
||||
".BMP",
|
||||
".gif",
|
||||
".GIF",
|
||||
".ico",
|
||||
".ICO",
|
||||
".jpeg",
|
||||
".JPEG",
|
||||
".jpg",
|
||||
".JPG",
|
||||
".m4v",
|
||||
".M4V",
|
||||
".mov",
|
||||
".MOV",
|
||||
".mp4",
|
||||
".MP4",
|
||||
".mta",
|
||||
".MTA",
|
||||
".png",
|
||||
".PNG",
|
||||
".tiff",
|
||||
".TIFF",
|
||||
".tif",
|
||||
".TIF"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
@ -37,6 +37,7 @@
|
||||
<PackageReference Include="Serilog" Version="2.12.0" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Metadata\Metadata.csproj" />
|
||||
<ProjectReference Include="..\Property\Property.csproj" />
|
||||
<ProjectReference Include="..\Shared\View-by-Distance.Shared.csproj" />
|
||||
</ItemGroup>
|
||||
|
@ -7,6 +7,7 @@ using System.Reflection;
|
||||
using System.Text;
|
||||
using System.Text.Json;
|
||||
using View_by_Distance.Drag.Drop.Set.Item.Models;
|
||||
using View_by_Distance.Shared.Models;
|
||||
using View_by_Distance.Shared.Models.Stateless;
|
||||
using View_by_Distance.Shared.Models.Stateless.Methods;
|
||||
|
||||
@ -15,6 +16,14 @@ namespace View_by_Distance.Drag.Drop.Set.Item;
|
||||
public partial class DragDropSetPropertyItem : Form
|
||||
{
|
||||
|
||||
private record Record(FileHolder FileHolder,
|
||||
bool IsIgnoreExtension,
|
||||
bool IsValidImageFormatExtension,
|
||||
int Id,
|
||||
DateTime? DateTimeOriginal,
|
||||
short? PropertyItemType,
|
||||
string? Value);
|
||||
|
||||
private readonly ILogger _Logger;
|
||||
private readonly TextBox _PathTextBox;
|
||||
private readonly TextBox _JsonTextBox;
|
||||
@ -23,6 +32,7 @@ public partial class DragDropSetPropertyItem : Form
|
||||
private readonly ProgressBar _ProgressBar;
|
||||
private readonly string _WorkingDirectory;
|
||||
private readonly IsEnvironment _IsEnvironment;
|
||||
private readonly Property.Models.Configuration _PropertyConfiguration;
|
||||
|
||||
public DragDropSetPropertyItem()
|
||||
{
|
||||
@ -50,6 +60,9 @@ public partial class DragDropSetPropertyItem : Form
|
||||
_ = ConfigurationLoggerConfigurationExtensions.Configuration(loggerConfiguration.ReadFrom, configurationRoot);
|
||||
Log.Logger = loggerConfiguration.CreateLogger();
|
||||
logger = Log.ForContext<DragDropSetPropertyItem>();
|
||||
Property.Models.Configuration propertyConfiguration = Property.Models.Binder.Configuration.Get(isEnvironment, configurationRoot);
|
||||
_PropertyConfiguration = propertyConfiguration;
|
||||
propertyConfiguration.Update();
|
||||
logger.Information("Complete");
|
||||
_Logger = logger;
|
||||
_AppSettings = appSettings;
|
||||
@ -102,18 +115,28 @@ public partial class DragDropSetPropertyItem : Form
|
||||
_JsonTextBox.Text = message;
|
||||
}
|
||||
|
||||
private static List<(string, int, DateTime?, short?, string?)> GetCollection(ASCIIEncoding asciiEncoding, int tagId, List<string> files)
|
||||
private List<Record> GetRecords(ASCIIEncoding asciiEncoding, int tagId, List<string> files)
|
||||
{
|
||||
List<(string, int, DateTime?, short?, string?)> results = new();
|
||||
List<Record> results = new();
|
||||
int? id;
|
||||
string? value;
|
||||
string? message;
|
||||
FileHolder fileHolder;
|
||||
bool isIgnoreExtension;
|
||||
DateTime? dateTimeOriginal;
|
||||
PropertyItem? propertyItem;
|
||||
Shared.Models.Property property;
|
||||
bool isValidImageFormatExtension;
|
||||
foreach (string file in files)
|
||||
{
|
||||
property = Property.Models.A_Property.GetImageProperty(file);
|
||||
if (property.Id is null)
|
||||
fileHolder = new(file);
|
||||
isValidImageFormatExtension = _PropertyConfiguration.ValidImageFormatExtensions.Contains(fileHolder.ExtensionLowered);
|
||||
isIgnoreExtension = isValidImageFormatExtension && _PropertyConfiguration.IgnoreExtensions.Contains(fileHolder.ExtensionLowered);
|
||||
(dateTimeOriginal, _, id, message) = Property.Models.Stateless.IProperty.Get(_PropertyConfiguration.PopulatePropertyId, fileHolder, isIgnoreExtension, isValidImageFormatExtension, asciiEncoding);
|
||||
if (message is not null)
|
||||
throw new Exception(message);
|
||||
if (id is null)
|
||||
continue;
|
||||
using Image image = Image.FromFile(file);
|
||||
using Image image = Image.FromFile(fileHolder.FullName);
|
||||
if (!image.PropertyIdList.Contains(tagId))
|
||||
(propertyItem, value) = (null, null);
|
||||
else
|
||||
@ -131,36 +154,37 @@ public partial class DragDropSetPropertyItem : Form
|
||||
value = null;
|
||||
}
|
||||
}
|
||||
results.Add((file, property.Id.Value, property.DateTimeOriginal, propertyItem?.Type, value));
|
||||
results.Add(new(fileHolder, isIgnoreExtension, isValidImageFormatExtension, id.Value, dateTimeOriginal, propertyItem?.Type, value));
|
||||
}
|
||||
if (files.Count != results.Count)
|
||||
throw new NotSupportedException();
|
||||
return results;
|
||||
}
|
||||
|
||||
private void SetPropertyItem(string setTo, int tagId, short type, ConstructorInfo constructorInfo, List<(string, int, DateTime?, short?, string?)> collection)
|
||||
private void SetPropertyItem(string setTo, int tagId, short type, ASCIIEncoding asciiEncoding, ConstructorInfo constructorInfo, List<Record> records)
|
||||
{
|
||||
int? id;
|
||||
Bitmap bitmap;
|
||||
string? message;
|
||||
string checkFile;
|
||||
PropertyItem? propertyItem;
|
||||
Shared.Models.Property property;
|
||||
foreach ((string file, int id, DateTime? dateTimeOriginal, short? propertyItemType, string? value) in collection)
|
||||
foreach (Record record in records)
|
||||
{
|
||||
if (propertyItemType is not null && propertyItemType.Value != type)
|
||||
if (record.PropertyItemType is not null && record.PropertyItemType.Value != type)
|
||||
throw new NotSupportedException();
|
||||
if ((dateTimeOriginal is null || !string.IsNullOrEmpty(value) || value == setTo) && !_AppSettings.IgnoreRulesKeyWords.Contains(setTo))
|
||||
if ((record.DateTimeOriginal is null || !string.IsNullOrEmpty(record.Value) || record.Value == setTo) && !_AppSettings.IgnoreRulesKeyWords.Contains(setTo))
|
||||
continue;
|
||||
checkFile = $"{file}.exif";
|
||||
propertyItem = IProperty.GetPropertyItem(constructorInfo, tagId, type, setTo);
|
||||
bitmap = new(file);
|
||||
checkFile = $"{record.FileHolder.FullName}.exif";
|
||||
propertyItem = Property.Models.Stateless.IProperty.GetPropertyItem(constructorInfo, tagId, type, setTo);
|
||||
bitmap = new(record.FileHolder.FullName);
|
||||
bitmap.SetPropertyItem(propertyItem);
|
||||
bitmap.Save(checkFile);
|
||||
bitmap.Dispose();
|
||||
property = Property.Models.A_Property.GetImageProperty(checkFile);
|
||||
if (property.Id is null || property.Id.Value != id)
|
||||
(_, _, id, message) = Property.Models.Stateless.IProperty.Get(_PropertyConfiguration.PopulatePropertyId, record.FileHolder, record.IsIgnoreExtension, record.IsValidImageFormatExtension, asciiEncoding);
|
||||
if (id is null || id.Value != record.Id)
|
||||
throw new NotSupportedException();
|
||||
File.Delete(file);
|
||||
File.Move(checkFile, file);
|
||||
File.Delete(record.FileHolder.FullName);
|
||||
File.Move(checkFile, record.FileHolder.FullName);
|
||||
}
|
||||
}
|
||||
|
||||
@ -170,11 +194,11 @@ public partial class DragDropSetPropertyItem : Form
|
||||
ASCIIEncoding asciiEncoding = new();
|
||||
int xpKeywords = (int)IExif.Tags.XPKeywords;
|
||||
ConstructorInfo? constructorInfo = typeof(PropertyItem).GetConstructor(BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Public, null, Array.Empty<Type>(), null) ?? throw new Exception();
|
||||
List<(string, int, DateTime?, short?, string?)> collection = GetCollection(asciiEncoding, xpKeywords, files);
|
||||
if (!collection.Any())
|
||||
List<Record> records = GetRecords(asciiEncoding, xpKeywords, files);
|
||||
if (!records.Any())
|
||||
SetMessage("No data");
|
||||
else
|
||||
SetPropertyItem(setTo, xpKeywords, type, constructorInfo, collection);
|
||||
SetPropertyItem(setTo, xpKeywords, type, asciiEncoding, constructorInfo, records);
|
||||
}
|
||||
|
||||
private void SetPropertyItem(string[] paths, string setTo)
|
||||
|
@ -50,5 +50,48 @@
|
||||
"ValidKeyWords": [
|
||||
"Review"
|
||||
],
|
||||
"WorkingDirectoryName": "PharesApps"
|
||||
"WorkingDirectoryName": "PharesApps",
|
||||
"Windows": {
|
||||
"Configuration": {
|
||||
"DateGroup": "dd514b88",
|
||||
"DiffPropertyDirectory": "",
|
||||
"FileNameDirectorySeparator": ".Z.",
|
||||
"ForcePropertyLastWriteTimeToCreationTime": false,
|
||||
"MaxImagesInDirectoryForTopLevelFirstPass": 10,
|
||||
"OutputExtension": ".jpg",
|
||||
"Pattern": "[^ABCDEFGHIJKLMNOPQRSTUVWXYZbcdfghjklmnpqrstvwxyz0-9]",
|
||||
"PopulatePropertyId": true,
|
||||
"PropertiesChangedForProperty": false,
|
||||
"ResultAllInOne": "_ _ _",
|
||||
"ResultAllInOneSubdirectoryLength": 2,
|
||||
"ResultCollection": "[]",
|
||||
"ResultContent": "()",
|
||||
"ResultSingleton": "{}",
|
||||
"RootDirectory": "C:/Tmp/Phares/Compare/Images-dd514b88",
|
||||
"IgnoreExtensions": [
|
||||
".gif",
|
||||
".GIF",
|
||||
".nef",
|
||||
".NEF",
|
||||
".pdf",
|
||||
".PDF"
|
||||
],
|
||||
"ValidImageFormatExtensions": [
|
||||
".bmp",
|
||||
".BMP",
|
||||
".gif",
|
||||
".GIF",
|
||||
".jpeg",
|
||||
".JPEG",
|
||||
".jpg",
|
||||
".JPG",
|
||||
".png",
|
||||
".PNG",
|
||||
".tiff",
|
||||
".TIFF",
|
||||
".tif",
|
||||
".TIF"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
@ -68,7 +68,6 @@
|
||||
"ResultContent": "()",
|
||||
"ResultSingleton": "{}",
|
||||
"RootDirectory": "C:/Tmp/Phares/Compare/Images-dd514b88",
|
||||
"WriteBitmapDataBytes": false,
|
||||
"IgnoreExtensions": [
|
||||
".gif",
|
||||
".GIF",
|
||||
@ -92,36 +91,6 @@
|
||||
".TIFF",
|
||||
".tif",
|
||||
".TIF"
|
||||
],
|
||||
"ValidMetadataExtensions": [
|
||||
".3gp",
|
||||
".3GP",
|
||||
".avi",
|
||||
".AVI",
|
||||
".bmp",
|
||||
".BMP",
|
||||
".gif",
|
||||
".GIF",
|
||||
".ico",
|
||||
".ICO",
|
||||
".jpeg",
|
||||
".JPEG",
|
||||
".jpg",
|
||||
".JPG",
|
||||
".m4v",
|
||||
".M4V",
|
||||
".mov",
|
||||
".MOV",
|
||||
".mp4",
|
||||
".MP4",
|
||||
".mta",
|
||||
".MTA",
|
||||
".png",
|
||||
".PNG",
|
||||
".tiff",
|
||||
".TIFF",
|
||||
".tif",
|
||||
".TIF"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
@ -190,11 +190,11 @@ public class D_Face
|
||||
{
|
||||
using (graphics = Graphics.FromImage(bitmap))
|
||||
graphics.DrawImage(source, new Rectangle(0, 0, width, height), rectangle, GraphicsUnit.Pixel);
|
||||
propertyItem = Shared.Models.Stateless.Methods.IProperty.GetPropertyItem(_ConstructorInfo, fileSource, type, locationJson);
|
||||
propertyItem = Property.Models.Stateless.IProperty.GetPropertyItem(_ConstructorInfo, fileSource, type, locationJson);
|
||||
bitmap.SetPropertyItem(propertyItem);
|
||||
propertyItem = Shared.Models.Stateless.Methods.IProperty.GetPropertyItem(_ConstructorInfo, artist, type, outputResolutionJson);
|
||||
propertyItem = Property.Models.Stateless.IProperty.GetPropertyItem(_ConstructorInfo, artist, type, outputResolutionJson);
|
||||
bitmap.SetPropertyItem(propertyItem);
|
||||
propertyItem = Shared.Models.Stateless.Methods.IProperty.GetPropertyItem(_ConstructorInfo, userComment, type, faceEncodingJson);
|
||||
propertyItem = Property.Models.Stateless.IProperty.GetPropertyItem(_ConstructorInfo, userComment, type, faceEncodingJson);
|
||||
bitmap.SetPropertyItem(propertyItem);
|
||||
bitmap.Save(fileInfo.FullName, _ImageCodecInfo, _EncoderParameters);
|
||||
}
|
||||
|
@ -16,6 +16,7 @@ using View_by_Distance.Property.Models;
|
||||
using View_by_Distance.Resize.Models;
|
||||
using View_by_Distance.Shared.Models;
|
||||
using View_by_Distance.Shared.Models.Methods;
|
||||
using View_by_Distance.Shared.Models.Stateless.Methods;
|
||||
using WindowsShortcutFactory;
|
||||
|
||||
namespace View_by_Distance.Instance;
|
||||
@ -126,9 +127,9 @@ public partial class DlibDotNet
|
||||
string peopleRootDirectory = Property.Models.Stateless.IResult.GetResultsDateGroupDirectory(propertyConfiguration, nameof(A2_People));
|
||||
string? rootResultsDirectory = Path.GetDirectoryName(Path.GetDirectoryName(peopleRootDirectory)) ?? throw new Exception();
|
||||
Storage storage = new(rootDirectory, rootResultsDirectory, peopleRootDirectory);
|
||||
_ = Shared.Models.Stateless.Methods.IPath.DeleteEmptyDirectories(Path.Combine(peopleRootDirectory, "{}"));
|
||||
(_GenealogicalDataCommunicationHeaderLines, Dictionary<string, List<string>> individuals, _GenealogicalDataCommunicationFooterLines) = Shared.Models.Stateless.Methods.IGenealogicalDataCommunication.GetIndividuals(configuration.GenealogicalDataCommunicationFile, requireNickName: true);
|
||||
_PersonContainers = Shared.Models.Stateless.Methods.IPersonContainer.GetPersonContainers(storage, configuration.MappingDefaultName, configuration.PersonBirthdayFormat, configuration.PersonCharacters.ToArray(), _Faces.FileNameExtension, individuals);
|
||||
_ = Shared.Models.Stateless.Methods.IPath.DeleteEmptyDirectories(Path.Combine(peopleRootDirectory, _Configuration.PropertyConfiguration.ResultSingleton));
|
||||
(_GenealogicalDataCommunicationHeaderLines, Dictionary<string, List<string>> individuals, _GenealogicalDataCommunicationFooterLines) = IGenealogicalDataCommunication.GetIndividuals(configuration.GenealogicalDataCommunicationFile, requireNickName: true);
|
||||
_PersonContainers = IPersonContainer.GetPersonContainers(storage, configuration.MappingDefaultName, configuration.PersonBirthdayFormat, configuration.PersonCharacters.ToArray(), _Faces.FileNameExtension, individuals);
|
||||
VerifyPersonContainersDisplayDirectoryAllFiles();
|
||||
}
|
||||
{
|
||||
@ -321,9 +322,9 @@ public partial class DlibDotNet
|
||||
eyeα = α is null ? null : (int)Math.Round(Math.Abs(α.Value));
|
||||
}
|
||||
confidencePercent = Shared.Models.Stateless.Methods.ILocation.GetConfidencePercent(_Configuration.FaceConfidencePercent, _Configuration.RangeFaceConfidence, face.Location.Confidence);
|
||||
faceAreaPermyriad = Shared.Models.Stateless.Methods.IMapping.GetAreaPermyriad(_Configuration.FaceAreaPermyriad, face.Location, face.OutputResolution);
|
||||
faceAreaPermyriad = IMapping.GetAreaPermyriad(_Configuration.FaceAreaPermyriad, face.Location, face.OutputResolution);
|
||||
wholePercentRectangle = Shared.Models.Stateless.Methods.ILocation.GetWholePercentages(face.Location, Shared.Models.Stateless.ILocation.Digits, face.OutputResolution);
|
||||
deterministicHashCodeKey = Shared.Models.Stateless.Methods.IMapping.GetDeterministicHashCodeKey(item.Property.Id.Value, face.Location, Shared.Models.Stateless.ILocation.Digits, face.OutputResolution);
|
||||
deterministicHashCodeKey = IMapping.GetDeterministicHashCodeKey(item.Property.Id.Value, face.Location, Shared.Models.Stateless.ILocation.Digits, face.OutputResolution);
|
||||
mappingFromLocation = new(faceAreaPermyriad, confidencePercent, deterministicHashCodeKey, eyeα, eyeReview, wholePercentRectangle);
|
||||
inSkipCollection = mapLogic.InSkipCollection(item.Property.Id.Value, mappingFromLocation);
|
||||
mappingFromFilter = new(isFocusModel, isFocusRelativePath, isIgnoreRelativePath, inSkipCollection);
|
||||
@ -356,7 +357,7 @@ public partial class DlibDotNet
|
||||
else
|
||||
{
|
||||
wholePercentRectangle = Shared.Models.Stateless.Methods.ILocation.GetWholePercentages(Shared.Models.Stateless.ILocation.Digits);
|
||||
deterministicHashCodeKey = Shared.Models.Stateless.Methods.IMapping.GetDeterministicHashCodeKey(item.Property.Id.Value, Shared.Models.Stateless.ILocation.Digits);
|
||||
deterministicHashCodeKey = IMapping.GetDeterministicHashCodeKey(item.Property.Id.Value, Shared.Models.Stateless.ILocation.Digits);
|
||||
mappingFromLocation = new(faceAreaPermyriad, confidencePercent, deterministicHashCodeKey, eyeα, eyeReview, wholePercentRectangle);
|
||||
inSkipCollection = mapLogic.InSkipCollection(item.Property.Id.Value, mappingFromLocation);
|
||||
mappingFromFilter = new(isFocusModel, isFocusRelativePath, isIgnoreRelativePath, inSkipCollection);
|
||||
@ -413,12 +414,13 @@ public partial class DlibDotNet
|
||||
List<string> parseExceptions = new();
|
||||
List<Tuple<string, DateTime>> subFileTuples = new();
|
||||
List<KeyValuePair<string, string>> metadataCollection;
|
||||
string[] changesFrom = new string[] { nameof(A_Property) };
|
||||
FileHolder resizedFileHolder = _Resize.GetResizedFileHolder(cResultsFullGroupDirectory, item, outputResolutionHasNumber);
|
||||
if (item.Property is null || item.Property.Id is null || item.Any())
|
||||
{
|
||||
LogItemPropertyIsNull(item);
|
||||
int? propertyHashCode = item.Property?.GetHashCode();
|
||||
property = propertyLogic.GetProperty(item, subFileTuples, parseExceptions);
|
||||
property = propertyLogic.GetProperty(metadata, item, subFileTuples, parseExceptions);
|
||||
item.Update(property);
|
||||
if (propertyHashCode is null)
|
||||
{
|
||||
@ -438,9 +440,13 @@ public partial class DlibDotNet
|
||||
subFileTuples.Add(new Tuple<string, DateTime>(nameof(A_Property), item.SourceDirectoryFileHolder.LastWriteTime.Value));
|
||||
else
|
||||
subFileTuples.Add(new Tuple<string, DateTime>(nameof(A_Property), new FileInfo(item.SourceDirectoryFileHolder.FullName).LastWriteTime));
|
||||
int sortOrderOnlyLengthIndex = IDirectory.GetSortOrderOnlyLengthIndex();
|
||||
bool nameWithoutExtensionIsIdFormat = Shared.Models.Stateless.Methods.IProperty.NameWithoutExtensionIsIdFormat(item.ImageFileHolder);
|
||||
bool nameWithoutExtensionIsPaddedIdFormat = IDirectory.NameWithoutExtensionIsPaddedIdFormat(item.ImageFileHolder, sortOrderOnlyLengthIndex);
|
||||
if (nameWithoutExtensionIsIdFormat && item.ImageFileHolder.NameWithoutExtension != item.Property.Id.ToString())
|
||||
LogNameWithoutExtensionIsIdFormatBut(item);
|
||||
if (nameWithoutExtensionIsPaddedIdFormat && item.ImageFileHolder.NameWithoutExtension.EndsWith(item.Property.Id.Value.ToString()[1..]))
|
||||
LogNameWithoutExtensionIsIdFormatBut(item);
|
||||
if (_BlurHasher is not null && resizedFileHolder.Exists && item.Property.Width is not null && item.Property.Width.Value > 4 && _Configuration.SaveBlurHashForOutputResolutions.Contains(outputResolution))
|
||||
{
|
||||
string? file = _BlurHasher.GetFile(resizedFileHolder);
|
||||
@ -451,8 +457,8 @@ public partial class DlibDotNet
|
||||
if (property is null || item.Property is null)
|
||||
throw new NullReferenceException(nameof(property));
|
||||
item.SetResizedFileHolder(_Resize.FileNameExtension, resizedFileHolder);
|
||||
MappingFromItem mappingFromItem = Shared.Models.Stateless.Methods.IMappingFromItem.GetMappingFromItem(containerDateTimes, item, resizedFileHolder);
|
||||
(int metadataGroups, metadataCollection) = metadata.GetMetadataCollection(subFileTuples, parseExceptions, mappingFromItem);
|
||||
MappingFromItem mappingFromItem = IMappingFromItem.GetMappingFromItem(containerDateTimes, item, resizedFileHolder);
|
||||
(int metadataGroups, metadataCollection) = metadata.GetMetadataCollection(subFileTuples, parseExceptions, changesFrom, mappingFromItem);
|
||||
if (_AppSettings.MaxDegreeOfParallelism < 2)
|
||||
ticks = LogDelta(ticks, nameof(B_Metadata.GetMetadataCollection));
|
||||
Dictionary<string, int[]> outputResolutionToResize = _Resize.GetResizeKeyValuePairs(_Configuration.PropertyConfiguration, cResultsFullGroupDirectory, subFileTuples, parseExceptions, metadataCollection, item.Property, mappingFromItem);
|
||||
@ -794,10 +800,10 @@ public partial class DlibDotNet
|
||||
|
||||
private void MapLogic(long ticks, Container[] containers, string a2PeopleSingletonDirectory, string dResultsFullGroupDirectory, string d2ResultsFullGroupDirectory, string fPhotoPrismContentDirectory, MapLogic mapLogic, string outputResolution, Dictionary<long, List<int>> personKeyToIds, List<Shared.Models.Face> distinctFilteredFaces, Mapping[] distinctFilteredMappingCollection, int totalNotMapped)
|
||||
{
|
||||
string dFacesContentDirectory = Path.Combine(dResultsFullGroupDirectory, "()");
|
||||
string d2FacePartsContentDirectory = Path.Combine(d2ResultsFullGroupDirectory, "()");
|
||||
string dFacesContentDirectory = Path.Combine(dResultsFullGroupDirectory, _Configuration.PropertyConfiguration.ResultContent);
|
||||
string d2FacePartsContentDirectory = Path.Combine(d2ResultsFullGroupDirectory, _Configuration.PropertyConfiguration.ResultContent);
|
||||
string d2FacePartsContentCollectionDirectory = Path.Combine(d2ResultsFullGroupDirectory, "[()]");
|
||||
string dFacesCollectionDirectory = Path.Combine(dResultsFullGroupDirectory, "[]", _Configuration.PropertyConfiguration.ResultAllInOne);
|
||||
string dFacesCollectionDirectory = Path.Combine(dResultsFullGroupDirectory, _Configuration.PropertyConfiguration.ResultCollection, _Configuration.PropertyConfiguration.ResultAllInOne);
|
||||
if (distinctFilteredMappingCollection.Any())
|
||||
{
|
||||
Shared.Models.Stateless.Methods.IPath.ChangeDateForEmptyDirectories(d2FacePartsContentDirectory, ticks);
|
||||
@ -871,24 +877,29 @@ public partial class DlibDotNet
|
||||
private static void LookForAbandoned(List<int> distinctFilteredIds, string directory, string directoryName)
|
||||
{
|
||||
string fileNameWithoutExtension;
|
||||
bool nameWithoutExtensionIsIdFormat;
|
||||
List<string> renameCollection = new();
|
||||
bool nameWithoutExtensionIsPaddedIdFormat;
|
||||
int sortOrderOnlyLengthIndex = IDirectory.GetSortOrderOnlyLengthIndex();
|
||||
string[] distinctFilteredIdsValues = distinctFilteredIds.Select(l => l.ToString()).ToArray();
|
||||
string[] files = Directory.GetFiles(directory, "*", SearchOption.AllDirectories);
|
||||
foreach (string file in files)
|
||||
{
|
||||
fileNameWithoutExtension = Path.GetFileNameWithoutExtension(Path.GetFileNameWithoutExtension(Path.GetFileNameWithoutExtension(file)));
|
||||
if (distinctFilteredIdsValues.Contains(fileNameWithoutExtension))
|
||||
nameWithoutExtensionIsIdFormat = Shared.Models.Stateless.Methods.IProperty.NameWithoutExtensionIsIdFormat(fileNameWithoutExtension);
|
||||
nameWithoutExtensionIsPaddedIdFormat = IDirectory.NameWithoutExtensionIsPaddedIdFormat(fileNameWithoutExtension, sortOrderOnlyLengthIndex);
|
||||
if (!nameWithoutExtensionIsIdFormat && !nameWithoutExtensionIsPaddedIdFormat)
|
||||
continue;
|
||||
if (!Shared.Models.Stateless.Methods.IProperty.NameWithoutExtensionIsIdFormat(fileNameWithoutExtension))
|
||||
if (distinctFilteredIdsValues.Contains(fileNameWithoutExtension))
|
||||
continue;
|
||||
renameCollection.Add(file);
|
||||
}
|
||||
if (renameCollection.Any())
|
||||
{
|
||||
if (directoryName.Length == 2)
|
||||
Shared.Models.Stateless.Methods.IDirectory.MoveFiles(renameCollection, directoryName, $"{directoryName[0]}abd{directoryName[^1]}");
|
||||
IDirectory.MoveFiles(renameCollection, directoryName, $"{directoryName[0]}abd{directoryName[^1]}");
|
||||
else if (directoryName.Length == 4)
|
||||
Shared.Models.Stateless.Methods.IDirectory.MoveFiles(renameCollection, directoryName, $"{directoryName[..2]}abd{directoryName[^2..]}");
|
||||
IDirectory.MoveFiles(renameCollection, directoryName, $"{directoryName[..2]}abd{directoryName[^2..]}");
|
||||
else
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
@ -906,7 +917,7 @@ public partial class DlibDotNet
|
||||
}
|
||||
}
|
||||
|
||||
private static void LookForAbandoned(ReadOnlyDictionary<int, List<LocationContainer<MetadataExtractor.Directory>>> idToLocationContainers, List<int> distinctFilteredIds)
|
||||
private void LookForAbandoned(ReadOnlyDictionary<int, List<LocationContainer<MetadataExtractor.Directory>>> idToLocationContainers, List<int> distinctFilteredIds)
|
||||
{
|
||||
List<string> renameCollection = new();
|
||||
foreach (KeyValuePair<int, List<LocationContainer<MetadataExtractor.Directory>>> keyValuePair in idToLocationContainers)
|
||||
@ -921,7 +932,7 @@ public partial class DlibDotNet
|
||||
}
|
||||
}
|
||||
if (renameCollection.Any())
|
||||
Shared.Models.Stateless.Methods.IDirectory.MoveFiles(renameCollection, "()", "(abd)");
|
||||
IDirectory.MoveFiles(renameCollection, _Configuration.PropertyConfiguration.ResultContent, "(abd)");
|
||||
}
|
||||
|
||||
private void LookForAbandoned(string bResultsFullGroupDirectory, Container[] containers, ReadOnlyDictionary<int, List<LocationContainer<MetadataExtractor.Directory>>> idToLocationContainers)
|
||||
@ -994,7 +1005,7 @@ public partial class DlibDotNet
|
||||
{
|
||||
if (item.Property?.Id is null || item.ResizedFileHolder is null)
|
||||
continue;
|
||||
mappingFromItem = Shared.Models.Stateless.Methods.IMappingFromItem.GetMappingFromItem(containerDateTimes, item, item.ResizedFileHolder);
|
||||
mappingFromItem = IMappingFromItem.GetMappingFromItem(containerDateTimes, item, item.ResizedFileHolder);
|
||||
if (distinctItems)
|
||||
{
|
||||
if (distinct.Contains(item.Property.Id.Value))
|
||||
@ -1137,6 +1148,7 @@ public partial class DlibDotNet
|
||||
private void Search(long ticks, string argZero, string propertyRoot)
|
||||
{
|
||||
int t;
|
||||
int count;
|
||||
string message;
|
||||
Container[] containers;
|
||||
A_Property propertyLogic;
|
||||
@ -1151,26 +1163,53 @@ public partial class DlibDotNet
|
||||
string fPhotoPrismContentDirectory;
|
||||
const string fileSearchFilter = "*";
|
||||
string fPhotoPrismSingletonDirectory;
|
||||
bool filesCollectionCountIsOne = false;
|
||||
List<string[]>? filesCollection = null;
|
||||
const string directorySearchFilter = "*";
|
||||
Dictionary<long, List<int>> personKeyToIds;
|
||||
bool eLastWriteTimeTimeSpanIsMoreThen = false;
|
||||
Dictionary<int, List<MappingFromPhotoPrism>> fileNameToCollection;
|
||||
(aResultsFullGroupDirectory, bResultsFullGroupDirectory) = GetResultsFullGroupDirectories();
|
||||
ProgressBarOptions options = new() { ProgressCharacter = '─', ProgressBarOnBottom = true, DisableBottomPercentage = true };
|
||||
string a2PeopleSingletonDirectory = Property.Models.Stateless.IResult.GetResultsDateGroupDirectory(_Configuration.PropertyConfiguration, nameof(A2_People), "{}");
|
||||
a2PeopleContentDirectory = Property.Models.Stateless.IResult.GetResultsDateGroupDirectory(_Configuration.PropertyConfiguration, nameof(A2_People), "([])");
|
||||
eDistanceContentDirectory = Property.Models.Stateless.IResult.GetResultsDateGroupDirectory(_Configuration.PropertyConfiguration, nameof(E_Distance), "()");
|
||||
fPhotoPrismContentDirectory = Property.Models.Stateless.IResult.GetResultsDateGroupDirectory(_Configuration.PropertyConfiguration, nameof(F_PhotoPrism), "()");
|
||||
fPhotoPrismSingletonDirectory = Property.Models.Stateless.IResult.GetResultsDateGroupDirectory(_Configuration.PropertyConfiguration, nameof(F_PhotoPrism), "{}");
|
||||
propertyLogic = new(_AppSettings.MaxDegreeOfParallelism, _Configuration.PropertyConfiguration, _Resize.FileNameExtension, _Configuration.Reverse, aResultsFullGroupDirectory);
|
||||
List<string[]> filesCollection = Shared.Models.Stateless.Methods.IDirectory.GetFilesCollection(_Configuration.PropertyConfiguration.RootDirectory, directorySearchFilter, fileSearchFilter);
|
||||
int count = filesCollection.Select(l => l.Length).Sum();
|
||||
if (filesCollection.Count == 1)
|
||||
eDistanceContentDirectory = Property.Models.Stateless.IResult.GetResultsDateGroupDirectory(_Configuration.PropertyConfiguration, nameof(E_Distance), _Configuration.PropertyConfiguration.ResultContent);
|
||||
TimeSpan eLastWriteTimeTimeSpan = new(ticks - new DirectoryInfo(eDistanceContentDirectory).LastWriteTime.Ticks);
|
||||
foreach (string outputResolution in _Configuration.OutputResolutions)
|
||||
{
|
||||
if (outputResolution.Any(l => char.IsNumber(l)))
|
||||
continue;
|
||||
eLastWriteTimeTimeSpanIsMoreThen = true;
|
||||
if (eLastWriteTimeTimeSpan.TotalDays < 1)
|
||||
break;
|
||||
ProgressBar progressBar;
|
||||
(cResultsFullGroupDirectory, _, _, _) = GetResultsFullGroupDirectories(outputResolution);
|
||||
IReadOnlyDictionary<string, string[]> fileGroups = Shared.Models.Stateless.Methods.IPath.GetKeyValuePairs(_Configuration.PropertyConfiguration, cResultsFullGroupDirectory, new string[] { _Configuration.PropertyConfiguration.ResultContent });
|
||||
filesCollection = IDirectory.GetFilesCollection(_Configuration.PropertyConfiguration.RootDirectory, directorySearchFilter, fileSearchFilter);
|
||||
message = $") Selecting for ## pattern directory - {(int)Math.Floor(new TimeSpan(DateTime.Now.Ticks - ticks).TotalSeconds)} total second(s)";
|
||||
count = filesCollection.Select(l => l.Length).Sum();
|
||||
filesCollectionCountIsOne = filesCollection.Count == 1;
|
||||
progressBar = new(count, message, options);
|
||||
(string[] distinctDirectories, List<(FileHolder, string)> toDoCollection) = IDirectory.GetToDoCollection(_Configuration.PropertyConfiguration, filesCollection, fileGroups[_Configuration.PropertyConfiguration.ResultContent], () => progressBar.Tick());
|
||||
progressBar.Dispose();
|
||||
message = $") Copying to ## pattern directory - {(int)Math.Floor(new TimeSpan(DateTime.Now.Ticks - ticks).TotalSeconds)} total second(s)";
|
||||
progressBar = new(count, message, options);
|
||||
_ = IDirectory.CopyOrMove(toDoCollection, move: false, moveBack: false, () => progressBar.Tick());
|
||||
progressBar.Dispose();
|
||||
break;
|
||||
}
|
||||
a2PeopleContentDirectory = Property.Models.Stateless.IResult.GetResultsDateGroupDirectory(_Configuration.PropertyConfiguration, nameof(A2_People), "([])");
|
||||
fPhotoPrismContentDirectory = Property.Models.Stateless.IResult.GetResultsDateGroupDirectory(_Configuration.PropertyConfiguration, nameof(F_PhotoPrism), _Configuration.PropertyConfiguration.ResultContent);
|
||||
fPhotoPrismSingletonDirectory = Property.Models.Stateless.IResult.GetResultsDateGroupDirectory(_Configuration.PropertyConfiguration, nameof(F_PhotoPrism), _Configuration.PropertyConfiguration.ResultSingleton);
|
||||
string a2PeopleSingletonDirectory = Property.Models.Stateless.IResult.GetResultsDateGroupDirectory(_Configuration.PropertyConfiguration, nameof(A2_People), _Configuration.PropertyConfiguration.ResultSingleton);
|
||||
propertyLogic = new(_AppSettings.MaxDegreeOfParallelism, _Configuration.PropertyConfiguration, _Resize.FileNameExtension, _Configuration.Reverse, aResultsFullGroupDirectory);
|
||||
if (filesCollectionCountIsOne)
|
||||
{
|
||||
if (filesCollection is null)
|
||||
throw new NullReferenceException(nameof(filesCollection));
|
||||
string resultsGroupDirectory;
|
||||
a2PeopleContentDirectory = null;
|
||||
eDistanceContentDirectory = Path.Combine($"{Path.GetPathRoot(argZero)}", "()");
|
||||
fPhotoPrismContentDirectory = Path.Combine($"{Path.GetPathRoot(argZero)}", "()");
|
||||
fPhotoPrismSingletonDirectory = Path.Combine($"{Path.GetPathRoot(argZero)}", "{}");
|
||||
eDistanceContentDirectory = Path.Combine($"{Path.GetPathRoot(argZero)}", _Configuration.PropertyConfiguration.ResultContent);
|
||||
fPhotoPrismContentDirectory = Path.Combine($"{Path.GetPathRoot(argZero)}", _Configuration.PropertyConfiguration.ResultContent);
|
||||
fPhotoPrismSingletonDirectory = Path.Combine($"{Path.GetPathRoot(argZero)}", _Configuration.PropertyConfiguration.ResultSingleton);
|
||||
for (int i = 1; i < 10; i++)
|
||||
{
|
||||
resultsGroupDirectory = Property.Models.Stateless.IResult.GetResultsGroupDirectory(_Configuration.PropertyConfiguration, string.Empty, create: true);
|
||||
@ -1182,31 +1221,25 @@ public partial class DlibDotNet
|
||||
propertyRoot = Property.Models.Stateless.IResult.GetResultsGroupDirectory(_Configuration.PropertyConfiguration, nameof(A_Property), create: false);
|
||||
propertyLogic = new(_AppSettings.MaxDegreeOfParallelism, _Configuration.PropertyConfiguration, _Resize.FileNameExtension, _Configuration.Reverse, aResultsFullGroupDirectory);
|
||||
}
|
||||
TimeSpan eLastWriteTimeTimeSpan = new(ticks - new DirectoryInfo(eDistanceContentDirectory).LastWriteTime.Ticks);
|
||||
if (eLastWriteTimeTimeSpanIsMoreThen)
|
||||
{
|
||||
foreach (string outputResolution in _Configuration.OutputResolutions)
|
||||
{
|
||||
if (outputResolution.Any(l => char.IsNumber(l)))
|
||||
continue;
|
||||
if (eLastWriteTimeTimeSpan.TotalDays < 1)
|
||||
break;
|
||||
ProgressBar progressBar;
|
||||
(cResultsFullGroupDirectory, _, _, _) = GetResultsFullGroupDirectories(outputResolution);
|
||||
IReadOnlyDictionary<string, string[]> fileGroups = Shared.Models.Stateless.Methods.IPath.GetKeyValuePairs(_Configuration.PropertyConfiguration, cResultsFullGroupDirectory, new string[] { _Configuration.PropertyConfiguration.ResultContent });
|
||||
message = $") Selecting for ## pattern directory - {(int)Math.Floor(new TimeSpan(DateTime.Now.Ticks - ticks).TotalSeconds)} total second(s)";
|
||||
progressBar = new(count, message, options);
|
||||
(string[] distinctDirectories, List<(FileHolder, string)> toDoCollection) = Shared.Models.Stateless.Methods.IDirectory.GetToDoCollection(_Configuration.PropertyConfiguration, copyDuplicates: false, filesCollection, fileGroups[_Configuration.PropertyConfiguration.ResultContent], () => progressBar.Tick());
|
||||
progressBar.Dispose();
|
||||
message = $") Copying to ## pattern directory - {(int)Math.Floor(new TimeSpan(DateTime.Now.Ticks - ticks).TotalSeconds)} total second(s)";
|
||||
progressBar = new(count, message, options);
|
||||
_ = Shared.Models.Stateless.Methods.IDirectory.CopyOrMove(toDoCollection, move: false, moveBack: false, () => progressBar.Tick());
|
||||
progressBar.Dispose();
|
||||
filesCollection = IDirectory.GetFilesCollection(Path.Combine(cResultsFullGroupDirectory, _Configuration.PropertyConfiguration.ResultContent, _Configuration.PropertyConfiguration.ResultAllInOne), directorySearchFilter, fileSearchFilter);
|
||||
count = filesCollection.Select(l => l.Length).Sum();
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (filesCollection is null)
|
||||
throw new NullReferenceException(nameof(filesCollection));
|
||||
message = $") Building Container(s) - {(int)Math.Floor(new TimeSpan(DateTime.Now.Ticks - ticks).TotalSeconds)} total second(s)";
|
||||
using (ProgressBar progressBar = new(2, message, options))
|
||||
{
|
||||
progressBar.Tick();
|
||||
string aPropertySingletonDirectory = Path.Combine(aResultsFullGroupDirectory, "{}");
|
||||
string aPropertySingletonDirectory = Path.Combine(aResultsFullGroupDirectory, _Configuration.PropertyConfiguration.ResultSingleton);
|
||||
if (!Directory.Exists(aPropertySingletonDirectory))
|
||||
_ = Directory.CreateDirectory(aPropertySingletonDirectory);
|
||||
(t, containers) = Shared.Models.Stateless.Methods.IContainer.GetContainers(_Configuration.PropertyConfiguration, aPropertySingletonDirectory, filesCollection);
|
||||
@ -1215,11 +1248,11 @@ public partial class DlibDotNet
|
||||
fileNameToCollection = !Directory.Exists(fPhotoPrismSingletonDirectory) ? fileNameToCollection = new() : F_PhotoPrism.GetFileNameToCollection(fPhotoPrismSingletonDirectory);
|
||||
B_Metadata metadata = new(_Configuration.PropertyConfiguration, _Configuration.ForceMetadataLastWriteTimeToCreationTime, _Configuration.PropertiesChangedForMetadata, bResultsFullGroupDirectory);
|
||||
MapLogic mapLogic = new(_AppSettings.MaxDegreeOfParallelism, _Configuration.PropertyConfiguration, _MapConfiguration, new(_PersonContainers), ticks, a2PeopleSingletonDirectory, eDistanceContentDirectory);
|
||||
_PersonContainers.AddRange(Shared.Models.Stateless.Methods.IPersonContainer.GetNonSpecificPeopleCollection(_Configuration.MappingDefaultName, _Configuration.PersonBirthdayFirstYear, _Configuration.PersonCharacters.ToArray(), _PersonContainers, ticks));
|
||||
_PersonContainers.AddRange(IPersonContainer.GetNonSpecificPeopleCollection(_Configuration.MappingDefaultName, _Configuration.PersonBirthdayFirstYear, _Configuration.PersonCharacters.ToArray(), _PersonContainers, ticks));
|
||||
containers = Shared.Models.Stateless.Methods.IContainer.SortContainers(_Configuration.PropertyConfiguration, _Configuration.IgnoreRelativePaths, _ArgZeroIsConfigurationRootDirectory, argZero, containers);
|
||||
personKeyToIds = mapLogic.GetPersonKeyToIds();
|
||||
if (!string.IsNullOrEmpty(_Configuration.GenealogicalDataCommunicationFile) && !string.IsNullOrEmpty(a2PeopleContentDirectory) && _GenealogicalDataCommunicationHeaderLines is not null && _GenealogicalDataCommunicationFooterLines is not null && _GenealogicalDataCommunicationHeaderLines.Any() && _GenealogicalDataCommunicationFooterLines.Any())
|
||||
Shared.Models.Stateless.Methods.IGenealogicalDataCommunication.CreateTree(_Configuration.MappingDefaultName, _Configuration.PersonBirthdayFormat, _Configuration.PropertyConfiguration.ResultAllInOne, _PersonContainers, _GenealogicalDataCommunicationHeaderLines, _GenealogicalDataCommunicationFooterLines, ticks, a2PeopleContentDirectory, personKeyToIds);
|
||||
IGenealogicalDataCommunication.CreateTree(_Configuration.MappingDefaultName, _Configuration.PersonBirthdayFormat, _Configuration.PropertyConfiguration.ResultAllInOne, _PersonContainers, _GenealogicalDataCommunicationHeaderLines, _GenealogicalDataCommunicationFooterLines, ticks, a2PeopleContentDirectory, personKeyToIds);
|
||||
ReadOnlyDictionary<int, List<LocationContainer<MetadataExtractor.Directory>>> idToLocationContainers = mapLogic.GetIdToLocationContainers();
|
||||
FullDoWork(argZero, propertyRoot, ticks, aResultsFullGroupDirectory, bResultsFullGroupDirectory, t, containers, propertyLogic, metadata, fileNameToCollection, idToLocationContainers, mapLogic);
|
||||
if (_Configuration.LookForAbandoned)
|
||||
@ -1257,11 +1290,11 @@ public partial class DlibDotNet
|
||||
continue;
|
||||
if (!_IsEnvironment.Development)
|
||||
{
|
||||
_ = Shared.Models.Stateless.Methods.IPath.DeleteEmptyDirectories(Path.Combine(aResultsFullGroupDirectory, "{}"));
|
||||
_ = Shared.Models.Stateless.Methods.IPath.DeleteEmptyDirectories(Path.Combine(bResultsFullGroupDirectory, "{}"));
|
||||
_ = Shared.Models.Stateless.Methods.IPath.DeleteEmptyDirectories(Path.Combine(cResultsFullGroupDirectory, "{}"));
|
||||
_ = Shared.Models.Stateless.Methods.IPath.DeleteEmptyDirectories(Path.Combine(aResultsFullGroupDirectory, _Configuration.PropertyConfiguration.ResultSingleton));
|
||||
_ = Shared.Models.Stateless.Methods.IPath.DeleteEmptyDirectories(Path.Combine(bResultsFullGroupDirectory, _Configuration.PropertyConfiguration.ResultSingleton));
|
||||
_ = Shared.Models.Stateless.Methods.IPath.DeleteEmptyDirectories(Path.Combine(cResultsFullGroupDirectory, _Configuration.PropertyConfiguration.ResultSingleton));
|
||||
if (_Configuration.LoadOrCreateThenSaveImageFacesResultsForOutputResolutions.Contains(outputResolution))
|
||||
_ = Shared.Models.Stateless.Methods.IPath.DeleteEmptyDirectories(Path.Combine(dResultsFullGroupDirectory, "[]"));
|
||||
_ = Shared.Models.Stateless.Methods.IPath.DeleteEmptyDirectories(Path.Combine(dResultsFullGroupDirectory, _Configuration.PropertyConfiguration.ResultCollection));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -3,25 +3,21 @@ using System.Text.Json.Serialization;
|
||||
|
||||
namespace View_by_Distance.Instance.Models;
|
||||
|
||||
public class AppSettings
|
||||
public record AppSettings(string Company,
|
||||
int MaxDegreeOfParallelism,
|
||||
string WorkingDirectoryName)
|
||||
{
|
||||
|
||||
public string Company { init; get; }
|
||||
public int MaxDegreeOfParallelism { init; get; }
|
||||
public string WorkingDirectoryName { init; get; }
|
||||
|
||||
[JsonConstructor]
|
||||
public AppSettings(string company, int maxDegreeOfParallelism, string workingDirectoryName)
|
||||
{
|
||||
Company = company;
|
||||
MaxDegreeOfParallelism = maxDegreeOfParallelism;
|
||||
WorkingDirectoryName = workingDirectoryName;
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
string result = JsonSerializer.Serialize(this, new JsonSerializerOptions() { WriteIndented = true });
|
||||
string result = JsonSerializer.Serialize(this, AppSettingsSourceGenerationContext.Default.AppSettings);
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
[JsonSourceGenerationOptions(WriteIndented = true)]
|
||||
[JsonSerializable(typeof(AppSettings))]
|
||||
internal partial class AppSettingsSourceGenerationContext : JsonSerializerContext
|
||||
{
|
||||
}
|
@ -1,5 +1,6 @@
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace View_by_Distance.Instance.Models.Binder;
|
||||
|
||||
@ -16,7 +17,7 @@ public class AppSettings
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
string result = JsonSerializer.Serialize(this, new JsonSerializerOptions() { WriteIndented = true });
|
||||
string result = JsonSerializer.Serialize(this, BinderAppSettingsSourceGenerationContext.Default.AppSettings);
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -36,9 +37,17 @@ public class AppSettings
|
||||
public static Models.AppSettings Get(IConfigurationRoot configurationRoot)
|
||||
{
|
||||
Models.AppSettings result;
|
||||
#pragma warning disable IL3050, IL2026
|
||||
AppSettings? appSettings = configurationRoot.Get<AppSettings>();
|
||||
#pragma warning restore IL3050, IL2026
|
||||
result = Get(appSettings);
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
[JsonSourceGenerationOptions(WriteIndented = true)]
|
||||
[JsonSerializable(typeof(AppSettings))]
|
||||
internal partial class BinderAppSettingsSourceGenerationContext : JsonSerializerContext
|
||||
{
|
||||
}
|
@ -121,7 +121,6 @@
|
||||
"SortingMinimumToUseSigma": 10,
|
||||
"TestDistanceResults": true,
|
||||
"UseFilterTries": 0,
|
||||
"WriteBitmapDataBytes": false,
|
||||
"CopyFacesAndSaveFaceLandmarkForOutputResolutions": [],
|
||||
"IgnoreExtensions": [
|
||||
".gif",
|
||||
@ -187,36 +186,6 @@
|
||||
".tif",
|
||||
".TIF"
|
||||
],
|
||||
"ValidMetadataExtensions": [
|
||||
".3gp",
|
||||
".3GP",
|
||||
".avi",
|
||||
".AVI",
|
||||
".bmp",
|
||||
".BMP",
|
||||
".gif",
|
||||
".GIF",
|
||||
".ico",
|
||||
".ICO",
|
||||
".jpeg",
|
||||
".JPEG",
|
||||
".jpg",
|
||||
".JPG",
|
||||
".m4v",
|
||||
".M4V",
|
||||
".mov",
|
||||
".MOV",
|
||||
".mp4",
|
||||
".MP4",
|
||||
".mta",
|
||||
".MTA",
|
||||
".png",
|
||||
".PNG",
|
||||
".tiff",
|
||||
".TIFF",
|
||||
".tif",
|
||||
".TIF"
|
||||
],
|
||||
"ValidResolutions": [
|
||||
"Original",
|
||||
"176 x 176",
|
||||
|
@ -67,7 +67,6 @@
|
||||
"ResultContent": "()",
|
||||
"ResultSingleton": "{}",
|
||||
"RootDirectory": "D:/Images",
|
||||
"WriteBitmapDataBytes": false,
|
||||
"IgnoreExtensions": [
|
||||
".gif",
|
||||
".GIF",
|
||||
@ -91,36 +90,6 @@
|
||||
".TIFF",
|
||||
".tif",
|
||||
".TIF"
|
||||
],
|
||||
"ValidMetadataExtensions": [
|
||||
".3gp",
|
||||
".3GP",
|
||||
".avi",
|
||||
".AVI",
|
||||
".bmp",
|
||||
".BMP",
|
||||
".gif",
|
||||
".GIF",
|
||||
".ico",
|
||||
".ICO",
|
||||
".jpeg",
|
||||
".JPEG",
|
||||
".jpg",
|
||||
".JPG",
|
||||
".m4v",
|
||||
".M4V",
|
||||
".mov",
|
||||
".MOV",
|
||||
".mp4",
|
||||
".MP4",
|
||||
".mta",
|
||||
".MTA",
|
||||
".png",
|
||||
".PNG",
|
||||
".tiff",
|
||||
".TIFF",
|
||||
".tif",
|
||||
".TIF"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
@ -39,7 +39,7 @@
|
||||
<PackageReference Include="System.Text.Json" Version="7.0.2" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Shared\View-by-Distance.Shared.csproj" />
|
||||
<ProjectReference Include="..\Property\Property.csproj" />
|
||||
<ProjectReference Include="..\Shared\View-by-Distance.Shared.csproj" />
|
||||
</ItemGroup>
|
||||
</Project>
|
@ -1,8 +1,12 @@
|
||||
using MetadataExtractor;
|
||||
using MetadataExtractor.Formats.Avi;
|
||||
using MetadataExtractor.Formats.Exif;
|
||||
using MetadataExtractor.Formats.QuickTime;
|
||||
using System.Diagnostics;
|
||||
using System.Text.Json;
|
||||
using View_by_Distance.Metadata.Models.Stateless;
|
||||
using View_by_Distance.Property.Models;
|
||||
using View_by_Distance.Property.Models.Stateless;
|
||||
using View_by_Distance.Shared.Models;
|
||||
using View_by_Distance.Shared.Models.Methods;
|
||||
using View_by_Distance.Shared.Models.Properties;
|
||||
using View_by_Distance.Shared.Models.Stateless;
|
||||
|
||||
@ -11,7 +15,7 @@ namespace View_by_Distance.Metadata.Models;
|
||||
/// <summary>
|
||||
// Dictionary<string, List<KeyValuePair<string, string>>>
|
||||
/// </summary>
|
||||
public class B_Metadata
|
||||
public class B_Metadata : IMetadata<MetadataExtractor.Directory>
|
||||
{
|
||||
|
||||
private readonly Serilog.ILogger? _Log;
|
||||
@ -21,6 +25,16 @@ public class B_Metadata
|
||||
private readonly IReadOnlyDictionary<string, string[]> _FileGroups;
|
||||
private readonly JsonSerializerOptions _WriteIndentedJsonSerializerOptions;
|
||||
|
||||
public B_Metadata(IPropertyConfiguration propertyConfiguration)
|
||||
{
|
||||
_PropertiesChangedForMetadata = false;
|
||||
_Log = Serilog.Log.ForContext<B_Metadata>();
|
||||
_PropertyConfiguration = propertyConfiguration;
|
||||
_ForceMetadataLastWriteTimeToCreationTime = false;
|
||||
_WriteIndentedJsonSerializerOptions = new JsonSerializerOptions { WriteIndented = true };
|
||||
_FileGroups = Shared.Models.Stateless.Methods.IPath.GetKeyValuePairs(propertyConfiguration, null, new string[] { propertyConfiguration.ResultSingleton });
|
||||
}
|
||||
|
||||
public B_Metadata(IPropertyConfiguration propertyConfiguration, bool forceMetadataLastWriteTimeToCreationTime, bool propertiesChangedForMetadata, string bResultsFullGroupDirectory)
|
||||
{
|
||||
_Log = Serilog.Log.ForContext<B_Metadata>();
|
||||
@ -49,12 +63,12 @@ public class B_Metadata
|
||||
List<string> tagNames = new();
|
||||
int type = (int)IExif.Tags.Orientation;
|
||||
string key = nameof(IExif.Tags.Orientation);
|
||||
IReadOnlyList<MetadataExtractor.Directory> directories = MetadataExtractor.ImageMetadataReader.ReadMetadata(subFile);
|
||||
IReadOnlyList<MetadataExtractor.Directory> directories = ImageMetadataReader.ReadMetadata(subFile);
|
||||
foreach (MetadataExtractor.Directory directory in directories)
|
||||
{
|
||||
if (!results.ContainsKey(directory.Name))
|
||||
results.Add(directory.Name, new());
|
||||
foreach (MetadataExtractor.Tag tag in directory.Tags)
|
||||
foreach (Tag tag in directory.Tags)
|
||||
{
|
||||
tagNames.Add(tag.Name);
|
||||
if (string.IsNullOrEmpty(tag.Description))
|
||||
@ -80,11 +94,10 @@ public class B_Metadata
|
||||
return results;
|
||||
}
|
||||
|
||||
public (int, List<KeyValuePair<string, string>>) GetMetadataCollection(List<Tuple<string, DateTime>> subFileTuples, List<string> parseExceptions, Shared.Models.MappingFromItem mappingFromItem)
|
||||
public (int, List<KeyValuePair<string, string>>) GetMetadataCollection(List<Tuple<string, DateTime>> subFileTuples, List<string> parseExceptions, string[] changesFrom, MappingFromItem mappingFromItem)
|
||||
{
|
||||
List<KeyValuePair<string, string>> results = new();
|
||||
string json = string.Empty;
|
||||
string[] changesFrom = new string[] { nameof(A_Property) };
|
||||
Dictionary<string, List<KeyValuePair<string, string>>>? dictionary;
|
||||
List<DateTime> dateTimes = (from l in subFileTuples where changesFrom.Contains(l.Item1) select l.Item2).ToList();
|
||||
(_, int directoryIndex) = Shared.Models.Stateless.Methods.IPath.GetDirectoryNameAndIndex(_PropertyConfiguration.ResultAllInOneSubdirectoryLength, mappingFromItem.ImageFileHolder.Name);
|
||||
@ -149,4 +162,104 @@ public class B_Metadata
|
||||
return new(dictionary.Count, results);
|
||||
}
|
||||
|
||||
(DateTime?, DateTime?[]) IMetadata<MetadataExtractor.Directory>.GetDateTimes(FileHolder fileHolder, IReadOnlyList<MetadataExtractor.Directory> directories)
|
||||
{
|
||||
List<DateTime?> results = new();
|
||||
DateTime? result = null;
|
||||
DateTime? dateTime;
|
||||
DateTime checkDateTime;
|
||||
string dateTimeFormat = Property.Models.Stateless.IProperty.DateTimeFormat();
|
||||
ExifDirectoryBase? exifDirectoryBase = directories.OfType<ExifDirectoryBase>().FirstOrDefault();
|
||||
results.Add(fileHolder.CreationTime);
|
||||
results.Add(fileHolder.LastWriteTime);
|
||||
if (exifDirectoryBase is not null)
|
||||
{
|
||||
if (exifDirectoryBase.TryGetDateTime(ExifDirectoryBase.TagDateTime, out checkDateTime))
|
||||
results.Add(checkDateTime);
|
||||
else
|
||||
{
|
||||
dateTime = Property.Models.Stateless.IProperty.GetDateTime(dateTimeFormat, exifDirectoryBase.GetString(ExifDirectoryBase.TagDateTime));
|
||||
if (dateTime is not null)
|
||||
results.Add(dateTime.Value);
|
||||
}
|
||||
if (exifDirectoryBase.TryGetDateTime(ExifDirectoryBase.TagDateTimeDigitized, out checkDateTime))
|
||||
results.Add(checkDateTime);
|
||||
else
|
||||
{
|
||||
dateTime = Property.Models.Stateless.IProperty.GetDateTime(dateTimeFormat, exifDirectoryBase.GetString(ExifDirectoryBase.TagDateTimeDigitized));
|
||||
if (dateTime is not null)
|
||||
results.Add(dateTime.Value);
|
||||
}
|
||||
if (exifDirectoryBase.TryGetDateTime(ExifDirectoryBase.TagDateTimeOriginal, out checkDateTime))
|
||||
{
|
||||
result ??= checkDateTime;
|
||||
results.Add(checkDateTime);
|
||||
}
|
||||
else
|
||||
{
|
||||
dateTime = Property.Models.Stateless.IProperty.GetDateTime(dateTimeFormat, exifDirectoryBase.GetString(ExifDirectoryBase.TagDateTimeOriginal));
|
||||
if (dateTime is not null)
|
||||
{
|
||||
result ??= dateTime.Value;
|
||||
results.Add(dateTime.Value);
|
||||
}
|
||||
}
|
||||
}
|
||||
AviDirectory? aviDirectory = directories.OfType<AviDirectory>().FirstOrDefault();
|
||||
if (aviDirectory is not null)
|
||||
{
|
||||
if (aviDirectory.TryGetDateTime(AviDirectory.TagDateTimeOriginal, out checkDateTime))
|
||||
{
|
||||
result ??= checkDateTime;
|
||||
results.Add(checkDateTime);
|
||||
}
|
||||
else
|
||||
{
|
||||
dateTime = Property.Models.Stateless.IProperty.GetDateTime(dateTimeFormat, aviDirectory.GetString(AviDirectory.TagDateTimeOriginal));
|
||||
if (dateTime is not null)
|
||||
{
|
||||
result ??= dateTime.Value;
|
||||
results.Add(dateTime.Value);
|
||||
}
|
||||
}
|
||||
}
|
||||
QuickTimeMovieHeaderDirectory? quickTimeMovieHeaderDirectory = directories.OfType<QuickTimeMovieHeaderDirectory>().FirstOrDefault();
|
||||
if (quickTimeMovieHeaderDirectory is not null)
|
||||
{
|
||||
if (quickTimeMovieHeaderDirectory.TryGetDateTime(QuickTimeMovieHeaderDirectory.TagCreated, out checkDateTime))
|
||||
{
|
||||
result ??= checkDateTime;
|
||||
results.Add(checkDateTime);
|
||||
}
|
||||
else
|
||||
{
|
||||
dateTime = Property.Models.Stateless.IProperty.GetDateTime(dateTimeFormat, quickTimeMovieHeaderDirectory.GetString(QuickTimeMovieHeaderDirectory.TagCreated));
|
||||
if (dateTime is not null)
|
||||
{
|
||||
result ??= dateTime.Value;
|
||||
results.Add(dateTime.Value);
|
||||
}
|
||||
}
|
||||
}
|
||||
QuickTimeTrackHeaderDirectory? quickTimeTrackHeaderDirectory = directories.OfType<QuickTimeTrackHeaderDirectory>().FirstOrDefault();
|
||||
if (quickTimeTrackHeaderDirectory is not null)
|
||||
{
|
||||
if (quickTimeTrackHeaderDirectory.TryGetDateTime(QuickTimeTrackHeaderDirectory.TagCreated, out checkDateTime))
|
||||
{
|
||||
result ??= checkDateTime;
|
||||
results.Add(checkDateTime);
|
||||
}
|
||||
else
|
||||
{
|
||||
dateTime = Property.Models.Stateless.IProperty.GetDateTime(dateTimeFormat, quickTimeTrackHeaderDirectory.GetString(QuickTimeTrackHeaderDirectory.TagCreated));
|
||||
if (dateTime is not null)
|
||||
{
|
||||
result ??= dateTime.Value;
|
||||
results.Add(dateTime.Value);
|
||||
}
|
||||
}
|
||||
}
|
||||
return new(result, results.ToArray());
|
||||
}
|
||||
|
||||
}
|
@ -3,11 +3,6 @@ namespace View_by_Distance.Metadata.Models.Stateless.Methods;
|
||||
public interface IMetadata
|
||||
{
|
||||
|
||||
(DateTime?, DateTime?[]) TestStatic_GetDateTimes(Shared.Models.FileHolder fileHolder, IReadOnlyList<MetadataExtractor.Directory> directories) =>
|
||||
GetDateTimes(fileHolder, directories);
|
||||
static (DateTime?, DateTime?[]) GetDateTimes(Shared.Models.FileHolder fileHolder, IReadOnlyList<MetadataExtractor.Directory> directories) =>
|
||||
Metadata.GetDateTimes(fileHolder, directories);
|
||||
|
||||
string? TestStatic_GetModel(IReadOnlyList<MetadataExtractor.Directory> directories) =>
|
||||
GetModel(directories);
|
||||
static string? GetModel(IReadOnlyList<MetadataExtractor.Directory> directories) =>
|
||||
|
@ -1,7 +1,5 @@
|
||||
using MetadataExtractor;
|
||||
using MetadataExtractor.Formats.Avi;
|
||||
using MetadataExtractor.Formats.Exif;
|
||||
using MetadataExtractor.Formats.QuickTime;
|
||||
using View_by_Distance.Shared.Models.Stateless;
|
||||
|
||||
namespace View_by_Distance.Metadata.Models.Stateless.Methods;
|
||||
@ -53,106 +51,6 @@ internal class Metadata
|
||||
return result;
|
||||
}
|
||||
|
||||
internal static (DateTime?, DateTime?[]) GetDateTimes(Shared.Models.FileHolder fileHolder, IReadOnlyList<MetadataExtractor.Directory> directories)
|
||||
{
|
||||
List<DateTime?> results = new();
|
||||
DateTime? result = null;
|
||||
DateTime? dateTime;
|
||||
DateTime checkDateTime;
|
||||
string dateTimeFormat = Shared.Models.Stateless.Methods.IProperty.DateTimeFormat();
|
||||
ExifDirectoryBase? exifDirectoryBase = directories.OfType<ExifDirectoryBase>().FirstOrDefault();
|
||||
results.Add(fileHolder.CreationTime);
|
||||
results.Add(fileHolder.LastWriteTime);
|
||||
if (exifDirectoryBase is not null)
|
||||
{
|
||||
if (exifDirectoryBase.TryGetDateTime(ExifDirectoryBase.TagDateTime, out checkDateTime))
|
||||
results.Add(checkDateTime);
|
||||
else
|
||||
{
|
||||
dateTime = Shared.Models.Stateless.Methods.IProperty.GetDateTime(dateTimeFormat, exifDirectoryBase.GetString(ExifDirectoryBase.TagDateTime));
|
||||
if (dateTime is not null)
|
||||
results.Add(dateTime.Value);
|
||||
}
|
||||
if (exifDirectoryBase.TryGetDateTime(ExifDirectoryBase.TagDateTimeDigitized, out checkDateTime))
|
||||
results.Add(checkDateTime);
|
||||
else
|
||||
{
|
||||
dateTime = Shared.Models.Stateless.Methods.IProperty.GetDateTime(dateTimeFormat, exifDirectoryBase.GetString(ExifDirectoryBase.TagDateTimeDigitized));
|
||||
if (dateTime is not null)
|
||||
results.Add(dateTime.Value);
|
||||
}
|
||||
if (exifDirectoryBase.TryGetDateTime(ExifDirectoryBase.TagDateTimeOriginal, out checkDateTime))
|
||||
{
|
||||
result ??= checkDateTime;
|
||||
results.Add(checkDateTime);
|
||||
}
|
||||
else
|
||||
{
|
||||
dateTime = Shared.Models.Stateless.Methods.IProperty.GetDateTime(dateTimeFormat, exifDirectoryBase.GetString(ExifDirectoryBase.TagDateTimeOriginal));
|
||||
if (dateTime is not null)
|
||||
{
|
||||
result ??= dateTime.Value;
|
||||
results.Add(dateTime.Value);
|
||||
}
|
||||
}
|
||||
}
|
||||
AviDirectory? aviDirectory = directories.OfType<AviDirectory>().FirstOrDefault();
|
||||
if (aviDirectory is not null)
|
||||
{
|
||||
if (aviDirectory.TryGetDateTime(AviDirectory.TagDateTimeOriginal, out checkDateTime))
|
||||
{
|
||||
result ??= checkDateTime;
|
||||
results.Add(checkDateTime);
|
||||
}
|
||||
else
|
||||
{
|
||||
dateTime = Shared.Models.Stateless.Methods.IProperty.GetDateTime(dateTimeFormat, aviDirectory.GetString(AviDirectory.TagDateTimeOriginal));
|
||||
if (dateTime is not null)
|
||||
{
|
||||
result ??= dateTime.Value;
|
||||
results.Add(dateTime.Value);
|
||||
}
|
||||
}
|
||||
}
|
||||
QuickTimeMovieHeaderDirectory? quickTimeMovieHeaderDirectory = directories.OfType<QuickTimeMovieHeaderDirectory>().FirstOrDefault();
|
||||
if (quickTimeMovieHeaderDirectory is not null)
|
||||
{
|
||||
if (quickTimeMovieHeaderDirectory.TryGetDateTime(QuickTimeMovieHeaderDirectory.TagCreated, out checkDateTime))
|
||||
{
|
||||
result ??= checkDateTime;
|
||||
results.Add(checkDateTime);
|
||||
}
|
||||
else
|
||||
{
|
||||
dateTime = Shared.Models.Stateless.Methods.IProperty.GetDateTime(dateTimeFormat, quickTimeMovieHeaderDirectory.GetString(QuickTimeMovieHeaderDirectory.TagCreated));
|
||||
if (dateTime is not null)
|
||||
{
|
||||
result ??= dateTime.Value;
|
||||
results.Add(dateTime.Value);
|
||||
}
|
||||
}
|
||||
}
|
||||
QuickTimeTrackHeaderDirectory? quickTimeTrackHeaderDirectory = directories.OfType<QuickTimeTrackHeaderDirectory>().FirstOrDefault();
|
||||
if (quickTimeTrackHeaderDirectory is not null)
|
||||
{
|
||||
if (quickTimeTrackHeaderDirectory.TryGetDateTime(QuickTimeTrackHeaderDirectory.TagCreated, out checkDateTime))
|
||||
{
|
||||
result ??= checkDateTime;
|
||||
results.Add(checkDateTime);
|
||||
}
|
||||
else
|
||||
{
|
||||
dateTime = Shared.Models.Stateless.Methods.IProperty.GetDateTime(dateTimeFormat, quickTimeTrackHeaderDirectory.GetString(QuickTimeTrackHeaderDirectory.TagCreated));
|
||||
if (dateTime is not null)
|
||||
{
|
||||
result ??= dateTime.Value;
|
||||
results.Add(dateTime.Value);
|
||||
}
|
||||
}
|
||||
}
|
||||
return new(result, results.ToArray());
|
||||
}
|
||||
|
||||
internal static string? GetModel(IReadOnlyList<MetadataExtractor.Directory> directories)
|
||||
{
|
||||
string? result;
|
||||
|
@ -67,7 +67,6 @@
|
||||
"ResultContent": "()",
|
||||
"ResultSingleton": "{}",
|
||||
"RootDirectory": "D:/Images",
|
||||
"WriteBitmapDataBytes": false,
|
||||
"IgnoreExtensions": [
|
||||
".gif",
|
||||
".GIF",
|
||||
@ -91,36 +90,6 @@
|
||||
".TIFF",
|
||||
".tif",
|
||||
".TIF"
|
||||
],
|
||||
"ValidMetadataExtensions": [
|
||||
".3gp",
|
||||
".3GP",
|
||||
".avi",
|
||||
".AVI",
|
||||
".bmp",
|
||||
".BMP",
|
||||
".gif",
|
||||
".GIF",
|
||||
".ico",
|
||||
".ICO",
|
||||
".jpeg",
|
||||
".JPEG",
|
||||
".jpg",
|
||||
".JPG",
|
||||
".m4v",
|
||||
".M4V",
|
||||
".mov",
|
||||
".MOV",
|
||||
".mp4",
|
||||
".MP4",
|
||||
".mta",
|
||||
".MTA",
|
||||
".png",
|
||||
".PNG",
|
||||
".tiff",
|
||||
".TIFF",
|
||||
".tif",
|
||||
".TIF"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
@ -45,7 +45,6 @@
|
||||
<PackageReference Include="Serilog" Version="2.12.0" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Metadata\Metadata.csproj" />
|
||||
<ProjectReference Include="..\Property\Property.csproj" />
|
||||
<ProjectReference Include="..\Resize\Resize.csproj" />
|
||||
<ProjectReference Include="..\Shared\View-by-Distance.Shared.csproj" />
|
||||
|
@ -2,9 +2,11 @@ using Microsoft.Extensions.Configuration;
|
||||
using Phares.Shared;
|
||||
using Serilog;
|
||||
using ShellProgressBar;
|
||||
using System.Text;
|
||||
using View_by_Distance.Move.By.Id.Models;
|
||||
using View_by_Distance.Shared.Models;
|
||||
using View_by_Distance.Shared.Models.Methods;
|
||||
using View_by_Distance.Shared.Models.Stateless.Methods;
|
||||
|
||||
namespace View_by_Distance.Move.By.Id;
|
||||
|
||||
@ -104,12 +106,14 @@ public class MoveById
|
||||
int? id;
|
||||
string? message;
|
||||
string[] matches;
|
||||
DateTime?[] dateTimes;
|
||||
FileHolder fileHolder;
|
||||
bool isIgnoreExtension;
|
||||
const string jpeg = ".jpeg";
|
||||
bool isValidImageFormatExtension;
|
||||
ASCIIEncoding asciiEncoding = new();
|
||||
bool nameWithoutExtensionIsIdFormat;
|
||||
bool nameWithoutExtensionIsPaddedIdFormat;
|
||||
int sortOrderOnlyLengthIndex = IDirectory.GetSortOrderOnlyLengthIndex();
|
||||
foreach (string file in allFiles)
|
||||
{
|
||||
progressBar.Tick();
|
||||
@ -119,16 +123,17 @@ public class MoveById
|
||||
if (allFiles.Contains($"{fileHolder.FullName}.id"))
|
||||
continue;
|
||||
isValidImageFormatExtension = _PropertyConfiguration.ValidImageFormatExtensions.Contains(fileHolder.ExtensionLowered);
|
||||
isIgnoreExtension = isValidImageFormatExtension && _PropertyConfiguration.IgnoreExtensions.Contains(fileHolder.ExtensionLowered);
|
||||
nameWithoutExtensionIsIdFormat = Shared.Models.Stateless.Methods.IProperty.NameWithoutExtensionIsIdFormat(fileHolder);
|
||||
if (!isIgnoreExtension && isValidImageFormatExtension)
|
||||
isIgnoreExtension = isValidImageFormatExtension && _PropertyConfiguration.IgnoreExtensions.Contains(fileHolder.ExtensionLowered);
|
||||
nameWithoutExtensionIsPaddedIdFormat = IDirectory.NameWithoutExtensionIsPaddedIdFormat(fileHolder, sortOrderOnlyLengthIndex);
|
||||
if (!isIgnoreExtension && !isValidImageFormatExtension)
|
||||
{
|
||||
if (fileHolder.ExtensionLowered == jpeg)
|
||||
continue;
|
||||
if (nameWithoutExtensionIsIdFormat)
|
||||
if (nameWithoutExtensionIsIdFormat || nameWithoutExtensionIsPaddedIdFormat)
|
||||
continue;
|
||||
}
|
||||
(_, dateTimes, id, message) = Shared.Models.Stateless.Methods.IProperty.Get(fileHolder, isIgnoreExtension, isValidImageFormatExtension, _PropertyConfiguration.PopulatePropertyId);
|
||||
(_, _, id, message) = Property.Models.Stateless.IProperty.Get(_PropertyConfiguration.PopulatePropertyId, fileHolder, isIgnoreExtension, isValidImageFormatExtension, asciiEncoding);
|
||||
if (id is null)
|
||||
continue;
|
||||
matches = (from l in allFiles where l.Contains($"{id}{fileHolder.ExtensionLowered}") select l).ToArray();
|
||||
|
@ -69,7 +69,6 @@
|
||||
"ResultContent": "()",
|
||||
"ResultSingleton": "{}",
|
||||
"RootDirectory": "C:/Tmp/Phares/Compare/Images-dd514b88",
|
||||
"WriteBitmapDataBytes": false,
|
||||
"IgnoreExtensions": [
|
||||
".gif",
|
||||
".GIF",
|
||||
@ -93,36 +92,6 @@
|
||||
".TIFF",
|
||||
".tif",
|
||||
".TIF"
|
||||
],
|
||||
"ValidMetadataExtensions": [
|
||||
".3gp",
|
||||
".3GP",
|
||||
".avi",
|
||||
".AVI",
|
||||
".bmp",
|
||||
".BMP",
|
||||
".gif",
|
||||
".GIF",
|
||||
".ico",
|
||||
".ICO",
|
||||
".jpeg",
|
||||
".JPEG",
|
||||
".jpg",
|
||||
".JPG",
|
||||
".m4v",
|
||||
".M4V",
|
||||
".mov",
|
||||
".MOV",
|
||||
".mp4",
|
||||
".MP4",
|
||||
".mta",
|
||||
".MTA",
|
||||
".png",
|
||||
".PNG",
|
||||
".tiff",
|
||||
".TIFF",
|
||||
".tif",
|
||||
".TIF"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
@ -5,7 +5,9 @@ using ShellProgressBar;
|
||||
using System.Drawing;
|
||||
using System.Drawing.Imaging;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using View_by_Distance.Offset.Date.Time.Original.Models;
|
||||
using View_by_Distance.Shared.Models;
|
||||
using View_by_Distance.Shared.Models.Methods;
|
||||
using View_by_Distance.Shared.Models.Stateless;
|
||||
|
||||
@ -14,6 +16,12 @@ namespace View_by_Distance.Offset.Date.Time.Original;
|
||||
public class OffsetDateTimeOriginal
|
||||
{
|
||||
|
||||
private record Record(FileHolder FileHolder,
|
||||
bool IsIgnoreExtension,
|
||||
bool IsValidImageFormatExtension,
|
||||
int Id,
|
||||
DateTime DateTime);
|
||||
|
||||
private readonly AppSettings _AppSettings;
|
||||
private readonly string _WorkingDirectory;
|
||||
private readonly Configuration _Configuration;
|
||||
@ -60,23 +68,34 @@ public class OffsetDateTimeOriginal
|
||||
{ }
|
||||
}
|
||||
|
||||
private static List<(string, int, DateTime)> GetCollection(string checkDirectory, DateTime minimumDateTime, DateTime maximumDateTime, long ticks)
|
||||
private List<Record> GetRecords(ASCIIEncoding asciiEncoding, string checkDirectory, DateTime minimumDateTime, DateTime maximumDateTime, long ticks)
|
||||
{
|
||||
List<(string, int, DateTime)> results = new();
|
||||
List<Record> results = new();
|
||||
DateTime dateTime;
|
||||
Shared.Models.Property property;
|
||||
int? id;
|
||||
string? message;
|
||||
DateTime[] dateTimes;
|
||||
FileHolder fileHolder;
|
||||
bool isIgnoreExtension;
|
||||
DateTime? dateTimeOriginal;
|
||||
bool isValidImageFormatExtension;
|
||||
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)
|
||||
fileHolder = new(file);
|
||||
isValidImageFormatExtension = _PropertyConfiguration.ValidImageFormatExtensions.Contains(fileHolder.ExtensionLowered);
|
||||
isIgnoreExtension = isValidImageFormatExtension && _PropertyConfiguration.IgnoreExtensions.Contains(fileHolder.ExtensionLowered);
|
||||
(dateTimeOriginal, dateTimes, id, message) = Property.Models.Stateless.IProperty.Get(_PropertyConfiguration.PopulatePropertyId, fileHolder, isIgnoreExtension, isValidImageFormatExtension, asciiEncoding);
|
||||
if (message is not null)
|
||||
throw new Exception(message);
|
||||
if (id is null || dateTimeOriginal is null)
|
||||
continue;
|
||||
dateTime = property.DateTimeOriginal.Value.AddTicks(ticks);
|
||||
dateTime = dateTimeOriginal.Value.AddTicks(ticks);
|
||||
if (dateTime < minimumDateTime)
|
||||
continue;
|
||||
if (dateTime > maximumDateTime)
|
||||
continue;
|
||||
results.Add((file, property.Id.Value, property.DateTimeOriginal.Value.AddTicks(ticks)));
|
||||
results.Add(new(fileHolder, isIgnoreExtension, isValidImageFormatExtension, id.Value, dateTimeOriginal.Value.AddTicks(ticks)));
|
||||
}
|
||||
if (files.Length != results.Count)
|
||||
throw new Exception();
|
||||
@ -85,14 +104,14 @@ public class OffsetDateTimeOriginal
|
||||
|
||||
#pragma warning disable CA1416
|
||||
|
||||
private static void DateFix(string sourceDirectory, string checkDirectory, DateTime minimumDateTime, DateTime maximumDateTime, long ticks)
|
||||
private void DateFix(string sourceDirectory, ASCIIEncoding asciiEncoding, string checkDirectory, DateTime minimumDateTime, DateTime maximumDateTime, long ticks)
|
||||
{
|
||||
int? id;
|
||||
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++)
|
||||
{
|
||||
@ -104,26 +123,28 @@ public class OffsetDateTimeOriginal
|
||||
}
|
||||
ticks++;
|
||||
}
|
||||
List<(string, int, DateTime)> collection = GetCollection(checkDirectory, minimumDateTime, maximumDateTime, ticks);
|
||||
List<Record> records = GetRecords(asciiEncoding, checkDirectory, minimumDateTime, maximumDateTime, ticks);
|
||||
ConstructorInfo? constructorInfo = typeof(PropertyItem).GetConstructor(BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Public, null, Array.Empty<Type>(), null) ?? throw new Exception();
|
||||
string message = nameof(OffsetDateTimeOriginal);
|
||||
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 progressBar = new(records.Count, message, options);
|
||||
foreach (Record record in records)
|
||||
{
|
||||
progressBar.Tick();
|
||||
if (ticksDirectory is null)
|
||||
throw new Exception();
|
||||
checkFile = Path.Combine(ticksDirectory, Path.GetFileName(file));
|
||||
checkFile = Path.Combine(ticksDirectory, record.FileHolder.Name);
|
||||
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);
|
||||
propertyItem = Property.Models.Stateless.IProperty.GetPropertyItem(constructorInfo, dateTimeOriginal, type, record.DateTime.ToString("yyyy:MM:dd HH:mm:ss"));
|
||||
bitmap = new(record.FileHolder.FullName);
|
||||
bitmap.SetPropertyItem(propertyItem);
|
||||
bitmap.Save(checkFile);
|
||||
bitmap.Dispose();
|
||||
property = Property.Models.A_Property.GetImageProperty(checkFile);
|
||||
if (property.Id is null || property.Id.Value != id)
|
||||
(_, _, id, message) = Property.Models.Stateless.IProperty.Get(_PropertyConfiguration.PopulatePropertyId, record.FileHolder, record.IsIgnoreExtension, record.IsValidImageFormatExtension, asciiEncoding);
|
||||
if (message is not null)
|
||||
throw new Exception(message);
|
||||
if (id is null || id.Value != record.Id)
|
||||
throw new Exception();
|
||||
}
|
||||
progressBar.Dispose();
|
||||
@ -131,13 +152,14 @@ public class OffsetDateTimeOriginal
|
||||
|
||||
#pragma warning restore CA1416
|
||||
|
||||
private static void DateFix(ILogger log, string sourceDirectory)
|
||||
private void DateFix(ILogger log, string sourceDirectory)
|
||||
{
|
||||
string checkDirectory;
|
||||
ASCIIEncoding asciiEncoding = new();
|
||||
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);
|
||||
DateFix(sourceDirectory, asciiEncoding, checkDirectory, DateTime.MinValue, DateTime.MaxValue, new TimeSpan(oneYearTicks - DateTime.MinValue.Ticks).Ticks);
|
||||
else
|
||||
{
|
||||
checkDirectory = Path.Combine(sourceDirectory, "1");
|
||||
@ -160,16 +182,40 @@ public class OffsetDateTimeOriginal
|
||||
log.Error("bad file(s) or target file(s) or maximum directory doesn't equal 1!");
|
||||
else
|
||||
{
|
||||
int? badId;
|
||||
int? targetId;
|
||||
string? badMessage;
|
||||
string? targetMessage;
|
||||
DateTime[] badDateTimes;
|
||||
bool badIsIgnoreExtension;
|
||||
DateTime[] targetDateTimes;
|
||||
bool targetIsIgnoreExtension;
|
||||
DateTime? badDateTimeOriginal;
|
||||
DateTime? targetDateTimeOriginal;
|
||||
FileHolder badFileHolder = new(badFiles.First());
|
||||
FileHolder targetFileHolder = new(targetFiles.First());
|
||||
bool badIsValidImageFormatExtension = _PropertyConfiguration.ValidImageFormatExtensions.Contains(badFileHolder.ExtensionLowered);
|
||||
bool targetIsValidImageFormatExtension = _PropertyConfiguration.ValidImageFormatExtensions.Contains(targetFileHolder.ExtensionLowered);
|
||||
badIsIgnoreExtension = badIsValidImageFormatExtension && _PropertyConfiguration.IgnoreExtensions.Contains(badFileHolder.ExtensionLowered);
|
||||
targetIsIgnoreExtension = targetIsValidImageFormatExtension && _PropertyConfiguration.IgnoreExtensions.Contains(targetFileHolder.ExtensionLowered);
|
||||
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)
|
||||
(badDateTimeOriginal, badDateTimes, badId, badMessage) = Property.Models.Stateless.IProperty.Get(_PropertyConfiguration.PopulatePropertyId, badFileHolder, badIsIgnoreExtension, badIsValidImageFormatExtension, asciiEncoding);
|
||||
if (badMessage is not null)
|
||||
throw new Exception(badMessage);
|
||||
if (!badDateTimes.Any() || badId is null)
|
||||
throw new Exception(badMessage);
|
||||
(targetDateTimeOriginal, targetDateTimes, targetId, targetMessage) = Property.Models.Stateless.IProperty.Get(_PropertyConfiguration.PopulatePropertyId, targetFileHolder, targetIsIgnoreExtension, targetIsValidImageFormatExtension, asciiEncoding);
|
||||
if (targetMessage is not null)
|
||||
throw new Exception(targetMessage);
|
||||
if (!targetDateTimes.Any() || targetId is null)
|
||||
throw new Exception(targetMessage);
|
||||
if (badDateTimeOriginal is null || targetDateTimeOriginal 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);
|
||||
TimeSpan timeSpan = new(targetDateTimeOriginal.Value.Ticks - badDateTimeOriginal.Value.Ticks);
|
||||
DateFix(sourceDirectory, asciiEncoding, checkDirectory, minimumDateTime, maximumDateTime, timeSpan.Ticks);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -66,7 +66,6 @@
|
||||
"ResultContent": "()",
|
||||
"ResultSingleton": "{}",
|
||||
"RootDirectory": "D:/Images",
|
||||
"WriteBitmapDataBytes": false,
|
||||
"IgnoreExtensions": [
|
||||
".gif",
|
||||
".GIF",
|
||||
@ -90,36 +89,6 @@
|
||||
".TIFF",
|
||||
".tif",
|
||||
".TIF"
|
||||
],
|
||||
"ValidMetadataExtensions": [
|
||||
".3gp",
|
||||
".3GP",
|
||||
".avi",
|
||||
".AVI",
|
||||
".bmp",
|
||||
".BMP",
|
||||
".gif",
|
||||
".GIF",
|
||||
".ico",
|
||||
".ICO",
|
||||
".jpeg",
|
||||
".JPEG",
|
||||
".jpg",
|
||||
".JPG",
|
||||
".m4v",
|
||||
".M4V",
|
||||
".mov",
|
||||
".MOV",
|
||||
".mp4",
|
||||
".MP4",
|
||||
".mta",
|
||||
".MTA",
|
||||
".png",
|
||||
".PNG",
|
||||
".tiff",
|
||||
".TIFF",
|
||||
".tif",
|
||||
".TIF"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
@ -19,7 +19,6 @@
|
||||
"ResultSingleton": "{}",
|
||||
"RootDirectory": "/srv/samba/share",
|
||||
"SaveDirectory": "/home/vscode",
|
||||
"WriteBitmapDataBytes": false,
|
||||
"IgnoreExtensions": [
|
||||
".gif",
|
||||
".GIF",
|
||||
@ -43,36 +42,6 @@
|
||||
".TIFF",
|
||||
".tif",
|
||||
".TIF"
|
||||
],
|
||||
"ValidMetadataExtensions": [
|
||||
".3gp",
|
||||
".3GP",
|
||||
".avi",
|
||||
".AVI",
|
||||
".bmp",
|
||||
".BMP",
|
||||
".gif",
|
||||
".GIF",
|
||||
".ico",
|
||||
".ICO",
|
||||
".jpeg",
|
||||
".JPEG",
|
||||
".jpg",
|
||||
".JPG",
|
||||
".m4v",
|
||||
".M4V",
|
||||
".mov",
|
||||
".MOV",
|
||||
".mp4",
|
||||
".MP4",
|
||||
".mta",
|
||||
".MTA",
|
||||
".png",
|
||||
".PNG",
|
||||
".tiff",
|
||||
".TIFF",
|
||||
".tif",
|
||||
".TIF"
|
||||
]
|
||||
}
|
||||
},
|
||||
@ -141,7 +110,6 @@
|
||||
"ResultSingleton": "{}",
|
||||
"RootDirectory": "C:/Tmp/Phares/Compare/Images-dd514b88",
|
||||
"SaveDirectory": "D:/Tmp",
|
||||
"WriteBitmapDataBytes": false,
|
||||
"IgnoreExtensions": [
|
||||
".gif",
|
||||
".GIF",
|
||||
@ -165,36 +133,6 @@
|
||||
".TIFF",
|
||||
".tif",
|
||||
".TIF"
|
||||
],
|
||||
"ValidMetadataExtensions": [
|
||||
".3gp",
|
||||
".3GP",
|
||||
".avi",
|
||||
".AVI",
|
||||
".bmp",
|
||||
".BMP",
|
||||
".gif",
|
||||
".GIF",
|
||||
".ico",
|
||||
".ICO",
|
||||
".jpeg",
|
||||
".JPEG",
|
||||
".jpg",
|
||||
".JPG",
|
||||
".m4v",
|
||||
".M4V",
|
||||
".mov",
|
||||
".MOV",
|
||||
".mp4",
|
||||
".MP4",
|
||||
".mta",
|
||||
".MTA",
|
||||
".png",
|
||||
".PNG",
|
||||
".tiff",
|
||||
".TIFF",
|
||||
".tif",
|
||||
".TIF"
|
||||
]
|
||||
}
|
||||
},
|
||||
|
@ -59,7 +59,6 @@
|
||||
"PopulatePropertyId": false,
|
||||
"PropertiesChangedForProperty": false,
|
||||
"RootDirectory": "C:/Tmp/Phares/Pictures",
|
||||
"WriteBitmapDataBytes": false,
|
||||
"IgnoreExtensions": [
|
||||
".gif",
|
||||
".GIF",
|
||||
@ -111,36 +110,6 @@
|
||||
".tif",
|
||||
".TIF"
|
||||
],
|
||||
"ValidMetadataExtensions": [
|
||||
".3gp",
|
||||
".3GP",
|
||||
".avi",
|
||||
".AVI",
|
||||
".bmp",
|
||||
".BMP",
|
||||
".gif",
|
||||
".GIF",
|
||||
".ico",
|
||||
".ICO",
|
||||
".jpeg",
|
||||
".JPEG",
|
||||
".jpg",
|
||||
".JPG",
|
||||
".m4v",
|
||||
".M4V",
|
||||
".mov",
|
||||
".MOV",
|
||||
".mp4",
|
||||
".MP4",
|
||||
".mta",
|
||||
".MTA",
|
||||
".png",
|
||||
".PNG",
|
||||
".tiff",
|
||||
".TIFF",
|
||||
".tif",
|
||||
".TIF"
|
||||
],
|
||||
"VerifyToSeason": [
|
||||
". 2000",
|
||||
". 2001",
|
||||
|
@ -1,14 +1,9 @@
|
||||
using ShellProgressBar;
|
||||
using System.Drawing;
|
||||
using System.Drawing.Imaging;
|
||||
using System.Globalization;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
using System.Text.Json;
|
||||
using View_by_Distance.Property.Models.Stateless;
|
||||
using View_by_Distance.Shared.Models;
|
||||
using View_by_Distance.Shared.Models.Properties;
|
||||
using View_by_Distance.Shared.Models.Stateless;
|
||||
|
||||
namespace View_by_Distance.Property.Models;
|
||||
|
||||
@ -62,201 +57,7 @@ public class A_Property
|
||||
return result;
|
||||
}
|
||||
|
||||
#pragma warning disable CA1416
|
||||
|
||||
private static List<DateTime> GetMetadataDateTimesByPattern(string dateTimeFormat, FileHolder fileHolder)
|
||||
{
|
||||
List<DateTime> results = new();
|
||||
try
|
||||
{
|
||||
DateTime checkDateTime;
|
||||
DateTime kristy = new(1976, 3, 8);
|
||||
IReadOnlyList<MetadataExtractor.Directory> directories = MetadataExtractor.ImageMetadataReader.ReadMetadata(fileHolder.FullName);
|
||||
foreach (MetadataExtractor.Directory directory in directories)
|
||||
{
|
||||
foreach (MetadataExtractor.Tag tag in directory.Tags)
|
||||
{
|
||||
if (string.IsNullOrEmpty(tag.Description) || tag.Description.Length != dateTimeFormat.Length)
|
||||
continue;
|
||||
if (!DateTime.TryParseExact(tag.Description, dateTimeFormat, CultureInfo.InvariantCulture, DateTimeStyles.None, out checkDateTime))
|
||||
continue;
|
||||
if (checkDateTime < kristy)
|
||||
continue;
|
||||
results.Add(checkDateTime);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception) { }
|
||||
return results;
|
||||
}
|
||||
|
||||
private static Shared.Models.Property GetImageProperty(FileHolder fileHolder, Shared.Models.Property? property, bool populateId, bool isIgnoreExtension, bool isValidImageFormatExtension, bool isValidMetadataExtensions, int? id, ASCIIEncoding asciiEncoding, bool writeBitmapDataBytes, string? angleBracket)
|
||||
{
|
||||
Shared.Models.Property result;
|
||||
byte[] bytes;
|
||||
string value;
|
||||
long fileLength;
|
||||
int? width = null;
|
||||
int? height = null;
|
||||
string? make = null;
|
||||
string? model = null;
|
||||
string dateTimeFormat;
|
||||
DateTime checkDateTime;
|
||||
DateTime? dateTime = null;
|
||||
PropertyItem? propertyItem;
|
||||
string? orientation = null;
|
||||
DateTime? gpsDateStamp = null;
|
||||
DateTime? dateTimeOriginal = null;
|
||||
DateTime? dateTimeDigitized = null;
|
||||
DateTime? dateTimeFromName = Shared.Models.Stateless.Methods.IProperty.GetDateTimeFromName(fileHolder);
|
||||
if (!isValidImageFormatExtension && isValidMetadataExtensions && fileHolder.Exists)
|
||||
{
|
||||
dateTimeFormat = "ddd MMM dd HH:mm:ss yyyy";
|
||||
List<DateTime> dateTimes = GetMetadataDateTimesByPattern(dateTimeFormat, fileHolder);
|
||||
if (dateTimes.Any())
|
||||
dateTimeOriginal = dateTimes.Min();
|
||||
}
|
||||
else if (!isIgnoreExtension && isValidImageFormatExtension && fileHolder.Exists)
|
||||
{
|
||||
try
|
||||
{
|
||||
using Image image = Image.FromFile(fileHolder.FullName);
|
||||
width = image.Width;
|
||||
height = image.Height;
|
||||
if (populateId && id is null)
|
||||
{
|
||||
using Bitmap bitmap = new(image);
|
||||
Rectangle rectangle = new(0, 0, image.Width, image.Height);
|
||||
BitmapData bitmapData = bitmap.LockBits(rectangle, ImageLockMode.ReadOnly, bitmap.PixelFormat);
|
||||
IntPtr intPtr = bitmapData.Scan0;
|
||||
int length = bitmapData.Stride * bitmap.Height;
|
||||
bytes = new byte[length];
|
||||
Marshal.Copy(intPtr, bytes, 0, length);
|
||||
bitmap.UnlockBits(bitmapData);
|
||||
id ??= Shared.Models.Stateless.Methods.IProperty.GetDeterministicHashCode(bytes);
|
||||
if (writeBitmapDataBytes && !string.IsNullOrEmpty(angleBracket))
|
||||
{
|
||||
FileInfo contentFileInfo = new(Path.Combine(angleBracket.Replace("<>", "()"), fileHolder.Name));
|
||||
File.WriteAllBytes(Path.ChangeExtension(contentFileInfo.FullName, string.Empty), bytes);
|
||||
}
|
||||
}
|
||||
dateTimeFormat = Shared.Models.Stateless.Methods.IProperty.DateTimeFormat();
|
||||
if (image.PropertyIdList.Contains((int)IExif.Tags.DateTime))
|
||||
{
|
||||
propertyItem = image.GetPropertyItem((int)IExif.Tags.DateTime);
|
||||
if (propertyItem?.Value is not null)
|
||||
{
|
||||
value = asciiEncoding.GetString(propertyItem.Value, 0, propertyItem.Len - 1);
|
||||
if (value.Length > dateTimeFormat.Length)
|
||||
value = value[..dateTimeFormat.Length];
|
||||
if (value.Length == dateTimeFormat.Length && DateTime.TryParseExact(value, dateTimeFormat, CultureInfo.InvariantCulture, DateTimeStyles.None, out checkDateTime))
|
||||
dateTime = checkDateTime;
|
||||
}
|
||||
}
|
||||
if (image.PropertyIdList.Contains((int)IExif.Tags.DateTimeDigitized))
|
||||
{
|
||||
propertyItem = image.GetPropertyItem((int)IExif.Tags.DateTimeDigitized);
|
||||
if (propertyItem?.Value is not null)
|
||||
{
|
||||
value = asciiEncoding.GetString(propertyItem.Value, 0, propertyItem.Len - 1);
|
||||
if (value.Length > dateTimeFormat.Length)
|
||||
value = value[..dateTimeFormat.Length];
|
||||
if (value.Length == dateTimeFormat.Length && DateTime.TryParseExact(value, dateTimeFormat, CultureInfo.InvariantCulture, DateTimeStyles.None, out checkDateTime))
|
||||
dateTimeDigitized = checkDateTime;
|
||||
}
|
||||
}
|
||||
if (image.PropertyIdList.Contains((int)IExif.Tags.DateTimeOriginal))
|
||||
{
|
||||
propertyItem = image.GetPropertyItem((int)IExif.Tags.DateTimeOriginal);
|
||||
if (propertyItem?.Value is not null)
|
||||
{
|
||||
value = asciiEncoding.GetString(propertyItem.Value, 0, propertyItem.Len - 1);
|
||||
if (value.Length > dateTimeFormat.Length)
|
||||
value = value[..dateTimeFormat.Length];
|
||||
if (value.Length == dateTimeFormat.Length && DateTime.TryParseExact(value, dateTimeFormat, CultureInfo.InvariantCulture, DateTimeStyles.None, out checkDateTime))
|
||||
dateTimeOriginal = checkDateTime;
|
||||
}
|
||||
}
|
||||
if (image.PropertyIdList.Contains((int)IExif.Tags.GPSDateStamp))
|
||||
{
|
||||
propertyItem = image.GetPropertyItem((int)IExif.Tags.GPSDateStamp);
|
||||
if (propertyItem?.Value is not null)
|
||||
{
|
||||
value = asciiEncoding.GetString(propertyItem.Value, 0, propertyItem.Len - 1);
|
||||
if (value.Length > dateTimeFormat.Length)
|
||||
value = value[..dateTimeFormat.Length];
|
||||
if (value.Length == dateTimeFormat.Length && DateTime.TryParseExact(value, dateTimeFormat, CultureInfo.InvariantCulture, DateTimeStyles.None, out checkDateTime))
|
||||
gpsDateStamp = checkDateTime;
|
||||
}
|
||||
}
|
||||
if (image.PropertyIdList.Contains((int)IExif.Tags.Make))
|
||||
{
|
||||
propertyItem = image.GetPropertyItem((int)IExif.Tags.Make);
|
||||
if (propertyItem?.Value is not null)
|
||||
{
|
||||
value = asciiEncoding.GetString(propertyItem.Value, 0, propertyItem.Len - 1);
|
||||
make = value;
|
||||
}
|
||||
}
|
||||
if (image.PropertyIdList.Contains((int)IExif.Tags.Model))
|
||||
{
|
||||
propertyItem = image.GetPropertyItem((int)IExif.Tags.Model);
|
||||
if (propertyItem?.Value is not null)
|
||||
{
|
||||
value = asciiEncoding.GetString(propertyItem.Value, 0, propertyItem.Len - 1);
|
||||
model = value;
|
||||
}
|
||||
}
|
||||
if (image.PropertyIdList.Contains((int)IExif.Tags.Orientation))
|
||||
{
|
||||
propertyItem = image.GetPropertyItem((int)IExif.Tags.Orientation);
|
||||
if (propertyItem?.Value is not null)
|
||||
{
|
||||
value = BitConverter.ToInt16(propertyItem.Value, 0).ToString();
|
||||
orientation = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception) { }
|
||||
}
|
||||
else
|
||||
dateTimeOriginal = null;
|
||||
if (fileHolder.Length is null)
|
||||
fileLength = 0;
|
||||
else
|
||||
fileLength = fileHolder.Length.Value;
|
||||
if (fileHolder.CreationTime is null && property?.CreationTime is null)
|
||||
throw new NullReferenceException(nameof(fileHolder.CreationTime));
|
||||
if (fileHolder.LastWriteTime is null && property?.LastWriteTime is null)
|
||||
throw new NullReferenceException(nameof(fileHolder.LastWriteTime));
|
||||
if (fileHolder.CreationTime is not null && fileHolder.LastWriteTime is not null)
|
||||
result = new(fileHolder.CreationTime.Value, dateTime, dateTimeDigitized, dateTimeFromName, dateTimeOriginal, fileLength, gpsDateStamp, height, id, fileHolder.LastWriteTime.Value, make, model, orientation, width);
|
||||
else if (property is not null)
|
||||
result = new(property.CreationTime, dateTime, dateTimeDigitized, dateTimeFromName, dateTimeOriginal, fileLength, gpsDateStamp, height, id, property.LastWriteTime, make, model, orientation, width);
|
||||
else
|
||||
throw new NullReferenceException(nameof(property));
|
||||
return result;
|
||||
}
|
||||
|
||||
public static Shared.Models.Property GetImageProperty(string fileName)
|
||||
{
|
||||
int? id = null;
|
||||
bool populateId = true;
|
||||
string? angleBracket = null;
|
||||
bool isIgnoreExtension = false;
|
||||
bool writeBitmapDataBytes = false;
|
||||
ASCIIEncoding asciiEncoding = new();
|
||||
bool isValidMetadataExtensions = true;
|
||||
FileHolder fileHolder = new(fileName);
|
||||
bool isValidImageFormatExtension = true;
|
||||
Shared.Models.Property? property = null;
|
||||
Shared.Models.Property result = GetImageProperty(fileHolder, property, populateId, isIgnoreExtension, isValidImageFormatExtension, isValidMetadataExtensions, id, asciiEncoding, writeBitmapDataBytes, angleBracket);
|
||||
return result;
|
||||
}
|
||||
|
||||
#pragma warning restore CA1416
|
||||
|
||||
private Shared.Models.Property GetPropertyOfPrivate(Item item, List<Tuple<string, DateTime>> sourceDirectoryFileTuples, List<string> parseExceptions, bool isIgnoreExtension, bool isValidMetadataExtensions)
|
||||
private Shared.Models.Property GetImageProperty(Shared.Models.Methods.IMetadata<MetadataExtractor.Directory> metadata, Item item, List<Tuple<string, DateTime>> sourceDirectoryFileTuples, List<string> parseExceptions, bool isIgnoreExtension)
|
||||
{
|
||||
Shared.Models.Property? result;
|
||||
int? id = null;
|
||||
@ -348,7 +149,7 @@ public class A_Property
|
||||
if (result is null)
|
||||
{
|
||||
id ??= item.ImageFileHolder.Id;
|
||||
result = GetImageProperty(item.ImageFileHolder, result, populateId, isIgnoreExtension, item.IsValidImageFormatExtension, isValidMetadataExtensions, id, _ASCIIEncoding, _Configuration.WriteBitmapDataBytes, angleBracket);
|
||||
(_, _, result) = Stateless.Property.GetProperty(populateId, metadata, item.ImageFileHolder, result, isIgnoreExtension, item.IsValidImageFormatExtension, id, _ASCIIEncoding);
|
||||
json = JsonSerializer.Serialize(result, _WriteIndentedJsonSerializerOptions);
|
||||
if (populateId && Shared.Models.Stateless.Methods.IPath.WriteAllText(fileInfo.FullName, json, updateDateWhenMatches: true, compareBeforeWrite: true))
|
||||
{
|
||||
@ -377,18 +178,17 @@ public class A_Property
|
||||
return result;
|
||||
}
|
||||
|
||||
private void SavePropertyParallelForWork(string sourceDirectory, List<Tuple<string, DateTime>> sourceDirectoryFileTuples, List<Tuple<string, DateTime>> sourceDirectoryChanges, Item item)
|
||||
private void SavePropertyParallelForWork(Shared.Models.Methods.IMetadata<MetadataExtractor.Directory> metadata, string sourceDirectory, List<Tuple<string, DateTime>> sourceDirectoryFileTuples, List<Tuple<string, DateTime>> sourceDirectoryChanges, Item item)
|
||||
{
|
||||
Shared.Models.Property property;
|
||||
List<string> parseExceptions = new();
|
||||
bool isValidMetadataExtensions = _Configuration.ValidMetadataExtensions.Contains(item.ImageFileHolder.ExtensionLowered);
|
||||
bool isIgnoreExtension = item.IsValidImageFormatExtension && _PropertyConfiguration.IgnoreExtensions.Contains(item.ImageFileHolder.ExtensionLowered);
|
||||
string filteredSourceDirectoryFileExtensionLowered = Path.Combine(sourceDirectory, $"{item.ImageFileHolder.NameWithoutExtension}{item.ImageFileHolder.ExtensionLowered}");
|
||||
if (item.IsValidImageFormatExtension && item.ImageFileHolder.FullName.Length == filteredSourceDirectoryFileExtensionLowered.Length && item.ImageFileHolder.FullName != filteredSourceDirectoryFileExtensionLowered)
|
||||
File.Move(item.ImageFileHolder.FullName, filteredSourceDirectoryFileExtensionLowered);
|
||||
if (item.FileSizeChanged is null || item.FileSizeChanged.Value || item.LastWriteTimeChanged is null || item.LastWriteTimeChanged.Value || item.Property is null)
|
||||
{
|
||||
property = GetPropertyOfPrivate(item, sourceDirectoryFileTuples, parseExceptions, isIgnoreExtension, isValidMetadataExtensions);
|
||||
property = GetImageProperty(metadata, item, sourceDirectoryFileTuples, parseExceptions, isIgnoreExtension);
|
||||
lock (sourceDirectoryChanges)
|
||||
sourceDirectoryChanges.Add(new Tuple<string, DateTime>(nameof(A_Property), DateTime.Now));
|
||||
lock (item)
|
||||
@ -396,7 +196,7 @@ public class A_Property
|
||||
}
|
||||
}
|
||||
|
||||
private void SavePropertyParallelWork(int maxDegreeOfParallelism, List<Exception> exceptions, List<Tuple<string, DateTime>> sourceDirectoryChanges, Container container, List<Item> items, string message)
|
||||
private void SavePropertyParallelWork(int maxDegreeOfParallelism, Shared.Models.Methods.IMetadata<MetadataExtractor.Directory> metadata, List<Exception> exceptions, List<Tuple<string, DateTime>> sourceDirectoryChanges, Container container, List<Item> items, string message)
|
||||
{
|
||||
List<Tuple<string, DateTime>> sourceDirectoryFileTuples = new();
|
||||
ParallelOptions parallelOptions = new() { MaxDegreeOfParallelism = maxDegreeOfParallelism };
|
||||
@ -409,7 +209,7 @@ public class A_Property
|
||||
long ticks = DateTime.Now.Ticks;
|
||||
DateTime dateTime = DateTime.Now;
|
||||
List<Tuple<string, DateTime>> collection;
|
||||
SavePropertyParallelForWork(container.SourceDirectory, sourceDirectoryChanges, sourceDirectoryFileTuples, items[i]);
|
||||
SavePropertyParallelForWork(metadata, container.SourceDirectory, sourceDirectoryChanges, sourceDirectoryFileTuples, items[i]);
|
||||
if (i == 0 || sourceDirectoryChanges.Any())
|
||||
progressBar.Tick();
|
||||
lock (sourceDirectoryFileTuples)
|
||||
@ -452,7 +252,7 @@ public class A_Property
|
||||
SetAngleBracketCollection(aResultsFullGroupDirectory, sourceDirectory, anyNullOrNoIsUniqueFileName);
|
||||
}
|
||||
|
||||
public void SavePropertyParallelWork(long ticks, int t, Container[] containers)
|
||||
public void SavePropertyParallelWork(long ticks, Shared.Models.Methods.IMetadata<MetadataExtractor.Directory> metadata, int t, Container[] containers)
|
||||
{
|
||||
if (_Log is null)
|
||||
throw new NullReferenceException(nameof(_Log));
|
||||
@ -478,7 +278,7 @@ public class A_Property
|
||||
SetAngleBracketCollection(container.SourceDirectory, anyNullOrNoIsUniqueFileName);
|
||||
totalSeconds = (int)Math.Truncate(new TimeSpan(DateTime.Now.Ticks - ticks).TotalSeconds);
|
||||
message = $"{i + 1:000} [{container.Items.Count:000}] / {containersLength:000} - {total} / {t} total - {totalSeconds} total second(s) - {outputResolution} - {container.SourceDirectory}";
|
||||
SavePropertyParallelWork(_MaxDegreeOfParallelism, exceptions, sourceDirectoryChanges, container, container.Items, message);
|
||||
SavePropertyParallelWork(_MaxDegreeOfParallelism, metadata, exceptions, sourceDirectoryChanges, container, container.Items, message);
|
||||
foreach (Exception exception in exceptions)
|
||||
_Log.Error(string.Concat(container.SourceDirectory, Environment.NewLine, exception.Message, Environment.NewLine, exception.StackTrace), exception);
|
||||
if (exceptions.Count == container.Items.Count)
|
||||
@ -499,7 +299,7 @@ public class A_Property
|
||||
}
|
||||
}
|
||||
|
||||
public Shared.Models.Property GetProperty(Item item, List<Tuple<string, DateTime>> sourceDirectoryFileTuples, List<string> parseExceptions)
|
||||
public Shared.Models.Property GetProperty(Shared.Models.Methods.IMetadata<MetadataExtractor.Directory> metadata, Item item, List<Tuple<string, DateTime>> sourceDirectoryFileTuples, List<string> parseExceptions)
|
||||
{
|
||||
Shared.Models.Property result;
|
||||
bool angleBracketCollectionAny = _AngleBracketCollection.Any();
|
||||
@ -509,9 +309,8 @@ public class A_Property
|
||||
throw new NullReferenceException(nameof(item.ImageFileHolder.DirectoryName));
|
||||
SetAngleBracketCollection(item.ImageFileHolder.DirectoryName, !item.IsUniqueFileName);
|
||||
}
|
||||
bool isValidMetadataExtensions = _Configuration.ValidMetadataExtensions.Contains(item.ImageFileHolder.ExtensionLowered);
|
||||
bool isIgnoreExtension = item.IsValidImageFormatExtension && _PropertyConfiguration.IgnoreExtensions.Contains(item.ImageFileHolder.ExtensionLowered);
|
||||
result = GetPropertyOfPrivate(item, sourceDirectoryFileTuples, parseExceptions, isIgnoreExtension, isValidMetadataExtensions);
|
||||
result = GetImageProperty(metadata, item, sourceDirectoryFileTuples, parseExceptions, isIgnoreExtension);
|
||||
if (!angleBracketCollectionAny)
|
||||
_AngleBracketCollection.Clear();
|
||||
return result;
|
||||
|
@ -27,9 +27,7 @@ public class Configuration
|
||||
[Display(Name = "Result Singleton"), Required] public string ResultSingleton { get; set; }
|
||||
[Display(Name = "Root Directory"), Required] public string RootDirectory { get; set; }
|
||||
[Display(Name = "Valid Image Format Extensions"), Required] public string[] ValidImageFormatExtensions { get; set; }
|
||||
[Display(Name = "Valid Metadata Extensions"), Required] public string[] ValidMetadataExtensions { get; set; }
|
||||
[Display(Name = "Verify to Season"), Required] public string[] VerifyToSeason { get; set; }
|
||||
[Display(Name = "Write Bitmap Data Bytes"), Required] public bool? WriteBitmapDataBytes { get; set; }
|
||||
|
||||
#nullable restore
|
||||
|
||||
@ -62,12 +60,9 @@ public class Configuration
|
||||
throw new NullReferenceException(nameof(configuration.ResultContent));
|
||||
if (configuration.ResultSingleton is null)
|
||||
throw new NullReferenceException(nameof(configuration.ResultSingleton));
|
||||
if (configuration.WriteBitmapDataBytes is null)
|
||||
throw new NullReferenceException(nameof(configuration.WriteBitmapDataBytes));
|
||||
configuration.IgnoreExtensions ??= Array.Empty<string>();
|
||||
configuration.PropertyContentCollectionFiles ??= Array.Empty<string>();
|
||||
configuration.ValidImageFormatExtensions ??= Array.Empty<string>();
|
||||
configuration.ValidMetadataExtensions ??= Array.Empty<string>();
|
||||
configuration.VerifyToSeason ??= Array.Empty<string>();
|
||||
result = new(configuration.DateGroup,
|
||||
configuration.FileNameDirectorySeparator,
|
||||
@ -86,9 +81,7 @@ public class Configuration
|
||||
configuration.ResultSingleton,
|
||||
configuration.RootDirectory,
|
||||
configuration.ValidImageFormatExtensions,
|
||||
configuration.ValidMetadataExtensions,
|
||||
configuration.VerifyToSeason,
|
||||
configuration.WriteBitmapDataBytes.Value);
|
||||
configuration.VerifyToSeason);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -34,8 +34,6 @@ public class Configuration : Shared.Models.Properties.IPropertyConfiguration
|
||||
public string ResultContent { init; get; }
|
||||
public string ResultSingleton { init; get; }
|
||||
public string[] ValidImageFormatExtensions { init; get; }
|
||||
public string[] ValidMetadataExtensions { init; get; }
|
||||
public bool WriteBitmapDataBytes { init; get; }
|
||||
|
||||
[JsonConstructor]
|
||||
public Configuration(string dateGroup,
|
||||
@ -55,9 +53,7 @@ public class Configuration : Shared.Models.Properties.IPropertyConfiguration
|
||||
string resultSingleton,
|
||||
string rootDirectory,
|
||||
string[] validImageFormatExtensions,
|
||||
string[] validMetadataExtensions,
|
||||
string[] verifyToSeason,
|
||||
bool writeBitmapDataBytes)
|
||||
string[] verifyToSeason)
|
||||
{
|
||||
DateGroup = dateGroup;
|
||||
FileNameDirectorySeparator = fileNameDirectorySeparator;
|
||||
@ -76,8 +72,6 @@ public class Configuration : Shared.Models.Properties.IPropertyConfiguration
|
||||
ResultSingleton = resultSingleton;
|
||||
_RootDirectory = rootDirectory;
|
||||
ValidImageFormatExtensions = validImageFormatExtensions;
|
||||
ValidMetadataExtensions = validMetadataExtensions;
|
||||
WriteBitmapDataBytes = writeBitmapDataBytes;
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
@ -109,8 +103,6 @@ public class Configuration : Shared.Models.Properties.IPropertyConfiguration
|
||||
throw new NullReferenceException(nameof(propertyConfiguration.PropertyContentCollectionFiles));
|
||||
if (propertyConfiguration.ValidImageFormatExtensions is null || !propertyConfiguration.ValidImageFormatExtensions.Any())
|
||||
throw new NullReferenceException(nameof(propertyConfiguration.ValidImageFormatExtensions));
|
||||
if (propertyConfiguration.ValidMetadataExtensions is null || !propertyConfiguration.ValidMetadataExtensions.Any())
|
||||
throw new NullReferenceException(nameof(propertyConfiguration.ValidMetadataExtensions));
|
||||
if (propertyConfiguration is null)
|
||||
throw new NullReferenceException(nameof(propertyConfiguration));
|
||||
if (string.IsNullOrEmpty(propertyConfiguration.DateGroup))
|
||||
|
51
Property/Models/Stateless/IProperty.cs
Normal file
51
Property/Models/Stateless/IProperty.cs
Normal file
@ -0,0 +1,51 @@
|
||||
using System.Drawing.Imaging;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using View_by_Distance.Shared.Models.Methods;
|
||||
|
||||
namespace View_by_Distance.Property.Models.Stateless;
|
||||
|
||||
public interface IProperty
|
||||
{
|
||||
|
||||
string TestStatic_DateTimeFormat() =>
|
||||
DateTimeFormat();
|
||||
static string DateTimeFormat() =>
|
||||
"yyyy:MM:dd HH:mm:ss";
|
||||
|
||||
int TestStatic_GetDeterministicHashCode(byte[] value) =>
|
||||
GetDeterministicHashCode(value);
|
||||
static int GetDeterministicHashCode(byte[] value) =>
|
||||
Property.GetDeterministicHashCode(value);
|
||||
|
||||
byte[] TestStatic_GetBytes(string value) =>
|
||||
GetBytes(value);
|
||||
static byte[] GetBytes(string value) =>
|
||||
Property.GetBytes(value);
|
||||
|
||||
DateTime? TestStatic_GetDateTime(string dateTimeFormat, string? value) =>
|
||||
GetDateTime(dateTimeFormat, value);
|
||||
static DateTime? GetDateTime(string dateTimeFormat, string? value) =>
|
||||
Property.GetDateTime(dateTimeFormat, value);
|
||||
|
||||
PropertyItem TestStatic_GetPropertyItem(ConstructorInfo constructorInfo, int id, short type, string value) =>
|
||||
GetPropertyItem(constructorInfo, id, type, value);
|
||||
static PropertyItem GetPropertyItem(ConstructorInfo constructorInfo, int id, short type, string value) =>
|
||||
Property.GetPropertyItem(constructorInfo, id, type, value);
|
||||
|
||||
(string?, DateTime[], Shared.Models.Property) TestStatic_GetProperty(bool populateId, IMetadata<MetadataExtractor.Directory>? metadata, Shared.Models.FileHolder fileHolder, Shared.Models.Property? property, bool isIgnoreExtension, bool isValidImageFormatExtension, int? id, ASCIIEncoding asciiEncoding) =>
|
||||
GetProperty(populateId, metadata, fileHolder, property, isIgnoreExtension, isValidImageFormatExtension, id, asciiEncoding);
|
||||
static (string?, DateTime[], Shared.Models.Property) GetProperty(bool populateId, IMetadata<MetadataExtractor.Directory>? metadata, Shared.Models.FileHolder fileHolder, Shared.Models.Property? property, bool isIgnoreExtension, bool isValidImageFormatExtension, int? id, ASCIIEncoding asciiEncoding) =>
|
||||
Property.GetProperty(populateId, metadata, fileHolder, property, isIgnoreExtension, isValidImageFormatExtension, id, asciiEncoding);
|
||||
|
||||
(DateTime?, DateTime[], int?, string?) TestStatic_Get(bool populateId, Shared.Models.FileHolder fileHolder, bool isIgnoreExtension, bool isValidImageFormatExtension, ASCIIEncoding asciiEncoding) =>
|
||||
Get(populateId, fileHolder, isIgnoreExtension, isValidImageFormatExtension, asciiEncoding);
|
||||
static (DateTime?, DateTime[], int?, string?) Get(bool populateId, Shared.Models.FileHolder fileHolder, bool isIgnoreExtension, bool isValidImageFormatExtension, ASCIIEncoding asciiEncoding) =>
|
||||
Property.Get(populateId, null, fileHolder, isIgnoreExtension, isValidImageFormatExtension, asciiEncoding);
|
||||
|
||||
(DateTime?, DateTime[], int?, string?) TestStatic_Get(bool populateId, IMetadata<MetadataExtractor.Directory>? metadata, Shared.Models.FileHolder fileHolder, bool isIgnoreExtension, bool isValidImageFormatExtension, ASCIIEncoding asciiEncoding) =>
|
||||
Get(populateId, metadata, fileHolder, isIgnoreExtension, isValidImageFormatExtension, asciiEncoding);
|
||||
static (DateTime?, DateTime[], int?, string?) Get(bool populateId, IMetadata<MetadataExtractor.Directory>? metadata, Shared.Models.FileHolder fileHolder, bool isIgnoreExtension, bool isValidImageFormatExtension, ASCIIEncoding asciiEncoding) =>
|
||||
Property.Get(populateId, metadata, fileHolder, isIgnoreExtension, isValidImageFormatExtension, asciiEncoding);
|
||||
|
||||
}
|
395
Property/Models/Stateless/Property.cs
Normal file
395
Property/Models/Stateless/Property.cs
Normal file
@ -0,0 +1,395 @@
|
||||
using System.Diagnostics;
|
||||
using System.Drawing;
|
||||
using System.Drawing.Imaging;
|
||||
using System.Globalization;
|
||||
using System.Reflection;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
using View_by_Distance.Shared.Models;
|
||||
using View_by_Distance.Shared.Models.Methods;
|
||||
using View_by_Distance.Shared.Models.Stateless;
|
||||
|
||||
namespace View_by_Distance.Property.Models.Stateless;
|
||||
|
||||
internal class Property
|
||||
{
|
||||
|
||||
internal static int GetDeterministicHashCode(byte[] value)
|
||||
{
|
||||
int result;
|
||||
unchecked
|
||||
{
|
||||
int hash1 = (5381 << 16) + 5381;
|
||||
int hash2 = hash1;
|
||||
for (int i = 0; i < value.Length; i += 2)
|
||||
{
|
||||
hash1 = ((hash1 << 5) + hash1) ^ value[i];
|
||||
if (i == value.Length - 1)
|
||||
break;
|
||||
hash2 = ((hash2 << 5) + hash2) ^ value[i + 1];
|
||||
}
|
||||
result = hash1 + (hash2 * 1566083941);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
#pragma warning disable CA1416
|
||||
|
||||
internal static PropertyItem GetPropertyItem(ConstructorInfo constructorInfo, int id, short type, string value)
|
||||
{
|
||||
PropertyItem result = (PropertyItem)constructorInfo.Invoke(null);
|
||||
int length;
|
||||
byte[] bytes;
|
||||
if (type == 2)
|
||||
{
|
||||
bytes = GetBytes(value);
|
||||
length = value.Length + 1;
|
||||
}
|
||||
else if (type == 1)
|
||||
{
|
||||
bytes = Encoding.Unicode.GetBytes($"{value}\0");
|
||||
length = bytes.Length;
|
||||
}
|
||||
else
|
||||
throw new NotSupportedException();
|
||||
result.Id = id;
|
||||
result.Len = length;
|
||||
result.Type = type;
|
||||
result.Value = bytes;
|
||||
return result;
|
||||
}
|
||||
|
||||
#pragma warning restore CA1416
|
||||
|
||||
internal static byte[] GetBytes(string value)
|
||||
{
|
||||
byte[] results = new byte[value.Length + 1];
|
||||
for (int i = 0; i < value.Length; i++)
|
||||
results[i] = (byte)value[i];
|
||||
results[value.Length] = 0x00;
|
||||
return results;
|
||||
}
|
||||
|
||||
internal static DateTime? GetDateTime(string dateTimeFormat, string? value)
|
||||
{
|
||||
DateTime? result;
|
||||
string alternateFormat = "ddd MMM dd HH:mm:ss yyyy";
|
||||
if (value is not null && DateTime.TryParse(value, out DateTime dateTime))
|
||||
result = dateTime;
|
||||
else if (value is not null && value.Length == dateTimeFormat.Length && DateTime.TryParseExact(value, dateTimeFormat, CultureInfo.InvariantCulture, DateTimeStyles.None, out dateTime))
|
||||
result = dateTime;
|
||||
else if (value is not null && value.Length == alternateFormat.Length && DateTime.TryParseExact(value, alternateFormat, CultureInfo.InvariantCulture, DateTimeStyles.None, out dateTime))
|
||||
result = dateTime;
|
||||
else
|
||||
result = null;
|
||||
return result;
|
||||
}
|
||||
|
||||
private static List<DateTime> GetDateTimes(DateTime?[] metadataDateTimes)
|
||||
{
|
||||
List<DateTime> results = new();
|
||||
foreach (DateTime? dateTime in metadataDateTimes)
|
||||
{
|
||||
if (dateTime is null || results.Contains(dateTime.Value))
|
||||
continue;
|
||||
results.Add(dateTime.Value);
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
private static List<DateTime> GetDateTimes(DateTime?[] dateTimes, DateTime?[] metadataDateTimes)
|
||||
{
|
||||
List<DateTime> results = new();
|
||||
foreach (DateTime? dateTime in metadataDateTimes)
|
||||
{
|
||||
if (dateTime is null || results.Contains(dateTime.Value))
|
||||
continue;
|
||||
results.Add(dateTime.Value);
|
||||
}
|
||||
foreach (DateTime? dateTime in dateTimes)
|
||||
{
|
||||
if (dateTime is null || results.Contains(dateTime.Value))
|
||||
continue;
|
||||
results.Add(dateTime.Value);
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
private static List<DateTime> GetDateTimes(FileHolder fileHolder, DateTime?[] dateTimes)
|
||||
{
|
||||
List<DateTime> results = new();
|
||||
string[] digits = Regex.Split(fileHolder.FullName, @"\D+");
|
||||
foreach (string digit in digits)
|
||||
{
|
||||
if (digit.Length != 4 || digit[..2] is not "19" and not "20" || !int.TryParse(digit, out int year))
|
||||
continue;
|
||||
results.Add(new(year, 1, 1));
|
||||
}
|
||||
foreach (DateTime? dateTime in dateTimes)
|
||||
{
|
||||
if (dateTime is null)
|
||||
continue;
|
||||
results.Add(dateTime.Value);
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
private static List<DateTime> GetDateTimes(DateTime dateTimeFromName, DateTime?[] dateTimes)
|
||||
{
|
||||
List<DateTime> results = new() { dateTimeFromName };
|
||||
foreach (DateTime? dateTime in dateTimes)
|
||||
{
|
||||
if (dateTime is null)
|
||||
continue;
|
||||
results.Add(dateTime.Value);
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
#pragma warning disable CA1416
|
||||
|
||||
internal static DateTime? GetDateTimeFromName(FileHolder fileHolder)
|
||||
{
|
||||
DateTime? result = null;
|
||||
int length;
|
||||
string format;
|
||||
string fullFormat;
|
||||
StringBuilder value = new();
|
||||
const string ticksExample = "##################";
|
||||
string[][] dateFormats = new string[][]
|
||||
{
|
||||
new string[] { string.Empty, "yyyyMMdd_HHmmss", string.Empty },
|
||||
new string[] { string.Empty, "yyyyMMddHHmmssfff", string.Empty },
|
||||
new string[] { string.Empty, "yyyyMMdd_", ticksExample },
|
||||
new string[] { string.Empty, "yyyy-MM-dd_", ticksExample },
|
||||
new string[] { string.Empty, "yyyy-MM-dd.", ticksExample },
|
||||
new string[] { string.Empty, "yyyy-MM-dd.", $"{ticksExample}.{fileHolder.Length}" },
|
||||
new string[] { string.Empty, "yyyy-MM-dd HH.mm.ss", string.Empty },
|
||||
new string[] { string.Empty, "yyyyMMdd_HHmmss", "_LLS" },
|
||||
new string[] { string.Empty, "yyyyMMdd_HHmmss", "_HDR" },
|
||||
new string[] { "WIN_", "yyyyMMdd_HH_mm_ss", "_Pro" },
|
||||
new string[] { "IMG_", "yyyyMMdd_HHmmss", string.Empty },
|
||||
new string[] { "IMG#####-", "yyyyMMdd-HHmm", string.Empty },
|
||||
new string[] { "CameraZOOM-", "yyyyMMddHHmmss", string.Empty },
|
||||
new string[] { "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 (fileHolder.NameWithoutExtension.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(fileHolder.NameWithoutExtension[i]);
|
||||
if (value.Length != format.Length)
|
||||
continue;
|
||||
if (DateTime.TryParseExact(value.ToString(), format, CultureInfo.InvariantCulture, DateTimeStyles.None, out DateTime checkDateTime))
|
||||
{
|
||||
if (fileHolder.NameWithoutExtension.Length < ticksExample.Length || !long.TryParse(fileHolder.NameWithoutExtension[^ticksExample.Length..], out long ticks))
|
||||
result = checkDateTime;
|
||||
else
|
||||
result = new DateTime(ticks);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
internal static (string?, DateTime[], Shared.Models.Property) GetProperty(bool populateId, IMetadata<MetadataExtractor.Directory>? metadata, FileHolder fileHolder, Shared.Models.Property? property, bool isIgnoreExtension, bool isValidImageFormatExtension, int? id, ASCIIEncoding asciiEncoding)
|
||||
{
|
||||
Shared.Models.Property result;
|
||||
byte[] bytes;
|
||||
string value;
|
||||
long fileLength;
|
||||
string? message;
|
||||
int? width = null;
|
||||
int? height = null;
|
||||
string? make = null;
|
||||
string? model = null;
|
||||
DateTime?[] dateTimes;
|
||||
string dateTimeFormat;
|
||||
DateTime checkDateTime;
|
||||
DateTime? dateTime = null;
|
||||
PropertyItem? propertyItem;
|
||||
string? orientation = null;
|
||||
DateTime? gpsDateStamp = null;
|
||||
List<DateTime> dateTimesByLogic;
|
||||
DateTime? dateTimeOriginal = null;
|
||||
DateTime? dateTimeDigitized = null;
|
||||
DateTime? dateTimeOriginalByLogic = null;
|
||||
IReadOnlyList<MetadataExtractor.Directory> directories;
|
||||
DateTime? dateTimeFromName = GetDateTimeFromName(fileHolder);
|
||||
if (!isValidImageFormatExtension && fileHolder.Exists && metadata is not null)
|
||||
{
|
||||
try
|
||||
{
|
||||
directories = MetadataExtractor.ImageMetadataReader.ReadMetadata(fileHolder.FullName);
|
||||
(dateTimeOriginalByLogic, DateTime?[] metadataDateTimes) = metadata.GetDateTimes(fileHolder, directories);
|
||||
dateTimesByLogic = GetDateTimes(metadataDateTimes);
|
||||
message = null;
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
dateTimesByLogic = new();
|
||||
message = string.Concat(new StackFrame().GetMethod()?.Name, " <", fileHolder.FullName, ">");
|
||||
}
|
||||
}
|
||||
else if (!isIgnoreExtension && isValidImageFormatExtension && fileHolder.Exists)
|
||||
{
|
||||
try
|
||||
{
|
||||
using Image image = Image.FromFile(fileHolder.FullName);
|
||||
width = image.Width;
|
||||
height = image.Height;
|
||||
if (populateId && id is null)
|
||||
{
|
||||
using Bitmap bitmap = new(image);
|
||||
Rectangle rectangle = new(0, 0, image.Width, image.Height);
|
||||
BitmapData bitmapData = bitmap.LockBits(rectangle, ImageLockMode.ReadOnly, bitmap.PixelFormat);
|
||||
IntPtr intPtr = bitmapData.Scan0;
|
||||
int length = bitmapData.Stride * bitmap.Height;
|
||||
bytes = new byte[length];
|
||||
Marshal.Copy(intPtr, bytes, 0, length);
|
||||
bitmap.UnlockBits(bitmapData);
|
||||
id ??= GetDeterministicHashCode(bytes);
|
||||
}
|
||||
dateTimeFormat = IProperty.DateTimeFormat();
|
||||
if (image.PropertyIdList.Contains((int)IExif.Tags.DateTime))
|
||||
{
|
||||
propertyItem = image.GetPropertyItem((int)IExif.Tags.DateTime);
|
||||
if (propertyItem?.Value is not null)
|
||||
{
|
||||
value = asciiEncoding.GetString(propertyItem.Value, 0, propertyItem.Len - 1);
|
||||
if (value.Length > dateTimeFormat.Length)
|
||||
value = value[..dateTimeFormat.Length];
|
||||
if (value.Length == dateTimeFormat.Length && DateTime.TryParseExact(value, dateTimeFormat, CultureInfo.InvariantCulture, DateTimeStyles.None, out checkDateTime))
|
||||
dateTime = checkDateTime;
|
||||
}
|
||||
}
|
||||
if (image.PropertyIdList.Contains((int)IExif.Tags.DateTimeDigitized))
|
||||
{
|
||||
propertyItem = image.GetPropertyItem((int)IExif.Tags.DateTimeDigitized);
|
||||
if (propertyItem?.Value is not null)
|
||||
{
|
||||
value = asciiEncoding.GetString(propertyItem.Value, 0, propertyItem.Len - 1);
|
||||
if (value.Length > dateTimeFormat.Length)
|
||||
value = value[..dateTimeFormat.Length];
|
||||
if (value.Length == dateTimeFormat.Length && DateTime.TryParseExact(value, dateTimeFormat, CultureInfo.InvariantCulture, DateTimeStyles.None, out checkDateTime))
|
||||
dateTimeDigitized = checkDateTime;
|
||||
}
|
||||
}
|
||||
if (image.PropertyIdList.Contains((int)IExif.Tags.DateTimeOriginal))
|
||||
{
|
||||
propertyItem = image.GetPropertyItem((int)IExif.Tags.DateTimeOriginal);
|
||||
if (propertyItem?.Value is not null)
|
||||
{
|
||||
value = asciiEncoding.GetString(propertyItem.Value, 0, propertyItem.Len - 1);
|
||||
if (value.Length > dateTimeFormat.Length)
|
||||
value = value[..dateTimeFormat.Length];
|
||||
if (value.Length == dateTimeFormat.Length && DateTime.TryParseExact(value, dateTimeFormat, CultureInfo.InvariantCulture, DateTimeStyles.None, out checkDateTime))
|
||||
dateTimeOriginal = checkDateTime;
|
||||
}
|
||||
}
|
||||
if (image.PropertyIdList.Contains((int)IExif.Tags.GPSDateStamp))
|
||||
{
|
||||
propertyItem = image.GetPropertyItem((int)IExif.Tags.GPSDateStamp);
|
||||
if (propertyItem?.Value is not null)
|
||||
{
|
||||
value = asciiEncoding.GetString(propertyItem.Value, 0, propertyItem.Len - 1);
|
||||
if (value.Length > dateTimeFormat.Length)
|
||||
value = value[..dateTimeFormat.Length];
|
||||
if (value.Length == dateTimeFormat.Length && DateTime.TryParseExact(value, dateTimeFormat, CultureInfo.InvariantCulture, DateTimeStyles.None, out checkDateTime))
|
||||
gpsDateStamp = checkDateTime;
|
||||
}
|
||||
}
|
||||
if (image.PropertyIdList.Contains((int)IExif.Tags.Make))
|
||||
{
|
||||
propertyItem = image.GetPropertyItem((int)IExif.Tags.Make);
|
||||
if (propertyItem?.Value is not null)
|
||||
{
|
||||
value = asciiEncoding.GetString(propertyItem.Value, 0, propertyItem.Len - 1);
|
||||
make = value;
|
||||
}
|
||||
}
|
||||
if (image.PropertyIdList.Contains((int)IExif.Tags.Model))
|
||||
{
|
||||
propertyItem = image.GetPropertyItem((int)IExif.Tags.Model);
|
||||
if (propertyItem?.Value is not null)
|
||||
{
|
||||
value = asciiEncoding.GetString(propertyItem.Value, 0, propertyItem.Len - 1);
|
||||
model = value;
|
||||
}
|
||||
}
|
||||
if (image.PropertyIdList.Contains((int)IExif.Tags.Orientation))
|
||||
{
|
||||
propertyItem = image.GetPropertyItem((int)IExif.Tags.Orientation);
|
||||
if (propertyItem?.Value is not null)
|
||||
{
|
||||
value = BitConverter.ToInt16(propertyItem.Value, 0).ToString();
|
||||
orientation = value;
|
||||
}
|
||||
}
|
||||
message = null;
|
||||
dateTimes = new DateTime?[] { fileHolder.LastWriteTime, fileHolder.CreationTime, dateTime, dateTimeDigitized, dateTimeOriginal, gpsDateStamp };
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
dateTimes = Array.Empty<DateTime?>();
|
||||
message = string.Concat(new StackFrame().GetMethod()?.Name, " <", fileHolder.FullName, ">");
|
||||
}
|
||||
if (metadata is not null && dateTimeOriginal is null)
|
||||
{
|
||||
try
|
||||
{
|
||||
directories = MetadataExtractor.ImageMetadataReader.ReadMetadata(fileHolder.FullName);
|
||||
(dateTimeOriginalByLogic, DateTime?[] metadataDateTimes) = metadata.GetDateTimes(fileHolder, directories);
|
||||
dateTimesByLogic = GetDateTimes(dateTimes, metadataDateTimes);
|
||||
message = null;
|
||||
}
|
||||
catch (Exception) { message = string.Concat(new StackFrame().GetMethod()?.Name, " <", fileHolder.FullName, ">"); }
|
||||
}
|
||||
if (dateTimeFromName is null)
|
||||
(dateTimeOriginalByLogic, dateTimesByLogic) = (dateTimeOriginal, GetDateTimes(fileHolder, dateTimes));
|
||||
else
|
||||
(dateTimeOriginalByLogic, dateTimesByLogic) = (dateTimeOriginal, GetDateTimes(dateTimeFromName.Value, dateTimes));
|
||||
}
|
||||
else
|
||||
(message, dateTimeOriginalByLogic, dateTimesByLogic) = (null, null, new());
|
||||
if (fileHolder.Length is null)
|
||||
fileLength = 0;
|
||||
else
|
||||
fileLength = fileHolder.Length.Value;
|
||||
if (fileHolder.CreationTime is null && property?.CreationTime is null)
|
||||
throw new NullReferenceException(nameof(fileHolder.CreationTime));
|
||||
if (fileHolder.LastWriteTime is null && property?.LastWriteTime is null)
|
||||
throw new NullReferenceException(nameof(fileHolder.LastWriteTime));
|
||||
if (fileHolder.CreationTime is not null && fileHolder.LastWriteTime is not null)
|
||||
result = new(fileHolder.CreationTime.Value, dateTime, dateTimeDigitized, dateTimeFromName, dateTimeOriginalByLogic, fileLength, gpsDateStamp, height, id, fileHolder.LastWriteTime.Value, make, model, orientation, width);
|
||||
else if (property is not null)
|
||||
result = new(property.CreationTime, dateTime, dateTimeDigitized, dateTimeFromName, dateTimeOriginalByLogic, fileLength, gpsDateStamp, height, id, property.LastWriteTime, make, model, orientation, width);
|
||||
else
|
||||
throw new NullReferenceException(nameof(property));
|
||||
return (message, dateTimesByLogic.ToArray(), result);
|
||||
}
|
||||
|
||||
#pragma warning restore CA1416
|
||||
|
||||
internal static (DateTime?, DateTime[], int?, string?) Get(bool populateId, IMetadata<MetadataExtractor.Directory>? metadata, FileHolder fileHolder, bool isIgnoreExtension, bool isValidImageFormatExtension, ASCIIEncoding asciiEncoding)
|
||||
{
|
||||
int? id = null;
|
||||
string? message;
|
||||
DateTime[] dateTimes;
|
||||
Shared.Models.Property? property = null;
|
||||
if (isIgnoreExtension || !isValidImageFormatExtension)
|
||||
(message, dateTimes, property) = (null, Array.Empty<DateTime>(), null);
|
||||
else
|
||||
(message, dateTimes, property) = GetProperty(populateId, metadata, fileHolder, property, isIgnoreExtension, isValidImageFormatExtension, id, asciiEncoding);
|
||||
return new(property?.DateTimeOriginal, dateTimes, property?.Id, message);
|
||||
}
|
||||
|
||||
}
|
@ -3,9 +3,12 @@ using Microsoft.Extensions.Configuration;
|
||||
using Phares.Shared;
|
||||
using Serilog;
|
||||
using ShellProgressBar;
|
||||
using System.Text;
|
||||
using View_by_Distance.Metadata.Models;
|
||||
using View_by_Distance.Rename.Models;
|
||||
using View_by_Distance.Shared.Models;
|
||||
using View_by_Distance.Shared.Models.Methods;
|
||||
using View_by_Distance.Shared.Models.Stateless.Methods;
|
||||
|
||||
namespace View_by_Distance.Rename;
|
||||
|
||||
@ -18,7 +21,7 @@ public class Rename
|
||||
List<FileHolder> FileHolders,
|
||||
bool FfmpegFilesPresent,
|
||||
DateTime? DateTimeOriginal,
|
||||
DateTime?[] DateTimes,
|
||||
DateTime[] DateTimes,
|
||||
int? Id);
|
||||
|
||||
private readonly AppSettings _AppSettings;
|
||||
@ -85,7 +88,7 @@ public class Rename
|
||||
if (string.IsNullOrEmpty(directory))
|
||||
continue;
|
||||
fileName = Path.GetFileName(file);
|
||||
if (!fileName.EndsWith(".id"))
|
||||
if (!fileName.EndsWith(".paddedId"))
|
||||
continue;
|
||||
lines = File.ReadAllLines(file);
|
||||
if (lines.Length < 2)
|
||||
@ -99,20 +102,23 @@ public class Rename
|
||||
return results;
|
||||
}
|
||||
|
||||
private List<Record> GetRecords(int offset, ProgressBar progressBar, string[] files)
|
||||
private List<Record> GetRecords(B_Metadata metadata, int offset, ProgressBar progressBar, string[] files)
|
||||
{
|
||||
List<Record> results = new();
|
||||
int? id;
|
||||
string? message;
|
||||
string? directory;
|
||||
DateTime?[] dateTimes;
|
||||
DateTime[] dateTimes;
|
||||
FileHolder fileHolder;
|
||||
string[]? ffmpegFiles;
|
||||
bool isIgnoreExtension;
|
||||
DateTime? dateTimeOriginal;
|
||||
bool isValidImageFormatExtension;
|
||||
ASCIIEncoding asciiEncoding = new();
|
||||
bool nameWithoutExtensionIsIdFormat;
|
||||
bool nameWithoutExtensionIsPaddedIdFormat;
|
||||
IReadOnlyList<MetadataExtractor.Directory> directories;
|
||||
int sortOrderOnlyLengthIndex = IDirectory.GetSortOrderOnlyLengthIndex();
|
||||
for (int i = 0; i < files.Length; i++)
|
||||
{
|
||||
progressBar.Tick();
|
||||
@ -122,12 +128,13 @@ public class Rename
|
||||
directory = Path.GetDirectoryName(files[i]);
|
||||
if (string.IsNullOrEmpty(directory))
|
||||
continue;
|
||||
if (fileHolder.ExtensionLowered == ".id" || fileHolder.ExtensionLowered == ".lsv" || fileHolder.DirectoryName is null)
|
||||
if (fileHolder.ExtensionLowered == ".paddedId" || fileHolder.ExtensionLowered == ".lsv" || fileHolder.DirectoryName is null)
|
||||
continue;
|
||||
if (files.Contains($"{fileHolder.FullName}.id"))
|
||||
if (files.Contains($"{fileHolder.FullName}.paddedId"))
|
||||
continue;
|
||||
nameWithoutExtensionIsIdFormat = Shared.Models.Stateless.Methods.IProperty.NameWithoutExtensionIsIdFormat(fileHolder);
|
||||
if (nameWithoutExtensionIsIdFormat)
|
||||
nameWithoutExtensionIsPaddedIdFormat = IDirectory.NameWithoutExtensionIsPaddedIdFormat(fileHolder, sortOrderOnlyLengthIndex);
|
||||
if (nameWithoutExtensionIsIdFormat || nameWithoutExtensionIsPaddedIdFormat)
|
||||
continue;
|
||||
isValidImageFormatExtension = _PropertyConfiguration.ValidImageFormatExtensions.Contains(fileHolder.ExtensionLowered);
|
||||
isIgnoreExtension = isValidImageFormatExtension && _PropertyConfiguration.IgnoreExtensions.Contains(fileHolder.ExtensionLowered);
|
||||
@ -157,7 +164,7 @@ public class Rename
|
||||
if (fileHolder.DirectoryName is null)
|
||||
continue;
|
||||
}
|
||||
(dateTimeOriginal, dateTimes, id, message) = Shared.Models.Stateless.Methods.IProperty.Get(fileHolder, isIgnoreExtension, isValidImageFormatExtension, _PropertyConfiguration.PopulatePropertyId);
|
||||
(dateTimeOriginal, dateTimes, id, message) = Property.Models.Stateless.IProperty.Get(_PropertyConfiguration.PopulatePropertyId, metadata, fileHolder, isIgnoreExtension, isValidImageFormatExtension, asciiEncoding);
|
||||
if (ffmpegFiles is not null)
|
||||
{
|
||||
fileHolder = new(files[i]);
|
||||
@ -171,11 +178,11 @@ public class Rename
|
||||
return results;
|
||||
}
|
||||
|
||||
private List<(FileHolder, string, string)> GetToDoCollection(ProgressBar progressBar, bool nefPresent, List<Record> records, int length)
|
||||
private List<(FileHolder, string, string)> GetToDoCollection(ProgressBar progressBar, bool nefPresent, List<Record> records, int intMinValueLength)
|
||||
{
|
||||
List<(FileHolder, string, string)> results = new();
|
||||
string id;
|
||||
int season;
|
||||
string paddedId;
|
||||
string checkFile;
|
||||
bool? isWrongYear;
|
||||
DateTime dateTime;
|
||||
@ -189,12 +196,9 @@ public class Rename
|
||||
string checkFileExtension;
|
||||
DateTime? dateTimeFromName;
|
||||
const string jpeg = ".jpeg";
|
||||
DateTime?[] metadataDateTimes;
|
||||
List<string> distinct = new();
|
||||
string[] directoryNameSegments;
|
||||
DateTime? dateTimeOriginalByLogic;
|
||||
DateTime? metadataDateTimeOriginal;
|
||||
IReadOnlyList<MetadataExtractor.Directory> directories;
|
||||
foreach (Record record in records)
|
||||
{
|
||||
progressBar.Tick();
|
||||
@ -205,19 +209,20 @@ public class Rename
|
||||
continue;
|
||||
if (string.IsNullOrEmpty(fileHolder.DirectoryName))
|
||||
continue;
|
||||
dateTimeFromName = !record.DateTimes.Any() ? null : record.DateTimes.First();
|
||||
if (fileHolder.ExtensionLowered == jpeg)
|
||||
{
|
||||
if (!record.IsIgnoreExtension && record.IsValidImageFormatExtension)
|
||||
{
|
||||
if (File.Exists($"{fileHolder.FullName}.id"))
|
||||
if (File.Exists($"{fileHolder.FullName}.paddedId"))
|
||||
{
|
||||
checkFile = Path.Combine(fileHolder.DirectoryName, $"{fileHolder.NameWithoutExtension}{jpg}.id");
|
||||
checkFile = Path.Combine(fileHolder.DirectoryName, $"{fileHolder.NameWithoutExtension}{jpg}.paddedId");
|
||||
if (File.Exists(checkFile))
|
||||
continue;
|
||||
if (distinct.Contains(checkFile))
|
||||
continue;
|
||||
distinct.Add(checkFile);
|
||||
results.Add(new(new($"{fileHolder.FullName}.id"), fileHolder.DirectoryName, checkFile));
|
||||
results.Add(new(new($"{fileHolder.FullName}.paddedId"), fileHolder.DirectoryName, checkFile));
|
||||
}
|
||||
checkFile = Path.Combine(fileHolder.DirectoryName, $"{fileHolder.NameWithoutExtension}{jpg}");
|
||||
if (File.Exists(checkFile))
|
||||
@ -238,7 +243,6 @@ public class Rename
|
||||
continue;
|
||||
}
|
||||
}
|
||||
dateTimeFromName = Shared.Models.Stateless.Methods.IProperty.GetDateTimeFromName(fileHolder);
|
||||
minimumDateTime = record.DateTimes.Min();
|
||||
if (minimumDateTime is null)
|
||||
throw new NotSupportedException();
|
||||
@ -246,24 +250,10 @@ public class Rename
|
||||
timeSpan = null;
|
||||
else
|
||||
timeSpan = new(Math.Abs(minimumDateTime.Value.Ticks - record.DateTimeOriginal.Value.Ticks));
|
||||
if (timeSpan is not null && timeSpan.Value.TotalMinutes < _AppSettings.MaxMinutesDelta)
|
||||
(dateTimeOriginalByLogic, metadataDateTimeOriginal, metadataDateTimes) = (record.DateTimeOriginal, null, Array.Empty<DateTime?>());
|
||||
else
|
||||
{
|
||||
if (_PropertyConfiguration.IgnoreExtensions.Contains(fileHolder.ExtensionLowered))
|
||||
continue;
|
||||
try
|
||||
{ directories = MetadataExtractor.ImageMetadataReader.ReadMetadata(fileHolder.FullName); }
|
||||
catch (Exception) { continue; }
|
||||
(metadataDateTimeOriginal, metadataDateTimes) = Metadata.Models.Stateless.Methods.IMetadata.GetDateTimes(fileHolder, directories);
|
||||
dateTimeOriginalByLogic = record.DateTimeOriginal is not null ? record.DateTimeOriginal : metadataDateTimeOriginal;
|
||||
if (record.FfmpegFilesPresent && dateTimeOriginalByLogic is not null)
|
||||
minimumDateTime = dateTimeOriginalByLogic.Value;
|
||||
if (dateTimeOriginalByLogic is null)
|
||||
if (timeSpan is null || timeSpan.Value.TotalMinutes > _AppSettings.MaxMinutesDelta)
|
||||
timeSpan = null;
|
||||
else
|
||||
timeSpan = new(Math.Abs(minimumDateTime.Value.Ticks - dateTimeOriginalByLogic.Value.Ticks));
|
||||
}
|
||||
dateTimeOriginalByLogic = record.DateTimeOriginal;
|
||||
if (timeSpan is null || timeSpan.Value.TotalMinutes > _AppSettings.MaxMinutesDelta)
|
||||
{
|
||||
if (string.IsNullOrEmpty(_AppSettings.DefaultUnknownDirectoryName))
|
||||
@ -287,10 +277,8 @@ public class Rename
|
||||
{
|
||||
if (dateTimeFromName is not null && isWrongYear is not null && isWrongYear.Value)
|
||||
minimumDateTime = dateTimeFromName.Value;
|
||||
else if (dateTimeOriginalByLogic is not null)
|
||||
minimumDateTime = dateTimeOriginalByLogic.Value;
|
||||
else
|
||||
minimumDateTime = new DateTime?[] { record.DateTimes.Where(l => l is not null).Min(), metadataDateTimes.Where(l => l is not null).Min() }.Min();
|
||||
else if (record.DateTimeOriginal is not null)
|
||||
minimumDateTime = record.DateTimeOriginal.Value;
|
||||
if (minimumDateTime is null)
|
||||
continue;
|
||||
checkFileExtension = fileHolder.ExtensionLowered == jpeg ? jpg : fileHolder.ExtensionLowered;
|
||||
@ -310,9 +298,9 @@ public class Rename
|
||||
{
|
||||
if (record.Id is null)
|
||||
continue;
|
||||
id = Shared.Models.Stateless.Methods.IDirectory.GetPaddedId(length, record.Index, record.Id.Value);
|
||||
paddedId = IDirectory.GetPaddedId(intMinValueLength, record.Index, record.Id.Value);
|
||||
checkFileExtension = fileHolder.ExtensionLowered == jpeg ? jpg : fileHolder.ExtensionLowered;
|
||||
checkFile = Path.Combine(seasonDirectory, $"{id}{checkFileExtension}");
|
||||
checkFile = Path.Combine(seasonDirectory, $"{paddedId}{checkFileExtension}");
|
||||
if (checkFile == fileHolder.FullName)
|
||||
continue;
|
||||
if (File.Exists(checkFile))
|
||||
@ -359,11 +347,12 @@ public class Rename
|
||||
const string fileSearchFilter = "*";
|
||||
const string directorySearchFilter = "*";
|
||||
List<string> distinctDirectories = new();
|
||||
B_Metadata metadata = new(_PropertyConfiguration);
|
||||
List<(FileHolder, string)> verifiedToDoCollection = new();
|
||||
List<(FileHolder, string, string)> toDoCollection = new();
|
||||
int offset = Shared.Models.Stateless.Methods.IDirectory.GetOffset();
|
||||
int offset = IDirectory.GetOffset();
|
||||
ProgressBarOptions options = new() { ProgressCharacter = '─', ProgressBarOnBottom = true, DisableBottomPercentage = true };
|
||||
List<string[]> filesCollection = Shared.Models.Stateless.Methods.IDirectory.GetFilesCollection(_PropertyConfiguration.RootDirectory, directorySearchFilter, fileSearchFilter);
|
||||
List<string[]> filesCollection = IDirectory.GetFilesCollection(_PropertyConfiguration.RootDirectory, directorySearchFilter, fileSearchFilter);
|
||||
int count = filesCollection.Select(l => l.Length).Sum();
|
||||
foreach (string[] files in filesCollection)
|
||||
{
|
||||
@ -389,30 +378,29 @@ public class Rename
|
||||
progressBar = new(files.Length, message, options);
|
||||
nefPresentCheck = files.Any(l => l.EndsWith(".NEF"));
|
||||
if (!nefPresentCheck)
|
||||
records.AddRange(GetRecords(offset + records.Count, progressBar, files));
|
||||
records.AddRange(GetRecords(metadata, offset + records.Count, progressBar, files));
|
||||
else
|
||||
{
|
||||
if (!nefPresent)
|
||||
nefPresent = true;
|
||||
records.AddRange(GetRecords(offset + records.Count, progressBar, (from l in files where l.EndsWith(".JPG") select l).ToArray()));
|
||||
records.AddRange(GetRecords(metadata, offset + records.Count, progressBar, (from l in files where l.EndsWith(".JPG") select l).ToArray()));
|
||||
}
|
||||
}
|
||||
progressBar.Dispose();
|
||||
}
|
||||
if (records.Any())
|
||||
{
|
||||
int length = 0;
|
||||
int intMinValueLength = int.MinValue.ToString().Length;
|
||||
foreach (Record record in records)
|
||||
{
|
||||
if (record.Id is null)
|
||||
continue;
|
||||
if (length > record.Id.Value.ToString().Length)
|
||||
continue;
|
||||
length = record.Id.Value.ToString().Length;
|
||||
if (intMinValueLength < record.Id.Value.ToString().Length)
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
message = $"{length}) comparing records";
|
||||
message = $"{intMinValueLength}) comparing records";
|
||||
progressBar = new(records.Count, message, options);
|
||||
toDoCollection.AddRange(GetToDoCollection(progressBar, nefPresent, records, length));
|
||||
toDoCollection.AddRange(GetToDoCollection(progressBar, nefPresent, records, intMinValueLength));
|
||||
progressBar.Dispose();
|
||||
}
|
||||
foreach ((FileHolder fileHolder, string directory, string to) in toDoCollection)
|
||||
@ -431,7 +419,7 @@ public class Rename
|
||||
if (File.Exists(to))
|
||||
continue;
|
||||
verifiedToDoCollection.Add(new(fileHolder, to));
|
||||
File.WriteAllText($"{to}.id", $"{to}{Environment.NewLine}{fileHolder.FullName}");
|
||||
File.WriteAllText($"{to}.paddedId", $"{to}{Environment.NewLine}{fileHolder.FullName}");
|
||||
}
|
||||
ConsoleKey? consoleKey = null;
|
||||
log.Information($"Ready to Move {verifiedToDoCollection.Count} files[i](s)?");
|
||||
|
@ -70,7 +70,6 @@
|
||||
"ResultContent": "()",
|
||||
"ResultSingleton": "{}",
|
||||
"RootDirectory": "D:/Images",
|
||||
"WriteBitmapDataBytes": false,
|
||||
"IgnoreExtensions": [
|
||||
".gif",
|
||||
".GIF",
|
||||
@ -94,36 +93,6 @@
|
||||
".TIFF",
|
||||
".tif",
|
||||
".TIF"
|
||||
],
|
||||
"ValidMetadataExtensions": [
|
||||
".3gp",
|
||||
".3GP",
|
||||
".avi",
|
||||
".AVI",
|
||||
".bmp",
|
||||
".BMP",
|
||||
".gif",
|
||||
".GIF",
|
||||
".ico",
|
||||
".ICO",
|
||||
".jpeg",
|
||||
".JPEG",
|
||||
".jpg",
|
||||
".JPG",
|
||||
".m4v",
|
||||
".M4V",
|
||||
".mov",
|
||||
".MOV",
|
||||
".mp4",
|
||||
".MP4",
|
||||
".mta",
|
||||
".MTA",
|
||||
".png",
|
||||
".PNG",
|
||||
".tiff",
|
||||
".TIFF",
|
||||
".tif",
|
||||
".TIF"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
@ -294,7 +294,7 @@ public class C_Resize
|
||||
|
||||
private void SaveResizedSubfile(Shared.Models.Property property, MappingFromItem mappingFromItem, int[] resize)
|
||||
{
|
||||
string dateTimeFormat = Shared.Models.Stateless.Methods.IProperty.DateTimeFormat();
|
||||
string dateTimeFormat = Property.Models.Stateless.IProperty.DateTimeFormat();
|
||||
DateTime dateTime = property.DateTimeOriginal is not null ? property.DateTimeOriginal.Value : Shared.Models.Stateless.Methods.IProperty.GetMinimumDateTime(property);
|
||||
string dateTimeValue = dateTime.ToString(dateTimeFormat);
|
||||
byte[] bytes = _ASCIIEncoding.GetBytes(dateTimeValue);
|
||||
|
@ -45,6 +45,7 @@
|
||||
<PackageReference Include="Serilog" Version="2.12.0" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Metadata\Metadata.csproj" />
|
||||
<ProjectReference Include="..\Property\Property.csproj" />
|
||||
<ProjectReference Include="..\Shared\View-by-Distance.Shared.csproj" />
|
||||
</ItemGroup>
|
||||
|
@ -2,6 +2,8 @@
|
||||
using Phares.Shared;
|
||||
using Serilog;
|
||||
using ShellProgressBar;
|
||||
using System.Text;
|
||||
using View_by_Distance.Metadata.Models;
|
||||
using View_by_Distance.Set.Created.Date.Models;
|
||||
using View_by_Distance.Shared.Models;
|
||||
using View_by_Distance.Shared.Models.Methods;
|
||||
@ -11,6 +13,8 @@ namespace View_by_Distance.Set.Created.Date;
|
||||
public class SetCreatedDate
|
||||
{
|
||||
|
||||
private record Record(FileHolder FileHolder, bool OriginalSet, DateTime DateTime);
|
||||
|
||||
private readonly AppSettings _AppSettings;
|
||||
private readonly string _WorkingDirectory;
|
||||
private readonly Configuration _Configuration;
|
||||
@ -61,19 +65,16 @@ public class SetCreatedDate
|
||||
{ }
|
||||
}
|
||||
|
||||
private List<(FileHolder, DateTime)> GetToDoCollection(ProgressBar progressBar, List<string[]> filesCollection)
|
||||
private List<Record> GetRecords(ProgressBar progressBar, ASCIIEncoding asciiEncoding, B_Metadata metadata, string[] files)
|
||||
{
|
||||
List<(FileHolder, DateTime)> results = new();
|
||||
List<Record> results = new();
|
||||
int? id;
|
||||
string? message;
|
||||
DateTime? dateTime;
|
||||
DateTime[] dateTimes;
|
||||
FileHolder fileHolder;
|
||||
DateTime?[] dateTimes;
|
||||
bool isIgnoreExtension;
|
||||
DateTime? dateTimeOriginal;
|
||||
bool isValidImageFormatExtension;
|
||||
foreach (string[] files in filesCollection)
|
||||
{
|
||||
foreach (string file in files)
|
||||
{
|
||||
progressBar.Tick();
|
||||
@ -86,27 +87,54 @@ public class SetCreatedDate
|
||||
isIgnoreExtension = isValidImageFormatExtension && _PropertyConfiguration.IgnoreExtensions.Contains(fileHolder.ExtensionLowered);
|
||||
if (isIgnoreExtension || !isValidImageFormatExtension)
|
||||
continue;
|
||||
(dateTimeOriginal, dateTimes, id, message) = Shared.Models.Stateless.Methods.IProperty.Get(fileHolder, isIgnoreExtension, isValidImageFormatExtension, _PropertyConfiguration.PopulatePropertyId);
|
||||
dateTime = dateTimeOriginal is not null ? dateTimeOriginal : dateTime = dateTimes.Min();
|
||||
if (dateTime is null)
|
||||
(dateTimeOriginal, dateTimes, id, message) = Property.Models.Stateless.IProperty.Get(_PropertyConfiguration.PopulatePropertyId, metadata, fileHolder, isIgnoreExtension, isValidImageFormatExtension, asciiEncoding);
|
||||
if (dateTimeOriginal is null)
|
||||
results.Add(new(fileHolder, false, dateTimes.Min()));
|
||||
else
|
||||
results.Add(new(fileHolder, true, dateTimeOriginal.Value));
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
private List<Record> GetToDoCollection(ProgressBar progressBar, List<string[]> filesCollection)
|
||||
{
|
||||
List<Record> results = new();
|
||||
int minutes;
|
||||
Record[] records;
|
||||
List<Record> unordered;
|
||||
ASCIIEncoding asciiEncoding = new();
|
||||
B_Metadata metadata = new(_PropertyConfiguration);
|
||||
List<Record[]> collections = new();
|
||||
foreach (string[] files in filesCollection)
|
||||
{
|
||||
minutes = 0;
|
||||
unordered = GetRecords(progressBar, asciiEncoding, metadata, files);
|
||||
records = (from l in unordered orderby l.DateTime, l.FileHolder.Name.Length, l.FileHolder.Name select l).ToArray();
|
||||
foreach (Record record in records)
|
||||
{
|
||||
if (record.DateTime == record.FileHolder.CreationTime)
|
||||
continue;
|
||||
if (dateTime.Value == fileHolder.CreationTime)
|
||||
continue;
|
||||
results.Add((fileHolder, dateTime.Value));
|
||||
if (record.OriginalSet)
|
||||
results.Add(new(record.FileHolder, record.OriginalSet, record.DateTime));
|
||||
else
|
||||
{
|
||||
minutes += 1;
|
||||
results.Add(new(record.FileHolder, record.OriginalSet, record.DateTime.AddMinutes(minutes)));
|
||||
}
|
||||
}
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
private static List<string> SetCreatedDateForeach(ProgressBar progressBar, List<(FileHolder, DateTime)> toDoCollection)
|
||||
private static List<string> SetCreatedDateForeach(ProgressBar progressBar, List<Record> toDoCollection)
|
||||
{
|
||||
List<string> results = new();
|
||||
foreach ((FileHolder fileHolder, DateTime dateTime) in toDoCollection)
|
||||
foreach (Record record in toDoCollection)
|
||||
{
|
||||
progressBar.Tick();
|
||||
results.Add(fileHolder.NameWithoutExtension);
|
||||
results.Add(record.FileHolder.NameWithoutExtension);
|
||||
try
|
||||
{ File.SetCreationTime(fileHolder.FullName, dateTime); }
|
||||
{ File.SetCreationTime(record.FileHolder.FullName, record.DateTime); }
|
||||
catch (Exception) { }
|
||||
}
|
||||
return results;
|
||||
@ -124,7 +152,7 @@ public class SetCreatedDate
|
||||
int count = filesCollection.Select(l => l.Length).Sum();
|
||||
ProgressBarOptions options = new() { ProgressCharacter = '─', ProgressBarOnBottom = true, DisableBottomPercentage = true };
|
||||
progressBar = new(count, message, options);
|
||||
List<(FileHolder, DateTime)> toDoCollection = GetToDoCollection(progressBar, filesCollection);
|
||||
List<Record> toDoCollection = GetToDoCollection(progressBar, filesCollection);
|
||||
progressBar.Dispose();
|
||||
log.Information($"Ready to set created date {toDoCollection.Count} file(s)?");
|
||||
for (int y = 0; y < int.MaxValue; y++)
|
||||
|
@ -68,7 +68,6 @@
|
||||
"ResultContent": "()",
|
||||
"ResultSingleton": "{}",
|
||||
"RootDirectory": "D:/Images",
|
||||
"WriteBitmapDataBytes": false,
|
||||
"IgnoreExtensions": [
|
||||
".gif",
|
||||
".GIF",
|
||||
@ -92,36 +91,6 @@
|
||||
".TIFF",
|
||||
".tif",
|
||||
".TIF"
|
||||
],
|
||||
"ValidMetadataExtensions": [
|
||||
".3gp",
|
||||
".3GP",
|
||||
".avi",
|
||||
".AVI",
|
||||
".bmp",
|
||||
".BMP",
|
||||
".gif",
|
||||
".GIF",
|
||||
".ico",
|
||||
".ICO",
|
||||
".jpeg",
|
||||
".JPEG",
|
||||
".jpg",
|
||||
".JPG",
|
||||
".m4v",
|
||||
".M4V",
|
||||
".mov",
|
||||
".MOV",
|
||||
".mp4",
|
||||
".MP4",
|
||||
".mta",
|
||||
".MTA",
|
||||
".png",
|
||||
".PNG",
|
||||
".tiff",
|
||||
".TIFF",
|
||||
".tif",
|
||||
".TIF"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
8
Shared/Models/Methods/IMetadata.cs
Normal file
8
Shared/Models/Methods/IMetadata.cs
Normal file
@ -0,0 +1,8 @@
|
||||
namespace View_by_Distance.Shared.Models.Methods;
|
||||
|
||||
public interface IMetadata<T>
|
||||
{
|
||||
|
||||
(DateTime?, DateTime?[]) GetDateTimes(FileHolder fileHolder, IReadOnlyList<T> directories);
|
||||
|
||||
}
|
@ -6,6 +6,11 @@ public interface IDirectory
|
||||
static int GetOffset() =>
|
||||
1000000;
|
||||
|
||||
int TestStatic_GetSortOrderOnlyLengthIndex() =>
|
||||
GetSortOrderOnlyLengthIndex();
|
||||
static int GetSortOrderOnlyLengthIndex() =>
|
||||
GetOffset().ToString().Length + 3;
|
||||
|
||||
char TestStatic_GetDirectory(string fileName) =>
|
||||
GetDirectory(fileName);
|
||||
static char GetDirectory(string fileName) =>
|
||||
@ -16,10 +21,23 @@ public interface IDirectory
|
||||
static int GetDirectory(char directory) =>
|
||||
directory == '-' ? 10 : int.TryParse(directory.ToString(), out int value) ? value : 11;
|
||||
|
||||
string TestStatic_GetPaddedId(int length, int index, int id) =>
|
||||
GetPaddedId(length, index, id);
|
||||
static string GetPaddedId(int length, int index, int id) =>
|
||||
id > -1 ? $"{index}070{id.ToString().PadLeft(length, '0')}" : $"{index}030{id.ToString()[1..].PadLeft(length, '0')}";
|
||||
string TestStatic_GetPaddedId(int intMinValueLength, int index, int id) =>
|
||||
GetPaddedId(intMinValueLength, index, id);
|
||||
static string GetPaddedId(int intMinValueLength, int index, int id) =>
|
||||
id > -1 ? $"{index}070{id.ToString().PadLeft(intMinValueLength, '0')}" : $"{index}030{id.ToString()[1..].PadLeft(intMinValueLength, '0')}";
|
||||
|
||||
bool TestStatic_NameWithoutExtensionIsPaddedIdFormat(string fileNameWithoutExtension, int sortOrderOnlyLengthIndex) =>
|
||||
NameWithoutExtensionIsPaddedIdFormat(fileNameWithoutExtension, sortOrderOnlyLengthIndex);
|
||||
static bool NameWithoutExtensionIsPaddedIdFormat(string fileNameWithoutExtension, int sortOrderOnlyLengthIndex) =>
|
||||
fileNameWithoutExtension.Length > sortOrderOnlyLengthIndex
|
||||
&& fileNameWithoutExtension[sortOrderOnlyLengthIndex] == '0'
|
||||
&& fileNameWithoutExtension[sortOrderOnlyLengthIndex - 3] == '0'
|
||||
&& fileNameWithoutExtension.All(l => char.IsNumber(l));
|
||||
|
||||
bool TestStatic_NameWithoutExtensionIsPaddedIdFormat(Models.FileHolder fileHolder, int sortOrderOnlyLengthIndex) =>
|
||||
NameWithoutExtensionIsPaddedIdFormat(fileHolder, sortOrderOnlyLengthIndex);
|
||||
static bool NameWithoutExtensionIsPaddedIdFormat(Models.FileHolder fileHolder, int sortOrderOnlyLengthIndex) =>
|
||||
NameWithoutExtensionIsPaddedIdFormat(fileHolder.NameWithoutExtension, sortOrderOnlyLengthIndex);
|
||||
|
||||
List<string[]> TestStatic_GetFilesCollection(string directory, string directorySearchFilter, string fileSearchFilter) =>
|
||||
GetFilesCollection(directory, directorySearchFilter, fileSearchFilter);
|
||||
@ -51,6 +69,11 @@ public interface IDirectory
|
||||
static void MoveFiles(List<string> files, string find, string replace) =>
|
||||
XDirectory.MoveFiles(files, find, replace);
|
||||
|
||||
(string[], List<(Models.FileHolder, string)>) TestStatic_GetToDoCollection(Properties.IPropertyConfiguration propertyConfiguration, List<string[]> filesCollection, string[] directories, Action? tick) =>
|
||||
GetToDoCollection(propertyConfiguration, filesCollection, directories, tick);
|
||||
static (string[], List<(Models.FileHolder, string)>) GetToDoCollection(Properties.IPropertyConfiguration propertyConfiguration, List<string[]> filesCollection, string[] directories, Action? tick) =>
|
||||
XDirectory.GetToDoCollection(propertyConfiguration, copyDuplicates: false, ifCanUseId: true, filesCollection, directories, tick);
|
||||
|
||||
(string[], List<(Models.FileHolder, string)>) TestStatic_GetToDoCollection(Properties.IPropertyConfiguration propertyConfiguration, bool copyDuplicates, bool ifCanUseId, List<string[]> filesCollection, string[] directories, Action? tick) =>
|
||||
GetToDoCollection(propertyConfiguration, copyDuplicates, ifCanUseId, filesCollection, directories, tick);
|
||||
static (string[], List<(Models.FileHolder, string)>) GetToDoCollection(Properties.IPropertyConfiguration propertyConfiguration, bool copyDuplicates, bool ifCanUseId, List<string[]> filesCollection, string[] directories, Action? tick) =>
|
||||
|
@ -1,24 +1,8 @@
|
||||
using System.Drawing.Imaging;
|
||||
using System.Reflection;
|
||||
|
||||
namespace View_by_Distance.Shared.Models.Stateless.Methods;
|
||||
|
||||
public interface IProperty
|
||||
{ // ...
|
||||
|
||||
string TestStatic_DateTimeFormat();
|
||||
static string DateTimeFormat() => "yyyy:MM:dd HH:mm:ss";
|
||||
|
||||
int TestStatic_GetDeterministicHashCode(byte[] value) =>
|
||||
GetDeterministicHashCode(value);
|
||||
static int GetDeterministicHashCode(byte[] value) =>
|
||||
Property.GetDeterministicHashCode(value);
|
||||
|
||||
DateTime? TestStatic_GetDateTime(string dateTimeFormat, string? value) =>
|
||||
GetDateTime(dateTimeFormat, value);
|
||||
static DateTime? GetDateTime(string dateTimeFormat, string? value) =>
|
||||
Property.GetDateTime(dateTimeFormat, value);
|
||||
|
||||
DateTime TestStatic_GetDateTime(Models.Property? property) =>
|
||||
GetDateTime(property);
|
||||
static DateTime GetDateTime(Models.Property? property) =>
|
||||
@ -54,26 +38,11 @@ public interface IProperty
|
||||
static (bool?, string[]) IsWrongYear(Models.FileHolder fileHolder, DateTime? dateTimeOriginal, List<DateTime> dateTimes) =>
|
||||
Property.IsWrongYear(fileHolder, dateTimeOriginal, dateTimes);
|
||||
|
||||
(DateTime?, DateTime?[], int?, string?) TestStatic_Get(Models.FileHolder fileHolder, bool isIgnoreExtension, bool isValidImageFormatExtension, bool populateId) =>
|
||||
Get(fileHolder, isIgnoreExtension, isValidImageFormatExtension, populateId);
|
||||
static (DateTime?, DateTime?[], int?, string?) Get(Models.FileHolder fileHolder, bool isIgnoreExtension, bool isValidImageFormatExtension, bool populateId) =>
|
||||
Property.Get(fileHolder, isIgnoreExtension, isValidImageFormatExtension, populateId);
|
||||
|
||||
DateTime? TestStatic_GetDateTimeFromName(Models.FileHolder fileHolder) =>
|
||||
GetDateTimeFromName(fileHolder);
|
||||
static DateTime? GetDateTimeFromName(Models.FileHolder fileHolder) =>
|
||||
Property.GetDateTimeFromName(fileHolder);
|
||||
|
||||
bool TestStatic_NameWithoutExtensionIsIdFormat(string fileNameWithoutExtension) =>
|
||||
NameWithoutExtensionIsIdFormat(fileNameWithoutExtension);
|
||||
static bool NameWithoutExtensionIsIdFormat(string fileNameWithoutExtension) =>
|
||||
Property.NameWithoutExtensionIsIdFormat(fileNameWithoutExtension);
|
||||
|
||||
bool TestStatic_NameWithoutExtensionIsIdFormat(string[] validImageFormatExtensions, Models.FileHolder fileHolder) =>
|
||||
NameWithoutExtensionIsIdFormat(validImageFormatExtensions, fileHolder);
|
||||
static bool NameWithoutExtensionIsIdFormat(string[] validImageFormatExtensions, Models.FileHolder fileHolder) =>
|
||||
Property.NameWithoutExtensionIsIdFormat(validImageFormatExtensions, fileHolder);
|
||||
|
||||
bool TestStatic_NameWithoutExtensionIsIdFormat(Models.FileHolder fileHolder) =>
|
||||
NameWithoutExtensionIsIdFormat(fileHolder);
|
||||
static bool NameWithoutExtensionIsIdFormat(Models.FileHolder fileHolder) =>
|
||||
@ -104,14 +73,4 @@ public interface IProperty
|
||||
static List<DateTime> GetDateTimes(DateTime creationTime, DateTime lastWriteTime, DateTime? dateTime, DateTime? dateTimeDigitized, DateTime? dateTimeFromName, DateTime? dateTimeOriginal, DateTime? gpsDateStamp) =>
|
||||
Property.GetDateTimes(creationTime, lastWriteTime, dateTime, dateTimeDigitized, dateTimeFromName, dateTimeOriginal, gpsDateStamp);
|
||||
|
||||
byte[] TestStatic_GetBytes(string value) =>
|
||||
GetBytes(value);
|
||||
static byte[] GetBytes(string value) =>
|
||||
Property.GetBytes(value);
|
||||
|
||||
PropertyItem TestStatic_GetPropertyItem(ConstructorInfo constructorInfo, int id, short type, string value) =>
|
||||
GetPropertyItem(constructorInfo, id, type, value);
|
||||
static PropertyItem GetPropertyItem(ConstructorInfo constructorInfo, int id, short type, string value) =>
|
||||
Property.GetPropertyItem(constructorInfo, id, type, value);
|
||||
|
||||
}
|
@ -1,11 +1,3 @@
|
||||
using System.Diagnostics;
|
||||
using System.Drawing;
|
||||
using System.Drawing.Imaging;
|
||||
using System.Globalization;
|
||||
using System.Reflection;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
|
||||
namespace View_by_Distance.Shared.Models.Stateless.Methods;
|
||||
|
||||
internal abstract class Property
|
||||
@ -24,25 +16,6 @@ internal abstract class Property
|
||||
return result;
|
||||
}
|
||||
|
||||
internal static int GetDeterministicHashCode(byte[] value)
|
||||
{
|
||||
int result;
|
||||
unchecked
|
||||
{
|
||||
int hash1 = (5381 << 16) + 5381;
|
||||
int hash2 = hash1;
|
||||
for (int i = 0; i < value.Length; i += 2)
|
||||
{
|
||||
hash1 = ((hash1 << 5) + hash1) ^ value[i];
|
||||
if (i == value.Length - 1)
|
||||
break;
|
||||
hash2 = ((hash2 << 5) + hash2) ^ value[i + 1];
|
||||
}
|
||||
result = hash1 + (hash2 * 1566083941);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
internal static (bool?, string[]) IsWrongYear(string[] segments, string year)
|
||||
{
|
||||
bool? result;
|
||||
@ -113,57 +86,6 @@ internal abstract class Property
|
||||
return new(result, results);
|
||||
}
|
||||
|
||||
internal static DateTime? GetDateTimeFromName(Models.FileHolder fileHolder)
|
||||
{
|
||||
DateTime? result = null;
|
||||
int length;
|
||||
string format;
|
||||
string fullFormat;
|
||||
StringBuilder value = new();
|
||||
const string ticksExample = "##################";
|
||||
string[][] dateFormats = new string[][]
|
||||
{
|
||||
new string[] { string.Empty, "yyyyMMdd_HHmmss", string.Empty },
|
||||
new string[] { string.Empty, "yyyyMMddHHmmssfff", string.Empty },
|
||||
new string[] { string.Empty, "yyyyMMdd_", ticksExample },
|
||||
new string[] { string.Empty, "yyyy-MM-dd_", ticksExample },
|
||||
new string[] { string.Empty, "yyyy-MM-dd.", ticksExample },
|
||||
new string[] { string.Empty, "yyyy-MM-dd.", $"{ticksExample}.{fileHolder.Length}" },
|
||||
new string[] { string.Empty, "yyyy-MM-dd HH.mm.ss", string.Empty },
|
||||
new string[] { string.Empty, "yyyyMMdd_HHmmss", "_LLS" },
|
||||
new string[] { string.Empty, "yyyyMMdd_HHmmss", "_HDR" },
|
||||
new string[] { "WIN_", "yyyyMMdd_HH_mm_ss", "_Pro" },
|
||||
new string[] { "IMG_", "yyyyMMdd_HHmmss", string.Empty },
|
||||
new string[] { "IMG#####-", "yyyyMMdd-HHmm", string.Empty },
|
||||
new string[] { "CameraZOOM-", "yyyyMMddHHmmss", string.Empty },
|
||||
new string[] { "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 (fileHolder.NameWithoutExtension.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(fileHolder.NameWithoutExtension[i]);
|
||||
if (value.Length != format.Length)
|
||||
continue;
|
||||
if (DateTime.TryParseExact(value.ToString(), format, CultureInfo.InvariantCulture, DateTimeStyles.None, out DateTime checkDateTime))
|
||||
{
|
||||
if (fileHolder.NameWithoutExtension.Length < ticksExample.Length || !long.TryParse(fileHolder.NameWithoutExtension[^ticksExample.Length..], out long ticks))
|
||||
result = checkDateTime;
|
||||
else
|
||||
result = new DateTime(ticks);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
internal static List<DateTime> GetDateTimes(DateTime creationTime, DateTime lastWriteTime, DateTime? dateTime, DateTime? dateTimeDigitized, DateTime? dateTimeFromName, DateTime? dateTimeOriginal, DateTime? gpsDateStamp)
|
||||
{
|
||||
List<DateTime> results = new()
|
||||
@ -355,7 +277,8 @@ internal abstract class Property
|
||||
internal static bool NameWithoutExtensionIsIdFormat(string fileNameWithoutExtension)
|
||||
{
|
||||
bool result;
|
||||
if (fileNameWithoutExtension.Length < 5)
|
||||
int intMinValueLength = int.MinValue.ToString().Length;
|
||||
if (fileNameWithoutExtension.Length < 5 || fileNameWithoutExtension.Length > intMinValueLength)
|
||||
result = false;
|
||||
else
|
||||
{
|
||||
@ -365,181 +288,4 @@ internal abstract class Property
|
||||
return result;
|
||||
}
|
||||
|
||||
internal static bool NameWithoutExtensionIsIdFormat(string[] validImageFormatExtensions, Models.FileHolder fileHolder)
|
||||
{
|
||||
bool result;
|
||||
bool changed;
|
||||
string? fileNameWithoutExtension = fileHolder.NameWithoutExtension;
|
||||
for (int i = 0; i < validImageFormatExtensions.Length; i++)
|
||||
{
|
||||
changed = false;
|
||||
foreach (string validImageFormatExtension in validImageFormatExtensions)
|
||||
{
|
||||
if (fileNameWithoutExtension.EndsWith(validImageFormatExtension))
|
||||
{
|
||||
changed = true;
|
||||
fileNameWithoutExtension = fileNameWithoutExtension[..^validImageFormatExtension.Length];
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!changed)
|
||||
break;
|
||||
}
|
||||
result = NameWithoutExtensionIsIdFormat(fileNameWithoutExtension);
|
||||
return result;
|
||||
}
|
||||
|
||||
#pragma warning disable CA1416
|
||||
|
||||
internal static (DateTime?, DateTime?[], int?, string?) Get(Models.FileHolder fileHolder, bool isIgnoreExtension, bool isValidImageFormatExtension, bool populateId)
|
||||
{
|
||||
int? id = null;
|
||||
string? message = null;
|
||||
DateTime? dateTime = null;
|
||||
DateTime? gpsDateStamp = null;
|
||||
DateTime? dateTimeOriginal = null;
|
||||
DateTime? dateTimeDigitized = null;
|
||||
if (!isIgnoreExtension && isValidImageFormatExtension)
|
||||
{
|
||||
try
|
||||
{
|
||||
byte[] bytes;
|
||||
string value;
|
||||
DateTime checkDateTime;
|
||||
PropertyItem? propertyItem;
|
||||
ASCIIEncoding asciiEncoding = new();
|
||||
string dateTimeFormat = IProperty.DateTimeFormat();
|
||||
using Image image = Image.FromFile(fileHolder.FullName);
|
||||
if (!populateId)
|
||||
id = null;
|
||||
else
|
||||
{
|
||||
using Bitmap bitmap = new(image);
|
||||
Rectangle rectangle = new(0, 0, image.Width, image.Height);
|
||||
BitmapData bitmapData = bitmap.LockBits(rectangle, ImageLockMode.ReadOnly, bitmap.PixelFormat);
|
||||
IntPtr intPtr = bitmapData.Scan0;
|
||||
int length = bitmapData.Stride * bitmap.Height;
|
||||
bytes = new byte[length];
|
||||
Marshal.Copy(intPtr, bytes, 0, length);
|
||||
bitmap.UnlockBits(bitmapData);
|
||||
id = IProperty.GetDeterministicHashCode(bytes);
|
||||
bitmap.Dispose();
|
||||
}
|
||||
if (image.PropertyIdList.Contains((int)IExif.Tags.DateTime))
|
||||
{
|
||||
propertyItem = image.GetPropertyItem((int)IExif.Tags.DateTime);
|
||||
if (propertyItem?.Value is not null)
|
||||
{
|
||||
value = asciiEncoding.GetString(propertyItem.Value, 0, propertyItem.Len - 1);
|
||||
if (value.Length > dateTimeFormat.Length)
|
||||
value = value[..dateTimeFormat.Length];
|
||||
if (value.Length == dateTimeFormat.Length && DateTime.TryParseExact(value, dateTimeFormat, CultureInfo.InvariantCulture, DateTimeStyles.None, out checkDateTime))
|
||||
dateTime = checkDateTime;
|
||||
else
|
||||
dateTime = GetDateTime(dateTimeFormat, value);
|
||||
}
|
||||
if (image.PropertyIdList.Contains((int)IExif.Tags.DateTimeDigitized))
|
||||
{
|
||||
propertyItem = image.GetPropertyItem((int)IExif.Tags.DateTimeDigitized);
|
||||
if (propertyItem?.Value is not null)
|
||||
{
|
||||
value = asciiEncoding.GetString(propertyItem.Value, 0, propertyItem.Len - 1);
|
||||
if (value.Length > dateTimeFormat.Length)
|
||||
value = value[..dateTimeFormat.Length];
|
||||
if (value.Length == dateTimeFormat.Length && DateTime.TryParseExact(value, dateTimeFormat, CultureInfo.InvariantCulture, DateTimeStyles.None, out checkDateTime))
|
||||
dateTimeDigitized = checkDateTime;
|
||||
else
|
||||
dateTimeDigitized = GetDateTime(dateTimeFormat, value);
|
||||
}
|
||||
}
|
||||
if (image.PropertyIdList.Contains((int)IExif.Tags.DateTimeOriginal))
|
||||
{
|
||||
propertyItem = image.GetPropertyItem((int)IExif.Tags.DateTimeOriginal);
|
||||
if (propertyItem?.Value is not null)
|
||||
{
|
||||
value = asciiEncoding.GetString(propertyItem.Value, 0, propertyItem.Len - 1);
|
||||
if (value.Length > dateTimeFormat.Length)
|
||||
value = value[..dateTimeFormat.Length];
|
||||
if (value.Length == dateTimeFormat.Length && DateTime.TryParseExact(value, dateTimeFormat, CultureInfo.InvariantCulture, DateTimeStyles.None, out checkDateTime))
|
||||
dateTimeOriginal = checkDateTime;
|
||||
else
|
||||
dateTimeOriginal = GetDateTime(dateTimeFormat, value);
|
||||
}
|
||||
}
|
||||
if (image.PropertyIdList.Contains((int)IExif.Tags.GPSDateStamp))
|
||||
{
|
||||
propertyItem = image.GetPropertyItem((int)IExif.Tags.GPSDateStamp);
|
||||
if (propertyItem?.Value is not null)
|
||||
{
|
||||
value = asciiEncoding.GetString(propertyItem.Value, 0, propertyItem.Len - 1);
|
||||
if (value.Length > dateTimeFormat.Length)
|
||||
value = value[..dateTimeFormat.Length];
|
||||
if (value.Length == dateTimeFormat.Length && DateTime.TryParseExact(value, dateTimeFormat, CultureInfo.InvariantCulture, DateTimeStyles.None, out checkDateTime))
|
||||
gpsDateStamp = checkDateTime;
|
||||
else
|
||||
gpsDateStamp = GetDateTime(dateTimeFormat, value);
|
||||
}
|
||||
}
|
||||
image.Dispose();
|
||||
}
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
message = string.Concat(new StackFrame().GetMethod()?.Name, " <", fileHolder.FullName, ">");
|
||||
}
|
||||
}
|
||||
DateTime?[] dateTimes = new DateTime?[] { fileHolder.LastWriteTime, fileHolder.CreationTime, dateTime, dateTimeDigitized, dateTimeOriginal, gpsDateStamp };
|
||||
return new(dateTimeOriginal, dateTimes, id, message);
|
||||
}
|
||||
|
||||
internal static PropertyItem GetPropertyItem(ConstructorInfo constructorInfo, int id, short type, string value)
|
||||
{
|
||||
PropertyItem result = (PropertyItem)constructorInfo.Invoke(null);
|
||||
int length;
|
||||
byte[] bytes;
|
||||
if (type == 2)
|
||||
{
|
||||
bytes = GetBytes(value);
|
||||
length = value.Length + 1;
|
||||
}
|
||||
else if (type == 1)
|
||||
{
|
||||
bytes = Encoding.Unicode.GetBytes($"{value}\0");
|
||||
length = bytes.Length;
|
||||
}
|
||||
else
|
||||
throw new NotSupportedException();
|
||||
result.Id = id;
|
||||
result.Len = length;
|
||||
result.Type = type;
|
||||
result.Value = bytes;
|
||||
return result;
|
||||
}
|
||||
|
||||
#pragma warning restore CA1416
|
||||
|
||||
internal static DateTime? GetDateTime(string dateTimeFormat, string? value)
|
||||
{
|
||||
DateTime? result;
|
||||
string alternateFormat = "ddd MMM dd HH:mm:ss yyyy";
|
||||
if (value is not null && DateTime.TryParse(value, out DateTime dateTime))
|
||||
result = dateTime;
|
||||
else if (value is not null && value.Length == dateTimeFormat.Length && DateTime.TryParseExact(value, dateTimeFormat, CultureInfo.InvariantCulture, DateTimeStyles.None, out dateTime))
|
||||
result = dateTime;
|
||||
else if (value is not null && value.Length == alternateFormat.Length && DateTime.TryParseExact(value, alternateFormat, CultureInfo.InvariantCulture, DateTimeStyles.None, out dateTime))
|
||||
result = dateTime;
|
||||
else
|
||||
result = null;
|
||||
return result;
|
||||
}
|
||||
|
||||
internal static byte[] GetBytes(string value)
|
||||
{
|
||||
byte[] results = new byte[value.Length + 1];
|
||||
for (int i = 0; i < value.Length; i++)
|
||||
results[i] = (byte)value[i];
|
||||
results[value.Length] = 0x00;
|
||||
return results;
|
||||
}
|
||||
|
||||
}
|
@ -3,7 +3,7 @@ namespace View_by_Distance.Shared.Models.Stateless.Methods;
|
||||
internal abstract partial class XDirectory
|
||||
{
|
||||
|
||||
private record SortedRecord(int? Id, Models.FileHolder FileHolder);
|
||||
private record SortedRecord(Models.FileHolder FileHolder, bool NameWithoutExtensionIsIdFormat, int? Id);
|
||||
|
||||
private static int GetCeilingAverage(List<string[]> fileCollection)
|
||||
{
|
||||
@ -244,7 +244,7 @@ internal abstract partial class XDirectory
|
||||
else if (fromFileInfo.Length == toFileInfo.Length && fromFileInfo.LastWriteTime == toFileInfo.LastWriteTime)
|
||||
checkDirectory = string.Concat(checkDirectory, ".del");
|
||||
else
|
||||
checkDirectory = string.Concat(checkDirectory, ".i");
|
||||
checkDirectory = string.Concat(checkDirectory, ".j");
|
||||
}
|
||||
File.Move(from, checkDirectory);
|
||||
}
|
||||
@ -280,30 +280,35 @@ internal abstract partial class XDirectory
|
||||
}
|
||||
}
|
||||
|
||||
private static (bool, SortedRecord[]) GetSortedRecords(List<string[]> filesCollection)
|
||||
private static SortedRecord[] GetSortedRecords(List<string[]> filesCollection)
|
||||
{
|
||||
bool result = true;
|
||||
List<SortedRecord> results = new();
|
||||
int? id;
|
||||
short? multiplier;
|
||||
char negativeMarker;
|
||||
int absoluteValueOfId;
|
||||
Models.FileHolder fileHolder;
|
||||
int offset = IDirectory.GetOffset();
|
||||
int offsetLength = offset.ToString().Length;
|
||||
int sortOrderOnlyLengthIndex = offsetLength + 3;
|
||||
bool nameWithoutExtensionIsIdFormat;
|
||||
bool nameWithoutExtensionIsPaddedIdFormat;
|
||||
int sortOrderOnlyLengthIndex = IDirectory.GetSortOrderOnlyLengthIndex();
|
||||
foreach (string[] files in filesCollection)
|
||||
{
|
||||
foreach (string file in files)
|
||||
{
|
||||
fileHolder = new Models.FileHolder(file);
|
||||
if (!result)
|
||||
nameWithoutExtensionIsIdFormat = IProperty.NameWithoutExtensionIsIdFormat(fileHolder);
|
||||
nameWithoutExtensionIsPaddedIdFormat = IDirectory.NameWithoutExtensionIsPaddedIdFormat(fileHolder, sortOrderOnlyLengthIndex);
|
||||
if (nameWithoutExtensionIsIdFormat)
|
||||
{
|
||||
multiplier = null;
|
||||
if (!int.TryParse(fileHolder.NameWithoutExtension, out absoluteValueOfId))
|
||||
id = null;
|
||||
else
|
||||
id = absoluteValueOfId;
|
||||
}
|
||||
else if (!nameWithoutExtensionIsPaddedIdFormat)
|
||||
{
|
||||
if (fileHolder.NameWithoutExtension.Length < sortOrderOnlyLengthIndex)
|
||||
{
|
||||
result = false;
|
||||
id = null;
|
||||
multiplier = null;
|
||||
}
|
||||
else
|
||||
@ -314,45 +319,52 @@ internal abstract partial class XDirectory
|
||||
else if (negativeMarker == '3')
|
||||
multiplier = -1;
|
||||
else
|
||||
{
|
||||
result = false;
|
||||
multiplier = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!result)
|
||||
id = null;
|
||||
else if (!int.TryParse(fileHolder.NameWithoutExtension[sortOrderOnlyLengthIndex..], out absoluteValueOfId))
|
||||
if (!int.TryParse(fileHolder.NameWithoutExtension[sortOrderOnlyLengthIndex..], out absoluteValueOfId))
|
||||
id = null;
|
||||
else
|
||||
{
|
||||
id = absoluteValueOfId * multiplier;
|
||||
results.Add(new(id, fileHolder));
|
||||
if (id is null || !fileHolder.NameWithoutExtension.EndsWith(id.Value.ToString()[1..]))
|
||||
id = null;
|
||||
}
|
||||
}
|
||||
return new(result, (from l in results orderby l.FileHolder.LastWriteTime, l.FileHolder.FullName.Length descending select l).ToArray());
|
||||
results.Add(new(fileHolder, nameWithoutExtensionIsIdFormat, id));
|
||||
}
|
||||
}
|
||||
return (from l in results orderby l.FileHolder.CreationTime, l.FileHolder.FullName.Length descending select l).ToArray();
|
||||
}
|
||||
|
||||
internal static (string[], List<(Models.FileHolder, string)>) GetToDoCollection(Properties.IPropertyConfiguration propertyConfiguration, bool copyDuplicates, bool ifCanUseId, List<string[]> filesCollection, string[] directories, Action? tick)
|
||||
{
|
||||
List<(Models.FileHolder, string)> results = new();
|
||||
string paddedId;
|
||||
string checkFile;
|
||||
string directory;
|
||||
FileInfo fileInfo;
|
||||
int directoryIndex;
|
||||
string directoryName;
|
||||
string paddedIdFile;
|
||||
bool wrapped = false;
|
||||
string directoryName;
|
||||
bool paddedCheck = false;
|
||||
SortedRecord sortedRecord;
|
||||
Models.FileHolder fileHolder;
|
||||
List<int> distinctIds = new();
|
||||
List<string> distinct = new();
|
||||
int offset = IDirectory.GetOffset();
|
||||
List<string> distinctDirectories = new();
|
||||
(bool all, SortedRecord[] sortedRecords) = GetSortedRecords(filesCollection);
|
||||
foreach (SortedRecord sortedRecord in sortedRecords)
|
||||
int intMinValueLength = int.MinValue.ToString().Length;
|
||||
SortedRecord[] sortedRecords = GetSortedRecords(filesCollection);
|
||||
for (int i = 0; i < sortedRecords.Length; i++)
|
||||
{
|
||||
tick?.Invoke();
|
||||
if (sortedRecord.FileHolder.Name.EndsWith("len") || sortedRecord.FileHolder.ExtensionLowered == ".id" || sortedRecord.FileHolder.ExtensionLowered == ".lsv" || sortedRecord.FileHolder.DirectoryName is null)
|
||||
sortedRecord = sortedRecords[i];
|
||||
fileHolder = sortedRecord.FileHolder;
|
||||
if (fileHolder.Name.EndsWith("len") || fileHolder.ExtensionLowered == ".id" || fileHolder.ExtensionLowered == ".lsv" || fileHolder.DirectoryName is null)
|
||||
continue;
|
||||
(_, directoryIndex) = IPath.GetDirectoryNameAndIndex(propertyConfiguration.ResultAllInOneSubdirectoryLength, sortedRecord.FileHolder.NameWithoutExtension);
|
||||
directoryName = Path.GetFileName(sortedRecord.FileHolder.DirectoryName);
|
||||
if (directoryName.Length < propertyConfiguration.ResultAllInOneSubdirectoryLength + 3 || !sortedRecord.FileHolder.Name.StartsWith(directoryName))
|
||||
(_, directoryIndex) = IPath.GetDirectoryNameAndIndex(propertyConfiguration.ResultAllInOneSubdirectoryLength, fileHolder.NameWithoutExtension);
|
||||
directoryName = Path.GetFileName(fileHolder.DirectoryName);
|
||||
if (directoryName.Length < propertyConfiguration.ResultAllInOneSubdirectoryLength + 3 || !fileHolder.Name.StartsWith(directoryName))
|
||||
{
|
||||
if (wrapped)
|
||||
continue;
|
||||
@ -364,28 +376,35 @@ internal abstract partial class XDirectory
|
||||
wrapped = true;
|
||||
directory = Path.Combine(directories[directoryIndex], directoryName);
|
||||
}
|
||||
if (all)
|
||||
if (ifCanUseId && sortedRecord.NameWithoutExtensionIsIdFormat && sortedRecord.Id is not null && fileHolder.DirectoryName is not null)
|
||||
{
|
||||
if (sortedRecord.Id is null || !sortedRecord.FileHolder.NameWithoutExtension.EndsWith(sortedRecord.Id.Value.ToString()[1..]))
|
||||
throw new NotSupportedException();
|
||||
paddedId = IDirectory.GetPaddedId(intMinValueLength, offset + i, sortedRecord.Id.Value);
|
||||
paddedIdFile = Path.Combine(fileHolder.DirectoryName, $"{paddedId}{fileHolder.ExtensionLowered}");
|
||||
if (!File.Exists(paddedIdFile))
|
||||
{
|
||||
File.Move(fileHolder.FullName, paddedIdFile);
|
||||
fileHolder = new(paddedIdFile);
|
||||
if (!paddedCheck)
|
||||
paddedCheck = true;
|
||||
}
|
||||
if (all && ifCanUseId)
|
||||
checkFile = Path.Combine(directory, $"{sortedRecord.Id}{sortedRecord.FileHolder.ExtensionLowered}");
|
||||
}
|
||||
if (ifCanUseId)
|
||||
checkFile = Path.Combine(directory, $"{sortedRecord.Id}{fileHolder.ExtensionLowered}");
|
||||
else
|
||||
checkFile = Path.Combine(directory, $"{sortedRecord.FileHolder.NameWithoutExtension}{sortedRecord.FileHolder.ExtensionLowered}");
|
||||
checkFile = Path.Combine(directory, $"{fileHolder.NameWithoutExtension}{fileHolder.ExtensionLowered}");
|
||||
if ((sortedRecord.Id is not null && distinctIds.Contains(sortedRecord.Id.Value)) || distinct.Contains(checkFile))
|
||||
{
|
||||
if (string.IsNullOrEmpty(sortedRecord.FileHolder.DirectoryName))
|
||||
if (string.IsNullOrEmpty(fileHolder.DirectoryName))
|
||||
continue;
|
||||
if (!copyDuplicates)
|
||||
continue;
|
||||
for (int i = 1; i < int.MaxValue; i++)
|
||||
for (int j = 1; j < int.MaxValue; j++)
|
||||
{
|
||||
fileInfo = new(checkFile);
|
||||
if (!fileInfo.Exists || sortedRecord.FileHolder.Length == fileInfo.Length && sortedRecord.FileHolder.LastWriteTime == fileInfo.LastWriteTime)
|
||||
checkFile = Path.Combine(directory, $"{sortedRecord.FileHolder.NameWithoutExtension}.{i}dup{sortedRecord.FileHolder.ExtensionLowered}");
|
||||
if (!fileInfo.Exists || fileHolder.Length == fileInfo.Length && fileHolder.LastWriteTime == fileInfo.LastWriteTime)
|
||||
checkFile = Path.Combine(directory, $"{fileHolder.NameWithoutExtension}.{j}dup{fileHolder.ExtensionLowered}");
|
||||
else
|
||||
checkFile = Path.Combine(directory, $"{sortedRecord.FileHolder.NameWithoutExtension}.{i}why{sortedRecord.FileHolder.ExtensionLowered}");
|
||||
checkFile = Path.Combine(directory, $"{fileHolder.NameWithoutExtension}.{j}why{fileHolder.ExtensionLowered}");
|
||||
if (sortedRecord.Id is not null)
|
||||
{
|
||||
if (distinctIds.Contains(sortedRecord.Id.Value))
|
||||
@ -395,7 +414,7 @@ internal abstract partial class XDirectory
|
||||
if (distinct.Contains(checkFile))
|
||||
continue;
|
||||
distinct.Add(checkFile);
|
||||
results.Add(new(sortedRecord.FileHolder, checkFile));
|
||||
results.Add(new(fileHolder, checkFile));
|
||||
if (!distinctDirectories.Contains(directory))
|
||||
distinctDirectories.Add(directory);
|
||||
break;
|
||||
@ -405,10 +424,12 @@ internal abstract partial class XDirectory
|
||||
distinct.Add(checkFile);
|
||||
if (sortedRecord.Id is not null)
|
||||
distinctIds.Add(sortedRecord.Id.Value);
|
||||
results.Add(new(sortedRecord.FileHolder, checkFile));
|
||||
results.Add(new(fileHolder, checkFile));
|
||||
if (!distinctDirectories.Contains(directory))
|
||||
distinctDirectories.Add(directory);
|
||||
}
|
||||
if (paddedCheck)
|
||||
throw new Exception("Maybe need to restart application!");
|
||||
return (distinctDirectories.ToArray(), results);
|
||||
}
|
||||
|
||||
|
@ -143,6 +143,7 @@ public class UnitTestResize
|
||||
List<Tuple<string, DateTime>> subFileTuples = new();
|
||||
List<KeyValuePair<string, string>> metadataCollection;
|
||||
int length = _PropertyConfiguration.RootDirectory.Length;
|
||||
string[] changesFrom = new string[] { nameof(A_Property) };
|
||||
string outputResolution = _Configuration.OutputResolutions[0];
|
||||
bool outputResolutionHasNumber = outputResolution.Any(l => char.IsNumber(l));
|
||||
(string cResultsFullGroupDirectory, _, _) = GetResultsFullGroupDirectories(outputResolution);
|
||||
@ -170,7 +171,7 @@ public class UnitTestResize
|
||||
Assert.IsNotNull(item.ImageFileHolder);
|
||||
if (item.Property is null)
|
||||
{
|
||||
property = propertyLogic.GetProperty(item, subFileTuples, parseExceptions);
|
||||
property = propertyLogic.GetProperty(metadata, item, subFileTuples, parseExceptions);
|
||||
item.Update(property);
|
||||
}
|
||||
if (property is null || item.Property is null)
|
||||
@ -180,7 +181,7 @@ public class UnitTestResize
|
||||
_ = blurHasher.Encode(resizedFileHolder);
|
||||
item.SetResizedFileHolder(resize.FileNameExtension, resizedFileHolder);
|
||||
MappingFromItem mappingFromItem = IMappingFromItem.GetMappingFromItem(item);
|
||||
(int _, metadataCollection) = metadata.GetMetadataCollection(subFileTuples, parseExceptions, mappingFromItem);
|
||||
(int _, metadataCollection) = metadata.GetMetadataCollection(subFileTuples, parseExceptions, changesFrom, mappingFromItem);
|
||||
outputResolutionToResize = resize.GetResizeKeyValuePairs(_Configuration.PropertyConfiguration, cResultsFullGroupDirectory, subFileTuples, parseExceptions, metadataCollection, item.Property, mappingFromItem);
|
||||
Assert.IsNotNull(mappingFromItem.ResizedFileHolder);
|
||||
resize.SaveResizedSubfile(_Configuration.PropertyConfiguration, outputResolution, cResultsFullGroupDirectory, subFileTuples, item, item.Property, mappingFromItem, outputResolutionToResize);
|
||||
|
@ -217,6 +217,7 @@ public class UnitTestFace
|
||||
List<Tuple<string, DateTime>> subFileTuples = new();
|
||||
List<KeyValuePair<string, string>> metadataCollection;
|
||||
int length = _PropertyConfiguration.RootDirectory.Length;
|
||||
string[] changesFrom = new string[] { nameof(A_Property) };
|
||||
string outputResolution = _Configuration.OutputResolutions[0];
|
||||
bool outputResolutionHasNumber = outputResolution.Any(l => char.IsNumber(l));
|
||||
(string cResultsFullGroupDirectory, _, _) = GetResultsFullGroupDirectories(outputResolution);
|
||||
@ -244,7 +245,7 @@ public class UnitTestFace
|
||||
Assert.IsNotNull(item.ImageFileHolder);
|
||||
if (item.Property is null)
|
||||
{
|
||||
property = propertyLogic.GetProperty(item, subFileTuples, parseExceptions);
|
||||
property = propertyLogic.GetProperty(metadata, item, subFileTuples, parseExceptions);
|
||||
item.Update(property);
|
||||
}
|
||||
if (property is null || item.Property is null)
|
||||
@ -252,7 +253,7 @@ public class UnitTestFace
|
||||
resizedFileHolder = resize.GetResizedFileHolder(cResultsFullGroupDirectory, item, outputResolutionHasNumber);
|
||||
item.SetResizedFileHolder(resize.FileNameExtension, resizedFileHolder);
|
||||
MappingFromItem mappingFromItem = IMappingFromItem.GetMappingFromItem(item);
|
||||
(int _, metadataCollection) = metadata.GetMetadataCollection(subFileTuples, parseExceptions, mappingFromItem);
|
||||
(int _, metadataCollection) = metadata.GetMetadataCollection(subFileTuples, parseExceptions, changesFrom, mappingFromItem);
|
||||
outputResolutionToResize = resize.GetResizeKeyValuePairs(_Configuration.PropertyConfiguration, cResultsFullGroupDirectory, subFileTuples, parseExceptions, metadataCollection, item.Property, mappingFromItem);
|
||||
Assert.IsNotNull(mappingFromItem.ResizedFileHolder);
|
||||
resize.SaveResizedSubfile(_Configuration.PropertyConfiguration, outputResolution, cResultsFullGroupDirectory, subFileTuples, item, item.Property, mappingFromItem, outputResolutionToResize);
|
||||
|
Reference in New Issue
Block a user