#!/usr/bin/env python
"""
mutt-notmuch-py

This is a Gmail-only version of the original mutt-notmuch script.

It will interactively ask you for a search query and then symlink the matching
messages to $HOME/.cache/mutt_results.

Add this to your muttrc.

macro index / "<enter-command>unset wait_key<enter><shell-escape>mutt-notmuch-py<enter><change-folder-readonly>~/.cache/mutt_results<enter>" \
          "search mail (using notmuch)"

This script overrides the $HOME/.cache/mutt_results each time you run a query.

Install this by adding this file somewhere on your PATH.

Only tested on OSX Lion.

(c) 2012 - Honza Pokorny
Licensed under BSD
"""
import hashlib, sys
from commands import getoutput
from mailbox import Maildir
from optparse import OptionParser


def digest(filename):
    with open(filename) as f:
        return hashlib.sha1(f.read()).hexdigest()


def pick_all_mail(messages):
    for m in messages:
        if 'All Mail' in m:
            return m


def empty_dir(directory):
    box = Maildir(directory)
    box.clear()


def command(cmd):
    return getoutput(cmd)


def main(dest_box):
    query = raw_input('Query: ')

    command('mkdir -p %s' % dest_box)
    command('mkdir -p %s/cur' % dest_box)
    command('mkdir -p %s/new' % dest_box)

    empty_dir(dest_box)

    files = command('notmuch search --output=files %s' % query).split('\n')
    files = filter(None, files)

    data = {}
    messages = []

    for f in files:
        try:
            sha = digest(f)
            if sha not in data.keys():
                data[sha] = [f]
            else:
                data[sha].append(f)
        except IOError:
            print 'File %s does not exist' % f

    for sha in data.keys():
        if is_gmail and len(data[sha]) > 1:
            messages.append(pick_all_mail(data[sha]))
        else:
            messages.append(data[sha][0])

    for m in messages:
        command('ln -s "%s" %s/cur/' % (m, dest_box))


if __name__ == '__main__':
    global is_gmail

    p = OptionParser("usage: %prog [OPTIONS] [RESULTDIR]")
    p.add_option('-g', '--gmail', dest='gmail',
                 action='store_true', default=True,
                 help='gmail-specific behavior')
    p.add_option('-G', '--not-gmail', dest='gmail',
                 action='store_false',
                 help='gmail-specific behavior')
    (options, args) = p.parse_args()

    is_gmail = options.gmail

    if args:
        dest = args[0]
    else:
        dest = '~/.cache/mutt_results'

    main(dest.rstrip('/'))

@@ -574,14 +574,9 @@
 H.%0A%0A
-Only t
+T
 este
@@ -588,16 +588,31 @@
 OSX Lion
+ and Arch Linux
 .%0A%0A(c) 2
@@ -653,16 +653,27 @@
  BSD%0A%22%22%22
+%0A%0Aimport os
 %0Aimport 
@@ -683,13 +683,9 @@
 hlib
-, sys
+%0A
 %0Afro
@@ -774,16 +774,52 @@
 nParser%0A
+from collections import defaultdict%0A
 %0A%0Adef di
@@ -1155,16 +1155,26 @@
 dest_box
+, is_gmail
 ):%0A    q
@@ -1206,46 +1206,8 @@
 ')%0A%0A
-    command('mkdir -p %25s' %25 dest_box)%0A
     
@@ -1392,54 +1392,37 @@
 n')%0A
+%0A
     
-files = filter(None, files)%0A%0A    data = %7B%7D
+data = defaultdict(list)
 %0A   
@@ -1469,11 +1469,16 @@
     
-try
+if not f
 :%0A  
@@ -1491,61 +1491,29 @@
     
-sha = digest(f)%0A            if sha not in data.keys()
+continue%0A%0A        try
 :%0A  
@@ -1526,50 +1526,24 @@
     
-    data%5B
 sha
-%5D
  = 
-%5Bf%5D%0A            else:%0A    
+digest(f)%0A
     
@@ -1611,17 +1611,17 @@
    print
- 
+(
 'File %25s
@@ -1640,16 +1640,17 @@
 ist' %25 f
+)
 %0A%0A    fo
@@ -1666,15 +1666,8 @@
 data
-.keys()
 :%0A  
@@ -1854,52 +1854,179 @@
     
-command('ln -s %22%25s%22 %25s/cur/' %25 (m, dest_box)
+if not m:%0A            continue%0A%0A        target = os.path.join(dest_box, 'cur', os.path.basename(m))%0A        if not os.path.exists(target):%0A            os.symlink(m, target
 )%0A%0A%0A
@@ -2056,29 +2056,8 @@
 _':%0A
-    global is_gmail%0A%0A
     
@@ -2442,38 +2442,8 @@
 ()%0A%0A
-    is_gmail = options.gmail%0A%0A
     
@@ -2528,25 +2528,122 @@
 s'%0A%0A    
-main
+# Use expanduser() so that os.symlink() won't get weirded out by tildes.%0A    main(os.path.expanduser
 (dest
+)
 .rstrip(
@@ -2646,10 +2646,25 @@
 rip('/')
+, options.gmail
 )%0A

Improve speed by using os.symlink() rather than ln