import browser_emu
-_moduleLogger = logging.getLogger("gvoice.backend")
+_moduleLogger = logging.getLogger(__name__)
class NetworkError(RuntimeError):
)
self._parse_with_validation(page)
- def send_sms(self, phoneNumber, message):
- phoneNumber = self._send_validation(phoneNumber)
+ def send_sms(self, phoneNumbers, message):
+ validatedPhoneNumbers = [
+ self._send_validation(phoneNumber)
+ for phoneNumber in phoneNumbers
+ ]
+ flattenedPhoneNumbers = ",".join(validatedPhoneNumbers)
page = self._get_page_with_token(
self._sendSmsURL,
{
- 'phoneNumber': phoneNumber,
+ 'phoneNumber': flattenedPhoneNumbers,
'text': message
},
)
raise ValueError('Number is not valid: "%s"' % number)
elif not self.is_authed():
raise RuntimeError("Not Authenticated")
-
- if len(number) == 11 and number[0] == 1:
- # Strip leading 1 from 11 digit dialing
- number = number[1:]
return number
def _parse_history(self, historyHtml):
for messageId, messageHtml in itergroup(splitVoicemail[1:], 2):
exactTimeGroup = self._exactVoicemailTimeRegex.search(messageHtml)
exactTime = exactTimeGroup.group(1).strip() if exactTimeGroup else ""
- exactTime = datetime.datetime.strptime(exactTime, "%m/%d/%y %I:%M %p")
+ exactTime = google_strptime(exactTime)
relativeTimeGroup = self._relativeVoicemailTimeRegex.search(messageHtml)
relativeTime = relativeTimeGroup.group(1).strip() if relativeTimeGroup else ""
locationGroup = self._voicemailLocationRegex.search(messageHtml)
exactTimeGroup = self._exactVoicemailTimeRegex.search(messageHtml)
exactTimeText = exactTimeGroup.group(1).strip() if exactTimeGroup else ""
- conv.time = datetime.datetime.strptime(exactTimeText, "%m/%d/%y %I:%M %p")
+ conv.time = google_strptime(exactTimeText)
relativeTimeGroup = self._relativeVoicemailTimeRegex.search(messageHtml)
conv.relTime = relativeTimeGroup.group(1).strip() if relativeTimeGroup else ""
locationGroup = self._voicemailLocationRegex.search(messageHtml)
exactTimeGroup = self._exactVoicemailTimeRegex.search(messageHtml)
exactTimeText = exactTimeGroup.group(1).strip() if exactTimeGroup else ""
- conv.time = datetime.datetime.strptime(exactTimeText, "%m/%d/%y %I:%M %p")
+ conv.time = google_strptime(exactTimeText)
relativeTimeGroup = self._relativeVoicemailTimeRegex.search(messageHtml)
conv.relTime = relativeTimeGroup.group(1).strip() if relativeTimeGroup else ""
conv.location = ""
return json
+def google_strptime(time):
+ """
+ Hack: Google always returns the time in the same locale. Sadly if the
+ local system's locale is different, there isn't a way to perfectly handle
+ the time. So instead we handle implement some time formatting
+ """
+ abbrevTime = time[:-3]
+ parsedTime = datetime.datetime.strptime(abbrevTime, "%m/%d/%y %I:%M")
+ if time[-2] == "PN":
+ parsedTime += datetime.timedelta(hours=12)
+ return parsedTime
+
+
def itergroup(iterator, count, padValue = None):
"""
Iterate in groups of 'count' values. If there
def guess_phone_type(number):
- if number.startswith("747") or number.startswith("1747"):
+ if number.startswith("747") or number.startswith("1747") or number.startswith("+1747"):
return GVoiceBackend.PHONE_TYPE_GIZMO
else:
return GVoiceBackend.PHONE_TYPE_MOBILE
numbers = backend.get_callback_numbers()
priorityOrderedCriteria = [
+ ("\+1747", None),
("1747", None),
+ ("747", None),
(None, "gizmo"),
(None, "computer"),
(None, "sip"),
]
for numberCriteria, descriptionCriteria in priorityOrderedCriteria:
+ numberMatcher = None
+ descriptionMatcher = None
+ if numberCriteria is not None:
+ numberMatcher = re.compile(numberCriteria)
+ elif descriptionCriteria is not None:
+ descriptionMatcher = re.compile(descriptionCriteria, re.I)
+
for number, description in numbers.iteritems():
- if numberCriteria is not None and re.compile(numberCriteria).match(number) is None:
+ if numberMatcher is not None and numberMatcher.match(number) is None:
continue
- if descriptionCriteria is not None and re.compile(descriptionCriteria).match(description) is None:
+ if descriptionMatcher is not None and descriptionMatcher.match(description) is None:
continue
return number