From 78b9596221268a59856b410c4360e3da6d2bd60a Mon Sep 17 00:00:00 2001 From: Ed Page Date: Sat, 28 Nov 2009 18:49:41 -0600 Subject: [PATCH] Implemented DnD in the backend and in the presence code Switching user alias to the account number Removing irrelevant TODOs clarified some TODOs --- src/aliasing.py | 19 +++++++++++++++++-- src/channel/contact_list.py | 8 -------- src/channel/text.py | 3 +-- src/connection.py | 8 ++------ src/gvoice/backend.py | 40 ++++++++++++++++++++++++++++++++++++++-- src/simple_presence.py | 30 +++++++++++++++--------------- 6 files changed, 73 insertions(+), 35 deletions(-) diff --git a/src/aliasing.py b/src/aliasing.py index 9d76629..ed79708 100644 --- a/src/aliasing.py +++ b/src/aliasing.py @@ -6,6 +6,12 @@ import gtk_toolbox import handle +USER_ALIAS_ACCOUNT = "account" +USER_ALIAS_CALLBACK = "callback" + +USER_ALIAS = USER_ALIAS_ACCOUNT + + _moduleLogger = logging.getLogger('aliasing') @@ -100,6 +106,10 @@ class AliasingMixin(telepathy.server.ConnectionInterfaceAliasing): @gtk_toolbox.log_exception(_moduleLogger) def SetAliases(self, aliases): _moduleLogger.debug("Called SetAliases") + if USER_ALIAS == USER_ALIAS_ACCOUNT: + raise telepathy.errors.PermissionDenied("No user customizable aliases") + elif USER_ALIAS != USER_ALIAS_CALLBACK: + raise RuntimeError("Invalid alias type: %r" % USER_ALIAS) # first validate that no other handle types are included userHandleAndAlias = None @@ -123,8 +133,13 @@ class AliasingMixin(telepathy.server.ConnectionInterfaceAliasing): def _get_alias(self, handleId): h = self.handle(telepathy.HANDLE_TYPE_CONTACT, handleId) if isinstance(h, handle.ConnectionHandle): - callbackNumber = self.session.backend.get_callback_number() - userAlias = make_pretty(callbackNumber) + if USER_ALIAS == USER_ALIAS_CALLBACK: + aliasNumber = self.session.backend.get_callback_number() + elif USER_ALIAS == USER_ALIAS_ACCOUNT: + aliasNumber = self.session.backend.get_account_number() + else: + raise RuntimeError("Invalid alias type: %r" % USER_ALIAS) + userAlias = make_pretty(aliasNumber) return userAlias else: contactId = h.contactID diff --git a/src/channel/contact_list.py b/src/channel/contact_list.py index c753f0b..e2a8493 100644 --- a/src/channel/contact_list.py +++ b/src/channel/contact_list.py @@ -43,12 +43,6 @@ class AllContactsListChannel(AbstractListChannel): @coroutines.expand_positional @gobject_utils.async def _on_contacts_refreshed(self, addressbook, added, removed, changed): - """ - @todo This currently filters out people not yet added to the contact - list. Something needs to be done about those - @todo This currently does not handle people with multiple phone - numbers, yay that'll be annoying to resolve - """ self._process_refresh(addressbook, added, removed) def _process_refresh(self, addressbook, added, removed): @@ -56,13 +50,11 @@ class AllContactsListChannel(AbstractListChannel): handlesAdded = [ handle.create_handle(connection, "contact", contactId, phoneNumber) for contactId in added - if contactId for (phoneType, phoneNumber) in addressbook.get_contact_details(contactId) ] handlesRemoved = [ handle.create_handle(connection, "contact", contactId, phoneNumber) for contactId in removed - if contactId for (phoneType, phoneNumber) in addressbook.get_contact_details(contactId) ] message = "" diff --git a/src/channel/text.py b/src/channel/text.py index d394b0f..83de6da 100644 --- a/src/channel/text.py +++ b/src/channel/text.py @@ -10,7 +10,6 @@ import handle _moduleLogger = logging.getLogger("channel.text") -# @todo Get receiving of texts to work class TextChannel(telepathy.server.ChannelTypeText): """ Look into implementing ChannelInterfaceMessages for rich text formatting @@ -38,7 +37,7 @@ class TextChannel(telepathy.server.ChannelTypeText): def _on_message_received(self, contactId, contactNumber, message): """ - @todo Attatch this to receiving a message + @todo Attatch this to receiving a message signal """ currentReceivedId = self._nextRecievedId diff --git a/src/connection.py b/src/connection.py index 00c0e83..2724a45 100644 --- a/src/connection.py +++ b/src/connection.py @@ -22,8 +22,7 @@ class TheOneRingConnection( ): # Overriding a base class variable - # @todo remove forward as one of the settings but instead use the alias - # with set sane defaults and saving it to an ini file + # Should the forwarding number be handled by the alias or by an option? _mandatory_parameters = { 'username' : 's', 'password' : 's', @@ -191,9 +190,6 @@ class TheOneRingConnection( return handles def _create_contact_handle(self, requestedHandleName): - """ - @todo Determine if nay of this is really needed - """ requestedContactId, requestedContactNumber = handle.ContactHandle.from_handle_name( requestedHandleName ) @@ -202,7 +198,7 @@ class TheOneRingConnection( def _on_invite_text(self, contactId): """ - @todo Make this work + @todo Get externally initiated conversations working """ h = self._create_contact_handle(contactId) diff --git a/src/gvoice/backend.py b/src/gvoice/backend.py index 9bada99..4a66181 100755 --- a/src/gvoice/backend.py +++ b/src/gvoice/backend.py @@ -136,6 +136,10 @@ class GVoiceBackend(object): self._accountNumRe = re.compile(r"""(.{14})""") self._callbackRe = re.compile(r"""\s+(.*?):\s*(.*?)\s*$""", re.M) + self._isDndURL = "https://www.google.com/voice/m/donotdisturb" + self._isDndRe = re.compile(r"""""") + self._setDndURL = "https://www.google.com/voice/m/savednd" + self._gvDialingStrRe = re.compile("This may take a few seconds", re.M) self._clicktocallURL = "https://www.google.com/voice/m/sendcall" self._sendSmsURL = "https://www.google.com/voice/m/sendsms" @@ -248,6 +252,32 @@ class GVoiceBackend(object): self._browser.cookies.clear() self._browser.cookies.save() + def is_dnd(self): + try: + isDndPage = self._browser.download(self._isDndURL) + except urllib2.URLError, e: + _moduleLogger.exception("Translating error: %s" % str(e)) + raise NetworkError("%s is not accesible" % self._isDndURL) + + dndGroup = self._isDndRe.search(isDndPage) + if dndGroup is None: + return False + dndStatus = dndGroup.group(1) + isDnd = True if dndStatus.strip().lower() == "true" else False + return isDnd + + def set_dnd(self, doNotDisturb): + dndPostData = urllib.urlencode({ + "doNotDisturb": 1 if doNotDisturb else 0, + "_rnr_se": self._token, + }) + + try: + dndPage = self._browser.download(self._setDndURL, dndPostData) + except urllib2.URLError, e: + _moduleLogger.exception("Translating error: %s" % str(e)) + raise NetworkError("%s is not accesible" % self._setDndURL) + def dial(self, number): """ This is the main function responsible for initating the callback @@ -668,6 +698,11 @@ def test_backend(username, password): if not backend.is_authed(): print "Login?: ", backend.login(username, password) print "Authenticated: ", backend.is_authed() + print "Is Dnd: ", backend.is_dnd() + #print "Setting Dnd", backend.set_dnd(True) + #print "Is Dnd: ", backend.is_dnd() + #print "Setting Dnd", backend.set_dnd(False) + #print "Is Dnd: ", backend.is_dnd() #print "Token: ", backend._token #print "Account: ", backend.get_account_number() @@ -711,6 +746,7 @@ def grab_debug_info(username, password): ("forward", backend._forwardURL), ("token", backend._tokenURL), ("login", backend._loginURL), + ("isdnd", backend._isDndURL), ("contacts", backend._contactsURL), ("voicemail", backend._voicemailURL), @@ -775,5 +811,5 @@ def grab_debug_info(username, password): if __name__ == "__main__": import sys logging.basicConfig(level=logging.DEBUG) - #test_backend(sys.argv[1], sys.argv[2]) - grab_debug_info(sys.argv[1], sys.argv[2]) + test_backend(sys.argv[1], sys.argv[2]) + #grab_debug_info(sys.argv[1], sys.argv[2]) diff --git a/src/simple_presence.py b/src/simple_presence.py index 6e6e324..8a615b4 100644 --- a/src/simple_presence.py +++ b/src/simple_presence.py @@ -3,6 +3,7 @@ import logging import telepathy import gtk_toolbox +import handle _moduleLogger = logging.getLogger("simple_presence") @@ -44,19 +45,22 @@ class SimplePresenceMixin(telepathy.server.ConnectionInterfaceSimplePresence): @gtk_toolbox.log_exception(_moduleLogger) def GetPresences(self, contacts): """ - @todo Copy Aliasing's approach to knowing if self and get whether busy or not - @return {ContactHandle: (Status, Presence Type, Message)} """ presences = {} for handleId in contacts: - handle = self.handle(telepathy.HANDLE_TYPE_CONTACT, handleId) - - presence = TheOneRingPresence.BUSY - personalMessage = u"" - presenceType = TheOneRingPresence.TO_PRESENCE_TYPE[presence] - - presences[handle] = (presenceType, presence, personalMessage) + h = self.handle(telepathy.HANDLE_TYPE_CONTACT, handleId) + if isinstance(h, handle.ConnectionHandle): + isDnd = self.session.backend.is_dnd() + presence = TheOneRingPresence.BUSY if isDnd else TheOneRingPresence.ONLINE + personalMessage = u"" + presenceType = TheOneRingPresence.TO_PRESENCE_TYPE[presence] + else: + presence = TheOneRingPresence.ONLINE + personalMessage = u"" + presenceType = TheOneRingPresence.TO_PRESENCE_TYPE[presence] + + presences[h] = (presenceType, presence, personalMessage) return presences @gtk_toolbox.log_exception(_moduleLogger) @@ -66,13 +70,9 @@ class SimplePresenceMixin(telepathy.server.ConnectionInterfaceSimplePresence): if status == TheOneRingPresence.ONLINE: - # @todo Implement dnd - #self.gvoice_backend.mark_dnd(True) - pass + self.gvoice_backend.set_dnd(False) elif status == TheOneRingPresence.BUSY: - # @todo Implement dnd - #self.gvoice_backend.mark_dnd(False) - raise telepathy.errors.NotAvailable("DnD support not yet added to TheOneRing") + self.gvoice_backend.set_dnd(True) else: raise telepathy.errors.InvalidArgument("Unsupported status: %r" % status) _moduleLogger.info("Setting Presence to '%s'" % status) -- 1.7.9.5