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):
52 csvReader = iter(csv.reader(open(csvPath, "rU")))
58 header = csvReader.next()
59 nameColumn, phoneColumns = cls._guess_columns(header)
64 for (phoneType, phoneColumn) in phoneColumns:
66 if len(row[phoneColumn]) == 0:
68 contactDetails.append((phoneType, row[phoneColumn]))
71 if len(contactDetails) != 0:
72 yield str(yieldCount), row[nameColumn], contactDetails
76 def _guess_columns(cls, row):
79 for i, item in enumerate(row):
80 if cls._nameRe.search(item) is not None:
81 names.append((item, i))
82 elif cls._phoneRe.search(item) is not None:
83 phones.append((item, i))
84 elif cls._mobileRe.search(item) is not None:
85 phones.append((item, i))
87 names.append(("Name", 0))
89 phones.append(("Phone", 1))
91 return names[0][1], phones
93 def clear_caches(self):
101 def contact_source_short_name(contactId):
104 def get_contacts(self):
106 @returns Iterable of (contact id, contact name)
108 for contact in self.__contacts:
111 def get_contact_details(self, contactId):
113 @returns Iterable of (Phone Type, Phone Number)
115 contactId = int(contactId)
116 return iter(self.__contacts[contactId][2])
119 class FilesystemAddressBookFactory(object):
122 "csv": CsvAddressBook,
125 def __init__(self, path):
128 def clear_caches(self):
131 def get_addressbooks(self):
133 @returns Iterable of (Address Book Factory, Book Id, Book Name)
135 for root, dirs, filenames in os.walk(self.__path):
136 for filename in filenames:
138 name, ext = filename.rsplit(".", 1)
142 if ext in self.FILETYPE_SUPPORT:
143 yield self, os.path.join(root, filename), name
145 def open_addressbook(self, bookId):
146 name, ext = bookId.rsplit(".", 1)
147 assert ext in self.FILETYPE_SUPPORT, "Unsupported file extension %s" % ext
148 return self.FILETYPE_SUPPORT[ext](bookId)
155 def print_filebooks(contactPath = None):
157 Included here for debugging.
159 Either insert it into the code or launch python with the "-i" flag
161 if contactPath is None:
162 contactPath = os.path.join(os.path.expanduser("~"), ".dialcentral", "contacts")
164 abf = FilesystemAddressBookFactory(contactPath)
165 for book in abf.get_addressbooks():
166 ab = abf.open_addressbook(book[1])
168 for contact in ab.get_contacts():
170 for details in ab.get_contact_details(contact[0]):
171 print "\t\t", details