#990 renaming: processor for hash (md5/sha1/sha256)

This commit is contained in:
Thibault Deckers 2024-04-22 22:43:21 +02:00
parent 949f9a514f
commit 65e224ef57
12 changed files with 204 additions and 41 deletions

View file

@ -7,6 +7,7 @@ All notable changes to this project will be documented in this file.
### Added ### Added
- Cataloguing: identify Apple variant of HDR images - Cataloguing: identify Apple variant of HDR images
- Collection: allow using hash (md5/sha1/sha256) when bulk renaming
- option to force using western arabic numerals for dates - option to force using western arabic numerals for dates
### Changed ### Changed

View file

@ -85,6 +85,7 @@ import deckers.thibault.aves.metadata.xmp.XMP.isMotionPhoto
import deckers.thibault.aves.metadata.xmp.XMP.isPanorama import deckers.thibault.aves.metadata.xmp.XMP.isPanorama
import deckers.thibault.aves.model.FieldMap import deckers.thibault.aves.model.FieldMap
import deckers.thibault.aves.utils.ContextUtils.queryContentPropValue import deckers.thibault.aves.utils.ContextUtils.queryContentPropValue
import deckers.thibault.aves.utils.HashUtils
import deckers.thibault.aves.utils.LogUtils import deckers.thibault.aves.utils.LogUtils
import deckers.thibault.aves.utils.MimeTypes import deckers.thibault.aves.utils.MimeTypes
import deckers.thibault.aves.utils.MimeTypes.TIFF_EXTENSION_PATTERN import deckers.thibault.aves.utils.MimeTypes.TIFF_EXTENSION_PATTERN
@ -104,6 +105,7 @@ import org.json.JSONObject
import java.nio.charset.StandardCharsets import java.nio.charset.StandardCharsets
import java.text.DecimalFormat import java.text.DecimalFormat
import java.text.ParseException import java.text.ParseException
import java.util.Locale
import kotlin.math.roundToInt import kotlin.math.roundToInt
import kotlin.math.roundToLong import kotlin.math.roundToLong
@ -1307,10 +1309,36 @@ class MetadataFetchHandler(private val context: Context) : MethodCallHandler {
return return
} }
val metadataMap = HashMap<String, Any>() val metadataMap = HashMap<String, Any?>()
val hashFields = fields.filter { it.startsWith(HASH_FIELD_PREFIX) }.toSet()
metadataMap.putAll(getHashFields(uri, mimeType, sizeBytes, hashFields))
val exifFields = fields.filterNot { hashFields.contains(it) }.toSet()
metadataMap.putAll(getExifFields(uri, mimeType, sizeBytes, exifFields))
result.success(metadataMap)
}
private fun getHashFields(uri: Uri, mimeType: String, sizeBytes: Long?, fields: Set<String>): FieldMap {
val metadataMap = HashMap<String, Any?>()
fields.forEach { field ->
val function = field.substringAfter(HASH_FIELD_PREFIX).lowercase(Locale.ROOT)
try {
Metadata.openSafeInputStream(context, uri, mimeType, sizeBytes)?.use { input ->
metadataMap[field] = HashUtils.getHash(input, function)
}
} catch (e: Exception) {
Log.w(LOG_TAG, "failed to get hash for mimeType=$mimeType uri=$uri function=$function", e)
}
}
return metadataMap
}
private fun getExifFields(uri: Uri, mimeType: String, sizeBytes: Long?, fields: Set<String>): FieldMap {
val metadataMap = HashMap<String, Any?>()
if (fields.isEmpty() || isVideo(mimeType)) { if (fields.isEmpty() || isVideo(mimeType)) {
result.success(metadataMap) return metadataMap
return
} }
var foundExif = false var foundExif = false
@ -1359,7 +1387,7 @@ class MetadataFetchHandler(private val context: Context) : MethodCallHandler {
} }
} }
result.success(metadataMap) return metadataMap
} }
companion object { companion object {
@ -1434,6 +1462,7 @@ class MetadataFetchHandler(private val context: Context) : MethodCallHandler {
// additional media key // additional media key
private const val KEY_HAS_EMBEDDED_PICTURE = "Has Embedded Picture" private const val KEY_HAS_EMBEDDED_PICTURE = "Has Embedded Picture"
private const val HASH_FIELD_PREFIX = "hash"
private const val VALUE_SKIPPED_DATA = "[skipped]" private const val VALUE_SKIPPED_DATA = "[skipped]"
} }
} }

