summaryrefslogtreecommitdiff
path: root/src/lib/album-photo-select.source.sh
blob: 06190f7fb12280a233f91440b9eb9afd185f255e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
# Album photo listing and random selection. Split out of
# album-render.source.sh (task ar0) so the "which photos are in this album, in
# what order, and which one do we pick for a background/splash" concern lives
# apart from the page orchestration, the tile-layout deciders and the thumbnail
# HTML. This is selection POLICY (shuffle/sort, splash-requires-a-blur, seeded
# random pick) and changes for different reasons than the rendering plumbing.
#
# These helpers are called by the orchestrator (album-render.source.sh) and by
# 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

    find "$DIST_DIR/$photos_dir" -maxdepth 1 -type f -printf '%f\n' \
        | maybe_shuffle
}

# Pagination single source of truth (task nr0): how many preview pages a given
# number of album photos splits into, with at most MAXPREVIEWS photos per page.
# album_page_records below realises exactly this many records by grouping the
# actual (shuffled) photo list, and the dry-run plan calls this helper to predict
# the page count from the incoming-image tally WITHOUT enumerating dist files. So
# the preview and a real --generate can never disagree on the page count: both
# express "ceil(image_count / MAXPREVIEWS)" through this one definition. An empty
# album yields 0 pages.
album_page_count_for_image_count() {
    local -ri image_count="$1"; shift

    if (( image_count <= 0 )); then
        printf '0\n'
        return
    fi
    printf '%d\n' "$(( (image_count + MAXPREVIEWS - 1) / MAXPREVIEWS ))"
}

# Group the album's photos into pages of at most MAXPREVIEWS, in their final
# (shuffled/sorted) order. The result is emitted one line per page as a
# tab-separated record "<page_num>\t<photo>\t<photo>..." so the caller can walk
# pages without keeping every page in memory at once. Order is fully
# deterministic (album_photo_files already applies the seeded shuffle), so the
# downstream parallelism only changes timing, never which photo lands where. The
# number of records produced here equals album_page_count_for_image_count of the
# photo count (same MAXPREVIEWS-per-page grouping); see that helper.
album_page_records() {
    local -r photos_dir="$1"; shift
    local photo
    local -i num=1
    local -i count=0
    local line=''

    while IFS= read -r photo; do
        if (( count == MAXPREVIEWS )); then
            printf '%d\t%s\n' "$num" "$line"
            (( ++num ))
            count=0
            line=''
        fi
        if (( count == 0 )); then
            line="$photo"
        else
            line="$line"$'\t'"$photo"
        fi
        (( ++count ))
    done < <(album_photo_files "$photos_dir")

    if (( count > 0 )); then
        printf '%d\t%s\n' "$num" "$line"
    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
    local photo

    while IFS= read -r photo; do
        if [ -f "$DIST_DIR/$blurs_dir/$photo" ]; then
            printf '%s\n' "$photo"
        fi
    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 photo
    local -a photos=()

    while IFS= read -r photo; do
        photos+=("$photo")
    done < <(splash_photo_files "$photos_dir" "$blurs_dir")

    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
    printf '\n'
}