xmp and json sidecar support

This commit is contained in:
2025-07-26 18:21:35 -07:00
parent 518af493a8
commit ebc1cf49f5
4 changed files with 60 additions and 27 deletions

View File

@ -1,5 +1,9 @@
using CliWrap; using CliWrap;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using Phares.Metadata.Models;
using Phares.Metadata.Models.Stateless;
using Phares.Shared.Models;
using Phares.Shared.Models.Stateless;
using ShellProgressBar; using ShellProgressBar;
using System.Collections.ObjectModel; using System.Collections.ObjectModel;
using System.Data; using System.Data;
@ -7,11 +11,7 @@ using System.Drawing;
using System.Drawing.Imaging; using System.Drawing.Imaging;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using System.Text.Json; using System.Text.Json;
using Phares.Metadata.Models;
using Phares.Metadata.Models.Stateless;
using View_by_Distance.Rename.Models; using View_by_Distance.Rename.Models;
using Phares.Shared.Models;
using Phares.Shared.Models.Stateless;
namespace View_by_Distance.Rename; namespace View_by_Distance.Rename;
@ -403,7 +403,7 @@ public partial class Rename : IRename, IDisposable
bool hasIgnoreKeyword = appSettings.MetadataSettings.IgnoreRulesKeyWords.Any(keywords.Contains); bool hasIgnoreKeyword = appSettings.MetadataSettings.IgnoreRulesKeyWords.Any(keywords.Contains);
string checkFileExtension = exifDirectory.FilePath.ExtensionLowered == jpeg ? jpg : exifDirectory.FilePath.ExtensionLowered; string checkFileExtension = exifDirectory.FilePath.ExtensionLowered == jpeg ? jpg : exifDirectory.FilePath.ExtensionLowered;
bool hasDateTimeOriginal = dateTime is not null; bool hasDateTimeOriginal = dateTime is not null;
string paddedId = IId.GetPaddedId(appSettings.ResultSettings, appSettings.MetadataSettings, exifDirectory.FilePath.Id.Value, exifDirectory.FilePath.ExtensionLowered, hasIgnoreKeyword, hasDateTimeOriginal, i); string paddedId = IId.GetPaddedId(appSettings.ResultSettings, appSettings.MetadataSettings, exifDirectory.FilePath, hasIgnoreKeyword, hasDateTimeOriginal, i);
string checkDirectory = appSettings.RenameSettings.InPlaceWithOriginalName ? Path.Combine(exifDirectory.FilePath.DirectoryFullPath, exifDirectory.FilePath.FileNameFirstSegment) : exifDirectory.FilePath.DirectoryFullPath; string checkDirectory = appSettings.RenameSettings.InPlaceWithOriginalName ? Path.Combine(exifDirectory.FilePath.DirectoryFullPath, exifDirectory.FilePath.FileNameFirstSegment) : exifDirectory.FilePath.DirectoryFullPath;
string checkFile = Path.Combine(checkDirectory, $"{paddedId}{checkFileExtension}"); string checkFile = Path.Combine(checkDirectory, $"{paddedId}{checkFileExtension}");
if (checkFile != exifDirectory.FilePath.FullName) if (checkFile != exifDirectory.FilePath.FullName)
@ -483,7 +483,7 @@ public partial class Rename : IRename, IDisposable
{ {
if (record.ExifDirectory.FilePath.Id is null) if (record.ExifDirectory.FilePath.Id is null)
continue; continue;
paddedId = IId.GetPaddedId(appSettings.ResultSettings, appSettings.MetadataSettings, record.ExifDirectory.FilePath.Id.Value, record.ExifDirectory.FilePath.ExtensionLowered, record.HasIgnoreKeyword, record.HasDateTimeOriginal, index: null); paddedId = IId.GetPaddedId(appSettings.ResultSettings, appSettings.MetadataSettings, record.ExifDirectory.FilePath, record.HasIgnoreKeyword, record.HasDateTimeOriginal, index: null);
identifier = new([], record.HasDateTimeOriginal, record.ExifDirectory.FilePath.Id.Value, record.ExifDirectory.FilePath.Length, paddedId, record.DateTime.Ticks); identifier = new([], record.HasDateTimeOriginal, record.ExifDirectory.FilePath.Id.Value, record.ExifDirectory.FilePath.Length, paddedId, record.DateTime.Ticks);
identifiers.Add(identifier); identifiers.Add(identifier);
} }
@ -523,7 +523,7 @@ public partial class Rename : IRename, IDisposable
record = sorted[i]; record = sorted[i];
if (record.ExifDirectory.FilePath.Id is null) if (record.ExifDirectory.FilePath.Id is null)
continue; continue;
paddedId = IId.GetPaddedId(appSettings.ResultSettings, appSettings.MetadataSettings, record.ExifDirectory.FilePath.Id.Value, record.ExifDirectory.FilePath.ExtensionLowered, record.HasIgnoreKeyword, record.HasDateTimeOriginal, i); paddedId = IId.GetPaddedId(appSettings.ResultSettings, appSettings.MetadataSettings, record.ExifDirectory.FilePath, record.HasIgnoreKeyword, record.HasDateTimeOriginal, i);
checkDirectory = GetCheckDirectory(appSettings, directoryInfo, record, ids, multipleDirectoriesWithFiles, paddedId); checkDirectory = GetCheckDirectory(appSettings, directoryInfo, record, ids, multipleDirectoriesWithFiles, paddedId);
if (string.IsNullOrEmpty(checkDirectory)) if (string.IsNullOrEmpty(checkDirectory))
continue; continue;