View file

@ -0,0 +1,35 @@
package deckers.thibault.aves.utils
import java.io.InputStream
import java.math.BigInteger
import java.security.MessageDigest
object HashUtils {
fun getHash(input: InputStream, algorithmKey: String): String {
val algorithm = toMessageDigestAlgorithm(algorithmKey)
val digest = MessageDigest.getInstance(algorithm)
val buffer = ByteArray(1 shl 14)
var read: Int
while ((input.read(buffer).also { read = it }) > 0) {
digest.update(buffer, 0, read)
}
val md5sum = digest.digest()
val output = BigInteger(1, md5sum).toString(16)
return when (algorithm) {
"MD5" -> output.padStart(32, '0') // 128 bits = 32 hex digits
"SHA-1" -> output.padStart(40, '0') // 160 bits = 40 hex digits
"SHA-256" -> output.padStart(64, '0') // 256 bits = 64 hex digits
else -> throw IllegalArgumentException("unsupported hash algorithm: $algorithmKey")
}
}
private fun toMessageDigestAlgorithm(algorithmKey: String): String {
return when (algorithmKey) {
"md5" -> "MD5"
"sha1" -> "SHA-1"
"sha256" -> "SHA-256"
else -> throw IllegalArgumentException("unsupported hash algorithm: $algorithmKey")
}
}
}

View file

@ -53,23 +53,30 @@ extension ExtraMetadataFieldConvert on MetadataField {
return MetadataType.mp4; return MetadataType.mp4;
case MetadataField.xmpXmpCreateDate: case MetadataField.xmpXmpCreateDate:
return MetadataType.xmp; return MetadataType.xmp;
case MetadataField.hashMd5:
case MetadataField.hashSha1:
case MetadataField.hashSha256:
return MetadataType.file;
} }
} }
String? get toPlatform { String? get toPlatform {
if (type == MetadataType.exif) { switch (type) {
return _toExifInterfaceTag(); case MetadataType.exif:
} else { return _toExifInterfaceTag();
switch (this) { case MetadataType.file:
case MetadataField.mp4GpsCoordinates: return name;
return 'gpsCoordinates'; default:
case MetadataField.mp4RotationDegrees: switch (this) {
return 'rotationDegrees'; case MetadataField.mp4GpsCoordinates:
case MetadataField.mp4Xmp: return 'gpsCoordinates';
return 'xmp'; case MetadataField.mp4RotationDegrees:
default: return 'rotationDegrees';
return null; case MetadataField.mp4Xmp:
} return 'xmp';
default:
return null;
}
} }
} }

View file

@ -23,6 +23,8 @@ extension ExtraMetadataTypeConvert on MetadataType {
return 'photoshop_irb'; return 'photoshop_irb';
case MetadataType.xmp: case MetadataType.xmp:
return 'xmp'; return 'xmp';
case MetadataType.file:
return 'file';
} }
} }
} }

View file

@ -440,6 +440,7 @@
"renameEntrySetPagePreviewSectionTitle": "Preview", "renameEntrySetPagePreviewSectionTitle": "Preview",
"renameProcessorCounter": "Counter", "renameProcessorCounter": "Counter",
"renameProcessorHash": "Hash",
"renameProcessorName": "Name", "renameProcessorName": "Name",
"deleteSingleAlbumConfirmationDialogMessage": "{count, plural, =1{Delete this album and the item in it?} other{Delete this album and the {count} items in it?}}", "deleteSingleAlbumConfirmationDialogMessage": "{count, plural, =1{Delete this album and the item in it?} other{Delete this album and the {count} items in it?}}",

View file

