4 DialCentral - Front end for Google's Grand Central service.
5 Copyright (C) 2008 Eric Warnke ericew AT gmail DOT com
7 This library is free software; you can redistribute it and/or
8 modify it under the terms of the GNU Lesser General Public
9 License as published by the Free Software Foundation; either
10 version 2.1 of the License, or (at your option) any later version.
12 This library is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 Lesser General Public License for more details.
17 You should have received a copy of the GNU Lesser General Public
18 License along with this library; if not, write to the Free Software
19 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21 Filesystem backend for contact support
30 class CsvAddressBook(object):
32 Currently supported file format
33 @li Has the first line as a header
34 @li Escapes with quotes
35 @li Comma as delimiter
36 @li Column 0 is name, column 1 is number
39 _nameRe = re.compile("name", re.IGNORECASE)
40 _phoneRe = re.compile("phone", re.IGNORECASE)
41 _mobileRe = re.compile("mobile", re.IGNORECASE)
43 def __init__(self, csvPath):
44 self.__csvPath = csvPath
45 self.__contacts = list(
46 self.read_csv(csvPath)
50 def read_csv(cls, csvPath):
51 csvReader = iter(csv.reader(open(csvPath, "rU")))
53 header = csvReader.next()
54 nameColumn, phoneColumns = cls._guess_columns(header)
59 for (phoneType, phoneColumn) in phoneColumns:
61 if len(row[phoneColumn]) == 0:
63 contactDetails.append((phoneType, row[phoneColumn]))
66 if len(contactDetails) != 0:
67 yield str(yieldCount), row[nameColumn], contactDetails
71 def _guess_columns(cls, row):
74 for i, item in enumerate(row):
75 if cls._nameRe.search(item) is not None:
76 names.append((item, i))
77 elif cls._phoneRe.search(item) is not None:
78 phones.append((item, i))
79 elif cls._mobileRe.search(item) is not None:
80 phones.append((item, i))
82 names.append(("Name", 0))
84 phones.append(("Phone", 1))
86 return names[0][1], phones
88 def clear_caches(self):
96 def contact_source_short_name(contactId):
99 def get_contacts(self):
101 @returns Iterable of (contact id, contact name)
103 for contact in self.__contacts:
106 def get_contact_details(self, contactId):
108 @returns Iterable of (Phone Type, Phone Number)
110 contactId = int(contactId)
111 return iter(self.__contacts[contactId][2])
114 class FilesystemAddressBookFactory(object):
117 "csv": CsvAddressBook,
120 def __init__(self, path):
123 def clear_caches(self):
126 def get_addressbooks(self):
128 @returns Iterable of (Address Book Factory, Book Id, Book Name)
130 for root, dirs, filenames in os.walk(self.__path):
131 for filename in filenames:
132 name, ext = filename.rsplit(".", 1)
133 if ext in self.FILETYPE_SUPPORT:
134 yield self, os.path.join(root, filename), name
136 def open_addressbook(self, bookId):
137 name, ext = bookId.rsplit(".", 1)
138 assert ext in self.FILETYPE_SUPPORT
139 return self.FILETYPE_SUPPORT[ext](bookId)
146 def print_filebooks(contactPath = None):
148 Included here for debugging.
150 Either insert it into the code or launch python with the "-i" flag
152 if contactPath is None:
153 contactPath = os.path.join(os.path.expanduser("~"), ".dialcentral", "contacts")
155 abf = FilesystemAddressBookFactory(contactPath)
156 for book in abf.get_addressbooks():
157 ab = abf.open_addressbook(book[1])
159 for contact in ab.get_contacts():
161 for details in ab.get_contact_details(contact[0]):
162 print "\t\t", details