using mutt, mu, offlineimap

  • August 26, 2011
Table of Contents

I have long experimented with an optimal mail setup. As some readers may be aware there are a lot of tutorials on how how to use mutt and offlineimap. I have had a mutt and offlineimap setup for quite a long time, however I decided to tune it a bit lately.

Why mutt? There are numerous articles out there referencing more efficient email handling. Merlin Mann’s InboxZero is quite popular. The basic idea is to never let any mail unprocessed, don’t show notifications and only check mails in certain intervals. If you use Apple Mail, you can use Mail Act-On which is quite nice as well. However mutt is much more efficient and flexible in it’s mail processing capabilities. At the same time it’s much faster than thunderbird.

I had switched to thunderbird when I discarded my old hackintosh netbook, with it’s slow Atom CPU. The most annoying part to me it seemed, was the fact that it would always bug me with nagscreens when my laptops connection dropped. (and the power consumption)

The offlineimap setup I use thus makes some use of NetworkManager to start and stop offlineimap and msmtpq when an internet connection exists. First of all I have two offlineimap setups, both offlineimap setups create the mailbox folders for mutt automatically as described in the offlineimap manual.

[general]
accounts = Gmail
maxsyncaccounts = 1
# This will suppress anything but errors
ui = Noninteractive.Quiet

[mbnames]
enabled = yes
filename = ~/.mutt/mailboxes
header = "mailboxes "
peritem = "+%(accountname)s/%(foldername)s"
sep = " "
footer = "\n"


[Account Gmail]
localrepository = GmailLocal
remoterepository = GmailRemote
autorefresh = 10
quick       = 5

[Repository GmailLocal]
type = Maildir
localfolders = ~/Mail/GMAIL
restoreatime = no

[Repository GmailRemote]
type = IMAP
ssl = yes
remotehost = imap.gmail.com
remoteuser = fubar@gmail.com

nametrans = lambda foldername: re.sub ('.*Drafts.*', 'drafts',
                              re.sub ('.*Sent Mail.*', 'sent',
                              re.sub ('.*Starred.*', 'flagged', folder)))
folderfilter = lambda foldername: foldername in ['.*INBOX.*', 'archives', 'pending']

Since I use the same hotkey for drafts and sent mail, I use nametrans to have these folders have a consistent name across all my mail accounts. The password for foobar@gmail.com is set in the .netrc file. Also this is the minimal sync setting for whenever I’m on 3G or similar. Since my laptop has an internal wireless and ethernet device eth0 and wlan0 are what I use to assume that there is proper internet existing. NetworkManager will thus call my dispatch.d script which will in turn launch
offlineimap and msmtpq.

#!/bin/sh -e

INTERFACE=$1 # The interface which is brought up or down
STATUS=$2 # The new state of the interface

USER=misterfoo
HOME=/home/$USER
CACHE=$HOME/.cache/daemonize
DAEMONIZE=/usr/sbin/daemonize
OFFLINEIMAP=/usr/bin/offlineimap
NOTIFY=/usr/bin/notify-send

# If the display variable is unset, find the correct display number
# and set the variable.
if [ -z "$DISPLAY" ]; then
    console=`fgconsole`
    dispnum=`ps t tty$console | sed -n -re 's,.*/X(org)? .*:([0-9]+).*,\2,p'`
    export DISPLAY=":$dispnum"
fi


case "$STATUS" in
    'up') # $INTERFACE is up
        su - $USER -c "$NOTIFY -i info 'Network action' 'Starting offlineimap'"
        if [[ "$INTERFACE" == "eth0" || "$INTERFACE" == "wlan0" ]]; then
            $DAEMONIZE -u $USER -l $CACHE/offline_lock -p $CACHE/offline_pid $OFFLINEIMAP -c $HOME/.offlineimaprc_full
        else
            $DAEMONIZE -u $USER -l $CACHE/offline_lock -p $CACHE/offline_pid $OFFLINEIMAP -c $HOME/.offlineimaprc
        fi
        $DAEMONIZE -u $USER -l $CACHE/msmtp_lock   -p $CACHE/msmtp_pid   $HOME/bin/msmtprun
        ;;
    'down') # $INTERFACE is down
        # Check for active interface and down if no one active
        if [ ! `nm-tool|grep State|cut -f2 -d' '` == "connected" ]; then
            su - $USER -c "$NOTIFY -i info 'Network action' 'Stopping offlineimap'"
            kill -TERM `cat $CACHE/offline_pid`
            kill -TERM `cat $CACHE/msmtp_pid`
        fi
        ;;
esac

daemonize is a little tool for running any command as daemon. With pid- and lockfile support. Since I use msmtp-queue to send mails and I may or may not want to send mails when I’m offline msmtpq -r needs to be run whenever I connect to the internet. Msmtprun is just that, a script that tries to run msmtq -r once every 5 minutes.

#!/bin/sh

while [ 1 ]; do
    /usr/bin/msmtpq -r &
    sleep 300
done

trap "echo -n exiting... ;kill $!;exit" INT TERM

A mutt config that should work in both linux and osx(with minor adjustments) can be found on my github page

I also recently switch to using mu instead of mairix, it’s much faster and more stable than mairix,

You basically do

mu index --quiet --maildir ~/Mail

once and then add something like

31 */2 * * * /usr/bin/mu index --quiet --maildir ~/Mail

to your crontab. The reindexing is very fast in my experience. You can find the hotkeys I use in my hooks and macros and macros_static files on github.

comments powered by Disqus

Related Posts

Protonet webOS socket example

I’ve just written a sample application for creating sockets in webOS applications. You can read the full blog post about it on the protonet homepage

Read More

Finally migrated to jekyll

I’ve finally jumped the bandwagon and migrated my blog to jekyll, takes a little to get used to, but I can’t say I regret it.

Read More

Changing the cursor color within tmux based on vi mode

As outlined on SE and SU you can execute actions in zsh when you change between normal and insert mode in a vi mode zsh session.

Read More