diff options
Diffstat (limited to 'src/lib')
| -rw-r--r-- | src/lib/album-photo-select.source.sh | 49 | ||||
| -rw-r--r-- | src/lib/album-render.source.sh | 8 | ||||
| -rw-r--r-- | src/lib/image-pipeline.source.sh | 5 | ||||
| -rw-r--r-- | src/lib/photo-list.source.sh | 77 | ||||
| -rw-r--r-- | src/lib/stats-render.source.sh | 45 |
5 files changed, 122 insertions, 62 deletions
diff --git a/src/lib/album-photo-select.source.sh b/src/lib/album-photo-select.source.sh index 0a889bc..2cb2e88 100644 --- a/src/lib/album-photo-select.source.sh +++ b/src/lib/album-photo-select.source.sh @@ -9,6 +9,10 @@ # the per-page render jobs at runtime; all libs are sourced before any code runs, # so availability does not depend on source order. +# Unlike the other photo listings this one keeps its own find rather than using +# list_photos (photo-list.source.sh): it pipes through maybe_shuffle, not sort, +# because the album's display order is the configurable (seeded) shuffle, not a +# plain sort. album_photo_files() { local -r photos_dir="$1"; shift @@ -49,6 +53,9 @@ album_page_records() { fi } +# Splash candidates: the album's photos (sorted) that also have a matching blur, +# since the splash page renders a blurred background. Lists via the shared +# list_photos (photo-list.source.sh) and filters to those with a blur present. splash_photo_files() { local -r photos_dir="$1"; shift local -r blurs_dir="$1"; shift @@ -58,16 +65,18 @@ splash_photo_files() { if [ -f "$DIST_DIR/$blurs_dir/$photo" ]; then printf '%s\n' "$photo" fi - done < <( - find "$DIST_DIR/$photos_dir" -maxdepth 1 -type f -printf '%f\n' \ - | sort - ) + done < <(list_photos "$photos_dir") } +# Pick a seeded-random splash photo: one of the album's photos that also has a +# matching blur. Shares the selection core (_pick_random_from_list, +# photo-list.source.sh) with the other pickers; only the candidate list (splash +# photos, not all photos), the "photo:<dir>:splash" namespace and the +# splash-specific empty error are particular to splash selection. Output and +# determinism are unchanged from the former inline implementation. random_splash_photo() { local -r photos_dir="$1"; shift local -r blurs_dir="$1"; shift - local -i index local photo local -a photos=() @@ -75,37 +84,11 @@ random_splash_photo() { photos+=("$photo") done < <(splash_photo_files "$photos_dir" "$blurs_dir") - if (( ${#photos[@]} == 0 )); then + if ! _pick_random_from_list "photo:$photos_dir:splash" photos; then printf 'ERROR: No splash photos found in %s with matching blurs in %s\n' \ "$(_display_path "$DIST_DIR/$photos_dir")" \ "$(_display_path "$DIST_DIR/$blurs_dir")" >&2 return 1 fi - - index=$(random_index "photo:$photos_dir:splash" "${#photos[@]}") - printf '%s\n' "${photos[index]}" -} - -randomphoto() { - local -r photos_dir="$1"; shift - local -r context="${1:-$photos_dir}" - local -i index - local photo - local -a photos=() - - while IFS= read -r photo; do - photos+=("$photo") - done < <( - find "$DIST_DIR/$photos_dir" -maxdepth 1 -type f -printf '%f\n' \ - | sort - ) - - if (( ${#photos[@]} == 0 )); then - printf 'ERROR: No photos found in %s\n' \ - "$(_display_path "$DIST_DIR/$photos_dir")" >&2 - return 1 - fi - - index=$(random_index "photo:$photos_dir:$context" "${#photos[@]}") - printf '%s\n' "${photos[index]}" + printf '\n' } diff --git a/src/lib/album-render.source.sh b/src/lib/album-render.source.sh index e039b07..4c65f69 100644 --- a/src/lib/album-render.source.sh +++ b/src/lib/album-render.source.sh @@ -5,8 +5,10 @@ # bundle now live in siblings, all sourced before this file: # - album-tile-layout.source.sh (tile_layout_for/build_tile_block/...) # - album-thumbnail-html.source.sh (build_preview_thumbnail/append_preview_grid) -# - album-photo-select.source.sh (album_photo_files/randomphoto/splash/...) -# This module calls into all three at runtime; all libs are sourced before any +# - album-photo-select.source.sh (album_photo_files/album_page_records/splash) +# The generic "pick one seeded-random photo from a dir" used for page backgrounds +# now comes from the shared pick_random_photo (photo-list.source.sh, task br0). +# This module calls into all of these at runtime; all libs are sourced before any # code runs, so the cross-module calls resolve regardless of source order. # # Maps each album photo filename to its view-page basename ("<page>-<preview>") @@ -39,7 +41,7 @@ start_preview_page() { local -r header_bar="$1"; shift local background_image - background_image=$(randomphoto "$photos_dir" "$page_name") + background_image=$(pick_random_photo "$photos_dir" "$page_name") template header "$page_name.html" \ html_dir "$html_dir" \ backhref "$backhref" \ diff --git a/src/lib/image-pipeline.source.sh b/src/lib/image-pipeline.source.sh index 934c3b5..06a5169 100644 --- a/src/lib/image-pipeline.source.sh +++ b/src/lib/image-pipeline.source.sh @@ -48,10 +48,7 @@ create_all_photo_derivatives() { job_pool_submit image_jobs "image derivative job for photo $photo" \ create_photo_derivatives "$photos_dir" "$thumbs_dir" "$blurs_dir" \ "$photo" - done < <( - find "$DIST_DIR/$photos_dir" -maxdepth 1 -type f -printf '%f\n' \ - | sort - ) + done < <(list_photos "$photos_dir") job_pool_wait image_jobs } diff --git a/src/lib/photo-list.source.sh b/src/lib/photo-list.source.sh new file mode 100644 index 0000000..9e7ce72 --- /dev/null +++ b/src/lib/photo-list.source.sh @@ -0,0 +1,77 @@ +# Shared photo listing and random-pick primitives (task br0). Several modules +# need the same two low-level operations: "list the files in a dist photos +# directory, sorted" and "pick one seeded-random entry from a list". Before this +# module they were re-implemented in album-photo-select, image-pipeline and +# stats-render, each with the same find|sort idiom and the same collect / +# empty-check / random_index / print dance. Centralising them here removes that +# duplication while keeping behaviour identical at every call site. +# +# Home rationale: the consumers live in three otherwise-unrelated subsystems +# (album rendering, the image pipeline, the stats pages), so the helpers do not +# belong to any one of them -- putting them in, say, album-photo-select would +# make image-pipeline depend on album code. This small low-level module depends +# only on random_index (random.source.sh), _display_path (template.source.sh) +# and the $DIST_DIR global, so it is sourced early -- after random/template but +# before image-pipeline / album-* / stats-* -- so every definition precedes its +# uses. All libs are sourced before any code runs. + +# List the regular files directly inside "$DIST_DIR/<dir>", one basename per +# line, sorted. This is the canonical replacement for the recurring +# find "$DIST_DIR/<dir>" -maxdepth 1 -type f -printf '%f\n' | sort +# idiom. Stderr is left untouched so callers keep full control: a caller that +# wants the find error on a missing directory gets it, and one that wants it +# suppressed (the stats background loader) adds its own 2>/dev/null. This is the +# SORTED listing; album_photo_files deliberately keeps its own maybe_shuffle +# variant because the album's display order is the configurable shuffle, not a +# plain sort. +list_photos() { + local -r photos_dir="$1"; shift + + find "$DIST_DIR/$photos_dir" -maxdepth 1 -type f -printf '%f\n' | sort +} + +# Pick one seeded-random entry from an already-collected list, addressed by +# nameref, and print it WITHOUT a trailing newline. The namespace seeds the +# choice so a given RANDOM_SEED yields a stable pick. Returns 1 (printing +# nothing) when the list is empty, leaving the empty/error policy to the caller. +# This is the shared core of pick_random_photo / random_splash_photo / +# _stats_random_background / _stats_pick_background, so the random_index call +# (and thus selection determinism) lives in exactly one place. Each caller keeps +# its own namespace string, so seeding is unchanged from the former inline code. +_pick_random_from_list() { + local -r namespace="$1"; shift + local -n _list_ref="$1"; shift + local -i index + + if (( ${#_list_ref[@]} == 0 )); then + return 1 + fi + index=$(random_index "$namespace" "${#_list_ref[@]}") + printf '%s' "${_list_ref[index]}" +} + +# Pick one seeded-random photo from the sorted listing of "$DIST_DIR/<dir>". +# This is the canonical "random photo" picker (formerly album-render's +# randomphoto): it prints the chosen basename followed by a newline, and on an +# empty directory emits an error and returns 1. The selection namespace is +# "photo:<dir>:<ctx>" (ctx defaults to the directory name), matching the +# historical context exactly so determinism is unchanged. +pick_random_photo() { + local -r photos_dir="$1"; shift + local -r context="${1:-$photos_dir}" + local photo + local -a photos=() + + while IFS= read -r photo; do + photos+=("$photo") + done < <(list_photos "$photos_dir") + + if (( ${#photos[@]} == 0 )); then + printf 'ERROR: No photos found in %s\n' \ + "$(_display_path "$DIST_DIR/$photos_dir")" >&2 + return 1 + fi + + _pick_random_from_list "photo:$photos_dir:$context" photos + printf '\n' +} diff --git a/src/lib/stats-render.source.sh b/src/lib/stats-render.source.sh index b13a3ae..5431d51 100644 --- a/src/lib/stats-render.source.sh +++ b/src/lib/stats-render.source.sh @@ -294,9 +294,13 @@ _stats_build_body() { # render the page without a populated photos directory. # Load the sorted photo list for blurred backgrounds once into a global. This # runs for every filter page (thousands of them), so the per-call directory scan -# randomphoto would otherwise do dominates the build. render_filter_pages loads -# it before forking the render jobs so each background subshell inherits the -# populated array instead of rescanning. +# the picker would otherwise do dominates the build. render_filter_pages loads it +# before forking the render jobs so each background subshell inherits the +# populated array instead of rescanning. The listing reuses the shared +# list_photos (photo-list.source.sh); 2>/dev/null keeps the original behaviour of +# silently yielding an empty list when the photos directory does not exist (e.g. +# unit tests). The STATS_BG_PHOTOS_LOADED guard preserves the once-only caching, +# so there is no per-page re-listing regression. _stats_load_background_photos() { if [ -n "${STATS_BG_PHOTOS_LOADED:-}" ]; then return @@ -305,46 +309,43 @@ _stats_load_background_photos() { local photo while IFS= read -r photo; do STATS_BG_PHOTOS+=("$photo") - done < <( - find "$DIST_DIR/$STATS_PHOTOS_DIR" -maxdepth 1 -type f -printf '%f\n' \ - 2>/dev/null | sort - ) + done < <(list_photos "$STATS_PHOTOS_DIR" 2>/dev/null) STATS_BG_PHOTOS_LOADED=yes } # Pick a seeded-random photo for a stats/camera page's blurred background from -# the cached photo list. Empty (plain black) when no photos exist. +# the cached photo list. Empty (plain black) when no photos exist. Shares the +# selection core (_pick_random_from_list, photo-list.source.sh); the +# "photo:<STATS_PHOTOS_DIR>:<context>" namespace is unchanged so determinism and +# the empty-string-on-empty degradation match the former inline code exactly. _stats_random_background() { local -r context="$1"; shift - local -i index _stats_load_background_photos - if (( ${#STATS_BG_PHOTOS[@]} == 0 )); then - return - fi - index=$(random_index "photo:$STATS_PHOTOS_DIR:$context" \ - "${#STATS_BG_PHOTOS[@]}") - printf '%s' "${STATS_BG_PHOTOS[index]}" + # An empty list is a normal "no background" degrade, not an error: swallow the + # picker's empty-list status (return 1) so the caller's set -e is unaffected, + # exactly like the former inline "return" on an empty list. + _pick_random_from_list "photo:$STATS_PHOTOS_DIR:$context" STATS_BG_PHOTOS \ + || return 0 } # Pick a seeded-random photo from a newline-separated list (a filter's own # photos) for a filter gallery's blurred background, so the background fits the -# category. Empty when the list is empty. +# category. Empty when the list is empty. Shares the selection core +# (_pick_random_from_list, photo-list.source.sh); the "photo:filter:<context>" +# namespace is unchanged so selection is identical to the former inline code. _stats_pick_background() { local -r context="$1"; shift local -r photos="$1"; shift local -a list=() local photo - local -i index while IFS= read -r photo; do [ -n "$photo" ] && list+=("$photo") done <<< "$photos" - if (( ${#list[@]} == 0 )); then - return - fi - index=$(random_index "photo:filter:$context" "${#list[@]}") - printf '%s' "${list[index]}" + # Empty list -> no background; swallow the picker's empty status so the + # caller's set -e is unaffected, matching the former inline "return". + _pick_random_from_list "photo:filter:$context" list || return 0 } render_stats_page() { |
