[telepathy-butterfly/master] Implemented Mail Notification Spec

Nicolas Dufresne nicolas.dufresne at collabora.co.uk
Mon Jan 11 12:27:04 PST 2010


Signed-off-by: Nicolas Dufresne <nicolas.dufresne at collabora.co.uk>
---
 .../Connection_Interface_Mail_Notification.py      |  128 ++++++++++++++++++
 butterfly/connection.py                            |    3 +
 butterfly/mail_notification.py                     |  142 ++++++++++++++++++++
 3 files changed, 273 insertions(+), 0 deletions(-)
 create mode 100644 butterfly/Connection_Interface_Mail_Notification.py
 create mode 100644 butterfly/mail_notification.py

diff --git a/butterfly/Connection_Interface_Mail_Notification.py b/butterfly/Connection_Interface_Mail_Notification.py
new file mode 100644
index 0000000..695c4fd
--- /dev/null
+++ b/butterfly/Connection_Interface_Mail_Notification.py
@@ -0,0 +1,128 @@
+# -*- coding: utf-8 -*-
+# Generated from the Telepathy spec
+""" Copyright (C) 2007 Collabora Limited 
+
+    This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Library General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+  
+"""
+
+import dbus.service
+
+
+class ConnectionInterfaceMailNotification(dbus.service.Interface):
+    """\
+      An interface to support receiving notifications about a e-mail
+        account associated with this connection. It is intended that the
+        connection manager has the means to provide necessary
+        information (URL, method, POST data) so that the client is 
+        able to open the user's inbox and possibly individual messages without 
+        having to re-authenticate. To use this interface, a client must first
+        subscribe using the Subscribe method.
+
+      When unread e-mails arrive into the into or unread e-mails are marked 
+        read or deleted the
+        UnreadMailsChanged signal
+        will be emitted with the new value of
+        UnreadMailCount, an array
+        of new or modified mails and the list of removed e-mail unique IDs. 
+        To open the web base mail client for the inbox folder or a specific
+        mail client must call RequestInboxURL
+        or RequestMailURL. Those methods
+        will do proper actions to retreive the information and provide
+        authentication free URL to the requested Web client interface.
+      
+      
+        Some protocol may not be able to provide a list of unread e-mails
+        but may provide some information about the messages received. On
+        such protocols, the MailsReceived
+        signal will also be emitted, with information about the e-mails.
+        The protocol does not keep track of any of this information.
+      
+    """
+
+    def __init__(self):
+        self._interfaces.add('org.freedesktop.Telepathy.Connection.Interface.MailNotification.DRAFT')
+
+    @dbus.service.method('org.freedesktop.Telepathy.Connection.Interface.MailNotification.DRAFT', in_signature='', out_signature='')
+    def Subscribe(self):
+        """
+        This method subscribes a client to the notification interface. This
+        should be called if a client wants to get notified of incoming
+        e-mails. Before anyone subscribes to the interface, the connection
+        manager should try to minimized memory usage and network traffic as
+        much as possible. The Control Manager must detect client disconnection
+        (e.g. in case of crash) and free resources that are no longer required.
+      
+        """
+        raise NotImplementedError
+  
+    @dbus.service.method('org.freedesktop.Telepathy.Connection.Interface.MailNotification.DRAFT', in_signature='', out_signature='')
+    def Unsubscribe(self):
+        """
+        This method unsubscribes a client from the notification interface. This
+        should called if a client no longer wants tot get notified of incoming
+        e-mails. When all the client has been Unsubscribed, the connection manager
+        should free all non-required information and reduce network traffic. It must
+        be possible to call Subscribe later.
+      
+        """
+        raise NotImplementedError
+  
+    @dbus.service.method('org.freedesktop.Telepathy.Connection.Interface.MailNotification.DRAFT', in_signature='', out_signature='(sua(ss))')
+    def RequestInboxURL(self):
+        """
+        This method create and return a URL and optionnal POST data that allow
+        openning the Inbox folder of your Web mail account. This URL may 
+        contains token with short life time. Thus, a client should not reuse it
+        and request a new URL whenever it is needed.
+        
+          We are not using properties here because the tokens may not be shared
+          between clients and that network may be required to obtain the
+          information that leads to authentication free Web access.
+        
+      
+        """
+        raise NotImplementedError
+  
+    @dbus.service.method('org.freedesktop.Telepathy.Connection.Interface.MailNotification.DRAFT', in_signature='ss', out_signature='(sua(ss))')
+    def RequestMailURL(self, id, url_data):
+        """
+        This method create and return a URL and optionnal POST data that allow
+        openning specific mail of your Web mail account. Refer to 
+        RequestInboxURL.
+      
+        """
+        raise NotImplementedError
+  
+    @dbus.service.signal('org.freedesktop.Telepathy.Connection.Interface.MailNotification.DRAFT', signature='aa{sv}')
+    def MailsReceived(self, mails):
+        """
+        Emitted when new e-mails messages arrive to the inbox associated with
+        this connection. This signal is used for protocol that are not able
+        to maintained UnreadMails list but
+        receives real-time notification about newly arrived e-mails.
+      
+        """
+        pass
+  
+    @dbus.service.signal('org.freedesktop.Telepathy.Connection.Interface.MailNotification.DRAFT', signature='uaa{sv}as')
+    def UnreadMailsChanged(self, count, mails_added, mails_removed):
+        """
+        Emitted when UnreadMails or 
+        UnreadMailCount have changed.
+      
+        """
+        pass
+  
\ No newline at end of file
diff --git a/butterfly/connection.py b/butterfly/connection.py
index 76eee3b..541d738 100644
--- a/butterfly/connection.py
+++ b/butterfly/connection.py
@@ -32,6 +32,7 @@ from butterfly.handle import ButterflyHandleFactory
 from butterfly.capabilities import ButterflyCapabilities
 from butterfly.contacts import ButterflyContacts
 from butterfly.channel_manager import ButterflyChannelManager
