3 # DialCentral - Front end for Google's Grand Central service.
4 # Copyright (C) 2008 Eric Warnke ericew AT gmail DOT com
6 # This library is free software; you can redistribute it and/or
7 # modify it under the terms of the GNU Lesser General Public
8 # License as published by the Free Software Foundation; either
9 # version 2.1 of the License, or (at your option) any later version.
11 # This library is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 # Lesser General Public License for more details.
16 # You should have received a copy of the GNU Lesser General Public
17 # License along with this library; if not, write to the Free Software
18 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22 Filesystem backend for contact support
31 class CsvAddressBook(object):
33 Currently supported file format
34 @li Has the first line as a header
35 @li Escapes with quotes
36 @li Comma as delimiter
37 @li Column 0 is name, column 1 is number
40 _nameRe = re.compile("name", re.IGNORECASE)
41 _phoneRe = re.compile("phone", re.IGNORECASE)
42 _mobileRe = re.compile("mobile", re.IGNORECASE)
44 def __init__(self, csvPath):
45 self.__csvPath = csvPath
46 self.__contacts = list(
47 self.read_csv(csvPath)
51 def read_csv(cls, csvPath):
52 csvReader = iter(csv.reader(open(csvPath, "rU")))
54 header = csvReader.next()
55 nameColumn, phoneColumns = cls._guess_columns(header)
60 for (phoneType, phoneColumn) in phoneColumns:
62 if len(row[phoneColumn]) == 0:
64 contactDetails.append((phoneType, row[phoneColumn]))
67 if len(contactDetails) != 0:
68 yield str(yieldCount), row[nameColumn], contactDetails
72 def _guess_columns(cls, row):
75 for i, item in enumerate(row):
76 if cls._nameRe.search(item) is not None:
77 names.append((item, i))
78 elif cls._phoneRe.search(item) is not None:
79 phones.append((item, i))
80 elif cls._mobileRe.search(item) is not None:
81 phones.append((item, i))
83 names.append(("Name", 0))
85 phones.append(("Phone", 1))
87 return names[0][1], phones
89 def clear_caches(self):
97 def contact_source_short_name(contactId):
100 def get_contacts(self):
102 @returns Iterable of (contact id, contact name)
104 for contact in self.__contacts:
107 def get_contact_details(self, contactId):
109 @returns Iterable of (Phone Type, Phone Number)
111 contactId = int(contactId)
112 return iter(self.__contacts[contactId][2])
115 class FilesystemAddressBookFactory(object):
118 "csv": CsvAddressBook,
121 def __init__(self, path):
124 def clear_caches(self):
127 def get_addressbooks(self):
129 @returns Iterable of (Address Book Factory, Book Id, Book Name)
131 for root, dirs, filenames in os.walk(self.__path):
132 for filename in filenames:
133 name, ext = filename.rsplit(".", 1)
134 if ext in self.FILETYPE_SUPPORT:
135 yield self, os.path.join(root, filename), name
137 def open_addressbook(self, bookId):
138 name, ext = bookId.rsplit(".", 1)
139 assert ext in self.FILETYPE_SUPPORT
140 return self.FILETYPE_SUPPORT[ext](bookId)
147 def print_filebooks(contactPath = None):
149 Included here for debugging.
151 Either insert it into the code or launch python with the "-i" flag
153 if contactPath is None:
154 contactPath = os.path.join(os.path.expanduser("~"), ".dialcentral", "contacts")
156 abf = FilesystemAddressBookFactory(contactPath)
157 for book in abf.get_addressbooks():
158 ab = abf.open_addressbook(book[1])
160 for contact in ab.get_contacts():
162 for details in ab.get_contact_details(contact[0]):
163 print "\t\t", details