From 84bfeb66b7e80072f63513e69a22ec9fb6e61d46 Mon Sep 17 00:00:00 2001 From: Robert Günzler Date: Fri, 15 Apr 2022 15:27:48 +0200 Subject: rework mail setup --- .config/mbsyncrc | 73 ++++++++++++++++++++++++++++++-- bin/hibiki/mailsync | 119 +++++++++++++++++++++++++++++++++++++++------------- 2 files changed, 158 insertions(+), 34 deletions(-) diff --git a/.config/mbsyncrc b/.config/mbsyncrc index 30c5c0b..9e8725a 100644 --- a/.config/mbsyncrc +++ b/.config/mbsyncrc @@ -1,20 +1,85 @@ +## gnzler + IMAPAccount gnzler Host mail.gandi.net User robert@gnzler.io PassCmd "pass email/gnzler.io | head -n1" SSLType IMAPS +IMAPStore gnzler +Account gnzler + MaildirStore local Path ~/Mail/gnzler/ INBOX ~/Mail/gnzler/INBOX SubFolders Verbatim -IMAPStore gnzler -Account gnzler - -Channel primary +Channel gnzler Far :gnzler: Near :local: Patterns INBOX Archive/2022 Drafts Sent lists Create Near +SyncState * +# WATCH OUT WHAT YOU'RE DOING +Expunge both + +## selfhosted + +IMAPAccount selfhosted +Host localhost:1430 +User postmaster@gnzler.de +PassCmd "pass email/postmaster@gnzler.io | head -n1" +SSLType None + +IMAPStore selfhosted +Account selfhosted + +## backup + +MaildirStore backup +Path ~/Mail/server.bak/ +INBOX ~/Mail/server.bak/INBOX +SubFolders Verbatim + +Channel backup +Far :gnzler: +Near :backup: +Patterns * +Create Both +SyncState * +Sync Pull + +## restore + +Channel restore +Far :selfhosted: +Near :backup: +Patterns * +Create Both +SyncState * +Sync Push + +## hu + +IMAPAccount hu +Host mailbox.informatik.hu-berlin.de +User guenzler +PassCmd "pass email/hu-berlin.de | head -n1" +SSLType IMAPS + +MaildirStore local-hu +Path ~/Mail/hu/ +INBOX ~/Mail/hu/INBOX +SubFolders Verbatim + +IMAPStore hu +Account hu + +Channel hu +Far :hu: +Near :local-hu: +Patterns INBOX +Create Near +SyncState * +# WATCH OUT WHAT YOU'RE DOING Expunge both diff --git a/bin/hibiki/mailsync b/bin/hibiki/mailsync index ae96bd0..3fc940f 100755 --- a/bin/hibiki/mailsync +++ b/bin/hibiki/mailsync @@ -3,52 +3,111 @@ set -e [ -n "$DEBUG" ] && set -x -# -# mbsync call here: -# -mbsync -c "$HOME/.config/mbsyncrc" primary +maildir="${HOME}/Mail" +cachefile=${XDG_CACHE_HOME}/mailsync.lastrun -# -# notifications-related only from here: -# +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)) -MAILDIR_PATTERN=$HOME/Mail/* -new_mail=$(find ${MAILDIR_PATTERN}/*/new/ -type f | wc -l) -old_mail=$(find ${MAILDIR_PATTERN}/*/cur/ -type f | wc -l) +notifysend() { + local summary=$1 + local body=$2 -notify() { notify-send \ -i /usr/share/icons/mdi/scalable/email-plus.svg \ -a mailsync \ -c audible \ - "$1" "$2" + "${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])))))' + 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_new_msg() { - msg=$1 +handle_msg() { + local msg=$1 + local from + local subject + local listid - from=$(awk '/^From:/{print $2}' "$msg" | decode) - subject=$(awk '/^Subject:/{print}' "$msg" | cut -d' ' -f2- | decode) - to=$(awk '/^To:/{print $2}' "$msg" | decode) + 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~> $(echo "${listid}" | sed -e 's|<|\<|g' -e 's|>|\>|g')" + fi + notifysend "${from}" "${subject}" +} - if [[ "$to" =~ (lists.sr.ht|noreply.github.com) ]]; then - subject="$to\n$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}" - notify "new mail from: $from" "$subject" + [ "${cur_or_new}" = "new" ] && [ -f "${cachefile}" ] && args+=(-newer "${cachefile}") + find "${maildir}"/"${acct}"/*/"${cur_or_new}"/ "${args[@]}" 2>/dev/null } -if [ "$new_mail" -gt 0 ]; then - new_inbox=$(find ${MAILDIR_PATTERN}/INBOX/new/ -type f) - if [ -n "$new_inbox" ]; then - for msg in "${new_inbox[@]}"; do - handle_new_msg "$msg" - done - else - notify "new mail" "new: $new_mail / old: $old_mail" - fi +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 -- cgit 1.4.1