+from butterfly.mail_notification import ButterflyMailNotification
 
 __all__ = ['ButterflyConnection']
 
@@ -45,6 +46,7 @@ class ButterflyConnection(telepathy.server.Connection,
         ButterflyAvatars,
         ButterflyCapabilities,
         ButterflyContacts,
+        ButterflyMailNotification,
         papyon.event.ClientEventInterface,
         papyon.event.InviteEventInterface,
         papyon.event.OfflineMessagesEventInterface):
@@ -105,6 +107,7 @@ class ButterflyConnection(telepathy.server.Connection,
             ButterflyAvatars.__init__(self)
             ButterflyCapabilities.__init__(self)
             ButterflyContacts.__init__(self)
+            ButterflyMailNotification.__init__(self)
             papyon.event.ClientEventInterface.__init__(self, self._msn_client)
             papyon.event.InviteEventInterface.__init__(self, self._msn_client)
             papyon.event.OfflineMessagesEventInterface.__init__(self, self._msn_client)
diff --git a/butterfly/mail_notification.py b/butterfly/mail_notification.py
new file mode 100644
index 0000000..2c3f69b
--- /dev/null
+++ b/butterfly/mail_notification.py
@@ -0,0 +1,142 @@
+# telepathy-butterfly - an MSN connection manager for Telepathy
+#
+# Copyright (C) 2009 Collabora Ltd.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+from base64 import b64encode, b64decode
+from butterfly.Connection_Interface_Mail_Notification import *
+import dbus.service
+import logging
+import papyon
+import telepathy
+import telepathy.constants
+
+
+__all__ = ['ButterflyMailNotification']
+
+logger = logging.getLogger('Butterfly.MailNotification')
+
+
+# Interface name
+CONN_IFACE_MAIL_NOTIFICATION = \
+    'org.freedesktop.Telepathy.Connection.Interface.MailNotification.DRAFT'
+
+# Mail_Notification_Flags (bitfield/set of flags, 0 for none)
+MAIL_NOTIFICATION_HAS_PROP_UNREADMAILCOUNT = 1
+MAIL_NOTIFICATION_HAS_PROP_UNREADMAILS = 2
+MAIL_NOTIFICATION_HAS_SIGNAL_MAILSRECEIVED = 4
+
+# HTTP_Method
+HTTP_METHOD_GET = 0
+HTTP_METHOD_POST = 1
+LAST_HTTP_METHOD = 1
+
+# Mail_Type
+MAIL_TYPE_SINGLE = 0
+MAIL_TYPE_THREAD = 1
+LAST_MAIL_TYPE = 1
+
+
+class ButterflyMailNotification(
+        telepathy.server.DBusProperties,
+        ConnectionInterfaceMailNotification,
+        papyon.event.MailboxEventInterface):
+
+    def __init__(self):
+        logger.debug("Initialized")
+        telepathy.server.DBusProperties.__init__(self)
+        ConnectionInterfaceMailNotification.__init__(self)
+        papyon.event.MailboxEventInterface.__init__(self, self.msn_client)
+
+        self._implement_property_get(CONN_IFACE_MAIL_NOTIFICATION,
+            {'Capabilities': lambda: self._capabilities,
+             'UnreadMailCount': lambda: self._unread_mail_count,})
+
+
+    @property
+    def _capabilities(self):
+        return MAIL_NOTIFICATION_HAS_PROP_UNREADMAILCOUNT \
+                | MAIL_NOTIFICATION_HAS_SIGNAL_MAILSRECEIVED
+
+
+    @property
+    def _unread_mail_count(self):
+        return self.msn_client.mailbox.unread_mail_count
+
+
+    def Subscribe(self):
+        pass
+
+
+    def Unsubscribe(self):
+        pass
+
+
+    @dbus.service.method(CONN_IFACE_MAIL_NOTIFICATION,
+            in_signature='', out_signature='(sua(ss))',
+            async_callbacks=('_success', '_error'))
+    def RequestInboxURL(self, _success, _error):
+        def got_url(post_url, form_dict, _success):
+            post_data = []
+            for key in form_dict:
+                post_data += ((key, form_dict[key]),)
+            _success((post_url, HTTP_METHOD_POST, post_data))
+
+        self.msn_client.mailbox.request_inbox_url(
+                lambda post_url, form_dict: got_url(post_url, form_dict,
+                    _success))
+
+    def RequestMailURL(self, id, url_data):
+        # Unserialize POST Data from base64 making sure it's good data.
+        # Data is of the form <key>:<value>[&<key>:<value>]* where key
+        # and value are base64 encoded.
+        post_data = []
+        for data in url_data.split('&'):
+            tmp_data = data.split(':')
+            if len(tmp_data) is not 2:
+                raise telepathy.errors.InvalidArgument
+            try:
+                final_data = (b64decode(tmp_data[0]), b64decode(tmp_data[1]))
+            except Exception, e:
+                raise telepathy.errors.InvalidArgument
+            post_data += (final_data,)
+        return (id, HTTP_METHOD_POST, post_data)
+
+
+    def on_mailbox_new_mail_received(self, mail_message):
+        logger.debug("New Mail " + str(mail_message))
+
+        # Serialize with POST data in base64 as decribed in previous function.
+        url_data = ''
+        for key in mail_message.form_data:
+            if url_data != '':
+                url_data += '&'
+            url_data += b64encode(key) + ':' + \
+                b64encode(mail_message.form_data[key])
+
+        mail = {'id': mail_message.post_url,
+                'type': MAIL_TYPE_SINGLE,
+                'url_data': url_data,
+                'senders': [(mail_message.name, mail_message.address)],
+                'subject':  mail_message._subject}
+
+        self.MailsReceived([mail])
+
+
+    def on_mailbox_unread_mail_count_changed(self, unread_mail_count,
+            initial=False):
+        logger.debug("Unread Mail Count Changed " + str(unread_mail_count))
+        self.UnreadMailsChanged(unread_mail_count, [], [])
-- 
1.5.6.5




More information about the telepathy-commits mailing list