View File

@ -29,16 +29,19 @@ public interface IId
public static bool NameWithoutExtensionIsIntelligentIdFormat(MetadataSettings metadataSettings, string fileNameFirstSegment) => public static bool NameWithoutExtensionIsIntelligentIdFormat(MetadataSettings metadataSettings, string fileNameFirstSegment) =>
fileNameFirstSegment.Length - 1 == metadataSettings.IntMinValueLength && fileNameFirstSegment[^1] is '0' or '1' or '2' or '3' or '4' or '5' or '6' or '7' or '8' or '9' && fileNameFirstSegment.All(char.IsNumber); fileNameFirstSegment.Length - 1 == metadataSettings.IntMinValueLength && fileNameFirstSegment[^1] is '0' or '1' or '2' or '3' or '4' or '5' or '6' or '7' or '8' or '9' && fileNameFirstSegment.All(char.IsNumber);
public static string GetPaddedId(ResultSettings resultSettings, MetadataSettings metadataSettings, FilePath filePath, int? index) =>
Id.GetPaddedId(resultSettings, metadataSettings, filePath, index);
public static bool NameWithoutExtensionIsPaddedIntelligentIdFormat(MetadataSettings metadataSettings, int sortOrderOnlyLengthIndex, string fileNameFirstSegment) => public static bool NameWithoutExtensionIsPaddedIntelligentIdFormat(MetadataSettings metadataSettings, int sortOrderOnlyLengthIndex, string fileNameFirstSegment) =>
fileNameFirstSegment.Length == metadataSettings.IntMinValueLength + sortOrderOnlyLengthIndex + 1 fileNameFirstSegment.Length == metadataSettings.IntMinValueLength + sortOrderOnlyLengthIndex + 1
&& fileNameFirstSegment[^1] is '0' or '1' or '2' or '3' or '4' or '5' or '6' or '7' or '8' or '9' && fileNameFirstSegment[^1] is '0' or '1' or '2' or '3' or '4' or '5' or '6' or '7' or '8' or '9'
&& fileNameFirstSegment.All(char.IsNumber); && fileNameFirstSegment.All(char.IsNumber);
public static string GetIntelligentId(ResultSettings resultSettings, MetadataSettings metadataSettings, long id, string extensionLowered, bool? hasIgnoreKeyword, bool? hasDateTimeOriginal) => public static string GetPaddedId(ResultSettings resultSettings, MetadataSettings metadataSettings, FilePath filePath, bool? hasIgnoreKeyword, bool? hasDateTimeOriginal, int? index) =>
Id.GetIntelligentId(resultSettings, metadataSettings, id, extensionLowered, hasIgnoreKeyword, hasDateTimeOriginal); filePath.Id is null ? throw new Exception() : GetPaddedId(resultSettings, metadataSettings, filePath.Id.Value, filePath.NameWithoutExtension, filePath.ExtensionLowered, hasIgnoreKeyword, hasDateTimeOriginal, index);
public static string GetPaddedId(ResultSettings resultSettings, MetadataSettings metadataSettings, int id, string extensionLowered, bool? hasIgnoreKeyword, bool? hasDateTimeOriginal, int? index) => public static string GetPaddedId(ResultSettings resultSettings, MetadataSettings metadataSettings, int id, string nameWithoutExtension, string extensionLowered, bool? hasIgnoreKeyword, bool? hasDateTimeOriginal, int? index) =>
Id.GetPaddedId(resultSettings, metadataSettings, id, extensionLowered, hasIgnoreKeyword, hasDateTimeOriginal, index); Id.GetPaddedId(resultSettings, metadataSettings, id, nameWithoutExtension, extensionLowered, hasIgnoreKeyword, hasDateTimeOriginal, index);
internal int TestStatic_GetDeterministicHashCode(byte[] value) => internal int TestStatic_GetDeterministicHashCode(byte[] value) =>
GetDeterministicHashCode(value); GetDeterministicHashCode(value);
@ -61,13 +64,16 @@ public interface IId
internal bool TestStatic_NameWithoutExtensionIsIntelligentIdFormat(MetadataSettings metadataSettings, string fileNameFirstSegment) => internal bool TestStatic_NameWithoutExtensionIsIntelligentIdFormat(MetadataSettings metadataSettings, string fileNameFirstSegment) =>
NameWithoutExtensionIsIntelligentIdFormat(metadataSettings, fileNameFirstSegment); NameWithoutExtensionIsIntelligentIdFormat(metadataSettings, fileNameFirstSegment);
internal string TestStatic_GetPaddedId(ResultSettings resultSettings, MetadataSettings metadataSettings, FilePath filePath, int? index) =>
GetPaddedId(resultSettings, metadataSettings, filePath, index);
internal bool TestStatic_NameWithoutExtensionIsPaddedIntelligentIdFormat(MetadataSettings metadataSettings, int sortOrderOnlyLengthIndex, string fileNameFirstSegment) => internal bool TestStatic_NameWithoutExtensionIsPaddedIntelligentIdFormat(MetadataSettings metadataSettings, int sortOrderOnlyLengthIndex, string fileNameFirstSegment) =>
NameWithoutExtensionIsPaddedIntelligentIdFormat(metadataSettings, sortOrderOnlyLengthIndex, fileNameFirstSegment); NameWithoutExtensionIsPaddedIntelligentIdFormat(metadataSettings, sortOrderOnlyLengthIndex, fileNameFirstSegment);
internal string TestStatic_GetIntelligentId(ResultSettings resultSettings, MetadataSettings metadataSettings, string extensionLowered, long id, bool? hasIgnoreKeyword, bool? hasDateTimeOriginal) => internal string TestStatic_GetPaddedId(ResultSettings resultSettings, MetadataSettings metadataSettings, FilePath filePath, bool? hasIgnoreKeyword, bool? hasDateTimeOriginal, int? index) =>
GetIntelligentId(resultSettings, metadataSettings, id, extensionLowered, hasIgnoreKeyword, hasDateTimeOriginal); GetPaddedId(resultSettings, metadataSettings, filePath, hasIgnoreKeyword, hasDateTimeOriginal, index);
internal string TestStatic_GetPaddedId(ResultSettings resultSettings, MetadataSettings metadataSettings, int id, string extensionLowered, bool? hasIgnoreKeyword, bool? hasDateTimeOriginal, int? index) => internal string TestStatic_GetPaddedId(ResultSettings resultSettings, MetadataSettings metadataSettings, int id, string nameWithoutExtension, string extensionLowered, bool? hasIgnoreKeyword, bool? hasDateTimeOriginal, int? index) =>
GetPaddedId(resultSettings, metadataSettings, id, extensionLowered, hasIgnoreKeyword, hasDateTimeOriginal, index); GetPaddedId(resultSettings, metadataSettings, id, nameWithoutExtension, extensionLowered, hasIgnoreKeyword, hasDateTimeOriginal, index);
} }

