changeset 1450:7797dda847ae

plugins xep-0277, groupblog: added subscriteToMany to replace massiveSubscribeGroupBlogs + added SatRosterProtocol.getJidsSet
author Goffi <goffi@goffi.org>
date Sat, 15 Aug 2015 22:20:43 +0200
parents 389357fd79ce
children 9b88b19b1ca8
files src/core/constants.py src/core/xmpp.py src/plugins/plugin_misc_groupblog.py src/plugins/plugin_xep_0277.py
diffstat 4 files changed, 114 insertions(+), 45 deletions(-) [+]
line wrap: on
line diff
--- a/src/core/constants.py	Sat Aug 15 22:13:27 2015 +0200
+++ b/src/core/constants.py	Sat Aug 15 22:20:43 2015 +0200
@@ -81,6 +81,11 @@
     ENTITY_MAIN_RESOURCE = '@MAIN_RESOURCE@'
     ENTITY_CAP_HASH = 'CAP_HASH'
 
+    ## Roster jids selection ##
+    ALL = 'ALL'
+    GROUP = 'GROUP'
+    JID = 'JID'
+
 
     ## Messages ##
     MESS_TYPE_INFO = 'info'
--- a/src/core/xmpp.py	Sat Aug 15 22:13:27 2015 +0200
+++ b/src/core/xmpp.py	Sat Aug 15 22:20:43 2015 +0200
@@ -307,6 +307,28 @@
         except KeyError:
             raise exceptions.UnknownGroupError(group)
 
+    def getJidsSet(self, type_, groups=None):
+        """Helper method to get a set of jids
+
+        @param type_(unicode): one of:
+            C.ALL: get all jids from roster
+            C.GROUP: get jids from groups (listed in "groups")
+        @groups(list[unicode]): list of groups used if type_==C.GROUP
+        @return (set(jid.JID)): set of selected jids
+        """
+        if type_ == C.ALL and groups is not None:
+            raise ValueError('groups must not be set for {} type'.format(C.ALL))
+
+        if type_ == C.ALL:
+            return set(self.getJids())
+        elif type_ == C.GROUP:
+            jids = set()
+            for group in groups:
+                jids.update(self.getJidsFromGroup(group))
+            return jids
+        else:
+            raise ValueError(u'Unexpected type_ {}'.format(type_))
+
 
 class SatPresenceProtocol(xmppim.PresenceClientProtocol):
 
--- a/src/plugins/plugin_misc_groupblog.py	Sat Aug 15 22:13:27 2015 +0200
+++ b/src/plugins/plugin_misc_groupblog.py	Sat Aug 15 22:20:43 2015 +0200
@@ -137,9 +137,6 @@
                               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)
 
@@ -658,25 +655,25 @@
             publishers_jids = publishers
         return self.getMassiveGroupBlogs(publishers_type, publishers_jids, rsm_data, profile_key)
 
-    def _getPublishersJIDs(self, publishers_type, publishers, client):
-        #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")
+    # def _getPublishersJIDs(self, publishers_type, publishers, client):
+    #     #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")
 
