plugin pubsub schema: values handling:

- "schema" attribute can now be specified directly as a data_form.Form (reparsing it will be avoided in this case)
- new "deserialise" parameter allows deserialisation from unicode strings in sendDataFormItem
- values can now be an iterable or directly the value to use (it will be put in a list automatically in the later case)
- "id" is now put directly in XMLUI's "id" field instea of "_id"
This commit is contained in:
Goffi 2017-10-06 10:55:51 +02:00
commit 9bca9328c3

View file

@ -30,6 +30,7 @@ from wokkel import disco, iwokkel
from wokkel import data_form
from wokkel import generic
from zope.interface import implements
from collections import Iterable
NS_SCHEMA = 'https://salut-a-toi/protocol/schema:0'
NS_SCHEMA_FORM = 'https://salut-a-toi/protocol/schema#schema:0'
@ -130,7 +131,9 @@ class PubsubSchema(object):
@param service(None, jid.JID): PubSub service
@param nodeIdentifier(unicode): node
@param schema(domish.Element, None): node schema
@param schema(domish.Element, data_form.Form, None): node schema
if domish.Element, will be converted to data form
if data_form.Form it will be returned without modification
if None, it will be retrieved from node (imply one additional XMPP request)
@return(data_form.Form): data form
"""
@ -139,6 +142,8 @@ class PubsubSchema(object):
schema = yield self.getSchema(client, service, nodeIdentifier)
if schema is None:
raise exceptions.DataError(_(u"no schema specified, and this node has no schema either, we can't construct the data form"))
elif isinstance(schema, data_form.Form):
defer.returnValue(schema)
try:
form = data_form.Form.fromElement(schema)
@ -206,7 +211,7 @@ class PubsubSchema(object):
@param form_ns (unicode, None): namespace of the form
None to accept everything, even if form has no namespace
@param schema(domish.Element, None): schema of the node if known
@param schema(domish.Element, data_form.Form, None): schema of the node if known
if None, it will be retrieved from node
other parameters as the same as for [getItems]
@return (list[unicode]): XMLUI of the forms
@ -225,7 +230,7 @@ class PubsubSchema(object):
continue
xmlui = xml_tools.dataFormResult2XMLUI(form, schema_form)
xmlui.addLabel('id')
xmlui.addText(item_elt['id'], name='_id')
xmlui.addText(item_elt['id'], name='id')
items_xmlui.append(xmlui)
break
defer.returnValue((items_xmlui, metadata))
@ -238,18 +243,22 @@ class PubsubSchema(object):
schema = generic.parseXml(schema.encode('utf-8'))
else:
schema = None
d = self.sendDataFormItem(client, service, nodeIdentifier, values, schema, item_id or None, extra)
d = self.sendDataFormItem(client, service, nodeIdentifier, values, schema, True, item_id or None, extra)
d.addCallback(lambda ret: ret or u'')
return d
@defer.inlineCallbacks
def sendDataFormItem(self, client, service, nodeIdentifier, values, schema=None, item_id=None, extra=None):
def sendDataFormItem(self, client, service, nodeIdentifier, values, schema=None, deserialise=False, item_id=None, extra=None):
"""Publish an item as a dataform when we know that there is a schema
@param values(dict[unicode, list[unicode]]): values set for the form
@param schema(unicode, None): data schema
@param values(dict[[iterable[object], object]): values set for the form
if not iterable, will be put in a list
@param schema(domish.Element, data_form.Form, None): data schema
None to retrieve data schema from node (need to do a additional XMPP call)
Schema is need to construct data form to publish
Schema is needed to construct data form to publish
@param deserialise(bool): if True, data are list of unicode and must be deserialized according to expected type
This is done in this method and not directly in _sendDataFormItem because we need to know the data type
which is in the form, not availablable in _sendDataFormItem
other parameters as the same as for [self._p.sendItem]
"""
form = yield self.getSchemaForm(client, service, nodeIdentifier, schema, form_type='submit')
@ -260,10 +269,13 @@ class PubsubSchema(object):
except KeyError:
log.warning(_(u"field {name} doesn't exist, ignoring it").format(name=name))
continue
if field.fieldType == 'boolean':
values_list = [C.bool(v) for v in values_list]
elif 'jid' in field.fieldType:
values_list = [jid.JID(v) for v in values_list]
if isinstance(values_list, basestring) or not isinstance(values_list, Iterable):
values_list = [values_list]
if deserialise:
if field.fieldType == 'boolean':
values_list = [C.bool(v) for v in values_list]
elif 'jid' in field.fieldType:
values_list = [jid.JID(v) for v in values_list]
field.values = values_list
yield self._p.sendItem(client, service, nodeIdentifier, form.toElement(), item_id, extra)