]> git.plutz.net Git - shellwiki/blob - handlers/20_attachment.sh
somewhat more readable URL selection
[shellwiki] / handlers / 20_attachment.sh
1 #!/bin/sh
2
3 attachment_convert(){
4   local attpath="$1"
5   local cachepath="${attpath%/#attachments/*}/#cache/${attpath#*/#attachments/}"
6   local res junk
7
8   case $attpath in
9     *.webm|*.mp4|*.mkv|*.avi)
10       cachepath="${cachepath}.webm"
11       ;;
12   esac
13
14   if [ -s "$cachepath" ]; then
15     printf %s "$cachepath"
16     return 0
17   elif [ -f "$cachepath" ]; then
18     printf %s "$attpath"
19     return 0
20   elif ! mkdir -p -- "${cachepath%/*}" && touch "$cachepath"; then
21     printf %s "$attpath"
22     return 0
23   fi
24
25   case $attpath in
26     *.jpg|*.jpeg|*.png)
27       read junk junk res junk <<-EOF
28         $(identify "$attpath")
29         EOF
30       if [ "${res%x*}" -gt 2048 ]; then
31         convert "$attpath" -resize 1920x-2 -quality 85 "$cachepath"
32       else
33         convert "$attpath" -quality 85 "$cachepath"
34       fi
35       printf %s "$cachepath"
36       return 0
37     ;;
38     *.webm|*.mp4|*.mkv|*.avi)
39       res=$(ffprobe -show_entries stream=width "$attpath" 2>&-)
40       res="${res#*width=}" res="${res%%${BR}*}"
41       if [ "$res" -gt 1280 ]; then
42         ( exec >&- 2>&1;
43           ffmpeg -y -nostdin -i "$attpath" \
44           -c:v libvpx -vf scale=1280:-2 -crf 28 -b:v 0 \
45           -c:a libvorbis -q:a 6 \
46           "${cachepath%.*}.tmp.webm" \
47           && mv -- "${cachepatch%.*}.tmp.webm" "${cachepath}" \
48         & ) &
49        
50       else
51         ( exec >&- 2>&1;
52           ffmpeg -y -nostdin -i "$attpath" \
53           -c:v libvpx -crf 28 -b:v 0 \
54           -c:a libvorbis -q:a 6 \
55           "${cachepath%.*}.tmp.webm" \
56           && mv -- "${cachepatch%.*}.tmp.webm" "${cachepath}" \
57         & ) &
58       fi
59       printf %s "$attpath"
60       return 0
61     ;;
62   esac
63 }
64
65 case ${PATH_INFO} in
66   */\[attachment\]/)
67     tsid="$(POST session_key)"; tsid="${tsid%% *}"
68     attachment_delete="$(POST delete)"
69
70     if [ "${CONTENT_TYPE%%;*}" = "multipart/form-data" ] && acl_write "${PATH_INFO%\[attachment\]/}"; then
71       . "$_EXEC/multipart.sh"
72       multipart_cache
73
74       # Validate session id from form to prevent CSRF
75       # Only validate if username is present, because no username means
76       # anonymous uploads are allowed via acl and cgilite/session.sh does not
77       # validate anonymous sessions from a multipart/formdata
78       if [ "$USER_NAME" -a "$(multipart session_id)" != "$SESSION_ID" ]; then
79         rm -- "$multipart_cachefile"
80         printf 'Refresh: %i\r\n' 4
81         theme_error 403
82         return 0
83       fi
84
85       mkdir -p "$_DATA/pages/${PATH_INFO%/\[attachment\]/}/#attachments/"
86       n=1; while filename=$(multipart_filename "file" "$n"); do
87         filename="$(printf %s "$filename" |tr /\\0 __)"
88         multipart "file" "$n" >"$_DATA/pages/${PATH_INFO%/\[attachment\]/}/#attachments/$filename"
89         n=$((n + 1))
90       done
91       rm -- "$multipart_cachefile"
92       REDIRECT "${_BASE}${PATH_INFO}"
93     elif [ "${CONTENT_TYPE%%;*}" = "multipart/form-data" ]; then
94       printf 'Refresh: %i\r\n' 4
95       theme_error 403
96       head -c $((CONTENT_LENGTH)) >/dev/null
97       return 0
98     elif [ "$attachment_delete" -a "$SESSION_ID" = "$tsid" ]; then
99       rm -- "$_DATA/pages/${PATH_INFO%/\[attachment\]/}/#attachments/$attachment_delete"
100       REDIRECT "${_BASE}${PATH_INFO}"
101     elif [ "$attachment_delete" ]; then
102       printf 'Refresh: %i\r\n' 4
103       theme_error 403
104       return 0
105     elif acl_read "${PATH_INFO%\[attachment\]/}"; then
106       theme_attachments "${PATH_INFO%\[attachment\]/}"
107       return 0
108     else
109       theme_error 404
110       return 0
111     fi
112     ;;
113
114   */\[attachment\]/*)
115     attpath="${PATH_INFO%/\[attachment\]/*}/#attachments/${PATH_INFO##*/}"
116
117     if ! acl_read "${PATH_INFO%/\[attachment\]/*}"; then
118       theme_error 403
119       return 0
120     elif [ -f "$_DATA/pages/$attpath" ]; then
121       FILE "$_DATA/pages/$attpath"
122       return 0
123     elif [ -f "$_EXEC/pages/$attpath" ]; then
124       FILE "$_EXEC/pages/$attpath"
125       return 0
126     else
127       theme_error 404
128       return 0
129     fi
130     ;;
131   */*/)
132     return 1
133     ;;
134   */*)
135     attpath="${PATH_INFO%/*}/#attachments/${PATH_INFO##*/}"
136
137     if ! acl_read "${PATH_INFO%/*}/"; then
138       theme_error 403
139       return 0
140     elif [ -f "$_DATA/pages/$attpath" ]; then
141       FILE "$(attachment_convert "$_DATA/pages/$attpath")"
142       return 0
143     elif [ -f "$_EXEC/pages/$attpath" ]; then
144       FILE "$(attachment_convert "$_EXEC/pages/$attpath")"
145       return 0
146     elif [ -d "$_DATA/pages/${PATH_INFO}" -o -d "$_EXEC/pages/${PATH_INFO}" ]; then
147       REDIRECT "${_BASE}${PATH_INFO}/"
148     elif [ "${PATH_INFO%\[*\]}" = "${PATH_INFO}" ]; then
149       theme_error 404
150       return 0
151     fi
152     ;;
153 esac
154
155 return 1