plugin XEP-0060: added/fixed subscribe/unsubscribe and subscriptions methods/bridge methods:

subscriptions now returns Subscription instances, and psSubscriptionsGet return dict with subscription data (node, subscriber, state)
This commit is contained in:
Goffi 2017-09-08 07:57:57 +02:00
commit b567e87e9b

View file

@ -98,6 +98,9 @@ class XEP_0060(object):
host.bridge.addMethod("psItemSend", ".plugin", in_sign='ssssa{ss}s', out_sign='s', method=self._sendItem, async=True)
host.bridge.addMethod("psRetractItem", ".plugin", in_sign='sssbs', out_sign='', method=self._retractItem, async=True)
host.bridge.addMethod("psRetractItems", ".plugin", in_sign='ssasbs', out_sign='', method=self._retractItems, async=True)
host.bridge.addMethod("psSubscribe", ".plugin", in_sign='sss', out_sign='', method=self._subscribe, async=True)
host.bridge.addMethod("psUnsubscribe", ".plugin", in_sign='sss', out_sign='', method=self._unsubscribe, async=True)
host.bridge.addMethod("psSubscriptionsGet", ".plugin", in_sign='sss', out_sign='aa{ss}', method=self._subscriptions, async=True)
host.bridge.addMethod("psSubscribeToMany", ".plugin", in_sign='a(ss)sa{ss}s', out_sign='s', method=self._subscribeToMany)
host.bridge.addMethod("psGetSubscribeRTResult", ".plugin", in_sign='ss', out_sign='(ua(sss))', method=self._manySubscribeRTResult, async=True)
host.bridge.addMethod("psGetFromMany", ".plugin", in_sign='a(ss)ia{ss}s', out_sign='s', method=self._getFromMany)
@ -579,13 +582,51 @@ class XEP_0060(object):
client = self.host.getClient(profile_key)
return client.pubsub_client.retractItems(service, nodeIdentifier, itemIdentifiers, notify=True)
def subscribe(self, service, nodeIdentifier, sub_jid=None, options=None, profile_key=C.PROF_KEY_NONE):
# TODO: reimplement a subscribtion cache, checking that we have not subscription before trying to subscribe
def _subscribe(self, service, nodeIdentifier, profile_key=C.PROF_KEY_NONE):
client = self.host.getClient(profile_key)
return client.pubsub_client.subscribe(service, nodeIdentifier, sub_jid or client.pubsub_client.parent.jid.userhostJID(), options=options)
service = None if not service else jid.JID(service)
return self.subscribe(client, service, nodeIdentifier)
def subscriptions(self, service, nodeIdentifier='', profile_key=C.PROF_KEY_NONE):
def subscribe(self, client, service, nodeIdentifier, sub_jid=None, options=None):
# TODO: reimplement a subscribtion cache, checking that we have not subscription before trying to subscribe
return client.pubsub_client.subscribe(service, nodeIdentifier, sub_jid or client.jid.userhostJID(), options=options)
def _unsubscribe(self, service, nodeIdentifier, profile_key=C.PROF_KEY_NONE):
client = self.host.getClient(profile_key)
service = None if not service else jid.JID(service)
return self.unsubscribe(client, service, nodeIdentifier)
def unsubscribe(self, client, service, nodeIdentifier, sub_jid=None, subscriptionIdentifier=None, sender=None):
return client.pubsub_client.unsubscribe(service, nodeIdentifier, sub_jid or client.jid.userhostJID(), subscriptionIdentifier, sender)
def _subscriptions(self, service, nodeIdentifier='', profile_key=C.PROF_KEY_NONE):
client = self.host.getClient(profile_key)
service = None if not service else jid.JID(service)
def gotSubscriptions(subscriptions):
# we replace pubsub.Subscription instance by dict that we can serialize
for idx, sub in enumerate(subscriptions):
sub_dict = {'node': sub.nodeIdentifier,
'subscriber': sub.subscriber.full(),
'state': sub.state
}
if sub.subscriptionIdentifier is not None:
sub_dict['id'] = sub.subscriptionIdentifier
subscriptions[idx] = sub_dict
return subscriptions
d = self.subscriptions(client, service, nodeIdentifier or None)
d.addCallback(gotSubscriptions)
return d
def subscriptions(self, client, service, nodeIdentifier=None):
"""retrieve subscriptions from a service
@param service(jid.JID): PubSub service
@param nodeIdentifier(unicode, None): node to check
None to get all subscriptions
"""
return client.pubsub_client.subscriptions(service, nodeIdentifier)
## misc tools ##
@ -593,7 +634,7 @@ class XEP_0060(object):
def getNodeURI(self, service, node, item=None):
"""Return XMPP URI of a PubSub node
@param service(jid.JID): PubSub service,
@param service(jid.JID): PubSub service
@param node(unicode): node
@return (unicode): URI of the node
"""
@ -862,6 +903,7 @@ class SatPubSubClient(rsm.PubSubClient):
@type service: L{JID<twisted.words.protocols.jabber.jid.JID>}
@param nodeIdentifier: The identifier of the node (leave empty to retrieve all subscriptions).
@type nodeIdentifier: C{unicode}
@return (list[pubsub.Subscription]): list of subscriptions
"""
request = pubsub.PubSubRequest('subscriptions')
request.recipient = service
@ -870,9 +912,14 @@ class SatPubSubClient(rsm.PubSubClient):
d = request.send(self.xmlstream)
def cb(iq):
# FIXME: to be checked
return [sub for sub in iq.pubsub.subscriptions.elements() if
(sub.uri == pubsub.NS_PUBSUB and sub.name == 'subscription')]
subs = []
for subscription_elt in iq.pubsub.subscriptions.elements(pubsub.NS_PUBSUB, 'subscription'):
subscription = pubsub.Subscription(subscription_elt['node'],
jid.JID(subscription_elt['jid']),
subscription_elt['subscription'],
subscriptionIdentifier=subscription_elt.getAttribute('subid'))
subs.append(subscription)
return subs
return d.addCallback(cb)