My mail configuration
authorBen Gamari <bgamari.foss@gmail.com>
Wed, 23 Feb 2011 14:22:57 +0000 (09:22 +1900)
committerW. Trevor King <wking@tremily.us>
Fri, 7 Nov 2014 17:37:56 +0000 (09:37 -0800)
fa/01e49725dec4d8cc71c7d4fbc7879c5e64ec8a [new file with mode: 0644]

diff --git a/fa/01e49725dec4d8cc71c7d4fbc7879c5e64ec8a b/fa/01e49725dec4d8cc71c7d4fbc7879c5e64ec8a
new file mode 100644 (file)
index 0000000..dd1c196
--- /dev/null
@@ -0,0 +1,326 @@
+Return-Path: <bgamari.foss@gmail.com>\r
+X-Original-To: notmuch@notmuchmail.org\r
+Delivered-To: notmuch@notmuchmail.org\r
+Received: from localhost (localhost [127.0.0.1])\r
+       by olra.theworths.org (Postfix) with ESMTP id BC2EF431FB6\r
+       for <notmuch@notmuchmail.org>; Wed, 23 Feb 2011 06:23:06 -0800 (PST)\r
+X-Virus-Scanned: Debian amavisd-new at olra.theworths.org\r
+X-Spam-Flag: NO\r
+X-Spam-Score: -0.799\r
+X-Spam-Level: \r
+X-Spam-Status: No, score=-0.799 tagged_above=-999 required=5\r
+       tests=[DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1,\r
+       FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_LOW=-0.7] autolearn=disabled\r
+Received: from olra.theworths.org ([127.0.0.1])\r
+       by localhost (olra.theworths.org [127.0.0.1]) (amavisd-new, port 10024)\r
+       with ESMTP id ODwLvKJv1aog for <notmuch@notmuchmail.org>;\r
+       Wed, 23 Feb 2011 06:23:03 -0800 (PST)\r
+Received: from mail-qw0-f53.google.com (mail-qw0-f53.google.com\r
+       [209.85.216.53]) (using TLSv1 with cipher RC4-SHA (128/128 bits))\r
+       (No client certificate requested)\r
+       by olra.theworths.org (Postfix) with ESMTPS id D4753431FB5\r
+       for <notmuch@notmuchmail.org>; Wed, 23 Feb 2011 06:23:02 -0800 (PST)\r
+Received: by qwc9 with SMTP id 9so3634960qwc.26\r
+       for <notmuch@notmuchmail.org>; Wed, 23 Feb 2011 06:23:00 -0800 (PST)\r
+DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma;\r
+       h=domainkey-signature:from:to:subject:user-agent:date:message-id\r
+       :mime-version:content-type;\r
+       bh=XNXQJ/4qiywr7H3pAoW8UzYwekyO85KZWLvkHnrlqJk=;\r
+       b=Se1aB/X9IBSehMQnTJOTIN4lSTF68cLaw0HSaMoc4DaTZhdMDafvAP1VvAzCoZdOmv\r
+       24+yaju5oq3u548esdb6MQS2KyIP4LHZOeI2JfKDXTg1JOgldS6Th8qQ4HvWnXP2Xngm\r
+       U2XKa6Wyi1Vgi7WniNrw95q61zH04lZIU9olc=\r
+DomainKey-Signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma;\r
+       h=from:to:subject:user-agent:date:message-id:mime-version\r
+       :content-type;\r
+       b=QPYHPHchycWoFKl79YakJTET3RucUNX6+2repdRdOI8UtFY70NIRJ21783CGUVjz0m\r
+       KHKxDRHRYAqKCli98h0hpBWnM269QjUqmFuyVJA2+LnxVhhCAWvVxFBEs9srQ+qgYIKg\r
+       AOCNr28kk8Zr7rFikajK+XYWw4vA88MHtnUOs=\r
+Received: by 10.229.229.139 with SMTP id ji11mr3041165qcb.174.1298470980042;\r
+       Wed, 23 Feb 2011 06:23:00 -0800 (PST)\r
+Received: from localhost (gamari.physics.umass.edu [128.119.56.223])\r
+       by mx.google.com with ESMTPS id g28sm5479260qck.37.2011.02.23.06.22.59\r
+       (version=TLSv1/SSLv3 cipher=OTHER);\r
+       Wed, 23 Feb 2011 06:22:59 -0800 (PST)\r
+From: Ben Gamari <bgamari.foss@gmail.com>\r
+To: notmuch <notmuch@notmuchmail.org>\r
+Subject: My mail configuration\r
+User-Agent: Notmuch/0.5-64-gdd23272 (http://notmuchmail.org) Emacs/23.1.1\r
+       (x86_64-pc-linux-gnu)\r
+Date: Wed, 23 Feb 2011 09:22:57 -0500\r
+Message-ID: <87tyfu3k5a.fsf@gmail.com>\r
+MIME-Version: 1.0\r
+Content-Type: text/plain; charset=us-ascii\r
+X-BeenThere: notmuch@notmuchmail.org\r
+X-Mailman-Version: 2.1.13\r
+Precedence: list\r
+List-Id: "Use and development of the notmuch mail system."\r
+       <notmuch.notmuchmail.org>\r
+List-Unsubscribe: <http://notmuchmail.org/mailman/options/notmuch>,\r
+       <mailto:notmuch-request@notmuchmail.org?subject=unsubscribe>\r
+List-Archive: <http://notmuchmail.org/pipermail/notmuch>\r
+List-Post: <mailto:notmuch@notmuchmail.org>\r
+List-Help: <mailto:notmuch-request@notmuchmail.org?subject=help>\r
+List-Subscribe: <http://notmuchmail.org/mailman/listinfo/notmuch>,\r
+       <mailto:notmuch-request@notmuchmail.org?subject=subscribe>\r
+X-List-Received-Date: Wed, 23 Feb 2011 14:23:06 -0000\r
+\r
+Here is my mail sorting script that has been slowly evolving for almost\r
+a year now. It uses the Python bindings, along with Bogofilter for spam\r
+filtering. There is also an update-spam script which brings the\r
+Bogofilter database in to synchronization with the notmuch tags. On this\r
+note, if someone wants to implement the ability to hide certain tags\r
+(say, those matching /\..+/) in the emacs interface it would be greatly\r
+appreciated. I have notmuch configured such that all new mail starts\r
+with just the "new" tag. The sorting script then takes it from\r
+there. Hope this will give folks some ideas.\r
+\r
+Cheers,\r
+\r
+- Ben\r
+\r
+\r
+===File ~/.env/mail/sort_mail.py============================\r
+#!/usr/bin/python\r
+\r
+# Warning:\r
+# Be careful about using Query.count_messages(), it's technically an estimate\r
+# and is not guarranteed to be correct\r
+\r
+import os\r
+import logging\r
+import time\r
+\r
+logging.basicConfig(level=logging.DEBUG)\r
+\r
+_tags = []\r
+start_time = time.time()\r
+\r
+def sf_list(name, tag):\r
+        #_tags.append( ('to:%s@lists.sourceforge.net' % name, ['list', tag]) )\r
+        #_tags.append( ('to:%s@lists.sf.net' % name, ['list', tag]) )\r
+        _tags.append( ('to:%s' % name, ['list', tag]) )\r
+\r
+def kernel_list(name, tag):\r
+        #_tags.append( ('to:%s@vger.kernel.org' % name, ['list', tag]) )\r
+        _tags.append( ('to:%s' % name, ['list', tag]) )\r
+\r
+def fdo_list(name, tag):\r
+        #_tags.append( ('to:%s@lists.freedesktop.org' % name, ['list', tag]) )\r
+        _tags.append( ('to:%s' % name, ['list', tag]) )\r
+\r
+def _list(name, tag):\r
+        _tags.append( ('to:%s' % name, ['list', tag]) )\r
+\r
+def tag(filter, *tags):\r
+        _tags.append( (filter, tags) )\r
+\r
+kernel_list('linux-kernel', 'lkml')\r
+kernel_list('mm-commits', 'mm-commits')\r
+kernel_list('linux-omap', 'linux-omap')\r
+kernel_list('linux-next', 'linux-next')\r
+kernel_list('linux-wireless', 'linux-wireless')\r
+kernel_list('linux-btrfs', 'btrfs')\r
+_list('linux-pm', 'linux-pm')\r
+_list('linux-arm-kernel', 'linux-arm')\r
+sf_list('oprofile-list', 'oprofile')\r
+sf_list('spi-devel-general', 'spi-devel')\r
+sf_list('linux1394-devel', 'ieee1394')\r
+\r
+sf_list('ipw3945-devel', 'ipw')\r
+_list('hostap@lists.shmoo.com', 'hostap')\r
+_list('ath9k-devel@', 'ath9k')\r
+_list('vim-dev@vim.org', 'vim')\r
+_list('vim_dev', 'vim')\r
+\r
+fdo_list('intel-gfx', 'intel-gfx')\r
+fdo_list('xorg', 'xorg')\r
+fdo_list('hal', 'hal')\r
+fdo_list('compiz', 'compiz')\r
+sf_list('dri-devel', 'dri')\r
+sf_list('dri-users', 'dri')\r
+sf_list('mesa3d-dev', 'mesa')\r
+fdo_list('mesa-dev', 'mesa')\r
+\r
+fdo_list('devkit-devel', 'devkit')\r
+sf_list('matplotlib-users', 'matplotlib')\r
+sf_list('matplotlib-devel', 'matplotlib')\r
+_list('notmuch@notmuchmail.org', 'notmuch')\r
+_list('eigen@lists.tuxfamily.org', 'eigen')\r
+_list('launchpad-users@lists.launchpad.net', 'launchpad')\r
+_list('boost@lists.boost.org', 'boost')\r
+_list('debian-python@lists.debian.org', 'debian-python')\r
+\r
+_list('geda-user@', 'geda')\r
+\r
+_list('openembedded-devel@lists.openembedded.org', 'openembedded')\r
+_list('beagleboard@googlegroups.com', 'beagleboard')\r
+_list('angstrom-distro-devel@linuxtogo.org', 'angstrom')\r
+_list('angstrom-distro-users@linuxtogo.org', 'angstrom')\r
+\r
+_list('mono-devel-list@lists.ximian.com', 'mono')\r
+_list('mono-list@', 'mono')\r
+_list('ubuntu-devel-discuss@lists.ubuntu.com', 'ubuntu-devel')\r
+_list('git@vger.kernel.org', 'git')\r
+_list('sup-talk@rubyforge.org', 'sup')\r
+_list('thrust-users@googlegroups.com', 'thrust')\r
+_list('golang-nuts@googlegroups.com', 'go')\r
+_list('numpy-discussion@scipy.org', 'numpy')\r
+_list('scipy-user@scipy.org', 'scipy')\r
+\r
+_list('rsync@lists.samba.org', 'rsync')\r
+tag('from:samba-bugs', 'bugs', 'rsync', 'list')\r
+\r
+_list('containers@', 'containers')\r
+\r
+tag('from:bugzilla', 'bugs', 'list')\r
+\r
+# Tags that aren't for lists\r
+tag('from:Facebook', 'facebook')\r
+tag('to:gdh@gdhour.com', 'gdh')\r
+\r
+tag('to:bgamari@gmail.com', 'gmail')\r
+tag('to:bgamari.foss@gmail.com', 'foss')\r
+tag('from:Ben Gamari', 'sent')\r
+tag('from:bgamari.foss', 'sent')\r
+\r
+from sort_junk import sort_junk\r
+from notmuch_utils import *\r
+import notmuch\r
+db = notmuch.Database(mode=notmuch.Database.MODE.READ_WRITE)\r
+\r
+# Freeze new messages\r
+q_new = notmuch.Query(db, 'tag:new')\r
+n_msgs = 0\r
+for msg in q_new.search_messages():\r
+        msg.freeze()\r
+        n_msgs += 1\r
+\r
+# Take care of basics\r
+tag_search(db, 'tag:new', '+unread', '+unseen')\r
+\r
+# Take care of feeds\r
+tag_search(db, 'folder:feeds', '+feeds', '-new')\r
+\r
+# Run through Bogofilter\r
+sort_junk(q_new)\r
+\r
+# Tag things\r
+for filter, tags in _tags:\r
+        tag_search(db, '%s and tag:new' % filter, *tags)\r
+\r
+# Ignore things I sent\r
+tag_search(db, 'tag:new and tag:sent', '-unseen', '-new', '-unread', '+watch')\r
+\r
+# Update watch tag\r
+for msg in q_new.search_messages():\r
+        q = notmuch.Query(db, 'tag:watch and thread:%s' % msg.get_thread_id())\r
+        if len(q.search_messages()) > 0:\r
+                logging.debug('watching %s' % msg.get_message_id())\r
+                msg.add_tag('watch')\r
+\r
+# Watched items should go to inbox\r
+tag_search(db, 'tag:new and tag:watch', '+inbox', '-new')\r
+\r
+# Ignore threads that I've already seen\r
+q = notmuch.Query(db, 'tag:new and tag:list')\r
+for msg in q.search_messages():\r
+        q2 = notmuch.Query(db, 'thread:%s and not tag:unseen' % msg.get_thread_id())\r
+        if len(q2.search_messages()) > 0:\r
+                msg.remove_tag('unseen')\r
+                msg.remove_tag('new')\r
+\r
+# Remove new from sorted list items\r
+tag_search(db, 'tag:new and tag:list', '-new')\r
+\r
+# Tag remaining new items for inbox\r
+tag_search(db, 'tag:new', '+inbox', '-new')\r
+\r
+# Thaw new messages\r
+for msg in q_new.search_messages():\r
+        msg.thaw()\r
+\r
+end_time = time.time()\r
+logging.info('Sorted %d messages in %1.2f seconds' % (n_msgs, end_time - start_time))\r
+\r
+============================================================\r
+\r
+\r
+===File ~/.env/mail/sort_junk.py============================\r
+#!/usr/bin/python\r
+\r
+import logging\r
+import subprocess\r
+from subprocess import PIPE\r
+import notmuch\r
+import re\r
+\r
+def sort_junk(query):\r
+        spam_re = re.compile('X-Bogosity:\s*Spam')\r
+        spamicity_re = re.compile('spamicity=(\d\.\d+)')\r
+        bf = subprocess.Popen(['bogofilter', '-bv'], stdin=PIPE, stdout=PIPE)\r
+        for msg in query.search_messages():\r
+                bf.stdin.write(msg.get_filename() + '\n')\r
+                l = bf.stdout.readline()\r
+                if re.search(spam_re, l):\r
+                        logging.debug('Message %s marked as junk' % msg.get_message_id())\r
+                        msg.add_tag('junk')\r
+        bf.stdin.close()\r
+\r
+if __name__ == '__main__':\r
+        import sys\r
+        db = notmuch.Database(mode=notmuch.Database.MODE.READ_WRITE)\r
+        query = notmuch.Query(db, ' '.join(sys.argv[1:]))\r
+        sort_junk(query)\r
+\r
+============================================================\r
+\r
+\r
+===File ~/.env/mail/update-junk=============================\r
+#!/usr/bin/python\r
+\r
+import notmuch\r
+from notmuch_utils import *\r
+import subprocess\r
+from time import time\r
+import sys\r
+\r
+logging.basicConfig(level=logging.INFO)\r
+\r
+db = notmuch.Database(mode=notmuch.Database.MODE.READ_WRITE)\r
+if '--clean' in sys.argv:\r
+        import shutil, os.path\r
+        shutil.rmtree(os.path.expanduser('~/.bogofilter'))\r
+        tag_search(db, 'tag:.bf_spam', '-.bf_spam')\r
+        tag_search(db, 'tag:.bf_ham', '-.bf_ham')\r
+\r
+def do_update(search, tag_func, bf_args):\r
+        start_time = time()\r
+        p = subprocess.Popen(['bogofilter', bf_args], stdin=subprocess.PIPE)\r
+        q = notmuch.Query(db, search)\r
+        n = 0\r
+        for msg in q.search_messages():\r
+                p.stdin.write('%s\n' % msg.get_filename())\r
+                tag_func(msg)\r
+                n += 1\r
+        p.stdin.close()\r
+        p.wait()\r
+        return (n, time()-start_time)\r
+\r
+logging.info('Registering spam')\r
+n,t = do_update('tag:junk and not tag:.bf_spam', lambda msg: msg.add_tag('.bf_spam'), '-sb')\r
+logging.info('Registered %d spam in %1.2f seconds' % (n,t))\r
+\r
+logging.info('Unregistering spam')\r
+n,t = do_update('not tag:junk and tag:.bf_spam', lambda msg: msg.remove_tag('.bf_spam'), '-Sb')\r
+logging.info('Unregistered %d spam in %1.2f seconds' % (n,t))\r
+\r
+# Only consider messages that have been read as ham\r
+logging.info('Registering ham')\r
+n,t = do_update('not tag:junk and not tag:unread and not tag:.bf_ham', lambda msg: msg.add_tag('.bf_ham'), '-nb')\r
+logging.info('Registered %d ham in %1.2f seconds' % (n,t))\r
+\r
+logging.info('Unregistering ham')\r
+n,t = do_update('tag:junk and tag:.bf_ham', lambda msg: msg.remove_tag('.bf_ham'), '-Nb')\r
+logging.info('Unregistered %d ham in %1.2f seconds' % (n,t))\r
+\r
+============================================================\r