changeset 477:031b0e0aaab8

plugin groupblog: subscriptions/notifications
author Goffi <goffi@goffi.org>
date Mon, 25 Jun 2012 00:08:16 +0200
parents b9fd32b46306
children f856575a62a6
files frontends/src/bridge/DBus.py src/bridge/DBus.py src/bridge/bridge_constructor/dbus_core_template.py src/bridge/bridge_constructor/dbus_frontend_template.py src/plugins/plugin_misc_groupblog.py src/plugins/plugin_xep_0060.py
diffstat 6 files changed, 101 insertions(+), 6 deletions(-) [+]
line wrap: on
line diff
--- a/frontends/src/bridge/DBus.py	Thu May 31 00:26:39 2012 +0200
+++ b/frontends/src/bridge/DBus.py	Mon Jun 25 00:08:16 2012 +0200
@@ -252,6 +252,12 @@
     def getMassiveLastGroupBlogs(self, publishers_type, publishers, max_items=10, profile_key='@DEFAULT@', callback=None, errback=None):
         return self.db_plugin_iface.getMassiveLastGroupBlogs(publishers_type, publishers, max_items, profile_key, reply_handler=callback, error_handler=errback)
     
+    def subscribeGroupBlog(self, jid, profile_key='@DEFAULT@', callback=None, errback=None):
+        return self.db_plugin_iface.subscribeGroupBlog(jid, profile_key, reply_handler=callback, error_handler=errback)
+    
+    def massiveSubscribeGroupBlogs(self, publishers_type, publishers, profile_key='@DEFAULT@', callback=None, errback=None):
+        return self.db_plugin_iface.massiveSubscribeGroupBlogs(publishers_type, publishers, profile_key, reply_handler=callback, error_handler=errback)
+    
     def sendPersonalEvent(self, event_type, data, profile_key):
         return self.db_plugin_iface.sendPersonalEvent(event_type, data, profile_key)
     
--- a/src/bridge/DBus.py	Thu May 31 00:26:39 2012 +0200
+++ b/src/bridge/DBus.py	Mon Jun 25 00:08:16 2012 +0200
@@ -34,6 +34,9 @@
 const_CORE_SUFFIX = ".core"
 const_PLUGIN_SUFFIX = ".plugin"
 
+class ParseError(Exception):
+    pass
+
 class MethodNotRegistered(dbus.DBusException):
     _dbus_error_name = const_ERROR_PREFIX + ".MethodNotRegistered"
 
@@ -50,7 +53,7 @@
     def __init__(self, twisted_error):
         super(GenericException,self).__init__()
         mess = twisted_error.getErrorMessage()
-        self._dbus_error_name = const_ERROR_PREFIX+"."+ (mess or str(err.__class__))
+        self._dbus_error_name = const_ERROR_PREFIX+"."+ (mess or str(twisted_error.__class__))
 
 class DbusObject(dbus.service.Object):
 
--- a/src/bridge/bridge_constructor/dbus_core_template.py	Thu May 31 00:26:39 2012 +0200
+++ b/src/bridge/bridge_constructor/dbus_core_template.py	Mon Jun 25 00:08:16 2012 +0200
@@ -34,6 +34,9 @@
 const_CORE_SUFFIX = ".core"
 const_PLUGIN_SUFFIX = ".plugin"
 
+class ParseError(Exception):
+    pass
+
 class MethodNotRegistered(dbus.DBusException):
     _dbus_error_name = const_ERROR_PREFIX + ".MethodNotRegistered"
 
@@ -50,7 +53,7 @@
     def __init__(self, twisted_error):
         super(GenericException,self).__init__()
         mess = twisted_error.getErrorMessage()
-        self._dbus_error_name = const_ERROR_PREFIX+"."+ (mess or str(err.__class__))
+        self._dbus_error_name = const_ERROR_PREFIX+"."+ (mess or str(twisted_error.__class__))
 
 class DbusObject(dbus.service.Object):
 
--- a/src/bridge/bridge_constructor/dbus_frontend_template.py	Thu May 31 00:26:39 2012 +0200
+++ b/src/bridge/bridge_constructor/dbus_frontend_template.py	Mon Jun 25 00:08:16 2012 +0200
@@ -145,6 +145,12 @@
     def getMassiveLastGroupBlogs(self, publishers_type, publishers, max_items=10, profile_key='@DEFAULT@', callback=None, errback=None):
         return self.db_plugin_iface.getMassiveLastGroupBlogs(publishers_type, publishers, max_items, profile_key, reply_handler=callback, error_handler=errback)
     
