# HG changeset patch # User Goffi # Date 1577559738 -3600 # Node ID cea52c9ddfd978a20af64abb30689fade0242988 # Parent 0b6d56a8f7e357f5ec7bf05e80a64d391d90d353 plugin XEP-0060, jp (pubsub/set): publish-options implementation: - publishing options (XEP-0060 §7.1.5) implementation. - jp pubsub/set can specify publish-options using `-f` and `-F` - doc has been updated to explain that - psItemSend and psItemsSend now use serialisation for "extra" - publish-options can be specified in extra['publish-options'] with those methods diff -r 0b6d56a8f7e3 -r cea52c9ddfd9 doc/jp/pubsub.rst --- a/doc/jp/pubsub.rst Fri Dec 27 13:30:20 2019 +0100 +++ b/doc/jp/pubsub.rst Sat Dec 28 20:02:18 2019 +0100 @@ -17,6 +17,15 @@ ``stdin`` is used to get the raw XML of the payload of the item to publish. +``-f KEY VALUE, --field KEY VALUE`` can be used to specify publish options, i.e. option +which must be set if the node already exists, or used if the node is to be created, see +`XEP-0060 §7.1.5`_ for details. + +In the same way as for :ref:`jp-pubsub_node_create`, ``-F, --full-prefix`` can be used if +you need to specify the full option name. + +.. _XEP-0060 §7.1.5: https://xmpp.org/extensions/xep-0060.html#publisher-publish-options + example ------- diff -r 0b6d56a8f7e3 -r cea52c9ddfd9 doc/jp/pubsub_node.rst --- a/doc/jp/pubsub_node.rst Fri Dec 27 13:30:20 2019 +0100 +++ b/doc/jp/pubsub_node.rst Sat Dec 28 20:02:18 2019 +0100 @@ -23,6 +23,8 @@ $ jp pubsub node info -n urn:xmpp:microblog:0 -k access_model -k publish_model +.. _jp-pubsub_node_create: + create ====== diff -r 0b6d56a8f7e3 -r cea52c9ddfd9 doc/overview.rst --- a/doc/overview.rst Fri Dec 27 13:30:20 2019 +0100 +++ b/doc/overview.rst Sat Dec 28 20:02:18 2019 +0100 @@ -66,7 +66,7 @@ ----- Cagou is the desktop/mobile frontend. It's probably the main interface for most users. It -is based on the `Kivy`_ framework and should run of most platforms (for now it is +is based on the `Kivy`_ framework and should run on most platforms (for now it is officially tested only on GNU/Linux and Android phones and tablets). .. _Kivy: https://kivy.org diff -r 0b6d56a8f7e3 -r cea52c9ddfd9 sat/plugins/plugin_xep_0060.py --- a/sat/plugins/plugin_xep_0060.py Fri Dec 27 13:30:20 2019 +0100 +++ b/sat/plugins/plugin_xep_0060.py Sat Dec 28 20:02:18 2019 +0100 @@ -201,7 +201,7 @@ host.bridge.addMethod( "psItemSend", ".plugin", - in_sign="ssssa{ss}s", + in_sign="ssssss", out_sign="s", method=self._sendItem, async_=True, @@ -209,7 +209,7 @@ host.bridge.addMethod( "psItemsSend", ".plugin", - in_sign="ssasa{ss}s", + in_sign="ssasss", out_sign="as", method=self._sendItems, async_=True, @@ -453,17 +453,18 @@ # d.addCallback(lambda subs: [sub.getAttribute('node') for sub in subs if sub.getAttribute('subscription') == filter_]) # return d - def _sendItem(self, service, nodeIdentifier, payload, item_id=None, extra=None, + def _sendItem(self, service, nodeIdentifier, payload, item_id=None, extra_ser="", profile_key=C.PROF_KEY_NONE): client = self.host.getClient(profile_key) service = None if not service else jid.JID(service) + extra = data_format.deserialise(extra_ser) d = self.sendItem( client, service, nodeIdentifier, payload, item_id or None, extra ) d.addCallback(lambda ret: ret or "") return d - def _sendItems(self, service, nodeIdentifier, items, extra=None, + def _sendItems(self, service, nodeIdentifier, items, extra_ser=None, profile_key=C.PROF_KEY_NONE): client = self.host.getClient(profile_key) service = None if not service else jid.JID(service) @@ -472,6 +473,7 @@ except Exception as e: raise exceptions.DataError(_("Can't parse items: {msg}").format( msg=e)) + extra = data_format.deserialise(extra_ser) d = self.sendItems( client, service, nodeIdentifier, items, extra ) @@ -501,8 +503,12 @@ @param extra(dict, None): extra option, not used yet @return (unicode, None): id of the created item """ + if extra is None: + extra = {} + publish_options = extra.get('publish_options') item_elt = pubsub.Item(id=item_id, payload=payload) - d = self.publish(client, service, nodeIdentifier, [item_elt]) + d = self.publish( + client, service, nodeIdentifier, [item_elt], options=publish_options) d.addCallback(self._getPublishedItemId, item_id) return d @@ -523,22 +529,28 @@ @param NodeIdentifier(unicode): PubSub node to use @param items(list[domish.Element]): whole item elements to send, "id" will be used if set - @param extra(dict, None): extra option, not used yet + @param extra(dict, None): extra options. Key can be: + - publish_options: dict of publish-options @return (list[unicode]): ids of the created items """ + if extra is None: + extra = {} parsed_items = [] for item in items: if item.name != 'item': raise exceptions.DataError(_("Invalid item: {xml}").format(item.toXml())) item_id = item.getAttribute("id") parsed_items.append(pubsub.Item(id=item_id, payload=item.firstChildElement())) - d = self.publish(client, service, nodeIdentifier, parsed_items) + publish_options = extra.get('publish_options') + d = self.publish( + client, service, nodeIdentifier, parsed_items, options=publish_options) d.addCallback(self._publishCb) return d - def publish(self, client, service, nodeIdentifier, items=None): + def publish(self, client, service, nodeIdentifier, items=None, options=None): return client.pubsub_client.publish( - service, nodeIdentifier, items, client.pubsub_client.parent.jid + service, nodeIdentifier, items, client.pubsub_client.parent.jid, + options=options ) def _unwrapMAMMessage(self, message_elt): diff -r 0b6d56a8f7e3 -r cea52c9ddfd9 sat_frontends/jp/cmd_pubsub.py --- a/sat_frontends/jp/cmd_pubsub.py Fri Dec 27 13:30:20 2019 +0100 +++ b/sat_frontends/jp/cmd_pubsub.py Sat Dec 28 20:02:18 2019 +0100 @@ -32,6 +32,7 @@ from sat_frontends.jp import arg_tools from sat_frontends.jp import xml_tools from functools import partial +from sat.tools.common import data_format from sat.tools.common import uri from sat.tools.common.ansi import ANSI as A from sat_frontends.tools import jid, strings @@ -104,8 +105,9 @@ help=_("create a node"), ) - def add_parser_options(self): - self.parser.add_argument( + @staticmethod + def add_node_config_options(parser): + parser.add_argument( "-f", "--field", action="append", @@ -115,18 +117,25 @@ metavar=("KEY", "VALUE"), help=_("configuration field to set"), ) - self.parser.add_argument( + parser.add_argument( "-F", "--full-prefix", action="store_true", help=_('don\'t prepend "pubsub#" prefix to field names'), ) + def add_parser_options(self): + self.add_node_config_options(self.parser) + + @staticmethod + def get_config_options(args): + if not args.full_prefix: + return {"pubsub#" + k: v for k, v in args.fields} + else: + return dict(args.fields) + async def start(self): - if not self.args.full_prefix: - options = {"pubsub#" + k: v for k, v in self.args.fields} - else: - options = dict(self.args.fields) + options = self.get_config_options(self.args) try: node_id = await self.host.bridge.psNodeCreate( self.args.service, @@ -730,6 +739,7 @@ ) def add_parser_options(self): + NodeCreate.add_node_config_options(self.parser) self.parser.add_argument( "item", nargs="?", @@ -741,6 +751,10 @@ element, etree = xml_tools.etreeParse(self, sys.stdin) element = xml_tools.getPayload(self, element) payload = etree.tostring(element, encoding="unicode") + extra = {} + publish_options = NodeCreate.get_config_options(self.args) + if publish_options: + extra['publish_options'] = publish_options try: published_id = await self.host.bridge.psItemSend( @@ -748,7 +762,7 @@ self.args.node, payload, self.args.item, - {}, + data_format.serialise(extra), self.profile, ) except Exception as e: @@ -869,7 +883,7 @@ self.pubsub_node, content, self.pubsub_item or "", - {}, + "", self.profile, ) if published_id: