Cutting down the thread spawning which should help avoid some bugs and cut down some...
[gc-dialer] / src / evo_backend.py
1 #!/usr/bin/python
2
3 """
4 DialCentral - Front end for Google's Grand Central service.
5 Copyright (C) 2008  Eric Warnke ericew AT gmail DOT com
6
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.
11
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.
16
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
20
21 Evolution Contact Support
22
23 @bug It seems the evolution contact API used is specific to the desktop.  evolution.ebook combined with abook is what is needed for Maemo.
24         http://maemo.org/maemo_release_documentation/maemo4.1.x/node8.html#SECTION00870000000000000000
25         https://garage.maemo.org/svn/pymaemo/packages/python-abook/trunk/tests/ especially contact_get_iter amd filter_model
26         http://pymaemo.garage.maemo.org/documentation/api/abook/index.html
27 """
28
29
30 try:
31         import evolution
32 except ImportError:
33         evolution = None
34
35
36 class EvolutionAddressBook(object):
37         """
38         @note Combined the factory and the addressbook for "simplicity" and "cutting down" the number of allocations/deallocations
39         """
40
41         def __init__(self, bookId = None):
42                 if not self.is_supported():
43                         return
44
45                 self._phoneTypes = None
46                 if bookId is not None:
47                         self._bookId = bookId
48                 else:
49                         try:
50                                 self._bookId = [
51                                         bookData[1]
52                                                 for bookData in self.get_addressbooks()
53                                 ][0]
54                         except IndexError:
55                                 global evolution
56                                 evolution = None
57                                 return
58                 self._book = evolution.ebook.open_addressbook(self._bookId)
59
60         @classmethod
61         def is_supported(cls):
62                 return evolution is not None
63
64         def get_addressbooks(self):
65                 """
66                 @returns Iterable of (Address Book Factory, Book Id, Book Name)
67                 """
68                 if not self.is_supported():
69                         return
70
71                 if len(evolution.ebook.list_addressbooks()) == 0 and evolution.ebook.open_addressbook('default') is not None:
72                         # It appears that Maemo's e-d-s does not always list the default addressbook, so we're faking it being listed
73                         yield self, "default", "Maemo"
74
75                 for bookId in evolution.ebook.list_addressbooks():
76                         yield self, bookId[1], bookId[0]
77
78         def open_addressbook(self, bookId):
79                 self._bookId = bookId
80                 self._book = evolution.ebook.open_addressbook(self._bookId)
81                 return self
82
83         @staticmethod
84         def contact_source_short_name(contactId):
85                 return "Evo"
86
87         def clear_caches(self):
88                 pass
89
90         @staticmethod
91         def factory_name():
92                 return "Evolution"
93
94         def get_contacts(self):
95                 """
96                 @returns Iterable of (contact id, contact name)
97                 """
98                 if not self.is_supported():
99                         return
100
101                 for contact in self._book.get_all_contacts():
102                         yield str(contact.get_uid()), contact.props.full_name
103
104         def get_contact_details(self, contactId):
105                 """
106                 @returns Iterable of (Phone Type, Phone Number)
107                 """
108                 contact = self._book.get_contact(int(contactId))
109
110                 if self._phoneTypes is None and contact is not None:
111                         self._phoneTypes = [pt for pt in dir(contact.props) if "phone" in pt.lower()]
112
113                 for phoneType in self._phoneTypes:
114                         phoneNumber = getattr(contact.props, phoneType)
115                         if isinstance(phoneNumber, str):
116                                 yield phoneType, phoneNumber
117
118
119 def print_evobooks():
120         """
121         Included here for debugging.
122
123         Either insert it into the code or launch python with the "-i" flag
124         """
125         if not EvolutionAddressBook.is_supported():
126                 print "No Evolution Support"
127                 return
128
129         eab = EvolutionAddressBook()
130         for book in eab.get_addressbooks():
131                 eab = eab.open_addressbook(book[1])
132                 print book
133                 for contact in eab.get_contacts():
134                         print "\t", contact
135                         for details in eab.get_contact_details(contact[0]):
136                                 print "\t\t", details