summaryrefslogtreecommitdiff
path: root/src/lib/metadata-cache.source.sh
diff options
context:
space:
mode:
authorPaul Buetow <paul@buetow.org>2026-06-24 10:36:25 +0300
committerPaul Buetow <paul@buetow.org>2026-06-24 10:36:25 +0300
commit6dfc0f1a9521cc4afe4941fc1328eec014b760a7 (patch)
tree4303307c104aa9dbe84e906eb9c0f1dd279469d9 /src/lib/metadata-cache.source.sh
parent99c5241d853daceb8cfaec91023730ff062858b7 (diff)
Promote single canonical identify-stream EXIF parser into metadata-cache (8r0)
The `identify -verbose` EXIF-line regex and its array-fill loop were duplicated in three places that had already drifted: album-metadata's photo_exif_details_html and _photo_exif_values_to (exif: only) and stats-aggregate's _stats_parse_identify_stream (exif: plus a native Geometry -> __geometry path). Promote one canonical parser, photo_exif_values_to, into metadata-cache.source.sh next to its sibling cache primitive cached_photo_identify_output. It reads an identify stream from stdin and fills a nameref associative array; it is a strict superset of all three former sites (bare exif: tag keys plus the synthetic __geometry key). - stats accumulate_photo_stats now calls photo_exif_values_to (stdin); _stats_parse_identify_stream is removed. - album _photo_exif_values_to is a thin wrapper that pipes cached_photo_identify_output through the canonical parser. - album photo_exif_details_html consumes the same parser and skips the __geometry key it does not display. metadata-cache is sourced before both consumers in LIB_SOURCES, so the canonical parser is available at use time. Regenerated bin/shuriken via `just build`. Added test_shared_identify_parser_returns_exif_and_geometry asserting one parse yields both an exif: key and __geometry. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Diffstat (limited to 'src/lib/metadata-cache.source.sh')
-rw-r--r--src/lib/metadata-cache.source.sh38
1 files changed, 38 insertions, 0 deletions
diff --git a/src/lib/metadata-cache.source.sh b/src/lib/metadata-cache.source.sh
index 45edd3c..ba40ca9 100644
--- a/src/lib/metadata-cache.source.sh
+++ b/src/lib/metadata-cache.source.sh
@@ -102,3 +102,41 @@ cached_photo_identify_output() {
print_cached_photo_identify_output "$cache_file"
}
+
+# Canonical `identify -verbose` stream parser. Reads an identify stream from
+# stdin and fills the caller-provided associative array (by nameref) with one
+# entry per recognised field. Promoted here (task 8r0) from three near-identical
+# copies that had already drifted -- album-metadata had two exif:-only loops and
+# stats-aggregate added a native Geometry path. This single definition is a
+# strict superset of all three: it lives next to cached_photo_identify_output so
+# both the album (tooltips, details tables) and the stats aggregator share one
+# regex and one set of key conventions, isolating any future identify-format
+# drift to one place.
+#
+# Keys produced:
+# - exif:* lines -> stored under the bare tag name (e.g. "Make", "FNumber"),
+# i.e. WITHOUT the leading "exif:" -- callers that want the prefixed label
+# (the details table) re-add it. This matches the historical album and stats
+# array keys exactly.
+# - the native Geometry line ("WxH+x+y") -> stored under the synthetic key
+# "__geometry"; stats reads this for dimension tallies, album ignores it.
+#
+# Reads from stdin (not from a photo path) so it composes with the cache layer:
+# stats pipes a fixture or cache stream straight in, while album wraps it with
+# `photo_exif_values_to ref < <(cached_photo_identify_output ...)`.
+photo_exif_values_to() {
+ local -n output_ref="$1"; shift
+ local line
+
+ output_ref=()
+ while IFS= read -r line; do
+ if [[ "$line" =~ ^[[:space:]]*exif:([^:]+):[[:space:]]*(.*)$ ]]; then
+ # output_ref writes to the caller-provided associative array.
+ # shellcheck disable=SC2034
+ output_ref["${BASH_REMATCH[1]}"]="${BASH_REMATCH[2]}"
+ elif [[ "$line" =~ ^[[:space:]]*Geometry:[[:space:]]*(.*)$ ]]; then
+ # shellcheck disable=SC2034
+ output_ref[__geometry]="${BASH_REMATCH[1]}"
+ fi
+ done
+}