@ -39,18 +39,6 @@ class NamingPattern {
final processorKey = match.group(1); final processorKey = match.group(1);
final processorOptions = match.group(3); final processorOptions = match.group(3);
switch (processorKey) { switch (processorKey) {
case DateNamingProcessor.key:
if (processorOptions != null) {
processors.add(DateNamingProcessor(processorOptions.trim(), locale));
}
case TagsNamingProcessor.key:
processors.add(TagsNamingProcessor(processorOptions?.trim() ?? ''));
case MetadataFieldNamingProcessor.key:
if (processorOptions != null) {
processors.add(MetadataFieldNamingProcessor(processorOptions.trim()));
}
case NameNamingProcessor.key:
processors.add(const NameNamingProcessor());
case CounterNamingProcessor.key: case CounterNamingProcessor.key:
int? start, padding; int? start, padding;
_applyProcessorOptions(processorOptions, (key, value) { _applyProcessorOptions(processorOptions, (key, value) {
@ -65,6 +53,22 @@ class NamingPattern {
} }
}); });
processors.add(CounterNamingProcessor(start: start ?? defaultCounterStart, padding: padding ?? defaultCounterPadding)); processors.add(CounterNamingProcessor(start: start ?? defaultCounterStart, padding: padding ?? defaultCounterPadding));
case DateNamingProcessor.key:
if (processorOptions != null) {
processors.add(DateNamingProcessor(processorOptions.trim(), locale));
}
case HashNamingProcessor.key:
if (processorOptions != null) {
processors.add(HashNamingProcessor(processorOptions.trim()));
}
case MetadataFieldNamingProcessor.key:
if (processorOptions != null) {
processors.add(MetadataFieldNamingProcessor(processorOptions.trim()));
}
case NameNamingProcessor.key:
processors.add(const NameNamingProcessor());
case TagsNamingProcessor.key:
processors.add(TagsNamingProcessor(processorOptions?.trim() ?? ''));
default: default:
debugPrint('unsupported naming processor: ${match.group(0)}'); debugPrint('unsupported naming processor: ${match.group(0)}');
} }
@ -106,6 +110,8 @@ class NamingPattern {
switch (processorKey) { switch (processorKey) {
case DateNamingProcessor.key: case DateNamingProcessor.key:
return '<$processorKey, yyyyMMdd-HHmmss>'; return '<$processorKey, yyyyMMdd-HHmmss>';
case HashNamingProcessor.key:
return '<$processorKey, md5>';
case TagsNamingProcessor.key: case TagsNamingProcessor.key:
return '<$processorKey, ->'; return '<$processorKey, ->';
case CounterNamingProcessor.key: case CounterNamingProcessor.key:
@ -204,9 +210,7 @@ class MetadataFieldNamingProcessor extends NamingProcessor {
} }
@override @override
Set<MetadataField> getRequiredFields() { Set<MetadataField> getRequiredFields() => {field}.whereNotNull().toSet();
return {field}.whereNotNull().toSet();
}
@override @override
String? process(AvesEntry entry, int index, Map<String, dynamic> fieldValues) { String? process(AvesEntry entry, int index, Map<String, dynamic> fieldValues) {
@ -247,3 +251,27 @@ class CounterNamingProcessor extends NamingProcessor {
@override @override
String? process(AvesEntry entry, int index, Map<String, dynamic> fieldValues) => '${index + start}'.padLeft(padding, '0'); String? process(AvesEntry entry, int index, Map<String, dynamic> fieldValues) => '${index + start}'.padLeft(padding, '0');
} }
@immutable
class HashNamingProcessor extends NamingProcessor {
static const key = 'hash';
static const optionFunction = 'function';
late final MetadataField? function;
@override
List<Object?> get props => [function];
HashNamingProcessor(String function) {
final lowerField = 'hash${function.toLowerCase()}';
this.function = MetadataField.values.firstWhereOrNull((v) => v.name.toLowerCase() == lowerField);
}
@override
Set<MetadataField> getRequiredFields() => {function}.whereNotNull().toSet();
@override
String? process(AvesEntry entry, int index, Map<String, dynamic> fieldValues) {
return fieldValues[function?.toPlatform]?.toString();
}
}

View file

@ -14,6 +14,7 @@ extension ExtraMetadataTypeView on MetadataType {
MetadataType.mp4 => 'MP4', MetadataType.mp4 => 'MP4',
MetadataType.photoshopIrb => 'Photoshop', MetadataType.photoshopIrb => 'Photoshop',
MetadataType.xmp => 'XMP', MetadataType.xmp => 'XMP',
MetadataType.file => 'File',
}; };
} }
} }

View file

