Attempts to detect a current session
@note Once logged in try not to reauth more than once a minute.
@returns If authenticated
+ @blocks
"""
isRecentledAuthed = (time.time() - self._lastAuthed) < 120
isPreviouslyAuthed = self._token is not None
"""
Attempt to login to GoogleVoice
@returns Whether login was successful or not
+ @blocks
"""
self.logout()
galxToken = self._get_token()
def persist(self):
self._browser.save_cookies()
+ def shutdown(self):
+ self._browser.save_cookies()
+ self._token = None
+ self._lastAuthed = 0.0
+
def logout(self):
self._browser.clear_cookies()
self._browser.save_cookies()
self._lastAuthed = 0.0
def is_dnd(self):
+ """
+ @blocks
+ """
isDndPage = self._get_page(self._isDndURL)
dndGroup = self._isDndRe.search(isDndPage)
return isDnd
def set_dnd(self, doNotDisturb):
+ """
+ @blocks
+ """
dndPostData = {
"doNotDisturb": 1 if doNotDisturb else 0,
}
def call(self, outgoingNumber):
"""
This is the main function responsible for initating the callback
+ @blocks
"""
outgoingNumber = self._send_validation(outgoingNumber)
subscriberNumber = None
"""
Cancels a call matching outgoing and forwarding numbers (if given).
Will raise an error if no matching call is being placed
+ @blocks
"""
page = self._get_page_with_token(
self._callCancelURL,
self._parse_with_validation(page)
def send_sms(self, phoneNumbers, message):
+ """
+ @blocks
+ """
validatedPhoneNumbers = [
self._send_validation(phoneNumber)
for phoneNumber in phoneNumbers
"""
Search your Google Voice Account history for calls, voicemails, and sms
Returns ``Folder`` instance containting matching messages
+ @blocks
"""
page = self._get_page(
self._XML_SEARCH_URL,
return json
def get_feed(self, feed):
+ """
+ @blocks
+ """
actualFeed = "_XML_%s_URL" % feed.upper()
feedUrl = getattr(self, actualFeed)
which can either be a ``Message`` instance, or a SHA1 identifier.
Saves files to ``adir`` (defaults to current directory).
Message hashes can be found in ``self.voicemail().messages`` for example.
- Returns location of saved file.
+ @returns location of saved file.
+ @blocks
"""
page = self._get_page(self._downloadVoicemailURL, {"id": messageId})
fn = os.path.join(adir, '%s.mp3' % messageId)
def get_recent(self):
"""
@returns Iterable of (personsName, phoneNumber, exact date, relative date, action)
+ @blocks
"""
for action, url in (
("Received", self._XML_RECEIVED_URL),
def get_contacts(self):
"""
@returns Iterable of (contact id, contact name)
+ @blocks
"""
page = self._get_page(self._XML_CONTACTS_URL)
contactsBody = self._contactsBodyRe.search(page)
if contactsBody is None:
raise RuntimeError("Could not extract contact information")
accountData = _fake_parse_json(contactsBody.group(1))
+ if accountData is None:
+ return
for contactId, contactDetails in accountData["contacts"].iteritems():
# A zero contact id is the catch all for unknown contacts
if contactId != "0":
yield contactId, contactDetails
def get_voicemails(self):
+ """
+ @blocks
+ """
voicemailPage = self._get_page(self._XML_VOICEMAIL_URL)
voicemailHtml = self._grab_html(voicemailPage)
voicemailJson = self._grab_json(voicemailPage)
+ if voicemailJson is None:
+ return ()
parsedVoicemail = self._parse_voicemail(voicemailHtml)
voicemails = self._merge_conversation_sources(parsedVoicemail, voicemailJson)
return voicemails
def get_texts(self):
+ """
+ @blocks
+ """
smsPage = self._get_page(self._XML_SMS_URL)
smsHtml = self._grab_html(smsPage)
smsJson = self._grab_json(smsPage)
+ if smsJson is None:
+ return ()
parsedSms = self._parse_sms(smsHtml)
smss = self._merge_conversation_sources(parsedSms, smsJson)
return smss
def mark_message(self, messageId, asRead):
+ """
+ @blocks
+ """
postData = {
"read": 1 if asRead else 0,
"id": messageId,
markPage = self._get_page(self._markAsReadURL, postData)
def archive_message(self, messageId):
+ """
+ @blocks
+ """
postData = {
"id": messageId,
}
"""
abbrevTime = time[:-3]
parsedTime = datetime.datetime.strptime(abbrevTime, "%m/%d/%y %I:%M")
- if time[-2] == "PN":
+ if time.endswith("PM"):
parsedTime += datetime.timedelta(hours=12)
return parsedTime
def safe_eval(s):
_TRUE_REGEX = re.compile("true")
_FALSE_REGEX = re.compile("false")
+ _COMMENT_REGEX = re.compile("^\s+//.*$", re.M)
s = _TRUE_REGEX.sub("True", s)
s = _FALSE_REGEX.sub("False", s)
- return eval(s, {}, {})
+ s = _COMMENT_REGEX.sub("#", s)
+ try:
+ results = eval(s, {}, {})
+ except SyntaxError:
+ _moduleLogger.exception("Oops")
+ results = None
+ return results
def _fake_parse_json(flattened):
Validates that the JSON response is A-OK
"""
try:
- assert 'ok' in response and response['ok']
+ assert response is not None
+ assert 'ok' in response
+ assert response['ok']
except AssertionError:
raise RuntimeError('There was a problem with GV: %s' % response)