summaryrefslogtreecommitdiff
path: root/src/lib/album-metadata.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/album-metadata.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/album-metadata.source.sh')
-rw-r--r--src/lib/album-metadata.source.sh64
1 files changed, 36 insertions, 28 deletions
diff --git a/src/lib/album-metadata.source.sh b/src/lib/album-metadata.source.sh
index b74bf8f..767ec4c 100644
--- a/src/lib/album-metadata.source.sh
+++ b/src/lib/album-metadata.source.sh
@@ -8,31 +8,40 @@
photo_exif_details_html() {
local -r photo="$1"; shift
local -r photo_path="$1"; shift
+ # exif_values is filled via the shared parser and iterated below.
+ # shellcheck disable=SC2034
+ local -A exif_values=()
local key
local key_html
- local line
local value
local value_html
local -i exif_count=0
- while IFS= read -r line; do
- if [[ "$line" =~ ^[[:space:]]*exif:([^:]+):[[:space:]]*(.*)$ ]]; then
- key="exif:${BASH_REMATCH[1]}"
- value="${BASH_REMATCH[2]}"
- key_html=$(_html_escape "$key")
- value_html=$(_html_escape "$value")
-
- if (( exif_count == 0 )); then
- printf '<table class="details">\n'
- printf '<tbody>\n'
- fi
-
- printf '<tr><th>%s</th><td>%s</td></tr>\n' \
- "$key_html" \
- "$value_html"
- (( ++exif_count ))
+ # Parse via the single canonical reader/parser (task 8r0) instead of a
+ # private exif: regex loop. The parser also yields a synthetic __geometry key
+ # from the native Geometry line; the details table only shows real exif: tags
+ # (rendered with their historical "exif:" label prefix), so __geometry is
+ # skipped explicitly below.
+ _photo_exif_values_to exif_values "$photo" "$photo_path"
+
+ for key in "${!exif_values[@]}"; do
+ if [ "$key" = '__geometry' ]; then
+ continue
+ fi
+ value="${exif_values[$key]}"
+ key_html=$(_html_escape "exif:$key")
+ value_html=$(_html_escape "$value")
+
+ if (( exif_count == 0 )); then
+ printf '<table class="details">\n'
+ printf '<tbody>\n'
fi
- done < <(cached_photo_identify_output "$photo" "$photo_path")
+
+ printf '<tr><th>%s</th><td>%s</td></tr>\n' \
+ "$key_html" \
+ "$value_html"
+ (( ++exif_count ))
+ done
if (( exif_count == 0 )); then
printf '<p class="details-empty">No EXIF details available.</p>\n'
@@ -58,20 +67,19 @@ _first_exif_value_to() {
done
}
+# Fill the caller's associative array with a photo's parsed EXIF values. Thin
+# wrapper that pairs the shared cache reader with the shared stream parser
+# (photo_exif_values_to, promoted to metadata-cache.source.sh in task 8r0): it
+# reads the cached identify output for this photo and pipes it through the one
+# canonical parser. The parser also captures a __geometry key, which album code
+# simply ignores.
_photo_exif_values_to() {
- local -n output_ref="$1"; shift
+ local -r target_array="$1"; shift
local -r photo="$1"; shift
local -r photo_path="$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]}"
- fi
- done < <(cached_photo_identify_output "$photo" "$photo_path")
+ photo_exif_values_to "$target_array" \
+ < <(cached_photo_identify_output "$photo" "$photo_path")
}
_photo_exif_tooltip_text_from_values() {