Skip to content
Patrick Totzke edited this page May 10, 2020 · 4 revisions

Passwords

I use pass to store my passwords. It uses git and gpg for that and is awesome.

intialize store and add a passwd

pass init
pass add mail/gmail

The passwd can be accessed using pass mail/gmail.

My .profile contains the following line to start a SSH/GPG agent which caches the password to unlock my gpg key.

export `gnome-keyring-daemon -s`

Fetching Mail (mbsync)

http://isync.sourceforge.net/mbsync.html

To synchronize mailboxes. My ~/.mbsyncrc looks something like the following. It uses PassCmd to get the imap passwords from pass.

IMAPAccount gmail
Host imap.gmail.com
User patricktotzke@gmail.com
PassCmd "/usr/bin/pass mail/gmail"
SSLVersions TLSv1.2
SSLType IMAPS
CertificateFile /etc/ssl/certs/ca-certificates.crt

IMAPStore gmail-remote
Account gmail
UseNamespace no

MaildirStore gmail-local
Path ~/mail/gmail/
Inbox ~/mail/gmail/Inbox

Channel gmail
Master :gmail-remote:
Slave :gmail-local:
# Take all except inside "Google Mail" apart from Send and Drafts, then discard IMAP duplicates
Patterns  * !"[Google Mail]*" "[Google Mail]/Sent Mail" "[Google Mail]/Drafts" "lists" !Sent !Drafts !starred
# Automatically create missing mailboxes, both locally and on the server
Create Both
# Save the synchronization state files in the relevant directory
SyncState *
CopyArrivalDate yes


IMAPAccount other
Host otherhost.com
User "otheruser@other.com"
PassCmd "/usr/bin/pass mail/other"

IMAPStore other-remote
Account other
UseNamespace no

MaildirStore other-local
Path ~/mail/other/
Inbox ~/mail/other/Inbox

Channel other
Master :other-remote:
Slave :other-local:
Create Both
SyncState *
CopyArrivalDate yes
Sync Pull

Tagging (afew)

I use afew for tagging. My ~/.config/afew/config looks like this.

[global]

[SpamFilter]
[KillThreadsFilter]
[ListMailsFilter]
[ArchiveSentMailsFilter]
sent_tag = sent

# add specific tags

[Filter.0]
query = 'subject:alot'
tags = +alot
message = alot mails

[Filter.1]
query = 'to:notmuch@notmuchmail.org AND (subject:emacs OR subject:elisp OR "(defun" OR "(setq" OR PATCH)'
tags = -inbox;-new;+notmuch
message = notmuch emacs stuff

[HeaderMatchingFilter.0]
header = subject
pattern = .*CfP.*
tags = +C4P;-inbox;-new
message = call for papers


# what's still new goes into the inbox
[InboxFilter]

Automation

I use the script below to check and index new mails from cron (and sometimes manually). It accesses passwords through the running gpg-agent.

It will sync all accounts configured for mbsync for which there is an equally named file in $ACCOUNTDIR. This allows me to temporarily disable polling specific accounts by removing/touching the file $ACCOUNTDIR/accountname.

#!/bin/bash
#
# Download and index new mail.
#
# Copyright (c) 2017 Patrick Totzke
# Dependencies: flock, nm-online, mbsync, notmuch, afew
# Example crontab entry:
#
#   */2 * * * * /usr/bin/flock -n /home/pazz/.pullmail.lock /home/pazz/bin/pullmail.sh > /home/pazz/.pullmail.log
# 

PATH=/home/pazz/.local/bin:/usr/local/bin/:$PATH
ACCOUNTDIR=/home/pazz/.pullmail/

# this makes the keyring daemon accessible
function keyring-control() {
        local -a vars=( \
                DBUS_SESSION_BUS_ADDRESS \
                GNOME_KEYRING_CONTROL \
                GNOME_KEYRING_PID \
                XDG_SESSION_COOKIE \
                GPG_AGENT_INFO \
                SSH_AUTH_SOCK \
        )
        local pid=$(ps -C i3 -o pid --no-heading)
        eval "unset ${vars[@]}; $(printf "export %s;" $(sed 's/\x00/\n/g' /proc/${pid//[^0-9]/}/environ | grep $(printf -- "-e ^%s= " "${vars[@]}")) )"
}

function log() { 
    notify-send -t 2000  'mail sync:' "$@"
}

function die() { 
    notify-send -t 2000 -u critical 'mail sync:' "$@"
    exit 1
}



# Let's Do stuff
keyring-control

# abort as soon as something fails
set -e

# abort if not online
nm-online -x -t 0

echo ---------------------------------------------------------
date
for accfile in `ls $ACCOUNTDIR`;
do
    ACC=$(basename $accfile)
    echo ------------------------  $ACC   ------------------------
    mbsync -V $ACC || log "$ACC failed"
done

# index and tag new mails
echo ------------------------ NOTMUCH ------------------------
notmuch new 2>/dev/null || die "NOTMUCH new failed"

echo ------------------------  AFEW   ------------------------
afew -v --tag --new || die "AFEW died"

echo ---------------------------------------------------------
echo "all done, goodbye."

I have a binding to this script in alot as well, to trigger it manually:

[bindings]
  % = "shellescape '/home/pazz/bin/pullmail.sh'; refresh"

Sending Mail (msmtp)

http://msmtp.sourceforge.net/

My `~/.msmtpc' looks like this.

account gmail
 host smtp.gmail.com
 from patricktotzke@gmail.com
 auth on
 tls on
 tls_certcheck off
 user patricktotzke@gmail.com
 passwordeval /usr/bin/pass mail/gmail
 port 587

account other
 host smtp.other.com
 from otheruser@other.com
 auth login
 tls on
 tls_min_dh_prime_bits 512
 user otheruser@other.com
 passwordeval /usr/bin/pass mail/other
 port 587

Polybar widget

I have a small custom polybar widget that shows an envelope in varying colour depending on my inbox: My ~/.config/polybar/config contains the following.

modules-right = mailicon mailicon-unread mailcount

[module/mailcount]
type = custom/script
interval = 1
format-padding = 0
label = %output:0:2%

exec = ~/.config/polybar/mail count
click-left = ~/.config/polybar/mail alot
click-middle = echo middle
click-right = echo right

[module/mailicon-unread]
type = custom/script
interval = 1
format-foreground = ${colors.background-highlight}
exec = ~/.config/polybar/mail icon-unread
click-left = ~/.config/polybar/mail alot
click-middle = echo middle
click-right = echo right

[module/mailicon]
type = custom/script
interval = 1
format-foreground = ${colors.foreground-alt}
exec = ~/.config/polybar/mail icon
click-left = ~/.config/polybar/mail alot
click-middle = echo middle
click-right = echo right

~/.config/polybar/mail is this simple script, which gets infor from notmuch and prints some icon:

#!/bin/bash

QUERY="is:inbox and not tag:killed"
IMG=""
#"🖂"

UNREAD=$(notmuch count $QUERY and is:unread)
if [ $1 = "count" ]; then
   echo $(notmuch count $QUERY)
elif [ $1 = "icon" ]; then
   if [ $UNREAD = "0" ]; then
       echo $IMG
   else
       echo ""
   fi
elif [ $1 = "icon-unread" ]; then
   if [ $UNREAD != "0" ]; then
       echo $IMG
   else
       echo ""
   fi
elif [ $1 = "alot" ]; then
   urxvt -e alot search $QUERY &
fi