summaryrefslogtreecommitdiff
path: root/src/lib/stats-aggregate.source.sh
AgeCommit message (Collapse)Author
2026-06-17pn0 decouple stats from album internalsPaul Buetow
Stats reached directly into album-module internals: the private global ALBUM_VIEW_PAGE_BY_PHOTO and the EXIF cache reader cached_photo_identify_output. Introduce a clean boundary, behaviour and generated HTML byte-identical. - Promote the EXIF identify cache primitive (cached_photo_identify_output plus its private helpers photo_cache_signature and print_cached_photo_identify_output) out of album-metadata.source.sh into a new shared src/lib/metadata-cache.source.sh, sourced before both album and stats (right after metadata-label in LIB_SOURCES). It is a low-level metadata primitive used by both consumers, so it no longer belongs to album internals. Signature/behaviour unchanged. - Add album_view_page_for_photo accessor in album-render.source.sh as the documented public API; keep ALBUM_VIEW_PAGE_BY_PHOTO as the album's private backing store. stats-filter-album.source.sh now calls the accessor instead of indexing the global, so a change to album page naming/caching stays contained in the album module. - Add test_album_stats_decoupling_boundary asserting the accessor returns the backing-store value and that the assembled bin/shuriken keeps the cache primitive in the shared module and no longer indexes the global from the stats filter section. Existing stats/album tests unchanged. Verified: 3-image fixture (STATS_PAGE=yes, fixed seed) diff -r of stashed original vs new build is byte-identical across all 47 dist files (only the inherent generated_at timestamp normalized). just test, just shellcheck, just check-generated and git diff --check all pass. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-17en0: make stats categories self-registering via STATS_CATEGORIESPaul Buetow
Adding an EXIF stats category previously required editing four places: the reset function, a new _stats_record_*, the body builder, and a new _stats_render_* section. Introduce a STATS_CATEGORIES registry (the single source of truth) and make the generic code iterate it instead. - STATS_CATEGORIES: ordered, pipe-delimited specs (count_array|prefix|heading|render_kind), declared -gra so it survives a function-scoped source. The array order IS the overview display order. - STATS_CATEGORY_BUCKETS: tab-delimited bucket ladders for the 'ordered' histogram kinds (apertures wide->narrow, etc.). - STATS_RECORD_FUNCTIONS: the per-photo recorder dispatch list. Collapsed touch-points: - reset_photo_exif_stats clears each registry count array via _stats_category_arrays. - accumulate_photo_stats dispatches recorders from STATS_RECORD_FUNCTIONS. - _stats_build_body iterates STATS_CATEGORIES, dispatching each spec through _stats_render_category (camera/ranked/ordered/month kinds). - _stats_render_ordered_section reads its ladder from STATS_CATEGORY_BUCKETS; the camera leaderboard is now ranked + a 'stats-leaderboard' list_class. Adding a category is now: append one STATS_CATEGORIES entry (plus a STATS_CATEGORY_BUCKETS row for an ordered ladder) and have a record function tally into its array. No edits to reset, the body builder, or a per-category render branch. Behaviour-preserving: category order, bucket order, headings, counts and links are unchanged. Verified byte-identical by diffing the stats/ output of the pre-change binary against the new one over the same fixture album. Added test_stats_categories_registry_is_single_source_of_truth (registered in main()) asserting reset, the body builder and the bucket ladders all derive from the registry; it fails if a category is added in only one place. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-17mn0 share camera Make+Model dedup helperPaul Buetow
The rule that joins a camera's EXIF Make + Model into one label while avoiding a duplicated manufacturer prefix (e.g. "Canon Canon EOS 5D" -> "Canon EOS 5D") was implemented independently in the album tooltip builder and the stats leaderboard tally. Extract it into a single shared helper camera_label_from_make_model in the new src/lib/metadata-label.source.sh, sourced before both callers. Both prior implementations were behavior-identical (empty model -> make, empty make -> model, exact/prefix dedup, case-sensitive), so this is a pure DRY refactor with no observable output change. Added a focused unit test covering dedup, plain concatenation and the empty-field edge cases. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-16cn0 split stats.source.sh into aggregate/render/filter-album modulesPaul Buetow
Pure code move: split the ~1248-line stats.source.sh (SRP+SoC) into three cohesive modules, all functions and STATS_* constants/globals moved verbatim: - stats-aggregate.source.sh: EXIF parsing, bucketing, _stats_tally, reset/collect_photo_exif_stats and the STATS_* maps. - stats-render.source.sh: stats overview page (sections, bars, leaderboard, render_stats_page, _stats_build_body, _stats_filter_link, background pickers). - stats-filter-album.source.sh: per-filter mini-albums (render_filter_pages, gallery/view/thumbnail builders, _stats_enqueue_filter_album). Updated LIB_SOURCES accordingly. No logic change (verified: all 55 functions and top-level globals preserved; full suite, shellcheck, check-generated, diff all pass). The SoC point (HTML built in bash rather than templates) is left for a follow-up (nn0/qn0). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>