mailhacks.org 9.9 KB

mailhacks with offline imap, org mode and notmuch

This is a set of hacks to pull email with https://github.com/OfflineIMAP/offlineimap, and classify it with https://notmuchmail.org/ tags and searches.

Reading mail is also accomplished using the notmuch emacs interface https://notmuchmail.org/screenshots/, and sending is accomplished with the standard emacs message mode, though other options (e.g. Thunderbird) for reading/sending a possible since offlineimap is just dumping files in a MailDir format.

This is an application of Marcus Ranum's concept "Artificial Ignorance" to my inbox, or egrep -v ignoreThis\|ignoreThat\|ignoreTheOther until there's nothing left. The goal is to keep inbox nearly empty

Basic process

  • pull mail down to local store with offlineimap

  • Look at inbox, apply tags to the largest unclassified entries

  • move them out of inbox

  • repeat

Ingesting Mail

  • This works with multiple IMAP accounts

Pull my latest mail

  import subprocess
  import sys

  cmd = "offlineimap > %s" % ("offlineimap.log")
  print "Running '%s'..." % (cmd),

  try:
      #retcode = subprocess.call("echo foo", shell=True)
      retcode = subprocess.call(cmd, shell=True)
      if retcode < 0:
          print >>sys.stderr, "Child was terminated by signal", -retcode
          print >>sys.stdout, "Child was terminated by signal", -retcode
      else:
          print >>sys.stderr, "Child returned", retcode
          print >>sys.stdout, "Child returned", retcode
  except OSError as e:
      print >>sys.stderr, "Execution failed:", e
      print >>sys.stdout, "Execution failed:", e

  print "Done."
Running 'offlineimap > offlineimap.log'... Child returned 0
Done.

Tell notmuch about the new mail

exec 2>&1;date;set -e; set -u; set -x

notmuch new
Fri Aug 19 07:09:12 EDT 2016
+ notmuch new
Processed 125 total files in 1s (63 files/sec.).
Added 119 new messages to the database. Detected 1 file rename.

Classifying Mail

Tags to classify things

tags header subject comments
+onion +lists to security-onion
+argus +lists subject ARGUS
+saag +lists to saag
+shmoolabs +lists subject Labs-Alumni
+honeypot +lists from honeynetproject@honeynet.org
+opsec +lists subject OPSEC
+listmgt +lists from -owner
+listmgt +lists from -requests
+lists subject BSATroop161
+sns from sns.amazonaws.com
+social from linkedin
+social subject Google+
+social from twitter.com eludom
+social from facebookmail.com>
+accounts from audible.com
+accounts from Amazon Web Services
+accounts from southwest.com
+accounts from account-update@amazon.com
+accounts from accounts.google.com
+accounts -inbox from livestream.com eludom
+finance from Mint.com
+church from lcfweb.org
+me from gmj
+me from eludom
+me from George Jones
+me from fooologist
+spam -inbox from tumblr.com
+spam -inbox +accounts subject Spam
+spam -inbox from noreply@youtube.com
+spam -inbox from news-googleplay@google.com
+spam +accounts -inbox from discard-report@pobox.com

Apply tags

import subprocess
import sys

for i in range(len(data)):
    cmd = "notmuch tag %s -- %s:\"%s\"" % (data[i][0],data[i][1],data[i][2])
    print "Running '%s'..." % (cmd),

    try:
        #retcode = subprocess.call("echo foo", shell=True)
        retcode = subprocess.call(cmd, shell=True)
        if retcode < 0:
            print >>sys.stderr, "Child was terminated by signal", -retcode
            print >>sys.stdout, "Child was terminated by signal", -retcode
        else:
            print >>sys.stderr, "Child returned", retcode
            print >>sys.stdout, "Child returned", retcode
    except OSError as e:
        print >>sys.stderr, "Execution failed:", e
        print >>sys.stdout, "Execution failed:", e

    print "Done."
