# HG changeset patch # User Goffi # Date 1439670043 -7200 # Node ID 7797dda847ae65c9a2d99f1fab9b9b9fa3599049 # Parent 389357fd79cee4b046162f722d12f7142d917622 plugins xep-0277, groupblog: added subscriteToMany to replace massiveSubscribeGroupBlogs + added SatRosterProtocol.getJidsSet diff -r 389357fd79ce -r 7797dda847ae src/core/constants.py --- 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' diff -r 389357fd79ce -r 7797dda847ae src/core/xmpp.py --- 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): diff -r 389357fd79ce -r 7797dda847ae src/plugins/plugin_misc_groupblog.py --- 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 ## diff -r 389357fd79ce -r 7797dda847ae src/plugins/plugin_xep_0277.py --- 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) +