#!/bin/sh # shellcheck disable=1090,2153 set -eu usage() { cat <<-'EOF' Usage: mailcfg ACTION mailcfg -h EOF } help() { cat <<-'EOF' Options: -h, --help show this message ACTION one of: - mbsync - msmtp - notmuchcfg - notmuchhook - alot Emit the generated configuration file for the chosen email program. Get the configuration files from $XDG_CONFIG_HOME/mailcfg/*.env, where every *.env file is a shell script that defines the variables used in this program: - $NAME - $LABEL - $IMAP - $SMTP - $ADDR One of the files also needs to define: - $DEFAULT_NAME - $DEFAULT_ADDR - $DEFAULT_LABEL An example of such file could be "30-andre@work.com.env": #!/bin/sh set -eu NAME='André!' LABEL='Work' IMAP='imap.work.com' SMTP='smtp.work.com' ADDR='andre@work.com' Examples: Get the alot configuration file: $ mailcfg alot EOF } for flag; do case "$flag" in --) break ;; --help) usage help exit ;; *) ;; esac done while getopts 'h' flag; do case "$flag" in h) usage help exit ;; *) usage >&2 exit 2 ;; esac done shift $((OPTIND - 1)) ACTION="${1:-}" eval "$(assert-arg "$ACTION" 'ACTION')" CFGDIR="${XDG_CONFIG_HOME:-$HOME/.config}/mailcfg" mbsync() { cat <<-'EOF' SyncState * Create Both Expunge Both Remove Both Sync All EOF for env in "$CFGDIR"/*.env; do . "$env" cat <<-EOF ## $LABEL IMAPAccount $LABEL Host $IMAP User $ADDR PassCmd "pass show $ADDR" SSLType IMAPS IMAPStore ${LABEL}Remote Account $LABEL MaildirStore ${LABEL}Local Path ~/Maildir/$LABEL/ Inbox ~/Maildir/$LABEL/INBOX SubFolders Verbatim Channel ${LABEL}Folders Far :${LABEL}Remote: Near :${LABEL}Local: Patterns * Group $LABEL Channel ${LABEL}Folders EOF done } msmtp() { cat <<-'EOF' defaults auth on tls on port 587 syslog on logfile ~/.local/var/log/msmtp EOF for env in "$CFGDIR"/*.env; do . "$env" cat <<-EOF account $LABEL host $SMTP from $ADDR user $ADDR passwordeval pass show $ADDR EOF done cat <<-EOF account default : $DEFAULT_LABEL EOF } notmuchcfg() { for env in "$CFGDIR"/*.env; do . "$env" done cat <<-EOF [user] name = $DEFAULT_NAME primary_email = $DEFAULT_ADDR EOF printf 'other_email = ' for env in "$CFGDIR"/*.env; do . "$env" if [ "$ADDR" = "$DEFAULT_ADDR" ]; then continue fi echo "$ADDR" done | paste -sd';' cat <<-'EOF' [new] tags = new; ignore = .mbsyncstate;.uidvalidity [search] exclude_tags = deleted;spam [maildir] synchronize_flags = true EOF } notmuchhook() { LABELS='' for env in "$CFGDIR"/*.env; do . "$env" if [ -z "$LABELS" ]; then LABELS="$LABEL" else LABELS="$LABELS $LABEL" fi done sed \ -e "s|@DIRS@|$LABELS|g" \ -e "s|@DEFAULT_LABEL@|$DEFAULT_LABEL|g" \ "$CFGDIR"/post-new } alot() { cat <<-'EOF' attachment_prefix = "~/Downloads/" [bindings] i = toggletags inbox I = search folder:/INBOX/ AND NOT tag:killed AND NOT tag:archive EOF echo " z archive s spam u unread r keep t track " | while read -r l; do if [ -z "$l" ]; then continue fi LC="$( echo "$l" | cut -d' ' -f1)" TAG="$(echo "$l" | cut -d' ' -f2)" UC="$(echo "$LC" | tr '[:lower:]' '[:upper:]')" cat <<-EOF $LC = toggletags $TAG $UC = search tag:$TAG AND NOT tag:killed EOF done cat <<-'EOF' M = search folder:/lists/ AND NOT tag:killed m = compose --tags inbox [[thread]] v = pipeto urlscan 2>/dev/null V = pipeto 'gpg -d | less' r = reply --all R = reply ' ' = fold; untag unread; move next unfolded P = pipeto 'git am' [accounts] EOF for env in "$CFGDIR"/*.env; do . "$env" cat <<-EOF [[$LABEL]] realname = $NAME address = $ADDR sendmail_command = msmtpq --account=$LABEL -t sent_box = maildir://~/Maildir/$LABEL/Sent draft_box = maildir://~/Maildir/$LABEL/Drafts gpg_key = 5BDAE9B8B2F6C6BCBB0D6CE581F90EC3CD356060 EOF done } case "$ACTION" in mbsync|msmtp|notmuchcfg|notmuchhook|alot) "$1" ;; *) printf 'Unsupported ACTION: "%s".\n\n' "$ACTION" >&2 usage >&2 exit 2 ;; esac