Mercurial > libervia-backend
diff sat/plugins/plugin_xep_0060.py @ 3758:b7cef1b24f83
plugins XEP-0060, XEP-0376, XEP-0465, CLI: PAM + PSS implementation:
- update psSubscriptionsGet to use serialised return value
- implement XEP-0376 Pubsub Account Management
- implement XEP-0465 Public Pubsub Subscriptions
- CLI `pubsub` commands updated accordingly, and added `--public` flags to `subscribe`,
`Subscriptions` and `node Subscriptions get`
⚠ `XEP-0465` is speculative, the XEP has been accepted by council but not published yet.
As is should be the next one, and current latest one is `XEP-0464`, `XEP-0465` has been
anticipated.
rel 365
author | Goffi <goffi@goffi.org> |
---|---|
date | Fri, 13 May 2022 18:38:05 +0200 |
parents | 5bda9d2e8b35 |
children | c61233f51b86 |
line wrap: on
line diff
--- a/sat/plugins/plugin_xep_0060.py Fri May 13 18:29:42 2022 +0200 +++ b/sat/plugins/plugin_xep_0060.py Fri May 13 18:38:05 2022 +0200 @@ -272,7 +272,7 @@ "psSubscriptionsGet", ".plugin", in_sign="sss", - out_sign="aa{ss}", + out_sign="s", method=self._subscriptions, async_=True, ) @@ -1204,36 +1204,48 @@ sender, ) - def _subscriptions(self, service, nodeIdentifier="", profile_key=C.PROF_KEY_NONE): + @utils.ensure_deferred + async def _subscriptions( + self, + service="", + nodeIdentifier="", + profile_key=C.PROF_KEY_NONE + ) -> str: client = self.host.getClient(profile_key) service = None if not service else jid.JID(service) + subs = await self.subscriptions(client, service, nodeIdentifier or None) + return data_format.serialise(subs) - 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 + async def subscriptions( + self, + client: SatXMPPEntity, + service: Optional[jid.JID] = None, + node: Optional[str] = None + ) -> List[Dict[str, Union[str, bool]]]: + """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) + cont, ret = await self.host.trigger.asyncReturnPoint( + "XEP-0060_subscriptions", client, service, node + ) + if not cont: + return ret + subs = await client.pubsub_client.subscriptions(service, node) + ret = [] + for sub in subs: + sub_dict = { + "service": service.host if service else client.jid.host, + "node": sub.nodeIdentifier, + "subscriber": sub.subscriber.full(), + "state": sub.state, + } + if sub.subscriptionIdentifier is not None: + sub_dict["id"] = sub.subscriptionIdentifier + ret.append(sub_dict) + return ret ## misc tools ## @@ -1325,17 +1337,25 @@ # subscribe # - def _getNodeSubscriptions(self, service_s, nodeIdentifier, profile_key): + @utils.ensure_deferred + async def _getNodeSubscriptions( + self, + service: str, + node: str, + profile_key: str + ) -> Dict[str, str]: client = self.host.getClient(profile_key) - d = self.getNodeSubscriptions( - client, jid.JID(service_s) if service_s else None, nodeIdentifier + subs = await self.getNodeSubscriptions( + client, jid.JID(service) if service else None, node ) - d.addCallback( - lambda subscriptions: {j.full(): a for j, a in subscriptions.items()} - ) - return d + return {j.full(): a for j, a in subs.items()} - def getNodeSubscriptions(self, client, service, nodeIdentifier): + async def getNodeSubscriptions( + self, + client: SatXMPPEntity, + service: Optional[jid.JID], + nodeIdentifier: str + ) -> Dict[jid.JID, str]: """Retrieve subscriptions to a node @param nodeIdentifier(unicode): node to get subscriptions from @@ -1346,36 +1366,32 @@ request.recipient = service request.nodeIdentifier = nodeIdentifier - def cb(iq_elt): - try: - subscriptions_elt = next( - iq_elt.pubsub.elements((pubsub.NS_PUBSUB, "subscriptions")) - ) - except StopIteration: - raise ValueError( - _("Invalid result: missing <subscriptions> element: {}").format( - iq_elt.toXml - ) + iq_elt = await request.send(client.xmlstream) + try: + subscriptions_elt = next( + iq_elt.pubsub.elements((pubsub.NS_PUBSUB, "subscriptions")) + ) + except StopIteration: + raise ValueError( + _("Invalid result: missing <subscriptions> element: {}").format( + iq_elt.toXml ) - except AttributeError as e: - raise ValueError(_("Invalid result: {}").format(e)) - try: - return { - jid.JID(s["jid"]): s["subscription"] - for s in subscriptions_elt.elements( - (pubsub.NS_PUBSUB, "subscription") - ) - } - except KeyError: - raise ValueError( - _("Invalid result: bad <subscription> element: {}").format( - iq_elt.toXml - ) + ) + except AttributeError as e: + raise ValueError(_("Invalid result: {}").format(e)) + try: + return { + jid.JID(s["jid"]): s["subscription"] + for s in subscriptions_elt.elements( + (pubsub.NS_PUBSUB, "subscription") ) - - d = request.send(client.xmlstream) - d.addCallback(cb) - return d + } + except KeyError: + raise ValueError( + _("Invalid result: bad <subscription> element: {}").format( + iq_elt.toXml + ) + ) def _setNodeSubscriptions( self, service_s, nodeIdentifier, subscriptions, profile_key=C.PROF_KEY_NONE