Starting to generalize the gv backend
authorEd Page <eopage@byu.net>
Tue, 29 Sep 2009 12:36:52 +0000 (07:36 -0500)
committerEd Page <eopage@byu.net>
Tue, 29 Sep 2009 12:36:52 +0000 (07:36 -0500)
src/channel/call.py
src/channel/text.py
src/channel_manager.py
src/connection.py
src/connection_manager.py
src/constants.py
src/gv_backend.py [changed mode: 0644->0755]
src/handle.py
support/theonering.manager

index 33ef173..21613b7 100644 (file)
@@ -12,9 +12,8 @@ class CallChannel(
                telepathy.server.ChannelInterfaceCallState,
        ):
 
                telepathy.server.ChannelInterfaceCallState,
        ):
 
-       def __init__(self, connection, conversation):
+       def __init__(self, connection):
                self._recv_id = 0
                self._recv_id = 0
-               self._conversation = conversation
                self._connRef = weakref.ref(connection)
 
                telepathy.server.ChannelTypeText.__init__(self, connection, None)
                self._connRef = weakref.ref(connection)
 
                telepathy.server.ChannelTypeText.__init__(self, connection, None)
index 8fe4a5f..e882bfd 100644 (file)
@@ -9,9 +9,8 @@ class TextChannel(telepathy.server.ChannelTypeText):
        Look into implementing ChannelInterfaceMessages for rich text formatting
        """
 
        Look into implementing ChannelInterfaceMessages for rich text formatting
        """
 
-       def __init__(self, connection, conversation):
+       def __init__(self, connection):
                self._recv_id = 0
                self._recv_id = 0
-               self._conversation = conversation
                self._connRef = weakref.ref(connection)
 
                telepathy.server.ChannelTypeText.__init__(self, connection, None)
                self._connRef = weakref.ref(connection)
 
                telepathy.server.ChannelTypeText.__init__(self, connection, None)
@@ -21,9 +20,7 @@ class TextChannel(telepathy.server.ChannelTypeText):
 
        def Send(self, messageType, text):
                if messageType == telepathy.CHANNEL_TEXT_MESSAGE_TYPE_NORMAL:
 
        def Send(self, messageType, text):
                if messageType == telepathy.CHANNEL_TEXT_MESSAGE_TYPE_NORMAL:
-                       self._conversation.send_text_message(text)
-               elif messageType == telepathy.CHANNEL_TEXT_MESSAGE_TYPE_ACTION and text == u"nudge":
-                       self._conversation.send_nudge()
+                       pass
                else:
                        raise telepathy.NotImplemented("Unhandled message type")
                self.Sent(int(time.time()), messageType, text)
                else:
                        raise telepathy.NotImplemented("Unhandled message type")
                self.Sent(int(time.time()), messageType, text)
index 90fdd99..979481f 100644 (file)
@@ -39,32 +39,26 @@ class ChannelManager(object):
                        self._connRef().add_channel(chan, handle, suppress_handler)
                return chan
 
                        self._connRef().add_channel(chan, handle, suppress_handler)
                return chan
 
-       def channel_for_text(self, handle, conversation=None, suppress_handler=False):
+       def channel_for_text(self, handle, suppress_handler=False):
                if handle in self._textChannels:
                        chan = self._textChannels[handle]
                else:
                        _moduleLogger.debug("Requesting new text channel")
                        contact = handle.contact
 
                if handle in self._textChannels:
                        chan = self._textChannels[handle]
                else:
                        _moduleLogger.debug("Requesting new text channel")
                        contact = handle.contact
 
-                       if conversation is None:
-                               client = self._connRef().msn_client
-                               conversation = None
-                       chan = channel.text.TextChannel(self._connRef(), conversation)
+                       chan = channel.text.TextChannel(self._connRef())
                        self._textChannels[handle] = chan
                        self._connRef().add_channel(chan, handle, suppress_handler)
                return chan
 
                        self._textChannels[handle] = chan
                        self._connRef().add_channel(chan, handle, suppress_handler)
                return chan
 
