aboutsummaryrefslogtreecommitdiffhomepage
path: root/bin/mail/comment.sh
diff options
context:
space:
mode:
Diffstat (limited to 'bin/mail/comment.sh')
-rwxr-xr-xbin/mail/comment.sh90
1 files changed, 72 insertions, 18 deletions
diff --git a/bin/mail/comment.sh b/bin/mail/comment.sh
index 807bcb2..d096ee8 100755
--- a/bin/mail/comment.sh
+++ b/bin/mail/comment.sh
@@ -1,41 +1,95 @@
1#! /bin/bash 1#! /bin/bash
2 2
3# Save incoming mail as comment
4# Usage:
5# echo '|<PATH_TO_THIS_SCRIPT>' >>~/.forward
6
7mailto=${mailto:-$(whoami)@${HOSTNAME:?HOSTNAME is not specified}}
3output_dir=${output_dir:-/srv/http} 8output_dir=${output_dir:-/srv/http}
4 9
10# Check mail is for comment {{{
11
5# Restore mail into variable 12# Restore mail into variable
6MAIL="$(tr -d '\r')" 13MAIL="$(tr -d '\r')"
7headers="$(<<<"$MAIL" sed '/^$/ q')" 14header="$(<<<"$MAIL" sed '/^$/ q')"
8contents="$(<<<"$MAIL" sed -n '/^$/,$ p' | sed '1d')" 15body="$(<<<"$MAIL" sed -n '/^$/,$ p' | sed '1d')"
16
17# determine mail is for comment by pattern
18pattern='^Subject: .*comment on (https?://)?([^/]+)?/([^ ]+)$'
19<<<"$header" grep -E "$pattern" >/dev/null || exit 0
20
21# }}}
22# Process header fields {{{
9 23
10# enable execute last command in pipe under current shell 24# enable execute last command in pipe under current shell
11shopt -s lastpipe; set +m; 25shopt -s lastpipe; set +m;
12 26
13# get route (target page of comment) and id 27# save each field of header into variables
14<<<"$MAIL" sed -En '/^To: comment+/ {s/^To: comment\+([^+]+)\+?(.*)@.*$/\1 \2/p; q}; /^$/q' \ 28<<<"$header" grep '^[a-zA-Z]' \
15| read route id 29| while read field value; do
30 declare field=$(<<<$field tr [:lower:] [:upper:] | tr '-' '_' | tr -d ':')
31 declare $field="${value}"
32done
33DATE=${DATE:+$(date --rfc-3339 seconds --date "$DATE")}
16 34
17# sender want comment on some page, but find no route for this 35# }}}
18if [ $route = "" ]; then 36# Get path of output file {{{
19 echo 'rcpt "comment+<ROUTE>" not matched' >&2 37
38path=$(<<<"$header" sed -En "\\|${pattern}| {s//\\3/p; q}")
39
40# sender want comment on some page, but find no path for this
41if [ $path = "" ]; then
42 echo 'Cannot get target of comment from mail' >&2
20 exit 1 43 exit 1
21fi 44fi
22 45
23output=$output_dir/${route#/}.comment 46# get output path
24exec 1>>$output 47[[ "$path" =~ '/$' ]] && path+=index
48path=${path#/}
49path=${path/.html}
50output=$output_dir/${path}.comment.html
51
52# }}}
53# Get comment from mail body {{{
25 54
26# check mail includes multiple part 55# check mail includes multiple part
27<<<"$headers" grep '^Content-Type:.*mixed' >/dev/null 56if [[ "$CONTENT_TYPE" =~ mixed ]]; then
28if [ $? -eq 0 ]; then 57 boundary="$(<<<"$CONTENT_TYPE" sed -En 's/^.*boundary="(.*)".*$/\1/p')"
29 boundary="$(<<<"$headers" sed -En 's/^Content-Type:.*boundary="(.*)".*$/\1/p')"
30 if [ $boundary = "" ]; then 58 if [ $boundary = "" ]; then
31 echo 'cannot get boundary from mail header' >&2 59 echo 'cannot get boundary from mail header' >&2
32 exit 1 60 exit 1
33 fi 61 fi
34 62
35 # print content of first mail part 63 # print content of first mail part
36 pattern="\\@^--${boundary}\$@" 64 boundaryPat="\\|^--${boundary}\$|"
37 <<<"$contents" sed -n "${pattern},${pattern} p" | sed -n "1,4d; ${pattern} q; p" 65 <<<"$body" sed -n "${boundaryPat},${boundaryPat} p" | sed -n "1,4d; ${boundaryPat} q; p" \
38else 66 | read body
39 # print content
40 <<<"$contents" sed '/^$/,$ p'
41fi 67fi
68
69# }}}
70# Write comment to output file {{{
71
72# add basic html layout for output file if necessary
73if [ ! -f $output ] || ! xmllint --html --nofixup-base-uris $output &>/dev/null; then
74 echo -e '<ul>\n</ul>' >$output
75fi
76# get line of insert position by header field "In-Reply-To"
77if [ -n "${IN_REPLY_TO}" ]; then
78 line=$(grep -n "^<!-- ${IN_REPLY_TO} -->$" $output | cut -d':' -f1)
79fi
80
81# insert comment into output file
82<<-COMMENT sed -i "${line:-1}r /dev/stdin" $output
83 <li>
84 <time datetime="${DATE}">${DATE}</time>
85 <a href="mailto:${mailto}?subject=comment on ${path}&in-reply-to=${MESSAGE_ID}">[reply]</a>
86
87 $(<<<"${body}" markdown)
88
89 <ul>
90 <!-- ${MESSAGE_ID} -->
91 </ul>
92 </li>
93COMMENT
94
95# }}}