Running 'notmuch tag +onion +lists -- to:"security-onion"'... Child returned 0
Done.
Running 'notmuch tag +argus +lists -- subject:"ARGUS"'... Child returned 0
Done.
Running 'notmuch tag +saag +lists -- to:"saag"'... Child returned 0
Done.
Running 'notmuch tag +shmoolabs +lists -- subject:"Labs-Alumni"'... Child returned 0
Done.
Running 'notmuch tag +honeypot +lists -- from:"honeynetproject@honeynet.org"'... Child returned 0
Done.
Running 'notmuch tag +opsec +lists -- subject:"OPSEC"'... Child returned 0
Done.
Running 'notmuch tag +listmgt +lists -- from:"-owner"'... Child returned 0
Done.
Running 'notmuch tag +listmgt +lists -- from:"-requests"'... Child returned 0
Done.
Running 'notmuch tag +lists -- subject:"BSATroop161"'... Child returned 0
Done.
Running 'notmuch tag +sns -- from:"sns.amazonaws.com"'... Child returned 0
Done.
Running 'notmuch tag +social -- from:"linkedin"'... Child returned 0
Done.
Running 'notmuch tag +social -- subject:"Google+"'... Child returned 0
Done.
Running 'notmuch tag +social -- from:"twitter.com"'... Child returned 0
Done.
Running 'notmuch tag +social -- from:"facebookmail.com>"'... Child returned 0
Done.
Running 'notmuch tag +accounts -- from:"audible.com"'... Child returned 0
Done.
Running 'notmuch tag +accounts -- from:"Amazon Web Services"'... Child returned 0
Done.
Running 'notmuch tag +accounts -- from:"southwest.com"'... Child returned 0
Done.
Running 'notmuch tag +accounts -- from:"account-update@amazon.com"'... Child returned 0
Done.
Running 'notmuch tag +accounts -- from:"accounts.google.com"'... Child returned 0
Done.
Running 'notmuch tag +accounts -inbox -- from:"livestream.com"'... Child returned 0
Done.
Running 'notmuch tag +finance -- from:"Mint.com"'... Child returned 0
Done.
Running 'notmuch tag +church -- from:"lcfweb.org"'... Child returned 0
Done.
Running 'notmuch tag +me -- from:"gmj"'... Child returned 0
Done.
Running 'notmuch tag +me -- from:"eludom"'... Child returned 0
Done.
Running 'notmuch tag +me -- from:"George Jones"'... Child returned 0
Done.
Running 'notmuch tag +me -- from:"fooologist"'... Child returned 0
Done.
Running 'notmuch tag +spam -inbox -- from:"tumblr.com"'... Child returned 0
Done.
Running 'notmuch tag +spam -inbox +accounts -- subject:"Spam"'... Child returned 0
Done.
Running 'notmuch tag +spam -inbox -- from:"noreply@youtube.com"'... Child returned 0
Done.
Running 'notmuch tag +spam -inbox -- from:"news-googleplay@google.com"'... Child returned 0
Done.
Running 'notmuch tag +spam +accounts -inbox -- from:"discard-report@pobox.com"'... Child returned 0
Done.

Action Items

TODO Do I need to tag everything all the time?

<2016-07-24 Sun>

  • It might be more efficient to only tag new messages, or messages in the inbox, etc. Right now, I tag all messages every time. Think about this. Is it a problem?

Moving things out of "inbox"

For now, this is just a list. I'm moving things out of inbox by hand. This could be fed to a code block like we're doing with tagByHeader above.

tags comment
lists
sns
social
accounts
spam

Move all list mail out of my inbox

exec 2>&1;date;set -e; set -u; set -x
 
notmuch tag -inbox -- tag:lists
Sun Jul 24 08:09:24 EDT 2016
+ notmuch tag -inbox -- tag:lists

Move a specific tag out of my inbox

Edit the tag below and execute the source block

exec 2>&1;date;set -e; set -u; set -x
 
notmuch tag -inbox -- tag:spam
Sun Jul 24 09:08:06 EDT 2016
+ notmuch tag -inbox -- tag:spam

Ideas and Docs