Saturday, November 21, 2009

Mutt Address Book Lookup on Snow Leopard

I like the default "Address Book" on Mac OS X. It is simple and easy to use. However, since Snow Leopard, we cannot use lbdb (the Little Brother's Database) anymore due to a bug. This is annoying for mutt users like me.

There are many alternative applications including abook, neuron, etc. But, is there any workaround to use the Address Book on Mac for mutt query?

Here is how I use Address Book with mutt on Mac.

Address Book internally uses sqlite database. You should be able to find the database file in the following path: $HOME/Library/Application Support/AddressBook/AddressBook-v22.abcddb. So, we can write a simple script that prints out the query result from the database.

Well, if you look at the database, you will see the name of each database field is kind of obfuscated. But don't worry. You only need to look at these two tables: ZABCDEMAILADDRESS and ZABCDRECORD. By querying the DB over the two tables, we can easily get what we want.

So, here is a brief how-to.
  1. Make a script as follows. (addressbook.rb)
  2. Put the script in your $HOME/.mutt directory.
  3. Modify your .muttrc file. (set query_command="~/.mutt/addressbook.rb '%s'")
  4. Enjoy!

addressbook.rb
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
#!/usr/bin/env ruby
if ARGV.count != 1
    puts "Not found."
    exit 1
end

output = `sqlite3 -separator \
\"\t\" ~/Library/Application\\ Support/AddressBook/AddressBook-v22.abcddb \
'select mail.ZADDRESS, rec.ZFIRSTNAME, rec.ZLASTNAME \
from ZABCDEMAILADDRESS as mail,ZABCDRECORD as rec \
where (mail.ZADDRESS like \"%#{ARGV[0]}%\" \
or rec.ZFIRSTNAME like \"%#{ARGV[0]}%\" \
or rec.ZLASTNAME like \"%#{ARGV[0]}%\") and rec.Z_PK=mail.ZOWNER'`

if $? != 0
    raise "Query Error"
else
    if output.empty?
        puts "Not found."
        exit 1
    end
    puts # start with blank line
    output.split("\n").each {|line|
        tuple = line.split("\t")
        if tuple.count != 3
            puts "Not found."
            exit 1
        end
        print tuple[0] + "\t" + tuple[1] + " " + tuple[2] + "\t\n"
    }
    exit 0
end

puts "Not found."
exit 1

1 comment:

About

My photo
Hi, I am a PhD candidate at CMU. I was one of the founding members of PPP (Plaid Parliament of Pwning). I like programming in OCaml, F#, Haskell, and C++.