-       def channel_forcall(self, handle, conversation=None, suppress_handler=False):
+       def channel_for_call(self, handle, suppress_handler=False):
                if handle in self._callChannels:
                        chan = self._callChannels[handle]
                else:
                        _moduleLogger.debug("Requesting new call channel")
                        contact = handle.contact
 
                if handle in self._callChannels:
                        chan = self._callChannels[handle]
                else:
                        _moduleLogger.debug("Requesting new call channel")
                        contact = handle.contact
 
-                       if conversation is None:
-                               client = self._connRef().msn_client
-                               conversation = None
-                       chan = channel.call.CallChannel(self._connRef(), conversation)
+                       chan = channel.call.CallChannel(self._connRef())
                        self._callChannels[handle] = chan
                        self._connRef().add_channel(chan, handle, suppress_handler)
                return chan
                        self._callChannels[handle] = chan
                        self._connRef().add_channel(chan, handle, suppress_handler)
                return chan
index 304491d..567d399 100644 (file)
@@ -17,7 +17,8 @@ class TheOneRingConnection(telepathy.server.Connection, simple_presence.SimplePr
 
        MANDATORY_PARAMETERS = {
                'account' : 's',
 
        MANDATORY_PARAMETERS = {
                'account' : 's',
-               'password' : 's'
+               'password' : 's',
+               'forward' : 's',
        }
        OPTIONAL_PARAMETERS = {
        }
        }
        OPTIONAL_PARAMETERS = {
        }
@@ -41,6 +42,7 @@ class TheOneRingConnection(telepathy.server.Connection, simple_presence.SimplePr
                                parameters['account'].encode('utf-8'),
                                parameters['password'].encode('utf-8'),
                        )
                                parameters['account'].encode('utf-8'),
                                parameters['password'].encode('utf-8'),
                        )
+                       self._callbackNumber = parameters['forward'].encode('utf-8')
                        self._channelManager = channel_manager.ChannelManager(self)
 
                        cookieFilePath = "%s/cookies.txt" % constants._data_path_
                        self._channelManager = channel_manager.ChannelManager(self)
 
                        cookieFilePath = "%s/cookies.txt" % constants._data_path_
@@ -79,6 +81,7 @@ class TheOneRingConnection(telepathy.server.Connection, simple_presence.SimplePr
                )
                try:
                        self._backend.login(*self._credentials)
                )
                try:
                        self._backend.login(*self._credentials)
