summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorPaul Buetow <paul@buetow.org>2026-06-14 23:07:12 +0300
committerPaul Buetow <paul@buetow.org>2026-06-14 23:07:12 +0300
commitb7d5c1102c3679b67532f30f2613e4d2d61c59ba (patch)
tree573548dc8762aeb7c642fed804894d280425f84c /src
parent0f0662850ad2df3502241cd1bdfcb366dd68d717 (diff)
rm0 wire stats feature into generate with STATS_PAGE toggle
Final integration of the stats-site feature: - Add STATS_PAGE config (default yes) mirroring SPLASH_PAGE through every layer: shuriken.default.conf, apply_config_defaults, CLI_OPTION_SPEC (--stats/--no-stats), the CLI_CONFIG_OVERRIDE_TARGETS allowlist (without which the flag was silently ignored), usage text, yes/no validation, print_config, the action config list + effective-setting log, the generation metadata, and the dry-run plan. - generate() now calls a gated generate_stats_pages helper after the album pages (and before archiving, so the stats/camera pages are tarballed): collect_photo_exif_stats + render_stats_page . . + render_camera_pages . . - Emit "stats_page" in shuriken.json next to "splash_page". - Gate the header Stats nav link behind STATS_PAGE via a new render_stats_page_html config_html field, so it is hidden (no 404) when stats are disabled. - Document STATS_PAGE and --stats/--no-stats in the README. - Tests: full --generate produces stats.html + camera-<slug>.html + the nav link and stats_page=true; --no-stats suppresses all three and sets stats_page=false; print-config and metadata expectations updated. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Diffstat (limited to 'src')
-rw-r--r--src/lib/action.source.sh2
-rw-r--r--src/lib/album.source.sh17
-rw-r--r--src/lib/bootstrap.source.sh2
-rw-r--r--src/lib/config.print.source.sh1
-rw-r--r--src/lib/config.source.sh1
-rw-r--r--src/lib/config.validate.source.sh1
-rw-r--r--src/lib/template.source.sh7
-rw-r--r--src/shuriken.default.conf3
-rwxr-xr-xsrc/shuriken.sh3
9 files changed, 37 insertions, 0 deletions
diff --git a/src/lib/action.source.sh b/src/lib/action.source.sh
index 987fd7a..e2649d7 100644
--- a/src/lib/action.source.sh
+++ b/src/lib/action.source.sh
@@ -53,6 +53,7 @@ run_action_body_context() {
RANDOM_SEED
SHUFFLE
SPLASH_PAGE
+ STATS_PAGE
TARBALL_INCLUDE
TARBALL_SUFFIX
TAR_OPTS
@@ -158,6 +159,7 @@ log_configured_action() {
log_verbose "Effective ImageMagick timeout: ${IMAGEMAGICK_TIMEOUT}s"
log_verbose "Effective tar timeout: ${TAR_TIMEOUT}s"
log_verbose "Effective splash page setting: $SPLASH_PAGE"
+ log_verbose "Effective stats page setting: $STATS_PAGE"
log_verbose "Effective tarball setting: $TARBALL_INCLUDE"
log_verbose "Effective sync delete setting: $SYNC_DELETE"
log_verbose "Effective force generation setting: $SHURIKEN_FORCE_GENERATE"
diff --git a/src/lib/album.source.sh b/src/lib/album.source.sh
index 2036591..c9812a2 100644
--- a/src/lib/album.source.sh
+++ b/src/lib/album.source.sh
@@ -927,6 +927,7 @@ _collect_generation_metadata() {
_GENERATION_METADATA["settings_random_seed"]="$RANDOM_SEED"
_GENERATION_METADATA["settings_shuffle"]="$SHUFFLE"
_GENERATION_METADATA["settings_splash_page"]="$SPLASH_PAGE"
+ _GENERATION_METADATA["settings_stats_page"]="$STATS_PAGE"
_GENERATION_METADATA["settings_original_basepath"]="$ORIGINAL_BASEPATH"
}
@@ -985,6 +986,8 @@ _generation_metadata_json() {
"$(_json_bool "${_GENERATION_METADATA["settings_shuffle"]}")"
printf ' "splash_page": %s,\n' \
"$(_json_bool "${_GENERATION_METADATA["settings_splash_page"]}")"
+ printf ' "stats_page": %s,\n' \
+ "$(_json_bool "${_GENERATION_METADATA["settings_stats_page"]}")"
printf ' "original_basepath": %s\n' \
"$(_json_string "${_GENERATION_METADATA["settings_original_basepath"]}")"
printf ' }\n'
@@ -1040,6 +1043,16 @@ create_generation_archive() {
fi
}
+# Aggregate EXIF stats and render the stats page plus the per-camera pages into
+# the dist root (html_dir and backhref are '.', matching render_album_pages).
+# Run after the album pages so the per-photo identify cache is already warm.
+generate_stats_pages() {
+ log_verbose 'Stats page enabled; collecting EXIF stats'
+ collect_photo_exif_stats
+ render_stats_page . .
+ render_camera_pages . .
+}
+
generate() {
local tarball_name=''
@@ -1056,6 +1069,9 @@ generate() {
prepare_generation_site_assets
clear_rendered_html
render_album_pages 'photos' '.' 'thumbs' 'blurs' '.' "$tarball_name"
+ if [ "$STATS_PAGE" = yes ]; then
+ generate_stats_pages
+ fi
create_generation_archive "$tarball_name"
write_generation_metadata "$tarball_name"
}
@@ -1158,6 +1174,7 @@ collect_dry_run_plan() {
plan_ref["random_seed"]="$RANDOM_SEED"
plan_ref["shuffle"]="$SHUFFLE"
plan_ref["splash_page"]="$SPLASH_PAGE"
+ plan_ref["stats_page"]="$STATS_PAGE"
plan_ref["image_count"]="$image_count"
plan_ref["tarball_include"]="$TARBALL_INCLUDE"
plan_ref["tarball_name_plan"]='not planned'
diff --git a/src/lib/bootstrap.source.sh b/src/lib/bootstrap.source.sh
index 67ba090..a047f5d 100644
--- a/src/lib/bootstrap.source.sh
+++ b/src/lib/bootstrap.source.sh
@@ -23,6 +23,8 @@ usage() {
--random-seed VALUE
--splash
--no-splash
+ --stats
+ --no-stats
--shuffle
--no-shuffle
--tarball
diff --git a/src/lib/config.print.source.sh b/src/lib/config.print.source.sh
index bad29ef..7b91b60 100644
--- a/src/lib/config.print.source.sh
+++ b/src/lib/config.print.source.sh
@@ -36,6 +36,7 @@ print_config() {
print_shell_assignment RANDOM_SEED "$RANDOM_SEED"
print_shell_assignment SHUFFLE "$SHUFFLE"
print_shell_assignment SPLASH_PAGE "$SPLASH_PAGE"
+ print_shell_assignment STATS_PAGE "$STATS_PAGE"
print_shell_assignment TARBALL_INCLUDE "$TARBALL_INCLUDE"
print_shell_assignment TARBALL_SUFFIX "$TARBALL_SUFFIX"
print_shell_assignment TAR_TIMEOUT "$TAR_TIMEOUT"
diff --git a/src/lib/config.source.sh b/src/lib/config.source.sh
index 348f167..50c331a 100644
--- a/src/lib/config.source.sh
+++ b/src/lib/config.source.sh
@@ -37,6 +37,7 @@ apply_config_defaults() {
RANDOM_SEED="${RANDOM_SEED:-}"
SHUFFLE="${SHUFFLE:-no}"
SPLASH_PAGE="${SPLASH_PAGE:-yes}"
+ STATS_PAGE="${STATS_PAGE:-yes}"
SYNC_DELETE="${SYNC_DELETE:-yes}"
TARBALL_INCLUDE="${TARBALL_INCLUDE:-no}"
TARBALL_SUFFIX="${TARBALL_SUFFIX:-.tar}"
diff --git a/src/lib/config.validate.source.sh b/src/lib/config.validate.source.sh
index b858144..bd2fccf 100644
--- a/src/lib/config.validate.source.sh
+++ b/src/lib/config.validate.source.sh
@@ -193,6 +193,7 @@ validate_common_config() {
validate_positive_integer_config_var TAR_TIMEOUT || return
validate_yes_no_config_var SHUFFLE || return
validate_yes_no_config_var SPLASH_PAGE || return
+ validate_yes_no_config_var STATS_PAGE || return
validate_yes_no_config_var TARBALL_INCLUDE || return
}
diff --git a/src/lib/template.source.sh b/src/lib/template.source.sh
index 9fd3ad4..8e5b93e 100644
--- a/src/lib/template.source.sh
+++ b/src/lib/template.source.sh
@@ -167,6 +167,7 @@ declare -ra TEMPLATE_RENDER_FIELD_SPECS=(
'render_redirect_page_html|context_html|redirect_page|redirect_page|redirect'
'render_show_header_bar|context_raw|show_header_bar|show_header_bar|header'
'render_stats_body_html|context_raw|stats_body|stats_body|stats'
+ 'render_stats_page_html|config_html|STATS_PAGE||'
'render_tarball_include|tarball_include|||'
'render_tarball_name_html|context_html|tarball_name|tarball_name|footer'
'render_thumbheight_html|config_html|THUMBHEIGHT||'
@@ -478,6 +479,12 @@ prepare_template_render_vars() {
ORIGINAL_BASEPATH)
context_value="$ORIGINAL_BASEPATH"
;;
+ STATS_PAGE)
+ # Always defaulted by apply_config_defaults; degrade to
+ # "no" (link hidden) if somehow unset so the header bar
+ # never references a stats page that was not generated.
+ context_value="${STATS_PAGE:-no}"
+ ;;
THUMBHEIGHT)
# Refresh-only configs do not require generation
# sizing fields; render absent values as empty.
diff --git a/src/shuriken.default.conf b/src/shuriken.default.conf
index 6c3ea47..c0fe41a 100644
--- a/src/shuriken.default.conf
+++ b/src/shuriken.default.conf
@@ -15,6 +15,9 @@ IMAGEMAGICK_TIMEOUT=60
# SHUFFLE=yes
# Generate a splash landing page at index.html.
SPLASH_PAGE=yes
+# Generate an EXIF stats page (stats.html) plus per-camera pages, and show the
+# Stats navigation link in page headers. Can be yes or no.
+STATS_PAGE=yes
# Set to any non-empty value for repeatable background, animation, timestamp,
# and shuffled preview choices.
# RANDOM_SEED=album-build-1
diff --git a/src/shuriken.sh b/src/shuriken.sh
index 482484c..b6a6cc5 100755
--- a/src/shuriken.sh
+++ b/src/shuriken.sh
@@ -40,6 +40,7 @@ declare -ra CLI_CONFIG_OVERRIDE_TARGETS=(
RANDOM_SEED
SHUFFLE
SPLASH_PAGE
+ STATS_PAGE
SYNC_DELETE
TARBALL_INCLUDE
)
@@ -58,6 +59,8 @@ declare -Ar CLI_OPTION_SPEC=(
[--no-shuffle]='kind=flag value=no config=SHUFFLE'
[--splash]='kind=flag value=yes config=SPLASH_PAGE'
[--no-splash]='kind=flag value=no config=SPLASH_PAGE'
+ [--stats]='kind=flag value=yes config=STATS_PAGE'
+ [--no-stats]='kind=flag value=no config=STATS_PAGE'
[--tarball]='kind=flag value=yes config=TARBALL_INCLUDE'
[--no-tarball]='kind=flag value=no config=TARBALL_INCLUDE'
[--force]='kind=flag value=yes target=SHURIKEN_FORCE_GENERATE'