+    def subscribeGroupBlog(self, jid, profile_key='@DEFAULT@', callback=None, errback=None):
+        return self.db_plugin_iface.subscribeGroupBlog(jid, profile_key, reply_handler=callback, error_handler=errback)
+    
+    def massiveSubscribeGroupBlogs(self, publishers_type, publishers, profile_key='@DEFAULT@', callback=None, errback=None):
+        return self.db_plugin_iface.massiveSubscribeGroupBlogs(publishers_type, publishers, profile_key, reply_handler=callback, error_handler=errback)
+    
     def sendPersonalEvent(self, event_type, data, profile_key):
         return self.db_plugin_iface.sendPersonalEvent(event_type, data, profile_key)
     
--- a/src/plugins/plugin_misc_groupblog.py	Thu May 31 00:26:39 2012 +0200
+++ b/src/plugins/plugin_misc_groupblog.py	Mon Jun 25 00:08:16 2012 +0200
@@ -34,6 +34,7 @@
 
 NS_PUBSUB = 'http://jabber.org/protocol/pubsub'
 NS_GROUPBLOG = 'http://goffi.org/protocol/groupblog'
+NS_NODE_PREFIX = 'urn:xmpp:groupblog:'
 #NS_PUBSUB_EXP = 'http://goffi.org/protocol/pubsub' #for non official features
 NS_PUBSUB_EXP = NS_PUBSUB #XXX: we can't use custom namespace as Wokkel's PubSubService use official NS
 NS_PUBSUB_ITEM_ACCESS = NS_PUBSUB_EXP + "#item-access"
@@ -88,6 +89,17 @@
                               in_sign='sasis', out_sign='a{saa{ss}}',
                               method=self.getMassiveLastGroupBlogs,
                               async = True)
+        
+        host.bridge.addMethod("subscribeGroupBlog", ".plugin", in_sign='ss', out_sign='',
+                               method=self.subscribeGroupBlog,
+                               async = True)
+       
+        host.bridge.addMethod("massiveSubscribeGroupBlogs", ".plugin", in_sign='sass', out_sign='',
+                               method=self.massiveSubscribeGroupBlogs,
+                               async = True)
+        
+        host.trigger.add("PubSubItemsReceived", self.pubSubItemsReceivedTrigger)
+       
     
     def getHandler(self, profile):
         return GroupBlog_handler()
@@ -115,7 +127,8 @@
             client.item_access_pubsub = None
             for entity in self.host.memory.getServerServiceEntities("pubsub", "service", profile):
                 _disco = yield client.disco.requestInfo(entity)
-                if set([NS_PUBSUB_ITEM_ACCESS, NS_PUBSUB_AUTO_CREATE, NS_PUBSUB_CREATOR_JID_CHECK]).issubset(_disco.features):
+                #if set([NS_PUBSUB_ITEM_ACCESS, NS_PUBSUB_AUTO_CREATE, NS_PUBSUB_CREATOR_JID_CHECK]).issubset(_disco.features):
+                if set([NS_PUBSUB_AUTO_CREATE, NS_PUBSUB_CREATOR_JID_CHECK]).issubset(_disco.features):
                     info(_("item-access powered pubsub service found: [%s]") % entity.full())
                     client.item_access_pubsub = entity
 
@@ -125,6 +138,24 @@
 
         defer.returnValue((profile, client))
 
