summaryrefslogtreecommitdiff
path: root/src/lib/image.source.sh
blob: 34e215ac25d40aa2921d4d942ef561ecf112dbba (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
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
cleanphotos() {
    local basename
    local photo
    local sub

    while IFS= read -r photo; do
        basename=$(basename "$photo")

        if [[ -f "$INCOMING_DIR/$basename" ]] \
            && is_supported_image_file "$basename"; then
            continue
        fi

        log_info "Cleaning up $(_display_path "$photo")"
        for sub in thumbs blurs photos; do
            if [ -f "$DIST_DIR/$sub/$basename" ]; then
                rm -f "$DIST_DIR/$sub/$basename"
                log_info "removed '$(_display_path "$DIST_DIR/$sub/$basename")'"
            fi
        done
    done < <(find "$DIST_DIR/photos" -maxdepth 1 -type f)
}

is_supported_image_file() {
    local -r file="$1"; shift
    local extension

    if [[ "$file" != *.* ]]; then
        return 1
    fi

    extension="${file##*.}"
    extension="${extension,,}"

    case "$extension" in
        gif|jpeg|jpg|png|webp)
            return 0
            ;;
        *)
            return 1
            ;;
    esac
}

incoming_image_files() {
    local file

    # $FIND (compat.source.sh): -printf is a GNU-only action, so this must run
    # against the resolved GNU find, not whatever "find" plain resolves to on
    # macOS/FreeBSD. The trailing sort is POSIX-portable and left as-is.
    while IFS= read -r file; do
        if is_supported_image_file "$file"; then
            printf '%s\n' "$file"
        fi
    done < <("$FIND" "$INCOMING_DIR" -maxdepth 1 -type f -printf '%f\n') \
        | sort
}

# File counters for the source tree and the generated dist. Moved here from
# album-metadata.source.sh (task 6r0): counting incoming/generated files is part
# of this module's file-enumeration concern -- count_incoming_images is a direct
# wrapper of incoming_image_files above, and count_files/count_tree_files are the
# generic siblings the generation-metadata and dry-run modules use to tally the
# produced photos, thumbs and HTML pages. Behaviour and signatures are unchanged.
count_files() {
    local -r dir="$1"; shift
    local -r name="${1:-}"; shift || true

    if [ ! -d "$dir" ]; then
        printf '0\n'
        return
    fi

    if [ -n "$name" ]; then
        find "$dir" -maxdepth 1 -type f -name "$name" | wc -l
    else
        find "$dir" -maxdepth 1 -type f | wc -l
    fi
}

count_incoming_images() {
    incoming_image_files | wc -l
}

count_tree_files() {
    local -r dir="$1"; shift
    local -r name="$1"; shift

    if [ ! -d "$dir" ]; then
        printf '0\n'
        return
    fi

    find "$dir" -type f -name "$name" | wc -l
}

warn_unsupported_incoming_files() {
    local file

    # $FIND (compat.source.sh): -printf is a GNU-only action.
    while IFS= read -r file; do
        if ! is_supported_image_file "$file"; then
            log_warning "Ignoring unsupported incoming file: $file"
        fi
    done < <("$FIND" "$INCOMING_DIR" -maxdepth 1 -type f -printf '%f\n' | sort)
}

scalephotos() {
    local photo

    # Throttled background job pool (max IMAGE_JOBS concurrent), addressed by the
    # single handle "image_jobs". job_pool_wait returns 1 if any job failed.
    job_pool_init image_jobs

    while IFS= read -r photo; do
        job_pool_submit image_jobs "image job for photo $photo" \
            scale_photo "$photo"
    done < <(incoming_image_files)

    job_pool_wait image_jobs
}

scale_photo() {
    local -r photo="$1"; shift
    local destphoto
    local dirname

    destphoto="$DIST_DIR/photos/$photo"
    dirname=$(dirname "$destphoto")
    mkdir -p "$dirname"

    if [ -f "$destphoto" ]; then
        log_verbose "Skipped existing photo $(_display_path "$destphoto")"
        return
    fi

    log_info "Processing $photo to $(_display_path "$destphoto")"
    if [ -n "$HEIGHT" ]; then
        # Scale down size.
        imagemagick \
            "$INCOMING_DIR/$photo" \
            -auto-orient \
            -geometry "x${HEIGHT}>" \
            "$destphoto"
    else
        # Keep original size.
        imagemagick \
            "$INCOMING_DIR/$photo" \
            -auto-orient \
            "$destphoto"
    fi
}