I’ve been using not-much mail in combination with offlineimap and astroid (as the front-end) to handle my email.

I wanted to implement a very useful function that I use with outlook for my work email: putting emails to sleep for a time and having them wake up automatically.

Basically, if there’s something I don’t need to worry about for a while, I don’t want to see it. I want to hide if for a while and then have it show up again later. I originally found the concept in this blog post.

Using the python library for not-much, I whipped up a script that let’s me implement this. I call it nmSandman (not-much Sandman).

nmSandman

Have offlineimap or not-much run this as part of a hook before or after new mail arrives. Also possible to have astroid run this in its ‘polling’ script or to just make a cron job for it.

#!/usr/bin/python
import notmuch
import re, datetime
from dateutil.relativedelta import relativedelta
#from pprint import pprint
today = datetime.datetime.now().date()
db = notmuch.Database(mode=notmuch.Database.MODE.READ_WRITE)

# Find Emails with Sleep Tags
query = db.create_query('tag:/^sleep[0-9]+[mwd]*$/')
for msg in query.search_messages():
    tags = msg.get_tags()
    for t in tags:
        if re.match(r'^sleep[0-9]+[mwd]*$', t):
            if re.match(r'^[0-9]{8}$',t[5:]):
                endDate = datetime.datetime.strptime(t[5:], '%Y%m%d').date()
                #print(t, endDate)
                if endDate < today:
                    #print("msg will now wake up")
                    msg.remove_tag(t)
            elif re.match(r'^[0-9]+[mwd]+$', t[5:]): 
                # Change Relative Delays to Dates
                #print("Changing delay to date")
                delay = int(t[5:-1])
                if t[-1] == 'w':
                    endDate = today + datetime.timedelta(weeks=delay)
                elif t[-1] == 'm':
                    endDate = today + relativedelta(months=+delay)
                else:
                    endDate = today + datetime.timedelta(days=delay)
                endTag = "sleep" + endDate.strftime('%Y%m%d')
                msg.remove_tag(t)
                msg.add_tag(endTag)

Workflow

When I want an email to go to sleep, I tag it with sleepX[dwm] to tell it to sleep for X days, weeks, or months. The script above searches for all messages with such tags and then changes them to the format sleepYYYYMMDD.

I’ve set the start-up searches in astroid’s config file to ignore any message with matching tags AND NOT tag:/^sleep[0-9]+[mwd]*$/. This way, I don’t see sleeping emails.

When it’s time to wake up, the script above removes the sleep tag, and the emails show up again in my searches.

Alot

The script works equally well with Alot. I’ve chosen to use astroid instead of Alot because astroid seems to start up much faster for me, and every once in a while, I do need to view the html-formatted message (which I couldn’t figure out how to get Alot to do)

Alot has a pipe-message-to command that should let me pipe messages to a browser or something, but I couldn’t figure out how to get that to work. So I switched to astroid even though I really like the ncurses feel of Alot.