View File

@ -30,8 +30,14 @@ internal abstract class Id
internal static byte GetHasDateTimeOriginal(ResultSettings resultSettings, FilePath filePath) => internal static byte GetHasDateTimeOriginal(ResultSettings resultSettings, FilePath filePath) =>
(byte)(IsIgnoreOrValidVideoFormatExtension(resultSettings, filePath) ? filePath.Id > -1 ? 6 : 4 : filePath.Id > -1 ? 9 : 1); (byte)(IsIgnoreOrValidVideoFormatExtension(resultSettings, filePath) ? filePath.Id > -1 ? 6 : 4 : filePath.Id > -1 ? 9 : 1);
private static string GetExtension(string nameWithoutExtension, string extensionLowered) =>
extensionLowered is not ".xmp" and not ".json" ? extensionLowered : Path.GetExtension(nameWithoutExtension);
private static string GetExtension(FilePath filePath) =>
GetExtension(filePath.NameWithoutExtension, filePath.ExtensionLowered);
private static bool IsIgnoreOrValidVideoFormatExtension(ResultSettings resultSettings, FilePath filePath) => private static bool IsIgnoreOrValidVideoFormatExtension(ResultSettings resultSettings, FilePath filePath) =>
IsIgnoreOrValidVideoFormatExtension(resultSettings, filePath.ExtensionLowered); IsIgnoreOrValidVideoFormatExtension(resultSettings, GetExtension(filePath));
private static bool IsIgnoreOrValidVideoFormatExtension(ResultSettings resultSettings, string extensionLowered) => private static bool IsIgnoreOrValidVideoFormatExtension(ResultSettings resultSettings, string extensionLowered) =>
resultSettings.IgnoreExtensions.Contains(extensionLowered) resultSettings.IgnoreExtensions.Contains(extensionLowered)
@ -70,9 +76,7 @@ internal abstract class Id
return result; return result;
} }
#pragma warning disable IDE0060 private static string GetIntelligentId(ResultSettings resultSettings, MetadataSettings metadataSettings, long id, string nameWithoutExtension, string extensionLowered, bool? hasIgnoreKeyword, bool? hasDateTimeOriginal)
internal static string GetIntelligentId(ResultSettings resultSettings, MetadataSettings metadataSettings, long id, string extensionLowered, bool? hasIgnoreKeyword, bool? hasDateTimeOriginal)
#pragma warning restore IDE0060
{ {
string result; string result;
StringBuilder stringBuilder = new(); StringBuilder stringBuilder = new();
@ -88,7 +92,8 @@ internal abstract class Id
} }
else if (id > -1) else if (id > -1)
{ {
if (IsIgnoreOrValidVideoFormatExtension(resultSettings, extensionLowered)) string checkExtension = GetExtension(nameWithoutExtension, extensionLowered);
if (IsIgnoreOrValidVideoFormatExtension(resultSettings, checkExtension))
key = hasIgnoreKeyword is not null && hasIgnoreKeyword.Value ? throw new NotImplementedException() : hasDateTimeOriginal.Value ? 6 : 5; key = hasIgnoreKeyword is not null && hasIgnoreKeyword.Value ? throw new NotImplementedException() : hasDateTimeOriginal.Value ? 6 : 5;
else else
key = hasIgnoreKeyword is not null && hasIgnoreKeyword.Value ? 8 : hasDateTimeOriginal.Value ? 9 : 7; key = hasIgnoreKeyword is not null && hasIgnoreKeyword.Value ? 8 : hasDateTimeOriginal.Value ? 9 : 7;
@ -96,7 +101,8 @@ internal abstract class Id
} }
else else
{ {
if (IsIgnoreOrValidVideoFormatExtension(resultSettings, extensionLowered)) string checkExtension = GetExtension(nameWithoutExtension, extensionLowered);
if (IsIgnoreOrValidVideoFormatExtension(resultSettings, checkExtension))
key = hasIgnoreKeyword is not null && hasIgnoreKeyword.Value ? throw new NotImplementedException() : hasDateTimeOriginal.Value ? 4 : 0; key = hasIgnoreKeyword is not null && hasIgnoreKeyword.Value ? throw new NotImplementedException() : hasDateTimeOriginal.Value ? 4 : 0;
else else
key = hasIgnoreKeyword is not null && hasIgnoreKeyword.Value ? 2 : hasDateTimeOriginal.Value ? 1 : 3; key = hasIgnoreKeyword is not null && hasIgnoreKeyword.Value ? 2 : hasDateTimeOriginal.Value ? 1 : 3;
@ -110,14 +116,17 @@ internal abstract class Id
return result; return result;
} }
internal static string GetPaddedId(ResultSettings resultSettings, MetadataSettings metadataSettings, int id, string extensionLowered, bool? hasIgnoreKeyword, bool? hasDateTimeOriginal, int? index) private static string GetIntelligentId(ResultSettings resultSettings, MetadataSettings metadataSettings, FilePath filePath) =>
filePath.Id is null ? throw new Exception() : GetIntelligentId(resultSettings, metadataSettings, filePath.Id.Value, filePath.NameWithoutExtension, filePath.ExtensionLowered, filePath.HasIgnoreKeyword, filePath.HasDateTimeOriginal);
internal static string GetPaddedId(ResultSettings resultSettings, MetadataSettings metadataSettings, int id, string nameWithoutExtension, string extensionLowered, bool? hasIgnoreKeyword, bool? hasDateTimeOriginal, int? index)
{ {
string result; string result;
if (metadataSettings.Offset < 0) if (metadataSettings.Offset < 0)
result = Guid.NewGuid().ToString(); result = Guid.NewGuid().ToString();
else else
{ {
string intelligentId = GetIntelligentId(resultSettings, metadataSettings, id, extensionLowered, hasIgnoreKeyword, hasDateTimeOriginal); string intelligentId = GetIntelligentId(resultSettings, metadataSettings, id, nameWithoutExtension, extensionLowered, hasIgnoreKeyword, hasDateTimeOriginal);
int check = GetId(resultSettings, metadataSettings, intelligentId); int check = GetId(resultSettings, metadataSettings, intelligentId);
if (check != id) if (check != id)
throw new NotSupportedException(); throw new NotSupportedException();
@ -126,4 +135,20 @@ internal abstract class Id
return result; return result;
} }
internal static string GetPaddedId(ResultSettings resultSettings, MetadataSettings metadataSettings, FilePath filePath, int? index)
{
string result;
if (metadataSettings.Offset < 0)
result = Guid.NewGuid().ToString();
else
{
string intelligentId = GetIntelligentId(resultSettings, metadataSettings, filePath);
int check = GetId(resultSettings, metadataSettings, intelligentId);
if (filePath.Id is not null && check != filePath.Id.Value)
throw new NotSupportedException();
result = index is null || metadataSettings.Offset == IId.DeterministicHashCode ? intelligentId : $"{metadataSettings.Offset + index}{intelligentId}";
}
return result;
}
} }

