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
This commit is contained in:
Goffi 2019-12-28 20:02:18 +01:00
commit b7a74d5034
5 changed files with 56 additions and 19 deletions

View file

@ -17,6 +17,15 @@ Publish a pubsub item.
``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
-------

View file

@ -23,6 +23,8 @@ Only print ``access_model`` and ``publish_model``::
$ jp pubsub node info -n urn:xmpp:microblog:0 -k access_model -k publish_model
.. _jp-pubsub_node_create:
create
======

View file

@ -66,7 +66,7 @@ Cagou
-----
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

View file

@ -201,7 +201,7 @@ class XEP_0060(object):
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 @@ class XEP_0060(object):
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 @@ class XEP_0060(object):
# 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 @@ class XEP_0060(object):
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 @@ class XEP_0060(object):
@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 @@ class XEP_0060(object):
@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):

View file

@ -32,6 +32,7 @@ from sat_frontends.jp import common
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 @@ class NodeCreate(base.CommandBase):
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 @@ class NodeCreate(base.CommandBase):
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'),
)
async def start(self):
if not self.args.full_prefix:
options = {"pubsub#" + k: v for k, v in self.args.fields}
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:
options = dict(self.args.fields)
return dict(args.fields)
async def start(self):
options = self.get_config_options(self.args)
try:
node_id = await self.host.bridge.psNodeCreate(
self.args.service,
@ -730,6 +739,7 @@ class Set(base.CommandBase):
)
def add_parser_options(self):
NodeCreate.add_node_config_options(self.parser)
self.parser.add_argument(
"item",
nargs="?",
@ -741,6 +751,10 @@ class Set(base.CommandBase):
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 @@ class Set(base.CommandBase):
self.args.node,
payload,
self.args.item,
{},
data_format.serialise(extra),
self.profile,
)
except Exception as e:
@ -869,7 +883,7 @@ class Edit(base.CommandBase, common.BaseEdit):
self.pubsub_node,
content,
self.pubsub_item or "",
{},
"",
self.profile,
)
if published_id: