diff options
Diffstat (limited to 'bin/mailsync')
| -rwxr-xr-x | bin/mailsync | 157 |
1 files changed, 157 insertions, 0 deletions
diff --git a/bin/mailsync b/bin/mailsync new file mode 100755 index 0000000..0fcb43b --- /dev/null +++ b/bin/mailsync @@ -0,0 +1,157 @@ +#!/bin/bash + +set -e +[ -n "$DEBUG" ] && set -x + +# check requirements +for tool in mbsync notify-send python awk gdbus iconez; do + if ! command -v "$tool" >/dev/null; then + printf '%s: %s not installed but required\n' "$(basename "$0")" "$tool" >&2 + exit 1 + fi +done + +maildir="${HOME}/mail" +cachefile=${XDG_CACHE_HOME}/mailsync.lastrun + +accounts=(gnzler hu) +list= +verbose= +while getopts a:lvh opt; do + case "${opt}" in + a) accounts=("${OPTARG}") ;; + l) list=1 ;; + v) verbose=1 ;; + h | ?) + printf "usage: %s [-h] [ACCOUNT...]\n" "$(basename "$0")" + printf "\n" + printf " -a ACCOUNTS, accunts to sync (default: \"%s\")\n" "${accounts[@]}" + printf " -l list mail\n" + printf " -v be verbose" + printf "\n" + exit 2 + ;; + esac +done +shift $((OPTIND - 1)) + +if [ -n "$1" ]; then + accounts=("$@") +fi + +notifysend() { + local summary=$1 + local body=$2 + local ico + shift 2 + + if ! printf "%s" "$*" | grep -- "-i" >/dev/null; then + ico="📨 " + fi + + # -i /usr/share/icons/mdi/scalable/email-plus.svg \ + notify-send $@ \ + -a mailsync \ + -c audible \ + "${ico:-}${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() or [""])[0]).strip()))))))' +} + +handle_msg() { + local msg=$1 + local from + local subject + local listid + local ico + + from=$(sed ':a; N; $!b a; s/\n\s\{1,\}/ /g' "${msg}" | awk '/^From:/{print}' | cut -d: -f2 | decode) + subject=$(sed ':a; N; $!b a; s/\n\s\{1,\}/ /g' "${msg}" | awk '/^Subject:/{print}' | cut -d: -f2 | decode) + listid=$(sed ':a; N; $!b a; s/\n\s\{1,\}/ /g' "${msg}" | awk '/^List-ID:/{print}' | cut -d: -f2 | decode) + if [ -n "${listid}" ]; then + subject="${subject}\n<span alpha='90%' size='small'>~> $(echo "${listid}" | sed -e 's|<|\<|g' -e 's|>|\>|g')</span>" + ico="$(iconez -sn email-multiple-outline)" + else + ico="$(iconez -sn email-receive-outline)" + fi + notifysend "${from}" "${subject}" -i "${ico}" -t 2000 +} + +list_msg() { + local acct=$2 + local args=(-type f -not -name '\.*') + local cachefile="${cachefile}.${acct}" + + find "${maildir}"/"${acct}"/{INBOX,lists}/new/ "${args[@]}" 2>/dev/null || true + + # local cur_or_new=${1:-new} + # if [ "${cur_or_new}" = "new" ]; then + # find "${maildir}"/"${acct}"/{INBOX,lists}/"${cur_or_new}"/ "${args[@]}" 2>/dev/null || true + # else + # find "${maildir}"/"${acct}"/*/"${cur_or_new}"/ "${args[@]}" 2>/dev/null || true + # fi +} + +run_notify() { + local acct=$1 + local new_mail + + new_mail=$(list_msg new "${acct}") + if [ -n "${new_mail}" ]; then + local num + num="$(echo "${new_mail}" | grep -c INBOX)" + # always print INBOX messages + for msg in $(echo "${new_mail}" | grep INBOX); do handle_msg "$msg"; done + + # everything else, limit to 5, just print the count otherwise + num="$(echo "${new_mail}" | grep -c -v INBOX)" + notifysend "${acct}: new" "Found ${num} new mail" -i "$(iconez -sn email-receive-outline)" + [ "${num}" -gt 5 ] && return + for msg in $(echo "${new_mail}" | grep -v INBOX); do handle_msg "$msg"; done + fi +} + +run_sync() { + local acct=$1 + + # exit if we're already running + pgrep mbsync >/dev/null && { + echo "mbsync is already running." + notifysend "mailsync stopped" "mbsync is already running" -i "$(iconez -sn email-off-outline)" + return + } + + # persistent notification + id=$(notifysend "${acct}: fetching new mail..." "running mbsync" -i "$(iconez -sn email-sync-outline)" --print-id --expire-time=0) + + mbsync_args= + [ -n "${verbose}" ] && mbsync_args="--verbose" + mbsync $mbsync_args --config="$HOME/.config/mbsyncrc" "$acct" + clear-notification "$id" + # create cachefile + touch "${cachefile}.${acct}" + + # index new messages + command notmuch >/dev/null 2>&1 && notmuch new +} + +# 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 + run_sync "${acct}" + run_notify "${acct}" + ) & +done + +wait |