-        if publishers_type == "ALL":
-            contacts = client.roster.getItems()
-            jids = [contact.jid.userhostJID() for contact in contacts]
-        elif publishers_type == "GROUP":
-            jids = []
-            for _group in publishers:
-                jids.extend(client.roster.getJidsFromGroup(_group))
-        elif publishers_type == 'JID':
-            jids = publishers
-        else:
-            raise UnknownType
-        return jids
+    #     if publishers_type == "ALL":
+    #         contacts = client.roster.getItems()
+    #         jids = [contact.jid.userhostJID() for contact in contacts]
+    #     elif publishers_type == "GROUP":
+    #         jids = []
+    #         for _group in publishers:
+    #             jids.extend(client.roster.getJidsFromGroup(_group))
+    #     elif publishers_type == 'JID':
+    #         jids = publishers
+    #     else:
+    #         raise UnknownType
+    #     return jids
 
     def getMassiveGroupBlogs(self, publishers_type, publishers, rsm_data=None, profile_key=C.PROF_KEY_NONE):
         """Get the last published microblogs for a list of groups or jids
@@ -709,28 +706,6 @@
         #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=C.PROF_KEY_NONE):
-        if publishers_type == 'JID':
-            publishers_jids = [jid.JID(publisher) for publisher in publishers]
-        else:
-            publishers_jids = publishers
-        return self.massiveSubscribeGroupBlogs(publishers_type, publishers_jids, profile_key)
-
-    @defer.inlineCallbacks
-    def massiveSubscribeGroupBlogs(self, publishers_type, publishers, profile_key=C.PROF_KEY_NONE):
-        """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
-        """
-        profile, client = yield self._initialise(profile_key)
-        #TODO: we need to use the server corresponding the the host of the jid
-
-        jids = self._getPublishersJIDs(publishers_type, publishers, client)
-        node_ids = [self.getNodeName(publisher) for publisher in jids]
-        d_list = yield self.host.plugins["XEP-0060"].subscribeToMany(client.item_access_pubsub, node_ids, profile_key=profile_key)
-        yield defer.DeferredList(d_list, consumeErrors=False)
-        defer.returnValue(None)
 
     ## delete ##
 
--- a/src/plugins/plugin_xep_0277.py	Sat Aug 15 22:13:27 2015 +0200
+++ b/src/plugins/plugin_xep_0277.py	Sat Aug 15 22:20:43 2015 +0200
@@ -73,8 +73,9 @@
                                    'return': 'list of microblog data (dict)'})
         host.bridge.addMethod("setMicroblogAccess", ".plugin", in_sign='ss', out_sign='',
                               method=self.setMicroblogAccess,
-                              async=True,
-                              doc={})
+                              async=True)
+        host.bridge.addMethod("mBSubscribeToMany", ".plugin", in_sign='sass', out_sign='s',
+                              method=self._mBSubscribeToMany)
 
     ## plugin management methods ##
 
@@ -401,3 +402,69 @@
             return self.host.plugins["XEP-0060"].setOptions(_jid.userhostJID(), NS_MICROBLOG, _jid.userhostJID(), _options, profile_key=profile_key)
 
         create_node().addCallback(cb).addErrback(err_cb)
+
+    ## methods to manage several stanzas/jids at once ##
+
+    # common
+
+    def _getClientAndNodeData(self, publishers_type, publishers, profile_key):
+        """Helper method to construct node_data from publishers_type/publishers
+
+        @param publishers_type: type of the list of publishers, one of:
+            C.ALL: get all jids from roster, publishers is not used
+            C.GROUP: get jids from groups
+            C.JID: use publishers directly as list of jids
+        @param publishers: list of publishers, according to "publishers_type" (None, list of groups or list of jids)
+        @param profile_key: %(doc_profile_key)s
+        """
+        client = self.host.getClient(profile_key)
+        if publishers_type == C.JID:
+            jids_set = set(publishers)
+        else:
+            jids_set = client.roster.getJidsSet(publishers_type, publishers)
+
+        node_data = []
+        for jid_ in jids_set:
+            node_data.append((jid_, NS_MICROBLOG))
+        return client, node_data
+
+    def _checkPublishers(self, publishers_type, publishers):
+        """Helper method to deserialise publishers coming from bridge
+
+        publishers_type(unicode): type of the list of publishers, one of:
+        publishers: list of publishers according to type
+        @return: deserialised (publishers_type, publishers) tuple
+        """
+        if publishers_type == C.ALL:
+            if publishers:
+                raise failure.Failure(ValueError("Can't use publishers with {} type".format(publishers_type)))
+            else:
+                publishers = None
+        elif publishers_type == C.JID:
+            publishers[:] = [jid.JID(publisher) for publisher in publishers]
+        return publishers_type, publishers
+
+    # subscribe #
+
+    def _mBSubscribeToMany(self, publishers_type, publishers, profile_key):
+        """
+
+        @return (str): session id: Use pubsub.getSubscribeRTResult to get the results
+        """
+        publishers_type, publishers = self._checkPublishers(publishers_type, publishers)
+        return self.mBSubscribeToMany(publishers_type, publishers, profile_key)
+
+    def mBSubscribeToMany(self, publishers_type, publishers, profile_key):
+        """Subscribe microblogs for a list of groups or jids
+
+        @param publishers_type: type of the list of publishers, one of:
+            C.ALL: get all jids from roster, publishers is not used
+            C.GROUP: get jids from groups
+            C.JID: use publishers directly as list of jids
+        @param publishers: list of publishers, according to "publishers_type" (None, list of groups or list of jids)
+        @param profile: %(doc_profile)s
+        @return (str): session id
+        """
+        client, node_data = self._getClientAndNodeData(publishers_type, publishers, profile_key)
+        return self.host.plugins["XEP-0060"].subscribeToMany(node_data, client.jid.userhostJID(), profile_key=profile_key)
+