+                       self._backend.set_callback_number(self._callbackNumber)
                except gv_backend.NetworkError:
                        self.StatusChanged(
                                telepathy.CONNECTION_STATUS_DISCONNECTED,
                except gv_backend.NetworkError:
                        self.StatusChanged(
                                telepathy.CONNECTION_STATUS_DISCONNECTED,
@@ -129,7 +132,10 @@ class TheOneRingConnection(telepathy.server.Connection, simple_presence.SimplePr
                elif type == telepathy.CHANNEL_TYPE_TEXT:
                        if handleType != telepathy.HANDLE_TYPE_CONTACT:
                                raise telepathy.NotImplemented("Only Contacts are allowed")
                elif type == telepathy.CHANNEL_TYPE_TEXT:
                        if handleType != telepathy.HANDLE_TYPE_CONTACT:
                                raise telepathy.NotImplemented("Only Contacts are allowed")
-                       contact = handle.contact
+                       channel = channelManager.channel_for_text(handle, None, suppressHandler)
+               elif type == telepathy.CHANNEL_TYPE_STREAMED_MEDIA:
+                       if handleType != telepathy.HANDLE_TYPE_CONTACT:
+                               raise telepathy.NotImplemented("Only Contacts are allowed")
                        channel = channelManager.channel_for_text(handle, None, suppressHandler)
                else:
                        raise telepathy.NotImplemented("unknown channel type %s" % type)
                        channel = channelManager.channel_for_text(handle, None, suppressHandler)
                else:
                        raise telepathy.NotImplemented("unknown channel type %s" % type)
@@ -141,7 +147,7 @@ class TheOneRingConnection(telepathy.server.Connection, simple_presence.SimplePr
                For org.freedesktop.telepathy.Connection
                """
                self.check_connected()
                For org.freedesktop.telepathy.Connection
                """
                self.check_connected()
-               self.check_handleType(handleType)
+               self.check_handle_type(handleType)
 
                handles = []
                for name in names:
 
                handles = []
                for name in names:
@@ -159,16 +165,18 @@ class TheOneRingConnection(telepathy.server.Connection, simple_presence.SimplePr
                return handles
 
        def _create_contact_handle(self, name):
                return handles
 
        def _create_contact_handle(self, name):
-               requestedContactId, requestedContactName = handle.field_split(name)
+               requestedContactId = name
 
                contacts = self._backend.get_contacts()
                contactsFound = [
                        (contactId, contactName) for (contactId, contactName) in contacts
 
                contacts = self._backend.get_contacts()
                contactsFound = [
                        (contactId, contactName) for (contactId, contactName) in contacts
-                       if contactName == name
+                       if contactId == requestedContactId
                ]
 
                if 0 < len(contactsFound):
                        contactId, contactName = contactsFound[0]
                ]
 
                if 0 < len(contactsFound):
                        contactId, contactName = contactsFound[0]
-                       h = handle.create_handle(self, 'contact', contactId, contactName)
+                       if len(contactsFound) != 1:
+                               _moduleLogger.error("Contact ID was not unique: %s for %s" % (contactId, contactName))
                else:
                else:
-                       h = handle.create_handle(self, 'contact', requestedContactId, requestedContactName)
+                       contactId, contactName = requestedContactId, ""
+               h = handle.create_handle(self, 'contact', contactId, contactName)
index 9f9dd88..e10f520 100644 (file)
@@ -35,9 +35,12 @@ class TheOneRingConnectionManager(telepathy.server.ConnectionManager):
                defaultParameters = ConnectionClass.PARAMETER_DEFAULTS
 
                for parameterName, parameterType in mandatoryParameters.iteritems():
                defaultParameters = ConnectionClass.PARAMETER_DEFAULTS
 
                for parameterName, parameterType in mandatoryParameters.iteritems():
+                       flags = telepathy.CONN_MGR_PARAM_FLAG_REQUIRED
+                       if parameterName == "password":
+                               flags |= telepathy.CONN_MGR_PARAM_FLAG_SECRET
                        param = (
                                parameterName,
                        param = (
                                parameterName,
-                               telepathy.CONN_MGR_PARAM_FLAG_REQUIRED,
+                               flags,
                                parameterType,
                                '',
                        )
                                parameterType,
                                '',
                        )
@@ -45,14 +48,19 @@ class TheOneRingConnectionManager(telepathy.server.ConnectionManager):
 
                for parameterName, parameterType in optionalParameters.iteritems():
                        if parameterName in defaultParameters:
 
                for parameterName, parameterType in optionalParameters.iteritems():
                        if parameterName in defaultParameters:
-                               param = (
-                                       parameterName,
-                                       telepathy.CONN_MGR_PARAM_FLAG_HAS_DEFAULT,
-                                       parameterName,
-                                       defaultParameters[parameterName],
-                               )
+                               flags = telepathy.CONN_MGR_PARAM_FLAG_HAS_DEFAULT
+                               if parameterName == "password":
+                                       flags |= telepathy.CONN_MGR_PARAM_FLAG_SECRET
+                               default = defaultParameters[parameterName]
                        else:
                        else:
-                               param = (parameterName, 0, parameterName, '')
+                               flags = 0
+                               default = ""
+                       param = (
+                               parameterName,
+                               flags,
+                               parameterName,
+                               default,
+                       )
                        result.append(param)
 
                return result
                        result.append(param)
 
                return result
index 8c24289..2b55ef8 100644 (file)
@@ -7,5 +7,5 @@ __build__ = 0
 __app_magic__ = 0xdeadbeef
 _data_path_ = os.path.join(os.path.expanduser("~"), ".telepathy-theonering")
 _user_settings_ = "%s/settings.ini" % _data_path_
 __app_magic__ = 0xdeadbeef
 _data_path_ = os.path.join(os.path.expanduser("~"), ".telepathy-theonering")
 _user_settings_ = "%s/settings.ini" % _data_path_
-_telepathy_protocol_name_ = "gvoice"
+_telepathy_protocol_name_ = "sip"
 _telepathy_implementation_name_ = "theonering"
 _telepathy_implementation_name_ = "theonering"
old mode 100644 (file)
new mode 100755 (executable)
index 4d6e19c..94bf180
@@ -241,35 +241,6 @@ class GVDialer(object):
                """
                return self._accountNum
 
                """
                return self._accountNum
 
-       def set_sane_callback(self):
-               """
-               Try to set a sane default callback number on these preferences
-               1) 1747 numbers ( Gizmo )
-               2) anything with gizmo in the name
-               3) anything with computer in the name
-               4) the first value
-               """
-               numbers = self.get_callback_numbers()
-
-               for number, description in numbers.iteritems():
-                       if re.compile(r"""1747""").match(number) is not None:
-                               self.set_callback_number(number)
-                               return
-
-               for number, description in numbers.iteritems():
-                       if re.compile(r"""gizmo""", re.I).search(description) is not None:
-                               self.set_callback_number(number)
-                               return
-
-               for number, description in numbers.iteritems():
-                       if re.compile(r"""computer""", re.I).search(description) is not None:
-                               self.set_callback_number(number)
-                               return
-
-               for number, description in numbers.iteritems():
-                       self.set_callback_number(number)
-                       return
-
        def get_callback_numbers(self):
                """
                @returns a dictionary mapping call back numbers to descriptions
        def get_callback_numbers(self):
                """
                @returns a dictionary mapping call back numbers to descriptions
@@ -307,23 +278,6 @@ class GVDialer(object):
                for exactDate, name, number, relativeDate, action in sortedRecent:
                        yield name, number, relativeDate, action
 
                for exactDate, name, number, relativeDate, action in sortedRecent:
                        yield name, number, relativeDate, action
 
-       def get_addressbooks(self):
-               """
-               @returns Iterable of (Address Book Factory, Book Id, Book Name)
-               """
-               yield self, "", ""
-
-       def open_addressbook(self, bookId):
-               return self
-
-       @staticmethod
-       def contact_source_short_name(contactId):
-               return "GV"
-
-       @staticmethod
-       def factory_name():
-               return "Google Voice"
-
        _contactsRe = re.compile(r"""<a href="/voice/m/contact/(\d+)">(.*?)</a>""", re.S)
        _contactsNextRe = re.compile(r""".*<a href="/voice/m/contacts(\?p=\d+)">Next.*?</a>""", re.S)
        _contactsURL = "https://www.google.com/voice/mobile/contacts"
        _contactsRe = re.compile(r"""<a href="/voice/m/contact/(\d+)">(.*?)</a>""", re.S)
        _contactsNextRe = re.compile(r""".*<a href="/voice/m/contacts(\?p=\d+)">Next.*?</a>""", re.S)
        _contactsURL = "https://www.google.com/voice/mobile/contacts"
@@ -398,10 +352,7 @@ class GVDialer(object):
                decoratedSms = self._decorate_sms(parsedSms)
 
                allMessages = itertools.chain(decoratedVoicemails, decoratedSms)
                decoratedSms = self._decorate_sms(parsedSms)
 
                allMessages = itertools.chain(decoratedVoicemails, decoratedSms)
-               sortedMessages = list(allMessages)
-               sortedMessages.sort(reverse=True)
-               for exactDate, header, number, relativeDate, message in sortedMessages:
-                       yield header, number, relativeDate, message
+               return allMessages
 
        def _grab_json(self, flatXml):
                xmlTree = ElementTree.fromstring(flatXml)
 
        def _grab_json(self, flatXml):
                xmlTree = ElementTree.fromstring(flatXml)
@@ -493,6 +444,7 @@ class GVDialer(object):
        _voicemailNumberRegex = re.compile(r"""<input type="hidden" class="gc-text gc-quickcall-ac" value="(.*?)"/>""", re.MULTILINE)
        _prettyVoicemailNumberRegex = re.compile(r"""<span class="gc-message-type">(.*?)</span>""", re.MULTILINE)
        _voicemailLocationRegex = re.compile(r"""<span class="gc-message-location">.*?<a.*?>(.*?)</a></span>""", re.MULTILINE)
        _voicemailNumberRegex = re.compile(r"""<input type="hidden" class="gc-text gc-quickcall-ac" value="(.*?)"/>""", re.MULTILINE)
        _prettyVoicemailNumberRegex = re.compile(r"""<span class="gc-message-type">(.*?)</span>""", re.MULTILINE)
        _voicemailLocationRegex = re.compile(r"""<span class="gc-message-location">.*?<a.*?>(.*?)</a></span>""", re.MULTILINE)
+       _messagesContactID = re.compile(r"""<a class=".*?gc-message-name-link.*?">.*?</a>\s*?<span .*?>(.*?)</span>""", re.MULTILINE)
        #_voicemailMessageRegex = re.compile(r"""<span id="\d+-\d+" class="gc-word-(.*?)">(.*?)</span>""", re.MULTILINE)
        #_voicemailMessageRegex = re.compile(r"""<a .*? class="gc-message-mni">(.*?)</a>""", re.MULTILINE)
        _voicemailMessageRegex = re.compile(r"""(<span id="\d+-\d+" class="gc-word-(.*?)">(.*?)</span>|<a .*? class="gc-message-mni">(.*?)</a>)""", re.MULTILINE)
        #_voicemailMessageRegex = re.compile(r"""<span id="\d+-\d+" class="gc-word-(.*?)">(.*?)</span>""", re.MULTILINE)
        #_voicemailMessageRegex = re.compile(r"""<a .*? class="gc-message-mni">(.*?)</a>""", re.MULTILINE)
        _voicemailMessageRegex = re.compile(r"""(<span id="\d+-\d+" class="gc-word-(.*?)">(.*?)</span>|<a .*? class="gc-message-mni">(.*?)</a>)""", re.MULTILINE)
@@ -522,6 +474,8 @@ class GVDialer(object):
                        number = numberGroup.group(1).strip() if numberGroup else ""
                        prettyNumberGroup = self._prettyVoicemailNumberRegex.search(messageHtml)
                        prettyNumber = prettyNumberGroup.group(1).strip() if prettyNumberGroup else ""
                        number = numberGroup.group(1).strip() if numberGroup else ""
                        prettyNumberGroup = self._prettyVoicemailNumberRegex.search(messageHtml)
                        prettyNumber = prettyNumberGroup.group(1).strip() if prettyNumberGroup else ""
+                       contactIdGroup = self._messagesContactID.search(messageHtml)
+                       contactId = contactIdGroup.group(1).strip() if contactIdGroup else number
 
                        messageGroups = self._voicemailMessageRegex.finditer(messageHtml)
                        messageParts = (
 
                        messageGroups = self._voicemailMessageRegex.finditer(messageHtml)
                        messageParts = (
@@ -531,6 +485,7 @@ class GVDialer(object):
 
                        yield {
                                "id": messageId.strip(),
 
                        yield {
                                "id": messageId.strip(),
+                               "contactId": contactId,
                                "name": name,
                                "time": exactTime,
                                "relTime": relativeTime,
                                "name": name,
                                "time": exactTime,
                                "relTime": relativeTime,
@@ -540,29 +495,23 @@ class GVDialer(object):
                                "messageParts": messageParts,
                        }
 
                                "messageParts": messageParts,
                        }
 
-       def _decorate_voicemail(self, parsedVoicemail):
+       def _decorate_voicemail(self, parsedVoicemails):
                messagePartFormat = {
                        "med1": "<i>%s</i>",
                        "med2": "%s",
                        "high": "<b>%s</b>",
                }
                messagePartFormat = {
                        "med1": "<i>%s</i>",
                        "med2": "%s",
                        "high": "<b>%s</b>",
                }
-               for voicemailData in parsedVoicemail:
-                       exactTime = voicemailData["time"]
-                       if voicemailData["name"]:
-                               header = voicemailData["name"]
-                       elif voicemailData["prettyNumber"]:
-                               header = voicemailData["prettyNumber"]
-                       elif voicemailData["location"]:
-                               header = voicemailData["location"]
-                       else:
-                               header = "Unknown"
+               for voicemailData in parsedVoicemails:
                        message = " ".join((
                                messagePartFormat[quality] % part
                                for (quality, part) in voicemailData["messageParts"]
                        )).strip()
                        if not message:
                                message = "No Transcription"
                        message = " ".join((
                                messagePartFormat[quality] % part
                                for (quality, part) in voicemailData["messageParts"]
                        )).strip()
                        if not message:
                                message = "No Transcription"
-                       yield exactTime, header, voicemailData["number"], voicemailData["relTime"], (message, )
+                       whoFrom = voicemailData["name"]
+                       when = voicemailData["time"]
+                       voicemailData["messageParts"] = ((whoFrom, message, when), )
+                       yield voicemailData
 
        _smsFromRegex = re.compile(r"""<span class="gc-message-sms-from">(.*?)</span>""", re.MULTILINE | re.DOTALL)
        _smsTextRegex = re.compile(r"""<span class="gc-message-sms-time">(.*?)</span>""", re.MULTILINE | re.DOTALL)
 
        _smsFromRegex = re.compile(r"""<span class="gc-message-sms-from">(.*?)</span>""", re.MULTILINE | re.DOTALL)
        _smsTextRegex = re.compile(r"""<span class="gc-message-sms-time">(.*?)</span>""", re.MULTILINE | re.DOTALL)
@@ -583,6 +532,8 @@ class GVDialer(object):
                        number = numberGroup.group(1).strip() if numberGroup else ""
                        prettyNumberGroup = self._prettyVoicemailNumberRegex.search(messageHtml)
                        prettyNumber = prettyNumberGroup.group(1).strip() if prettyNumberGroup else ""
                        number = numberGroup.group(1).strip() if numberGroup else ""
                        prettyNumberGroup = self._prettyVoicemailNumberRegex.search(messageHtml)
                        prettyNumber = prettyNumberGroup.group(1).strip() if prettyNumberGroup else ""
+                       contactIdGroup = self._messagesContactID.search(messageHtml)
+                       contactId = contactIdGroup.group(1).strip() if contactIdGroup else number
 
                        fromGroups = self._smsFromRegex.finditer(messageHtml)
                        fromParts = (group.group(1).strip() for group in fromGroups)
 
                        fromGroups = self._smsFromRegex.finditer(messageHtml)
                        fromParts = (group.group(1).strip() for group in fromGroups)
@@ -595,32 +546,84 @@ class GVDialer(object):
 
                        yield {
                                "id": messageId.strip(),
 
                        yield {
                                "id": messageId.strip(),
+                               "contactId": contactId,
                                "name": name,
                                "time": exactTime,
                                "relTime": relativeTime,
                                "prettyNumber": prettyNumber,
                                "number": number,
                                "name": name,
                                "time": exactTime,
                                "relTime": relativeTime,
                                "prettyNumber": prettyNumber,
                                "number": number,
+                               "location": "",
                                "messageParts": messageParts,
                        }
 
                                "messageParts": messageParts,
                        }
 
-       def _decorate_sms(self, parsedSms):
-               for messageData in parsedSms:
-                       exactTime = messageData["time"]
-                       if messageData["name"]:
-                               header = messageData["name"]
-                       elif messageData["prettyNumber"]:
-                               header = messageData["prettyNumber"]
-                       else:
-                               header = "Unknown"
-                       number = messageData["number"]
-                       relativeTime = messageData["relTime"]
-                       messages = [
-                               "<b>%s</b>: %s" % (messagePart[0], messagePart[-1])
-                               for messagePart in messageData["messageParts"]
-                       ]
-                       if not messages:
-                               messages = ("No Transcription", )
-                       yield exactTime, header, number, relativeTime, messages
+       def _decorate_sms(self, parsedTexts):
+               return parsedTexts
+
+
+def set_sane_callback(backend):
+       """
+       Try to set a sane default callback number on these preferences
+       1) 1747 numbers ( Gizmo )
+       2) anything with gizmo in the name
+       3) anything with computer in the name
+       4) the first value
+       """
+       numbers = backend.get_callback_numbers()
+
+       priorityOrderedCriteria = [
+               ("1747", None),
+               (None, "gizmo"),
+               (None, "computer"),
+               (None, "sip"),
+               (None, None),
+       ]
+
+       for numberCriteria, descriptionCriteria in priorityOrderedCriteria:
+               for number, description in numbers.iteritems():
+                       if numberCriteria is not None and re.compile(numberCriteria).match(number) is None:
+                               continue
+                       if descriptionCriteria is not None and re.compile(descriptionCriteria).match(description) is None:
+                               continue
+                       backend.set_callback_number(number)
+                       return
+
+
+def sort_messages(allMessages):
+       sortableAllMessages = [
+               (message["time"], message)
+               for message in allMessages
+       ]
+       sortableAllMessages.sort(reverse=True)
+       return (
+               message
+               for (exactTime, message) in sortableAllMessages
+       )
+
+
+def decorate_message(messageData):
+       exactTime = messageData["time"]
+       if messageData["name"]:
+               header = messageData["name"]
+       elif messageData["prettyNumber"]:
+               header = messageData["prettyNumber"]
+       else:
+               header = "Unknown"
+       number = messageData["number"]
+       relativeTime = messageData["relTime"]
+
+       messageParts = list(messageData["messageParts"])
+       if len(messageParts) == 0:
+               messages = ("No Transcription", )
+       elif len(messageParts) == 1:
+               messages = (messageParts[0][1], )
+       else:
+               messages = [
+                       "<b>%s</b>: %s" % (messagePart[0], messagePart[-1])
+                       for messagePart in messageParts
+               ]
+
+       decoratedResults = header, number, relativeTime, messages
+       return decoratedResults
 
 
 def test_backend(username, password):
 
 
 def test_backend(username, password):
@@ -640,7 +643,15 @@ def test_backend(username, password):
        # for contact in backend.get_contacts():
        #       print contact
        #       pprint.pprint(list(backend.get_contact_details(contact[0])))
        # for contact in backend.get_contacts():
        #       print contact
        #       pprint.pprint(list(backend.get_contact_details(contact[0])))
-       for message in backend.get_messages():
-         pprint.pprint(message)
+       #for message in backend.get_messages():
+       #  pprint.pprint(message)
+       for message in sort_messages(backend.get_messages()):
+         pprint.pprint(decorate_message(message))
 
        return backend
 
        return backend
+
+
+if __name__ == "__main__":
+       import sys
+       logging.basicConfig(level=logging.DEBUG)
+       test_backend(sys.argv[1], sys.argv[2])
index e2c7ae3..702e35a 100644 (file)
@@ -64,34 +64,26 @@ class ConnectionHandle(TheOneRingHandle):
                self.profile = connection.username
 
 
                self.profile = connection.username
 
 
-def field_join(fields):
-       """
-       >>> field_join("1", "First Name")
-       '1#First Name'
-       """
-       return "#".join(fields)
-
-
-def field_split(fields):
-       """
-       >>> field_split('1#First Name')
-       ['1', 'First Name']
-       """
-       return fields.split("#")
-
-
 class ContactHandle(TheOneRingHandle):
 
        def __init__(self, connection, id, contactId, contactAccount):
                handleType = telepathy.HANDLE_TYPE_CONTACT
 class ContactHandle(TheOneRingHandle):
 
        def __init__(self, connection, id, contactId, contactAccount):
                handleType = telepathy.HANDLE_TYPE_CONTACT
-               handleName = field_join(contactId, contactAccount)
+               handleName = contactId
                TheOneRingHandle.__init__(self, connection, id, handleType, handleName)
 
                TheOneRingHandle.__init__(self, connection, id, handleType, handleName)
 
-               self.account = contactAccount
+               self._account = contactAccount
                self._id = contactId
 
        @property
                self._id = contactId
 
        @property
-       def contact(self):
+       def contactID(self):
+               return self._id
+
+       @property
+       def contactName(self):
+               return self._account
+
+       @property
+       def contactDetails(self):
                return self._conn.gvoice_client.get_contact_details(self._id)
 
 
                return self._conn.gvoice_client.get_contact_details(self._id)
 
 
index 31b8dbd..5a9bbaf 100644 (file)
@@ -5,4 +5,5 @@ ObjectPath = /org/freedesktop/Telepathy/ConnectionManager/theonering
 
 [Protocol GoogleVoice]
 param-account = s required
 
 [Protocol GoogleVoice]
 param-account = s required
-param-password = s required
+param-password = s required secret
+param-forward = s required