summary refs log tree commit diff
path: root/bin/hibiki/mailsync
blob: 3fc940f7c56420d54e77583225552c10380210cc (plain) (blame)
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
#!/bin/bash

set -e
[ -n "$DEBUG" ] && set -x

maildir="${HOME}/Mail"
cachefile=${XDG_CACHE_HOME}/mailsync.lastrun

accounts=(gnzler hu)
list=
verbose=
while getopts a:l:vh opt; do
	case "${opt}" in
	a) accounts=("${OPTARG}") ;;
	l) list="${OPTARG}" ;;
	v) verbose=1 ;;
	h | ?)
		printf "usage: %s [-h]\n" "$(basename "$0")"
		printf "\n"
		printf "  -a ACCOUNTS, accunts to sync (default: \"%s\")\n" "$(echo "${accounts[@]}")"
		printf "  -l CUR_OR_NEW, list new or current mails (default: \"%s\")\n" "${list}"
		printf "  -v be verbose"
		printf "\n"
		exit 2
		;;
	esac
done
shift $((OPTIND - 1))

notifysend() {
	local summary=$1
	local body=$2

	notify-send \
		-i /usr/share/icons/mdi/scalable/email-plus.svg \
		-a mailsync \
		-c audible \
		"${summary}" "${body}"
}

decode() {
	python -c 'import sys;import email.header;print(("".join(list(map(lambda s: s[0] if (type(s[0]) == str) else s[0].decode(s[1] or "utf-8"), email.header.decode_header((sys.stdin.readlines()[0]).strip()))))))'
}

handle_msg() {
	local msg=$1
	local from
	local subject
	local listid

	from=$(awk '/^From:/{print}' "${msg}" | cut -d':' -f2- | decode)
	subject=$(awk '/^Subject:/{print}' "${msg}" | cut -d':' -f2- | decode)
	listid=$(awk '/^List-ID:/{print}' "${msg}" | cut -d':' -f2- | decode)
	if [ -n "${listid}" ]; then
		subject="${subject}\n<span alpha='90%' size='small'>~> $(echo "${listid}" | sed -e 's|<|\&lt;|g' -e 's|>|\&gt;|g')</span>"
	fi
	notifysend "${from}" "${subject}"
}

notify() {
	local acct=$1
	local new_mail

	new_mail=$(list_msg new "${acct}")
	if [ -n "$new_mail" ]; then
		printf "found %d new mail\n" "$(echo "${new_mail}" | wc -l)"
		for msg in ${new_mail}; do handle_msg "$msg"; done
	fi
}

list_msg() {
	local cur_or_new=${1:-new}
	local acct=$2
	local args=(-type f)
	local cachefile="${cachefile}.${acct}"

	[ "${cur_or_new}" = "new" ] && [ -f "${cachefile}" ] && args+=(-newer "${cachefile}")
	find "${maildir}"/"${acct}"/*/"${cur_or_new}"/ "${args[@]}" 2>/dev/null
}

sync() {
	local acct=$1

	# exit if we're already running
	pgrep mbsync >/dev/null && {
		echo "mbsync is already running."
		return
	}
	mbsync_args=
	[ -n "${verbose}" ] && mbsync_args="--verbose"
	mbsync $mbsync_args --config="$HOME/.config/mbsyncrc" "$acct"
	# create cachefile
	touch "${cachefile}.${acct}"
}

# only list new mail, don't sync
if [ -z "${accounts[*]}" ]; then
	echo "no account specified" >&2
	exit 1
fi

for acct in "${accounts[@]}"; do
	(
		if [ -n "${list}" ]; then
			list_msg "${list}" "${acct}"
			exit 0 # exit ()& subshell
		fi
		sync "${acct}"
		notify "${acct}"
	) &
done

wait