plugins xep-0277, groupblog: added subscriteToMany to replace massiveSubscribeGroupBlogs + added SatRosterProtocol.getJidsSet

This commit is contained in:
Goffi 2015-08-15 22:20:43 +02:00
commit 2b20bff614
4 changed files with 115 additions and 46 deletions

View file

@ -81,6 +81,11 @@ class Const(object):
ENTITY_MAIN_RESOURCE = '@MAIN_RESOURCE@'
ENTITY_CAP_HASH = 'CAP_HASH'
## Roster jids selection ##
ALL = 'ALL'
GROUP = 'GROUP'
JID = 'JID'
## Messages ##
MESS_TYPE_INFO = 'info'

View file

@ -307,6 +307,28 @@ class SatRosterProtocol(xmppim.RosterClientProtocol):
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):

View file

@ -137,9 +137,6 @@ class GroupBlog(object):
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 @@ class GroupBlog(object):
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 @@ class GroupBlog(object):
#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 ##

View file

@ -73,8 +73,9 @@ class XEP_0277(object):
'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 @@ class XEP_0277(object):
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)