+    def pubSubItemsReceivedTrigger(self, event, profile):
+        """"Trigger which catch groupblogs events"""
+        if event.nodeIdentifier.startswith(NS_NODE_PREFIX):
+            for item in event.items:
+                microblog_data = self.host.plugins["XEP-0277"].item2mbdata(item)
+                self.host.bridge.personalEvent(event.sender.full(), "MICROBLOG", microblog_data, profile)
+            return False
+        return True
+
+
+
+    def getNodeName(self, publisher):
+        """Retrieve the name of publisher's node
+        @param publisher: publisher's jid
+        @return: node's name (string)"""
+        return NS_NODE_PREFIX + publisher.userhost()
+
+
 
     def _publishMblog(self, service, client, access_type, access_list, message):
         """Actually publish the message on the group blog
@@ -152,7 +183,7 @@
         else:
             error(_("Unknown access_type"))
             raise BadAccessTypeError
-        defer_blog = self.host.plugins["XEP-0060"].publish(service, client.jid.userhost(), items=[mblog_item], profile_key=client.profile)
+        defer_blog = self.host.plugins["XEP-0060"].publish(service, self.getNodeName(client.jid), items=[mblog_item], profile_key=client.profile)
         defer_blog.addErrback(self._mblogPublicationFailed)
 
     def _mblogPublicationFailed(self, failure):
@@ -199,7 +230,7 @@
         
         def initialised(result):
             profile, client = result
-            d = self.host.plugins["XEP-0060"].getItems(client.item_access_pubsub, jid.JID(pub_jid).userhost(),
+            d = self.host.plugins["XEP-0060"].getItems(client.item_access_pubsub, self.getNodeName(jid.JID(pub_jid)),
                                                        max_items=max_items, profile_key=profile_key)
             d.addCallback(lambda items: map(self.host.plugins["XEP-0277"].item2mbdata, items))
             d.addErrback(lambda ignore: {}) #TODO: more complete error management (log !)
@@ -235,7 +266,7 @@
                 jids = [contact.jid.userhost() for contact in contacts]
                 mblogs = []
                 for _jid in jids:
-                    d = self.host.plugins["XEP-0060"].getItems(client.item_access_pubsub, jid.JID(_jid).userhost(),
+                    d = self.host.plugins["XEP-0060"].getItems(client.item_access_pubsub, self.getNodeName(jid.JID(_jid)),
                                                                max_items=max_items, profile_key=profile_key)
                     d.addCallback(lambda items, source_jid: (source_jid, map(self.host.plugins["XEP-0277"].item2mbdata, items)), _jid)
                     mblogs.append(d)
@@ -254,6 +285,50 @@
         return self.initialise(profile_key).addCallback(initialised)
         #TODO: we need to use the server corresponding the the host of the jid
 
+    def subscribeGroupBlog(self, pub_jid, profile_key='@DEFAULT'):
+        def initialised(result):
+            profile, client = result
+            d = self.host.plugins["XEP-0060"].subscribe(client.item_access_pubsub, self.getNodeName(jid.JID(pub_jid)),
+                                                        profile_key=profile_key)
+            return d
+
+        #TODO: we need to use the server corresponding the the host of the jid
+        return self.initialise(profile_key).addCallback(initialised)
+
+
+    def massiveSubscribeGroupBlogs(self, publishers_type, publishers, profile_key='@DEFAULT@'):
+        """Subscribe microblogs for a list of groups or jids
+        @param publishers_type: type of the list of publishers (one of "GROUP" or "JID" or "ALL")
+        @param publishers: list of publishers, according to "publishers_type" (list of groups or list of jids)
+        @param profile_key: profile key
+        """
+        def initialised(result):
+            profile, client = result
+
+            if publishers_type == "ALL":
+                contacts = client.roster.getItems()
+                jids = [contact.jid.userhost() for contact in contacts]
+                mblogs = []
+                for _jid in jids:
+                    d = self.host.plugins["XEP-0060"].subscribe(client.item_access_pubsub, self.getNodeName(jid.JID(_jid)),
+                                                                profile_key=profile_key)
+                    mblogs.append(d)
+                dlist = defer.DeferredList(mblogs)
+                return dlist
+
+            return defer.fail("Unknown type")
+
+
+        #TODO: custom exception
+        if publishers_type not in ["GROUP", "JID", "ALL"]:
+            raise Exception("Bad call, unknown publishers_type")
+        if publishers_type=="ALL" and publishers:
+            raise Exception("Publishers list must be empty when getting microblogs for all contacts")
+        return self.initialise(profile_key).addCallback(initialised)
+        #TODO: we need to use the server corresponding the the host of the jid
+
+
+
 class GroupBlog_handler(XMPPHandler):
     implements(iwokkel.IDisco)
     
--- a/src/plugins/plugin_xep_0060.py	Thu May 31 00:26:39 2012 +0200
+++ b/src/plugins/plugin_xep_0060.py	Mon Jun 25 00:08:16 2012 +0200
@@ -131,6 +131,8 @@
         pubsub.PubSubClient.connectionInitialized(self)
     
     def itemsReceived(self, event):
+        if not self.host.trigger.point("PubSubItemsReceived", event, self.parent.profile):
+            return
         for node in self.parent_plugin.managedNodes:
             if event.nodeIdentifier == node[0]:
                 return node[1](event, self.parent.profile)