]> git.plutz.net Git - shellwiki/blob - handlers/40_attachment.sh
bugfix: handle white space in filenames for image conversion
[shellwiki] / handlers / 40_attachment.sh
1 #!/bin/sh
2
3 # Copyright 2022 - 2023 Paul Hänsch
4
5 # Permission to use, copy, modify, and/or distribute this software for any
6 # purpose with or without fee is hereby granted, provided that the above
7 # copyright notice and this permission notice appear in all copies.
8
9 # THE SOFTWARE IS PROVIDED “AS IS” AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
12 # SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
15 # IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16
17 . "$_EXEC/cgilite/file.sh"
18
19 # REV_ATTACHMENTS="${REV_ATTACHMENTS:-false}"
20
21 attachment_convert(){
22   local attpath="$1"
23   local cachepath="${attpath%/#attachments/*}/#cache/${attpath#*/#attachments/}"
24   local res junk
25
26   case $attpath in
27     *.webm|*.mp4|*.mkv|*.avi)
28       cachepath="${cachepath}.webm"
29       ;;
30   esac
31
32   if [ -s "$cachepath" ]; then
33     printf %s "$cachepath"
34     return 0
35   elif [ -f "$cachepath" ]; then
36     printf %s "$attpath"
37     return 0
38   elif ! mkdir -p -- "${cachepath%/*}" && touch -- "$cachepath"; then
39     printf %s "$attpath"
40     return 0
41   fi
42
43   case $attpath in
44     *.[jJ][pP][gG]|*.[jJ][pP][eE][gG]|*.[pP][nN][gG])
45       res="$(identify -- "$attpath")"
46       res="${res% * * * * * *}" res="${res##* }"
47       if [ "${res%x*}" -gt 2048 ]; then
48         convert "$attpath" -resize 1920x-2 -quality 85 "$cachepath"
49       else
50         convert "$attpath" -quality 85 "$cachepath"
51       fi
52       printf %s "$cachepath"
53       return 0
54     ;;
55     *.[wW][eE][bB][mM]|*.[mM][pP]4|*.[mM][kK][vV]|*.[aA][vV][iI])
56       res=$(ffprobe -show_entries stream=width "$attpath" 2>&-)
57       res="${res#*width=}" res="${res%%${BR}*}"
58       if [ "$res" -gt 1280 ]; then
59         ( exec >&- 2>&1;
60           ffmpeg -y -nostdin -i "$attpath" \
61           -c:v libvpx -vf scale=1280:-2 -crf 28 -b:v 0 \
62           -c:a libvorbis -q:a 6 \
63           "${cachepath%.*}.tmp.webm" \
64           && mv -- "${cachepatch%.*}.tmp.webm" "${cachepath}" \
65         & ) &
66        
67       else
68         ( exec >&- 2>&1;
69           ffmpeg -y -nostdin -i "$attpath" \
70           -c:v libvpx -crf 28 -b:v 0 \
71           -c:a libvorbis -q:a 6 \
72           "${cachepath%.*}.tmp.webm" \
73           && mv -- "${cachepatch%.*}.tmp.webm" "${cachepath}" \
74         & ) &
75       fi
76       printf %s "$attpath"
77       return 0
78     ;;
79     *) printf %s "$attpath";;
80   esac
81 }
82
83 case ${PATH_INFO} in
84   */\[attachment\]/)
85     # no trailing slash
86     REDIRECT "${_BASE}${PATH_INFO%/}"
87     ;;
88   */*/)
89     # attached files never end on /
90     return 1
91     ;;
92   */\[attachment\])
93     # show attachment page
94     page="${PATH_INFO%\[attachment\]}"
95
96     if [ ! -d "$_DATA/pages${page}" -a ! -d "$_DATA/pages${page}" ]; then
97       # base page does not exist
98       return 1
99     elif [ "${CONTENT_TYPE%%;*}" = "multipart/form-data" ]; then
100       # pass uploads to next handler
101       return 1
102     elif [ "$(POST action)" ]; then
103       # pass edits to next handler
104       return 1
105     elif ! acl_read "${page}"; then
106       theme_error 403
107       return 0
108     else
109       theme_attachments "${page}"
110       return 0
111     fi
112     ;;
113
114   */\[attachment\]/*)
115     attpath="${PATH_INFO%/\[attachment\]/*}/#attachments/${PATH_INFO##*/}"
116
117     if [ ! -f "$_DATA/pages/$attpath" -a ! -f "$_EXEC/pages/$attpath" ]; then
118       return 1
119     elif ! acl_read "${PATH_INFO%/\[attachment\]/*}"; then
120       theme_error 403
121       return 0
122     elif [ -f "$_DATA/pages/$attpath" ]; then
123       FILE "$_DATA/pages/$attpath"
124       return 0
125     elif [ -f "$_EXEC/pages/$attpath" ]; then
126       FILE "$_EXEC/pages/$attpath"
127       return 0
128     fi
129     ;;
130   */*)
131     attpath="${PATH_INFO%/*}/#attachments/${PATH_INFO##*/}"
132
133     if [ ! -f "$_DATA/pages/$attpath" -a ! -f "$_EXEC/pages/$attpath" ]; then
134       return 1
135     elif ! acl_read "${PATH_INFO%/*}/"; then
136       theme_error 403
137       return 0
138     elif [ -f "$_DATA/pages/$attpath" ]; then
139       FILE "$(attachment_convert "$_DATA/pages/$attpath")"
140       return 0
141     elif [ -f "$_EXEC/pages/$attpath" ]; then
142       FILE "$(attachment_convert "$_EXEC/pages/$attpath")"
143       return 0
144     fi
145     ;;
146 esac
147
148 return 1