4 DialCentral - Front end for Google's GoogleVoice 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 Google Voice backend code
24 http://thatsmith.com/2009/03/google-voice-addon-for-firefox/
25 http://posttopic.com/topic/google-voice-add-on-development
28 from __future__ import with_statement
33 from gvoice import gvoice
36 _moduleLogger = logging.getLogger(__name__)
39 class GVDialer(object):
41 def __init__(self, cookieFile = None):
42 self._gvoice = gvoice.GVoiceBackend(cookieFile)
44 def is_quick_login_possible(self):
46 @returns True then is_authed might be enough to login, else full login is required
48 return self._gvoice.is_quick_login_possible()
50 def is_authed(self, force = False):
52 Attempts to detect a current session
53 @note Once logged in try not to reauth more than once a minute.
54 @returns If authenticated
56 return self._gvoice.is_authed(force)
58 def login(self, username, password):
60 Attempt to login to GoogleVoice
61 @returns Whether login was successful or not
63 return self._gvoice.login(username, password)
66 return self._gvoice.logout()
69 return self._gvoice.persist()
72 return self._gvoice.is_dnd()
74 def set_dnd(self, doNotDisturb):
75 return self._gvoice.set_dnd(doNotDisturb)
77 def call(self, outgoingNumber):
79 This is the main function responsible for initating the callback
81 return self._gvoice.call(outgoingNumber)
83 def cancel(self, outgoingNumber=None):
85 Cancels a call matching outgoing and forwarding numbers (if given).
86 Will raise an error if no matching call is being placed
88 return self._gvoice.cancel(outgoingNumber)
90 def send_sms(self, phoneNumbers, message):
91 self._gvoice.send_sms(phoneNumbers, message)
93 def search(self, query):
95 Search your Google Voice Account history for calls, voicemails, and sms
96 Returns ``Folder`` instance containting matching messages
98 return self._gvoice.search(query)
100 def get_feed(self, feed):
101 return self._gvoice.get_feed(feed)
103 def download(self, messageId, adir):
105 Download a voicemail or recorded call MP3 matching the given ``msg``
106 which can either be a ``Message`` instance, or a SHA1 identifier.
107 Saves files to ``adir`` (defaults to current directory).
108 Message hashes can be found in ``self.voicemail().messages`` for example.
109 Returns location of saved file.
111 return self._gvoice.download(messageId, adir)
113 def is_valid_syntax(self, number):
115 @returns If This number be called ( syntax validation only )
117 return self._gvoice.is_valid_syntax(number)
119 def get_account_number(self):
121 @returns The GoogleVoice phone number
123 return self._gvoice.get_account_number()
125 def get_callback_numbers(self):
127 @returns a dictionary mapping call back numbers to descriptions
128 @note These results are cached for 30 minutes.
130 return self._gvoice.get_callback_numbers()
132 def set_callback_number(self, callbacknumber):
134 Set the number that GoogleVoice calls
135 @param callbacknumber should be a proper 10 digit number
137 return self._gvoice.set_callback_number(callbacknumber)
139 def get_callback_number(self):
141 @returns Current callback number or None
143 return self._gvoice.get_callback_number()
145 def get_recent(self):
147 @returns Iterable of (personsName, phoneNumber, exact date, relative date, action)
149 return list(self._gvoice.get_recent())
151 def get_contacts(self):
153 @returns Fresh dictionary of items
155 return dict(self._gvoice.get_contacts())
157 def get_messages(self):
158 return list(self._get_messages())
160 def _get_messages(self):
161 voicemails = self._gvoice.get_voicemails()
162 smss = self._gvoice.get_texts()
163 conversations = itertools.chain(voicemails, smss)
164 for conversation in conversations:
165 messages = conversation.messages
167 (message.whoFrom, self._format_message(message), message.when)
168 for message in messages
172 "id": conversation.id,
173 "contactId": conversation.contactId,
174 "name": conversation.name,
175 "time": conversation.time,
176 "relTime": conversation.relTime,
177 "prettyNumber": conversation.prettyNumber,
178 "number": conversation.number,
179 "location": conversation.location,
180 "messageParts": messageParts,
181 "type": conversation.type,
182 "isRead": conversation.isRead,
183 "isTrash": conversation.isTrash,
184 "isSpam": conversation.isSpam,
185 "isArchived": conversation.isArchived,
189 def clear_caches(self):
192 def get_addressbooks(self):
194 @returns Iterable of (Address Book Factory, Book Id, Book Name)
198 def open_addressbook(self, bookId):
202 def contact_source_short_name(contactId):
207 return "Google Voice"
209 def _format_message(self, message):
210 messagePartFormat = {
216 messagePartFormat[text.accuracy] % text.text
217 for text in message.body
221 def sort_messages(allMessages):
222 sortableAllMessages = [
223 (message["time"], message)
224 for message in allMessages
226 sortableAllMessages.sort(reverse=True)
229 for (exactTime, message) in sortableAllMessages
233 def decorate_recent(recentCallData):
235 @returns (personsName, phoneNumber, date, action)
237 contactId = recentCallData["contactId"]
238 if recentCallData["name"]:
239 header = recentCallData["name"]
240 elif recentCallData["prettyNumber"]:
241 header = recentCallData["prettyNumber"]
242 elif recentCallData["location"]:
243 header = recentCallData["location"]
247 number = recentCallData["number"]
248 relTime = recentCallData["relTime"]
249 action = recentCallData["action"]
250 return contactId, header, number, relTime, action
253 def decorate_message(messageData):
254 contactId = messageData["contactId"]
255 exactTime = messageData["time"]
256 if messageData["name"]:
257 header = messageData["name"]
258 elif messageData["prettyNumber"]:
259 header = messageData["prettyNumber"]
262 number = messageData["number"]
263 relativeTime = messageData["relTime"]
265 messageParts = list(messageData["messageParts"])
266 if len(messageParts) == 0:
267 messages = ("No Transcription", )
268 elif len(messageParts) == 1:
269 messages = (messageParts[0][1], )
272 "<b>%s</b>: %s" % (messagePart[0], messagePart[1])
273 for messagePart in messageParts
276 decoratedResults = contactId, header, number, relativeTime, messages
277 return decoratedResults