View File

@ -1,15 +1,15 @@
using CliWrap; using CliWrap;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using Phares.Metadata.Models;
using Phares.Metadata.Models.Stateless;
using Phares.Shared.Models;
using Phares.Shared.Models.Stateless;
using ShellProgressBar; using ShellProgressBar;
using System.Collections.ObjectModel; using System.Collections.ObjectModel;
using System.Drawing; using System.Drawing;
using System.Drawing.Imaging; using System.Drawing.Imaging;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using System.Text.Json; using System.Text.Json;
using Phares.Metadata.Models;
using Phares.Metadata.Models.Stateless;
using Phares.Shared.Models;
using Phares.Shared.Models.Stateless;
using View_by_Distance.Windows.Models; using View_by_Distance.Windows.Models;
namespace View_by_Distance.Windows; namespace View_by_Distance.Windows;
@ -268,9 +268,11 @@ public partial class Windows : IWindows, IDisposable
messages.Add($"{nginxFileSystem.URI.OriginalString}"); messages.Add($"{nginxFileSystem.URI.OriginalString}");
return; return;
} }
string nameWithoutExtension = Path.GetFileNameWithoutExtension(nginxFileSystem.Name);
string paddedId = IId.GetPaddedId(resultSettings: appSettings.ResultSettings, string paddedId = IId.GetPaddedId(resultSettings: appSettings.ResultSettings,
metadataSettings: appSettings.MetadataSettings, metadataSettings: appSettings.MetadataSettings,
id: deterministicHashCode.Id.Value, id: deterministicHashCode.Id.Value,
nameWithoutExtension: nameWithoutExtension,
extensionLowered: appSettings.ResultSettings.ValidImageFormatExtensions[0], extensionLowered: appSettings.ResultSettings.ValidImageFormatExtensions[0],
hasIgnoreKeyword: null, hasIgnoreKeyword: null,
hasDateTimeOriginal: null, hasDateTimeOriginal: null,