#!/bin/bash set -eu [ -n "${DEBUG:-}" ] && set -x # check requirements for tool in mbsync fyi python awk; 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:-$HOME/.cache}/mailsync.lastrun accounts=(gnzler) 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 notifyclose() { fyi --close "$1" } notifysend() { local summary="${1:?missing summary}" body="${2:?missing body}" shift 2 fyi --print-id $@ -a mailsync \ -i "${ico:-}" \ "$summary" "$body" | cut -d= -f2 } try() { [ "$1" = "--" ] && shift 1 if ! { error=$( set +x eval $* 2>&3 ); } 3>&1; then notifysend "failed :(" "$error" -c error return 1 fi } 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()))))))' } 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 } run_notify() { local acct=$1 local new_mail local num local nid new_mail=$(list_msg new "${acct}") num=$(echo "$new_mail" | wc -l) nid=$(notifysend "${acct}: new mail" "found ${num} new messages" --expire-time=6000) } run_sync() { local acct=$1 local nid local ret # exit if we're already running pgrep mbsync >/dev/null && { echo "mbsync is already running." notifysend "${acct}: mailsync stopped" "mbsync is already running" return } # flush msmtp nid=$(notifysend "${acct}: flushing queue" "running msmtp-queue" --expire-time=0) try -- msmtp-queue -r || true # run sync nid=$(notifysend "${acct}: syncing mail" "running mbsync" --expire-time=0 --replaces=$nid) mbsync_args= [ -n "${verbose}" ] && mbsync_args="--verbose" try -- mbsync $mbsync_args --config="$HOME/.config/mbsyncrc" "$acct" # create cachefile touch "${cachefile}.${acct}" # index new messages if command -v notmuch >/dev/null 2>&1; then nid=$(notifysend "${acct}: syncing mail" "running notmuch" --expire-time=0 --replaces=$nid) try -- notmuch new fi # update address book if command -v maildir-rank-addr >/dev/null 2>&1; then nid=$(notifysend "${acct}: syncing mail" "running maildir-rank-addr" --expire-time=0 --replaces=$nid) maildir-rank-addr \ --maildir=${maildir}/${acct} \ --outputpath=${maildir}/addressbook \ --addresses='(r|robert)@gnzler\.(de|io),robert(|\.)guenzler@gmail.com,therobotbase@gmail.com,robertg@balena.io,robert.gunzler@postman.com,robert@unikraft.io' \ --filters='r\+.*@gnzler\.(de|io)' fi notifyclose "$nid" } # 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