diff options
Diffstat (limited to 'src/lib')
| -rw-r--r-- | src/lib/album.source.sh | 15 | ||||
| -rw-r--r-- | src/lib/stats.source.sh | 89 |
2 files changed, 56 insertions, 48 deletions
diff --git a/src/lib/album.source.sh b/src/lib/album.source.sh index 17502ff..532c218 100644 --- a/src/lib/album.source.sh +++ b/src/lib/album.source.sh @@ -1091,8 +1091,10 @@ clear_exif_cache() { generate_stats_pages() { log_verbose 'Stats page enabled; collecting EXIF stats' collect_photo_exif_stats - render_stats_page . . - render_filter_pages . . + # Keep the album root uncluttered: the stats overview is stats/index.html and + # every filter mini-album lives under stats/<pagebase>/ (see render_filter_pages). + render_stats_page stats .. index + render_filter_pages } generate() { @@ -1285,10 +1287,11 @@ print_dry_run_plan() { printf ' %s/[redirect].html (%s navigation redirects)\n' \ "${plan_ref["dist_dir"]}" "${plan_ref["redirect_count"]}" if [ "${plan_ref["stats_page"]}" = yes ]; then - # The exact camera-page count needs EXIF aggregation, which dry-run - # does not perform, so list them as a wildcard. - printf ' %s/stats.html (EXIF stats page)\n' "${plan_ref["dist_dir"]}" - printf ' %s/camera-*.html (per-camera pages)\n' \ + # The exact filter mini-album set needs EXIF aggregation, which dry-run + # does not perform, so list them as a wildcard under stats/. + printf ' %s/stats/index.html (EXIF stats page)\n' \ + "${plan_ref["dist_dir"]}" + printf ' %s/stats/*/ (filter mini-albums)\n' \ "${plan_ref["dist_dir"]}" fi if [ "${plan_ref["tarball_include"]}" = yes ]; then diff --git a/src/lib/stats.source.sh b/src/lib/stats.source.sh index 2844973..afc2d3b 100644 --- a/src/lib/stats.source.sh +++ b/src/lib/stats.source.sh @@ -702,7 +702,9 @@ _stats_filter_link() { pagebase="${STATS_FILTER_PAGEBASE[$catkey]:-}" if [ -n "$pagebase" ]; then - printf '<a href="%s.html">%s</a>' "$pagebase" "$label_html" + # The stats overview lives at stats/index.html and each mini-album at + # stats/<pagebase>/index.html, so link relative to the overview. + printf '<a href="%s/index.html">%s</a>' "$pagebase" "$label_html" else printf '%s' "$label_html" fi @@ -987,13 +989,20 @@ render_stats_page() { declare -gr STATS_PHOTOS_DIR='photos' declare -gr STATS_THUMBS_DIR='thumbs' declare -gr STATS_BLURS_DIR='blurs' +# Everything stats-related lives under this dist subdirectory so the album root +# only holds the main album: the stats overview is stats/index.html and each +# filter mini-album is stats/<pagebase>/ (gallery index.html + view pages +# <index>.html). This keeps the file count in any single directory bounded. +declare -gr STATS_DIR='stats' +# Relative path from a filter mini-album page (dist/stats/<pagebase>/...) back to +# the album root (dist/), used for shared assets and album links. +declare -gr STATS_FILTER_BACKHREF='../..' # Emit one thumbnail anchor for a filter gallery: a thumb image (from thumbs/) # linking to this filter's view page for that photo (<pagebase>--<index>.html). # The photo filename is HTML-escaped; the pagebase and index are filename-safe. _stats_filter_thumbnail() { local -r backhref_html="$1"; shift - local -r pagebase="$1"; shift local -ri index="$1"; shift local -r photo="$1"; shift local photo_html @@ -1002,8 +1011,9 @@ _stats_filter_thumbnail() { photo_html=$(_html_escape "$photo") # Same seeded animation the album thumbnail uses for this photo. animation_class=$(random_animation_css_class slow "$photo") - printf ' <a name="%s" href="%s/%s--%d.html">' \ - "$photo_html" "$backhref_html" "$pagebase" "$index" + # The view page sits in the same directory as this gallery, so link to it by + # bare index; the thumbnail image lives at the album root via backhref. + printf ' <a name="%s" href="%d.html">' "$photo_html" "$index" printf '<img class="thumb %s" src="%s/%s/%s" /></a>\n' \ "$animation_class" "$backhref_html" "$STATS_THUMBS_DIR" "$photo_html" } @@ -1012,7 +1022,6 @@ _stats_filter_thumbnail() { # list, preserving aggregation (encounter) order for deterministic output. _stats_build_filter_thumbs() { local -r backhref_html="$1"; shift - local -r pagebase="$1"; shift local -r photos="$1"; shift local photo local -i index=0 @@ -1020,7 +1029,7 @@ _stats_build_filter_thumbs() { while IFS= read -r photo; do if [ -n "$photo" ]; then (( ++index )) - _stats_filter_thumbnail "$backhref_html" "$pagebase" "$index" "$photo" + _stats_filter_thumbnail "$backhref_html" "$index" "$photo" fi done <<< "$photos" } @@ -1028,36 +1037,35 @@ _stats_build_filter_thumbs() { # Render a filter gallery page (<pagebase>.html): header + camera.tmpl (heading + # pre-built thumbnail grid) + footer. camera.tmpl is reused for every filter; the # heading is the bucket's title (camera name, "ISO 400", "Year 2023", ...). +# Each filter mini-album lives in its own directory stats/<pagebase>/, so the +# gallery is index.html and the view pages are <index>.html. backhref is fixed +# (../.. back to the album root). camera.tmpl/cameraview.tmpl are reused. _stats_render_filter_gallery() { - local -r html_dir="$1"; shift - local -r backhref="$1"; shift - local -r backhref_html="$1"; shift local -r pagebase="$1"; shift local thumbs local background_image - local -r page="$pagebase.html" + local -r html_dir="$STATS_DIR/$pagebase" + local -r backhref="$STATS_FILTER_BACKHREF" + local -r backhref_html="$STATS_FILTER_BACKHREF" local -r title="${STATS_FILTER_TITLE[$pagebase]:-}" thumbs=$(_stats_build_filter_thumbs \ - "$backhref_html" "$pagebase" "${STATS_FILTER_PHOTOS[$pagebase]}") - background_image=$(_stats_random_background "$page") - template header "$page" \ + "$backhref_html" "${STATS_FILTER_PHOTOS[$pagebase]}") + background_image=$(_stats_random_background "$pagebase/index") + template header index.html \ html_dir "$html_dir" backhref "$backhref" \ blurs_dir "$STATS_BLURS_DIR" background_image "$background_image" \ show_header_bar 'yes' - template camera "$page" \ + template camera index.html \ html_dir "$html_dir" backhref "$backhref" \ camera_name "$title" camera_thumbs "$thumbs" - template footer "$page" \ + template footer index.html \ html_dir "$html_dir" backhref "$backhref" tarball_name '' } # Render one filter view page (<pagebase>--<index>.html): header + cameraview # body + footer, with prev/next cycling within the filter. _stats_render_filter_view_page() { - local -r html_dir="$1"; shift - local -r backhref="$1"; shift - local -r backhref_html="$1"; shift local -r pagebase="$1"; shift local -r photo="$1"; shift local -ri index="$1"; shift @@ -1065,11 +1073,13 @@ _stats_render_filter_view_page() { local -ri next="$1"; shift local body local background_image - local -r page="$pagebase--$index.html" + local -r html_dir="$STATS_DIR/$pagebase" + local -r backhref="$STATS_FILTER_BACKHREF" + local -r page="$index.html" body=$(_stats_build_filterview_body \ - "$backhref_html" "$pagebase" "$photo" "$prev" "$next") - background_image=$(_stats_random_background "$page") + "$STATS_FILTER_BACKHREF" "$photo" "$prev" "$next") + background_image=$(_stats_random_background "$pagebase/$index") template header "$page" \ html_dir "$html_dir" backhref "$backhref" \ blurs_dir "$STATS_BLURS_DIR" background_image "$background_image" \ @@ -1086,7 +1096,6 @@ _stats_render_filter_view_page() { # image link. _stats_build_filterview_body() { local -r backhref_html="$1"; shift - local -r pagebase="$1"; shift local -r photo="$1"; shift local -ri prev="$1"; shift local -ri next="$1"; shift @@ -1108,15 +1117,17 @@ _stats_build_filterview_body() { details_link=$(printf ' <a href="%s/%s-details.html">Details</a> |' \ "$backhref_html" "$view_page") fi - _stats_print_filterview_body "$backhref_html" "$pagebase" "$photo_html" \ + _stats_print_filterview_body "$backhref_html" "$photo_html" \ "$animation_class" "$tooltip_attr" "$details_link" "$prev" "$next" } # Emit the filter view page markup. Split out so _stats_build_filterview_body # stays focused on assembling the pieces. +# The prev/next/gallery links are same-directory (this view page lives in the +# filter's own stats/<pagebase>/ dir); the image, details, and direct links go +# back to the album root via backhref. _stats_print_filterview_body() { local -r backhref_html="$1"; shift - local -r pagebase="$1"; shift local -r photo_html="$1"; shift local -r animation_class="$1"; shift local -r tooltip_attr="$1"; shift @@ -1126,14 +1137,14 @@ _stats_print_filterview_body() { cat <<END <div class='view'> - <a href="$backhref_html/$pagebase--$next.html"> + <a href="$next.html"> <img class='view $animation_class' border='0' src='$backhref_html/$STATS_PHOTOS_DIR/$photo_html'$tooltip_attr /> </a> <div class="navigator"> - <a href="$backhref_html/$pagebase--$prev.html" class="arrow">⇐</a> - <a href="$backhref_html/$pagebase.html">Gallery</a> |$details_link + <a href="$prev.html" class="arrow">⇐</a> + <a href="index.html">Gallery</a> |$details_link <a href="$backhref_html/$STATS_PHOTOS_DIR/$photo_html">Direct link</a> - <a href="$backhref_html/$pagebase--$next.html" class="arrow">⇒</a> + <a href="$next.html" class="arrow">⇒</a> </div> </div> END @@ -1143,9 +1154,6 @@ END # shared render job pool, waiting for a free slot (<= IMAGE_JOBS) before each # background render so parallelism follows the configured IMAGE_JOBS. _stats_enqueue_filter_album() { - local -r html_dir="$1"; shift - local -r backhref="$1"; shift - local -r backhref_html="$1"; shift local -r pagebase="$1"; shift local -r pids_name="$1"; shift local -r statuses_name="$1"; shift @@ -1166,8 +1174,7 @@ _stats_enqueue_filter_album() { wait_for_template_render_job_slot \ "$pids_name" "$statuses_name" "$labels_name" "$failed_name" - _stats_render_filter_gallery \ - "$html_dir" "$backhref" "$backhref_html" "$pagebase" & + _stats_render_filter_gallery "$pagebase" & pids_ref+=("$!") labels_ref["$!"]="filter gallery $pagebase" @@ -1175,11 +1182,10 @@ _stats_enqueue_filter_album() { wait_for_template_render_job_slot \ "$pids_name" "$statuses_name" "$labels_name" "$failed_name" _stats_render_filter_view_page \ - "$html_dir" "$backhref" "$backhref_html" "$pagebase" \ - "${photo_list[i - 1]}" "$i" \ + "$pagebase" "${photo_list[i - 1]}" "$i" \ "$(( i == 1 ? n : i - 1 ))" "$(( i == n ? 1 : i + 1 ))" & pids_ref+=("$!") - labels_ref["$!"]="filter view $pagebase--$i" + labels_ref["$!"]="filter view $pagebase/$i" done } @@ -1188,10 +1194,11 @@ _stats_enqueue_filter_album() { # dist-relative output dir ("." for a top-level album) and backhref the relative # path back to the album root ("."), the same values render_stats_page uses. # Pagebases are walked in LC_ALL=C order for reproducible enqueue order. +# Render every filter mini-album under dist/stats/<pagebase>/ in parallel. Each +# mini-album's location and backhref are fixed by the layout (see STATS_DIR / +# STATS_FILTER_BACKHREF), so no path arguments are needed. Call +# collect_photo_exif_stats first to fill STATS_FILTER_PHOTOS. render_filter_pages() { - local -r html_dir="$1"; shift - local -r backhref="$1"; shift - local backhref_html local pagebase # Render job pool, throttled to IMAGE_JOBS by the job-pool helpers. local -a render_job_pids=() @@ -1204,13 +1211,11 @@ render_filter_pages() { if (( ${#STATS_FILTER_PHOTOS[@]} == 0 )); then return fi - backhref_html=$(_html_escape "$backhref") # Load the background photo list once now so every forked render job inherits # the cached array rather than rescanning the photos directory per page. _stats_load_background_photos while IFS= read -r pagebase; do - _stats_enqueue_filter_album \ - "$html_dir" "$backhref" "$backhref_html" "$pagebase" \ + _stats_enqueue_filter_album "$pagebase" \ render_job_pids render_job_statuses render_job_labels render_failed done < <(printf '%s\n' "${!STATS_FILTER_PHOTOS[@]}" | LC_ALL=C sort) wait_for_template_render_jobs \ |