@ -119,14 +119,19 @@ class _RenameEntrySetPageState extends State<RenameEntrySetPage> {
icon: AIcons.more, icon: AIcons.more,
title: MaterialLocalizations.of(context).moreButtonTooltip, title: MaterialLocalizations.of(context).moreButtonTooltip,
items: [ items: [
MetadataField.exifMake, ...[
MetadataField.exifModel, MetadataField.exifMake,
] MetadataField.exifModel,
.map((field) => PopupMenuItem( ]
value: MetadataFieldNamingProcessor.keyWithField(field), .map((field) => PopupMenuItem(
child: MenuRow(text: field.title), value: MetadataFieldNamingProcessor.keyWithField(field),
)) child: MenuRow(text: field.title),
.toList(), )),
PopupMenuItem(
value: HashNamingProcessor.key,
child: MenuRow(text: l10n.renameProcessorHash),
)
],
), ),
]; ];
}, },

View file

@ -45,6 +45,8 @@ enum MetadataType {
photoshopIrb, photoshopIrb,
// XMP: https://en.wikipedia.org/wiki/Extensible_Metadata_Platform // XMP: https://en.wikipedia.org/wiki/Extensible_Metadata_Platform
xmp, xmp,
// others (hash, etc.)
file,
} }
class MetadataTypes { class MetadataTypes {

View file

@ -7,6 +7,7 @@ enum MetadataSyntheticField {
} }
enum MetadataField { enum MetadataField {
// exif
exifDate, exifDate,
exifDateOriginal, exifDateOriginal,
exifDateDigitized, exifDateDigitized,
@ -46,10 +47,16 @@ enum MetadataField {
exifMake, exifMake,
exifModel, exifModel,
exifUserComment, exifUserComment,
// mp4
mp4GpsCoordinates, mp4GpsCoordinates,
mp4RotationDegrees, mp4RotationDegrees,
mp4Xmp, mp4Xmp,
// xmp
xmpXmpCreateDate, xmpXmpCreateDate,
// file
hashMd5,
hashSha1,
hashSha256,
} }
class MetadataFields { class MetadataFields {

View file

@ -1,9 +1,11 @@
{ {
"ar": [ "ar": [
"renameProcessorHash",
"settingsForceWesternArabicNumeralsTile" "settingsForceWesternArabicNumeralsTile"
], ],
"be": [ "be": [
"renameProcessorHash",
"settingsForceWesternArabicNumeralsTile" "settingsForceWesternArabicNumeralsTile"
], ],
@ -241,6 +243,7 @@
"renameEntrySetPageInsertTooltip", "renameEntrySetPageInsertTooltip",
"renameEntrySetPagePreviewSectionTitle", "renameEntrySetPagePreviewSectionTitle",
"renameProcessorCounter", "renameProcessorCounter",
"renameProcessorHash",
"renameProcessorName", "renameProcessorName",
"deleteSingleAlbumConfirmationDialogMessage", "deleteSingleAlbumConfirmationDialogMessage",
"deleteMultiAlbumConfirmationDialogMessage", "deleteMultiAlbumConfirmationDialogMessage",
@ -677,6 +680,7 @@
"videoActionABRepeat", "videoActionABRepeat",
"videoRepeatActionSetStart", "videoRepeatActionSetStart",
"videoRepeatActionSetEnd", "videoRepeatActionSetEnd",
"renameProcessorHash",
"settingsForceWesternArabicNumeralsTile" "settingsForceWesternArabicNumeralsTile"
], ],
@ -793,6 +797,7 @@
"renameEntrySetPageInsertTooltip", "renameEntrySetPageInsertTooltip",
"renameEntrySetPagePreviewSectionTitle", "renameEntrySetPagePreviewSectionTitle",
"renameProcessorCounter", "renameProcessorCounter",
"renameProcessorHash",
"renameProcessorName", "renameProcessorName",
"deleteSingleAlbumConfirmationDialogMessage", "deleteSingleAlbumConfirmationDialogMessage",
"deleteMultiAlbumConfirmationDialogMessage", "deleteMultiAlbumConfirmationDialogMessage",
@ -1229,6 +1234,7 @@
"videoActionABRepeat", "videoActionABRepeat",
"videoRepeatActionSetStart", "videoRepeatActionSetStart",
"videoRepeatActionSetEnd", "videoRepeatActionSetEnd",
"renameProcessorHash",
"collectionActionSetHome", "collectionActionSetHome",
"setHomeCustomCollection", "setHomeCustomCollection",
"settingsThumbnailShowHdrIcon", "settingsThumbnailShowHdrIcon",
@ -1494,6 +1500,7 @@
"renameEntrySetPageInsertTooltip", "renameEntrySetPageInsertTooltip",
"renameEntrySetPagePreviewSectionTitle", "renameEntrySetPagePreviewSectionTitle",
"renameProcessorCounter", "renameProcessorCounter",
"renameProcessorHash",
"renameProcessorName", "renameProcessorName",
"deleteSingleAlbumConfirmationDialogMessage", "deleteSingleAlbumConfirmationDialogMessage",
"deleteMultiAlbumConfirmationDialogMessage", "deleteMultiAlbumConfirmationDialogMessage",
@ -1930,6 +1937,7 @@
"videoActionABRepeat", "videoActionABRepeat",
"videoRepeatActionSetStart", "videoRepeatActionSetStart",
"videoRepeatActionSetEnd", "videoRepeatActionSetEnd",
"renameProcessorHash",
"settingsForceWesternArabicNumeralsTile" "settingsForceWesternArabicNumeralsTile"
], ],
@ -1939,6 +1947,7 @@
"videoActionABRepeat", "videoActionABRepeat",
"videoRepeatActionSetStart", "videoRepeatActionSetStart",
"videoRepeatActionSetEnd", "videoRepeatActionSetEnd",
"renameProcessorHash",
"castDialogTitle", "castDialogTitle",
"aboutDataUsageSectionTitle", "aboutDataUsageSectionTitle",
"aboutDataUsageData", "aboutDataUsageData",
@ -1956,6 +1965,7 @@
], ],
"es": [ "es": [
"renameProcessorHash",
"settingsForceWesternArabicNumeralsTile" "settingsForceWesternArabicNumeralsTile"
], ],
@ -1964,6 +1974,7 @@
"videoActionABRepeat", "videoActionABRepeat",
"videoRepeatActionSetStart", "videoRepeatActionSetStart",
"videoRepeatActionSetEnd", "videoRepeatActionSetEnd",
"renameProcessorHash",
"settingsForceWesternArabicNumeralsTile" "settingsForceWesternArabicNumeralsTile"
], ],
@ -2011,6 +2022,7 @@
"renameEntrySetPageInsertTooltip", "renameEntrySetPageInsertTooltip",
"renameEntrySetPagePreviewSectionTitle", "renameEntrySetPagePreviewSectionTitle",
"renameProcessorCounter", "renameProcessorCounter",
"renameProcessorHash",
"renameProcessorName", "renameProcessorName",
"deleteSingleAlbumConfirmationDialogMessage", "deleteSingleAlbumConfirmationDialogMessage",
"deleteMultiAlbumConfirmationDialogMessage", "deleteMultiAlbumConfirmationDialogMessage",
@ -2527,6 +2539,7 @@
"renameEntrySetPageInsertTooltip", "renameEntrySetPageInsertTooltip",
"renameEntrySetPagePreviewSectionTitle", "renameEntrySetPagePreviewSectionTitle",
"renameProcessorCounter", "renameProcessorCounter",
"renameProcessorHash",
"renameProcessorName", "renameProcessorName",
"deleteSingleAlbumConfirmationDialogMessage", "deleteSingleAlbumConfirmationDialogMessage",
"deleteMultiAlbumConfirmationDialogMessage", "deleteMultiAlbumConfirmationDialogMessage",
@ -2959,6 +2972,7 @@
], ],
"fr": [ "fr": [
"renameProcessorHash",
"settingsForceWesternArabicNumeralsTile" "settingsForceWesternArabicNumeralsTile"
], ],
@ -3089,6 +3103,7 @@
"renameEntrySetPageInsertTooltip", "renameEntrySetPageInsertTooltip",
"renameEntrySetPagePreviewSectionTitle", "renameEntrySetPagePreviewSectionTitle",
"renameProcessorCounter", "renameProcessorCounter",
"renameProcessorHash",
"renameProcessorName", "renameProcessorName",
"deleteSingleAlbumConfirmationDialogMessage", "deleteSingleAlbumConfirmationDialogMessage",
"deleteMultiAlbumConfirmationDialogMessage", "deleteMultiAlbumConfirmationDialogMessage",
@ -3775,6 +3790,7 @@
"renameEntrySetPageInsertTooltip", "renameEntrySetPageInsertTooltip",
"renameEntrySetPagePreviewSectionTitle", "renameEntrySetPagePreviewSectionTitle",
"renameProcessorCounter", "renameProcessorCounter",
"renameProcessorHash",
"renameProcessorName", "renameProcessorName",
"deleteSingleAlbumConfirmationDialogMessage", "deleteSingleAlbumConfirmationDialogMessage",
"deleteMultiAlbumConfirmationDialogMessage", "deleteMultiAlbumConfirmationDialogMessage",
@ -4427,6 +4443,7 @@
"renameEntrySetPageInsertTooltip", "renameEntrySetPageInsertTooltip",
"renameEntrySetPagePreviewSectionTitle", "renameEntrySetPagePreviewSectionTitle",
"renameProcessorCounter", "renameProcessorCounter",
"renameProcessorHash",
"renameProcessorName", "renameProcessorName",
"deleteSingleAlbumConfirmationDialogMessage", "deleteSingleAlbumConfirmationDialogMessage",
"deleteMultiAlbumConfirmationDialogMessage", "deleteMultiAlbumConfirmationDialogMessage",
@ -4859,10 +4876,12 @@
], ],
"hu": [ "hu": [
"renameProcessorHash",
"settingsForceWesternArabicNumeralsTile" "settingsForceWesternArabicNumeralsTile"
], ],
"id": [ "id": [
"renameProcessorHash",
"settingsForceWesternArabicNumeralsTile" "settingsForceWesternArabicNumeralsTile"
], ],
@ -4871,6 +4890,7 @@
"videoActionABRepeat", "videoActionABRepeat",
"videoRepeatActionSetStart", "videoRepeatActionSetStart",
"videoRepeatActionSetEnd", "videoRepeatActionSetEnd",
"renameProcessorHash",
"settingsForceWesternArabicNumeralsTile" "settingsForceWesternArabicNumeralsTile"
], ],
@ -4879,6 +4899,7 @@
"videoActionABRepeat", "videoActionABRepeat",
"videoRepeatActionSetStart", "videoRepeatActionSetStart",
"videoRepeatActionSetEnd", "videoRepeatActionSetEnd",
"renameProcessorHash",
"collectionActionSetHome", "collectionActionSetHome",
"setHomeCustomCollection", "setHomeCustomCollection",
"settingsThumbnailShowHdrIcon", "settingsThumbnailShowHdrIcon",
@ -4911,6 +4932,7 @@
"videoResumptionModeAlways", "videoResumptionModeAlways",
"widgetTapUpdateWidget", "widgetTapUpdateWidget",
"vaultBinUsageDialogMessage", "vaultBinUsageDialogMessage",
"renameProcessorHash",
"exportEntryDialogQuality", "exportEntryDialogQuality",
"exportEntryDialogWriteMetadata", "exportEntryDialogWriteMetadata",
"castDialogTitle", "castDialogTitle",
@ -5172,6 +5194,7 @@
"renameEntrySetPageInsertTooltip", "renameEntrySetPageInsertTooltip",
"renameEntrySetPagePreviewSectionTitle", "renameEntrySetPagePreviewSectionTitle",
"renameProcessorCounter", "renameProcessorCounter",
"renameProcessorHash",
"renameProcessorName", "renameProcessorName",
"deleteSingleAlbumConfirmationDialogMessage", "deleteSingleAlbumConfirmationDialogMessage",
"deleteMultiAlbumConfirmationDialogMessage", "deleteMultiAlbumConfirmationDialogMessage",
@ -5604,6 +5627,7 @@
], ],
"ko": [ "ko": [
"renameProcessorHash",
"settingsForceWesternArabicNumeralsTile" "settingsForceWesternArabicNumeralsTile"
], ],
@ -5661,6 +5685,7 @@
"authenticateToConfigureVault", "authenticateToConfigureVault",
"authenticateToUnlockVault", "authenticateToUnlockVault",
"vaultBinUsageDialogMessage", "vaultBinUsageDialogMessage",
"renameProcessorHash",
"exportEntryDialogQuality", "exportEntryDialogQuality",
"exportEntryDialogWriteMetadata", "exportEntryDialogWriteMetadata",
"tooManyItemsErrorDialogMessage", "tooManyItemsErrorDialogMessage",
@ -5964,6 +5989,7 @@
"renameEntrySetPageInsertTooltip", "renameEntrySetPageInsertTooltip",
"renameEntrySetPagePreviewSectionTitle", "renameEntrySetPagePreviewSectionTitle",
"renameProcessorCounter", "renameProcessorCounter",
"renameProcessorHash",
"renameProcessorName", "renameProcessorName",
"deleteSingleAlbumConfirmationDialogMessage", "deleteSingleAlbumConfirmationDialogMessage",
"deleteMultiAlbumConfirmationDialogMessage", "deleteMultiAlbumConfirmationDialogMessage",
@ -6407,6 +6433,7 @@
"widgetOpenPageHome", "widgetOpenPageHome",
"widgetOpenPageCollection", "widgetOpenPageCollection",
"widgetOpenPageViewer", "widgetOpenPageViewer",
"renameProcessorHash",
"menuActionConfigureView", "menuActionConfigureView",
"castDialogTitle", "castDialogTitle",
"aboutDataUsageClearCache", "aboutDataUsageClearCache",
@ -6532,6 +6559,7 @@
"settingsVideoEnablePip", "settingsVideoEnablePip",
"widgetTapUpdateWidget", "widgetTapUpdateWidget",
"patternDialogEnter", "patternDialogEnter",
"renameProcessorHash",
"castDialogTitle", "castDialogTitle",
"aboutDataUsageInternal", "aboutDataUsageInternal",
"aboutDataUsageExternal", "aboutDataUsageExternal",
@ -6593,6 +6621,7 @@
"authenticateToConfigureVault", "authenticateToConfigureVault",
"authenticateToUnlockVault", "authenticateToUnlockVault",
"vaultBinUsageDialogMessage", "vaultBinUsageDialogMessage",
"renameProcessorHash",
"exportEntryDialogQuality", "exportEntryDialogQuality",
"exportEntryDialogWriteMetadata", "exportEntryDialogWriteMetadata",
"tooManyItemsErrorDialogMessage", "tooManyItemsErrorDialogMessage",
@ -6655,6 +6684,7 @@
"widgetTapUpdateWidget", "widgetTapUpdateWidget",
"authenticateToConfigureVault", "authenticateToConfigureVault",
"authenticateToUnlockVault", "authenticateToUnlockVault",
"renameProcessorHash",
"viewDialogSortSectionTitle", "viewDialogSortSectionTitle",
"viewDialogReverseSortOrder", "viewDialogReverseSortOrder",
"castDialogTitle", "castDialogTitle",
@ -6922,6 +6952,7 @@
"renameEntrySetPagePatternFieldLabel", "renameEntrySetPagePatternFieldLabel",
"renameEntrySetPageInsertTooltip", "renameEntrySetPageInsertTooltip",
"renameProcessorCounter", "renameProcessorCounter",
"renameProcessorHash",
"deleteSingleAlbumConfirmationDialogMessage", "deleteSingleAlbumConfirmationDialogMessage",
"deleteMultiAlbumConfirmationDialogMessage", "deleteMultiAlbumConfirmationDialogMessage",
"exportEntryDialogFormat", "exportEntryDialogFormat",
@ -7306,10 +7337,12 @@
], ],
"pl": [ "pl": [
"renameProcessorHash",
"settingsForceWesternArabicNumeralsTile" "settingsForceWesternArabicNumeralsTile"
], ],
"pt": [ "pt": [
"renameProcessorHash",
"settingsForceWesternArabicNumeralsTile" "settingsForceWesternArabicNumeralsTile"
], ],
@ -7318,10 +7351,12 @@
"videoActionABRepeat", "videoActionABRepeat",
"videoRepeatActionSetStart", "videoRepeatActionSetStart",
"videoRepeatActionSetEnd", "videoRepeatActionSetEnd",
"renameProcessorHash",
"settingsForceWesternArabicNumeralsTile" "settingsForceWesternArabicNumeralsTile"
], ],
"ru": [ "ru": [
"renameProcessorHash",
"settingsForceWesternArabicNumeralsTile" "settingsForceWesternArabicNumeralsTile"
], ],
@ -7582,6 +7617,7 @@
"renameEntrySetPageInsertTooltip", "renameEntrySetPageInsertTooltip",
"renameEntrySetPagePreviewSectionTitle", "renameEntrySetPagePreviewSectionTitle",
"renameProcessorCounter", "renameProcessorCounter",
"renameProcessorHash",
"renameProcessorName", "renameProcessorName",
"deleteSingleAlbumConfirmationDialogMessage", "deleteSingleAlbumConfirmationDialogMessage",
"deleteMultiAlbumConfirmationDialogMessage", "deleteMultiAlbumConfirmationDialogMessage",
@ -8018,6 +8054,7 @@
"videoActionABRepeat", "videoActionABRepeat",
"videoRepeatActionSetStart", "videoRepeatActionSetStart",
"videoRepeatActionSetEnd", "videoRepeatActionSetEnd",
"renameProcessorHash",
"settingsForceWesternArabicNumeralsTile" "settingsForceWesternArabicNumeralsTile"
], ],
@ -8276,6 +8313,7 @@
"renameEntrySetPageInsertTooltip", "renameEntrySetPageInsertTooltip",
"renameEntrySetPagePreviewSectionTitle", "renameEntrySetPagePreviewSectionTitle",
"renameProcessorCounter", "renameProcessorCounter",
"renameProcessorHash",
"renameProcessorName", "renameProcessorName",
"deleteSingleAlbumConfirmationDialogMessage", "deleteSingleAlbumConfirmationDialogMessage",
"deleteMultiAlbumConfirmationDialogMessage", "deleteMultiAlbumConfirmationDialogMessage",
@ -8727,6 +8765,7 @@
"renameAlbumDialogLabel", "renameAlbumDialogLabel",
"renameAlbumDialogLabelAlreadyExistsHelper", "renameAlbumDialogLabelAlreadyExistsHelper",
"renameEntrySetPageTitle", "renameEntrySetPageTitle",
"renameProcessorHash",
"deleteSingleAlbumConfirmationDialogMessage", "deleteSingleAlbumConfirmationDialogMessage",
"deleteMultiAlbumConfirmationDialogMessage", "deleteMultiAlbumConfirmationDialogMessage",
"editEntryDialogTargetFieldsHeader", "editEntryDialogTargetFieldsHeader",
@ -9076,6 +9115,7 @@
"authenticateToConfigureVault", "authenticateToConfigureVault",
"authenticateToUnlockVault", "authenticateToUnlockVault",
"vaultBinUsageDialogMessage", "vaultBinUsageDialogMessage",
"renameProcessorHash",
"exportEntryDialogQuality", "exportEntryDialogQuality",
"exportEntryDialogWriteMetadata", "exportEntryDialogWriteMetadata",
"editEntryDateDialogExtractFromTitle", "editEntryDateDialogExtractFromTitle",
@ -9430,10 +9470,12 @@
], ],
"tr": [ "tr": [
"renameProcessorHash",
"settingsForceWesternArabicNumeralsTile" "settingsForceWesternArabicNumeralsTile"
], ],
"uk": [ "uk": [
"renameProcessorHash",
"settingsForceWesternArabicNumeralsTile" "settingsForceWesternArabicNumeralsTile"
], ],
@ -9442,6 +9484,7 @@
"videoActionABRepeat", "videoActionABRepeat",
"videoRepeatActionSetStart", "videoRepeatActionSetStart",
"videoRepeatActionSetEnd", "videoRepeatActionSetEnd",
"renameProcessorHash",
"settingsForceWesternArabicNumeralsTile" "settingsForceWesternArabicNumeralsTile"
], ],
@ -9450,6 +9493,7 @@
"videoActionABRepeat", "videoActionABRepeat",
"videoRepeatActionSetStart", "videoRepeatActionSetStart",
"videoRepeatActionSetEnd", "videoRepeatActionSetEnd",
"renameProcessorHash",
"settingsForceWesternArabicNumeralsTile" "settingsForceWesternArabicNumeralsTile"
], ],
@ -9458,6 +9502,7 @@
"videoActionABRepeat", "videoActionABRepeat",
"videoRepeatActionSetStart", "videoRepeatActionSetStart",
"videoRepeatActionSetEnd", "videoRepeatActionSetEnd",
"renameProcessorHash",
"settingsForceWesternArabicNumeralsTile" "settingsForceWesternArabicNumeralsTile"
] ]
} }