A python version using python-evolution bindings

Shameless ripoff from:

import evolution
import sys

query = ' '.join(sys.argv[1:])

results_dict = {}

for addrDesc, addrName in evolution.ebook.list_addressbooks():
    if "couchdb" in addrName:
        #Couchdb se suele colgar, lo excluyo de las busquedas
    addresses = evolution.ebook.open_addressbook(addrName)
    results = # Returns List of results
    for a in results:
        email = a.get_property('email-1').lower()
        fullName = a.get_property('full-name')
        nick = a.get_property('nickname')
        if email is not None:
            results_dict[email] = (fullName, nick)

if len(results_dict) == 0:
    print " no matches"
elif len(results_dict) == 1:
    print " 1 match! you are lucky"
    print " %d matches, now use your brain" % len(results_dict)

for email, val in results_dict.items():
    print '%s\t%s\t%s' % (email, val[0], val[1])

Original Version

#!/bin/env python
# Description: A Python script for use with the Mutt query_command
# which lets you search your Evolution address book for contacts.
# For additional information/help contact Homme Zwaagstra
# (<>)

import cStringIO
import sys, os

def die(msg):
    print >> sys.stderr, msg

# Try and import required but non standard modules
    import vobject
except ImportError:
    die("""The vobject module is required to access vcards.
It can be found at <>""")

    import bsddb3
except ImportError:
    die("""The bsddb3 module is required to access the Evolution addresses.
It can be found at <>""")

def read_evolution(address_file):
    """Read the evolution address book into a buffer, returning the buffer"""

    buf = cStringIO.StringIO()
    contacts = bsddb3.hashopen(address_file)
    for val in contacts.db.values()[1:]:
        vcard = val.replace('\x00', "\n")

    # set the buffer cursor to the beginning
    return buf

# The location of the evolution address book
address_file = '~/.evolution/addressbook/local/system/addressbook.db'

# The query as a case insensitive string
query = sys.argv[1].lower()

# Could be a simple vcard file...
#vcards = file('~/personal/contacts.vcf', 'r')
# ...but we read the vcards from the evolution address book
vcards = read_evolution(os.path.expanduser(address_file))

# iterate through the vcard, accumulating a list of matches to the query.
print "Searching contacts for %s..." % query,
contact_count = 0
matches = []
for vcard in vobject.readComponents(vcards):
        if query in vcard.fn.value.lower():
                for email in vcard.contents['email']:
                    matches.append((email.value, vcard.fn.value))
            except KeyError:
    except AttributeError:
    contact_count += 1

match_count = len(matches)
if not match_count:
    print " no matches in %d entries" % contact_count

if match_count > 1:
    plural = 'es'
    plural = ''
print " %d match%s in %d entries" % (match_count, plural, contact_count)
for contact in matches:
    print "%s\t%s" % contact

Another one using evolution-data-server in C

/* mutt-eds-query.c
 * Sertaç Ö. Y&#305;ld&#305;z <sertacyildizATgmailDOTcom>
 * compilation (requires evolution-data-server development libraries):
 * gcc `pkg-config --cflags --libs libebook-1.2` -o mutt-eds-query mutt-eds-query.c

#include <libebook/e-book.h>
#include <libebook/e-contact.h>
#include <libebook/e-book-query.h>

#define PROGRAM_NAME	"mutt-eds-query"
#define VERSION		"0.1"

static void
print_mutt_line (const gchar *email, const gchar *name,
		 const gchar *nick, const gchar *notes)
	printf ("%s\t%s\t%-10s %s\n",
		email ? email : "",
		name  ?  name : "",
		nick  ?  nick : "",
		notes ?  notes: "");

static void
process_results (gpointer data, gpointer user_data)
	EContact *contact;
	const gchar *fullname, *nickname, *notes;
	GList *emails, *e;

	g_return_if_fail (E_IS_CONTACT(data));
	contact = E_CONTACT (data);

	fullname = e_contact_get_const (contact, E_CONTACT_FULL_NAME);
	nickname = e_contact_get_const (contact, E_CONTACT_NICKNAME);
	notes	 = e_contact_get_const (contact, E_CONTACT_NOTE);
	emails = e_contact_get (contact, E_CONTACT_EMAIL);

	for (e = emails; e; e = e->next)
		print_mutt_line ((const char *) e->data, fullname,
				 nickname, notes);

	g_list_foreach (emails, (GFunc) g_free, NULL);
	g_list_free (emails);

static void
usage (const gchar *me)
	fprintf (stderr, "%s (v" VERSION ") : simple e-d-s wrapper for mutt\n", me);
	fprintf (stderr, "Usage: %s <query>\n\n", me);

main (int argc, char *argv[])
	EBook *book;
	EBookQuery *query;
	GList *contacts;


	if ( argc > 1 && g_strstr_len (argv[1], 3, "-h")) {
		usage (PROGRAM_NAME);
		exit (1);

	if (argc == 1)
		query = e_book_query_any_field_contains ("");
		query = e_book_query_any_field_contains (argv[1]);

	if (query == NULL) {
		fprintf (stderr, "Couldn't create query.\n");
		exit (2);

	book = e_book_new_system_addressbook (NULL);
	if (!e_book_open (book, TRUE, NULL)) {
		fprintf (stderr, "Couldn't load system addressbook.\n");
		exit (2);

	if (!e_book_get_contacts (book, query, &contacts, NULL)) {
		fprintf (stderr, "Couldn't get query results.\n");
		exit (2);

	e_book_query_unref (query);
	g_object_unref (book);

	if (contacts == NULL) {
		printf ("No matches.\n");
		return (-1);
	} else {
		printf ("Matches for '%s'...\n", argv[1]);
		g_list_foreach (contacts, (GFunc) process_results, NULL);

	return 0;
Last modified 5 years ago Last modified on Feb 18, 2012 5:08:57 AM