changeset 178:07114105885a

Send last published item on subscription if node is so configured.
author Ralph Meijer <ralphm@ik.nu>
date Thu, 10 Apr 2008 14:02:53 +0000
parents faf1c9bc2612
children 42e23a62b57f
files idavoll/backend.py idavoll/test/test_backend.py
diffstat 2 files changed, 66 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- a/idavoll/backend.py	Thu Apr 10 11:18:29 2008 +0000
+++ b/idavoll/backend.py	Thu Apr 10 14:02:53 2008 +0000
@@ -159,6 +159,7 @@
             raise error.Forbidden()
 
         d = node.add_subscription(subscriber, 'subscribed')
+        d.addCallback(lambda _: self._send_last_published(node, subscriber))
         d.addCallback(lambda _: 'subscribed')
         d.addErrback(self._get_subscription, node, subscriber)
         d.addCallback(self._return_subscription, node.id)
@@ -171,6 +172,23 @@
     def _return_subscription(self, result, node_id):
         return node_id, result
 
+    def _send_last_published(self, node, subscriber):
+        def notify_item(items):
+            if not items:
+                return
+
+            self.dispatch({'items': items,
+                           'node_id': node.id,
+                           'subscriber': subscriber},
+                          '//event/pubsub/notify')
+
+        config = node.get_configuration()
+        if config["pubsub#send_last_published_item"] != 'on_sub':
+            return
+
+        d = self.get_items(node.id, subscriber.userhostJID(), 1)
+        d.addCallback(notify_item)
+
     def unsubscribe(self, node_id, subscriber, requestor):
         if subscriber.userhostJID() != requestor:
             return defer.fail(error.Forbidden())
@@ -422,7 +440,10 @@
     def _notify(self, data):
         items = data['items']
         nodeIdentifier = data['node_id']
-        d = self.backend.get_notification_list(nodeIdentifier, items)
+        if 'subscriber' not in data:
+            d = self.backend.get_notification_list(nodeIdentifier, items)
+        else:
+            d = defer.succeed([(data['subscriber'], items)])
         d.addCallback(lambda notifications: self.notifyPublish(self.serviceJID,
                                                                nodeIdentifier,
                                                                notifications))
--- a/idavoll/test/test_backend.py	Thu Apr 10 11:18:29 2008 +0000
+++ b/idavoll/test/test_backend.py	Thu Apr 10 14:02:53 2008 +0000
@@ -15,6 +15,7 @@
 from idavoll import backend, error
 
 OWNER = jid.JID('owner@example.com')
+NS_PUBSUB = 'http://jabber.org/protocol/pubsub'
 
 class BackendTest(unittest.TestCase):
     def test_delete_node(self):
@@ -106,6 +107,48 @@
         d = self.backend.publish('node', items, OWNER)
         return d
 
+    def test_notifyOnSubscription(self):
+        """
+        Test notification of last published item on subscription.
+        """
+        ITEM = "<item xmlns='%s' id='1'/>" % NS_PUBSUB
+
+        class testNode:
+            id = 'node'
+            def get_affiliation(self, entity):
+                if entity is OWNER:
+                    return defer.succeed('owner')
+            def get_configuration(self):
+                return {'pubsub#deliver_payloads': True,
+                        'pubsub#persist_items': False,
+                        'pubsub#send_last_published_item': 'on_sub'}
+            def get_items(self, max_items):
+                return [ITEM]
+            def add_subscription(self, subscriber, state):
+                return defer.succeed(None)
+
+        class testStorage:
+            def get_node(self, node_id):
+                return defer.succeed(testNode())
+
+        def cb(data):
+            print [ITEM] == data['items']
+            self.assertEquals('node', data['node_id'])
+            self.assertEquals([ITEM], data['items'])
+            self.assertEquals(OWNER, data['subscriber'])
+
+        self.storage = testStorage()
+        self.backend = backend.BackendService(self.storage)
+        self.storage.backend = self.backend
+
+        d1 = defer.Deferred()
+        d1.addCallback(cb)
+        self.backend.register_notifier(d1.callback)
+        d2 = self.backend.subscribe('node', OWNER, OWNER)
+        return defer.gatherResults([d1, d2])
+
+    test_notifyOnSubscription.timeout = 2
+
 
 class BaseTestBackend(object):
     """
@@ -130,6 +173,7 @@
     def register_pre_delete(self, pre_delete_fn):
         return
 
+
 class PubSubServiceFromBackendTest(unittest.TestCase):
 
     def test_unsubscribeNotSubscribed(self):