Skip to content

Instantly share code, notes, and snippets.

What would you like to do?
Search Mac Address Book with Python via the Scripting Bridge
# -*- coding: utf-8 -*-
# vim: fileencoding=utf-8
Search Mac Address Book contacts via official API
from __future__ import print_function, unicode_literals
import sys
from time import time
from collections import defaultdict
import AddressBook as ab
def _make_list(cdw):
"""Make a list from CoreDataWrapper"""
if not cdw:
return []
values = []
for i in range(cdw.count()):
return values
# map dict keys to AB properties and conversion funcs
_text_property_map = {
# output key : (property, conversion func)
'first_name': (ab.kABFirstNameProperty, None),
'last_name': (ab.kABLastNameProperty, None),
'company': (ab.kABOrganizationProperty, None),
'emails': (ab.kABEmailProperty, _make_list),
def ab_person_to_dict(person):
"""Convert ABPerson to Python dict"""
d = {}
d['emails'] = []
for key in _text_property_map:
prop, func = _text_property_map[key]
value = person.valueForProperty_(prop)
if func:
value = func(value)
if not value:
value = ''
d[key] = value
return d
def search(query):
"""Search Mac Address Book and return pythonified results"""
address_book = ab.ABAddressBook.sharedAddressBook()
# build search criteria
criteria = []
for key in _text_property_map:
prop, func = _text_property_map[key]
None, None,
search = ab.ABSearchElement.searchElementForConjunction_children_(
ab.kABSearchOr, criteria)
# search Address Book
people = address_book.recordsMatchingSearchElement_(search)
results = defaultdict(set)
for person in [ab_person_to_dict(person) for person in people]:
key = '{} {}'.format(person.get('first_name', ''),
person.get('last_name', '')).strip()
for addr in person['emails']:
return results
def main():
if len(sys.argv) < 2:
print('Usage : <query> [<query> ...]')
return 1
for query in sys.argv[1:]:
s = time()
people = search(query)
print("{} results for '{}' in {:.4f} seconds".format(len(people),
time() - s))
print('-' * 40)
for name, addrs in people.items():
print('{} : {}'.format(name, list(addrs)))
if __name__ == '__main__':
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.