plugin XEP-0060: fixes listing the nodes on the pubsub service
This commit is contained in:
parent
5781d78d2b
commit
0d80ce6cc2
1 changed files with 42 additions and 26 deletions
|
|
@ -60,7 +60,7 @@ class XEP_0060(object):
|
|||
self.host = host
|
||||
self.managedNodes = []
|
||||
self.clients = {}
|
||||
self.node_cache = Sessions(timeout=30, resettable_timeout=False)
|
||||
self.node_cache = Sessions(timeout=60, resettable_timeout=False)
|
||||
|
||||
def getHandler(self, profile):
|
||||
self.clients[profile] = SatPubSubClient(self.host, self)
|
||||
|
|
@ -93,48 +93,64 @@ class XEP_0060(object):
|
|||
raise Exception(err_mess)
|
||||
return profile, client
|
||||
|
||||
@defer.inlineCallbacks
|
||||
def _getDeferredNodeCache(self, session_id, init, profile):
|
||||
"""Manage a node cache with deferred initialisation and concurrent access.
|
||||
|
||||
@param session_id (string): node cache session ID
|
||||
@param init (Deferred): deferred list of strings to initialise the cache.
|
||||
@param profile (str): %(doc_profile)s
|
||||
@return: Deferred list[str]
|
||||
"""
|
||||
if session_id in self.node_cache:
|
||||
cache = self.node_cache.profileGet(session_id, profile)
|
||||
if cache['nodes'] is None:
|
||||
# init is still running
|
||||
d = defer.Deferred()
|
||||
cache['waiting'].append(d)
|
||||
return d
|
||||
return defer.succeed(cache['nodes'])
|
||||
|
||||
cache = {'init': init, 'waiting': [], 'nodes': None}
|
||||
self.node_cache.newSession(cache, session_id=session_id, profile=profile)
|
||||
|
||||
def cb(nodes):
|
||||
cache['nodes'] = nodes
|
||||
for d in cache['waiting']:
|
||||
d.callback(nodes)
|
||||
return nodes
|
||||
|
||||
return init.addCallback(cb)
|
||||
|
||||
def listNodes(self, service, nodeIdentifier='', profile=C.PROF_KEY_NONE):
|
||||
"""Retrieve the name of the nodes that are accesible on the target service.
|
||||
"""Retrieve the name of the nodes that are accessible on the target service.
|
||||
|
||||
@param service (JID): target service
|
||||
@param nodeIdentifier (str): the parent node name (leave empty to retrieve first-level nodes)
|
||||
@param profile (str): %(doc_profile)s
|
||||
@return: list[str]
|
||||
@return: Deferred list[str]
|
||||
"""
|
||||
session_id = profile + "@found@" + service.userhost()
|
||||
# FIXME: this can be called from self.subscribeToMany before the cache has been built by self.getItemsFromMany
|
||||
if session_id in self.node_cache:
|
||||
cache = self.node_cache.profileGet(session_id, profile)
|
||||
else:
|
||||
# FIXME: we arrive here while the cache is already being built...
|
||||
result = yield self.getDiscoItems(service, nodeIdentifier, profile_key=profile)
|
||||
node_names = [item.getAttribute('node') for item in result.toElement().children if item.hasAttribute('node')]
|
||||
dummy, cache = self.node_cache.newSession(node_names, session_id=session_id, profile=profile)
|
||||
defer.returnValue(cache)
|
||||
session_id = profile + '@found@' + service.userhost()
|
||||
d = self.getDiscoItems(service, nodeIdentifier, profile_key=profile)
|
||||
d.addCallback(lambda result: [item.getAttribute('node') for item in result.toElement().children if item.hasAttribute('node')])
|
||||
return self._getDeferredNodeCache(session_id, d, profile)
|
||||
|
||||
@defer.inlineCallbacks
|
||||
def listSubscribedNodes(self, service, nodeIdentifier='', filter='subscribed', profile=C.PROF_KEY_NONE):
|
||||
def listSubscribedNodes(self, service, nodeIdentifier='', filter_='subscribed', profile=C.PROF_KEY_NONE):
|
||||
"""Retrieve the name of the nodes to which the profile is subscribed on the target service.
|
||||
|
||||
@param service (JID): target service
|
||||
@param nodeIdentifier (str): the parent node name (leave empty to retrieve all subscriptions)
|
||||
@param filter (str): filter the result according to the given subscription type:
|
||||
@param filter_ (str): filter the result according to the given subscription type:
|
||||
- None: do not filter
|
||||
- 'pending': subscription has been approved yet by the node owner
|
||||
- 'unconfigured': subscription options have not been configured yet
|
||||
- 'subscribed': subscription is complete
|
||||
@param profile (str): %(doc_profile)s
|
||||
@return: list[str]
|
||||
@return: Deferred list[str]
|
||||
"""
|
||||
session_id = profile + "@subscriptions@" + service.userhost()
|
||||
if session_id in self.node_cache:
|
||||
cache = self.node_cache.profileGet(session_id, profile)
|
||||
else:
|
||||
subs = yield self.subscriptions(service, nodeIdentifier, profile_key=profile)
|
||||
node_names = [sub.getAttribute('node') for sub in subs if sub.getAttribute('subscription') == filter]
|
||||
dummy, cache = self.node_cache.newSession(node_names, session_id=session_id, profile=profile)
|
||||
defer.returnValue(cache)
|
||||
session_id = profile + '@subscriptions@' + service.userhost()
|
||||
d = self.subscriptions(service, nodeIdentifier, profile_key=profile)
|
||||
d.addCallback(lambda subs: [sub.getAttribute('node') for sub in subs if sub.getAttribute('subscription') == filter_])
|
||||
return self._getDeferredNodeCache(session_id, d, profile)
|
||||
|
||||
def publish(self, service, nodeIdentifier, items=None, profile_key=C.PROF_KEY_NONE):
|
||||
profile, client = self.__getClientNProfile(profile_key, 'publish item')
|
||||
|
|
|
|||
Loading…
Reference in a new issue