diff src/plugins/plugin_exp_pubsub_schema.py @ 2371:2268df8c99bf

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"
author Goffi <goffi@goffi.org>
date Fri, 06 Oct 2017 10:55:51 +0200
parents 41c7717b52cd
children 3704cb959ae8
line wrap: on
line diff
--- a/src/plugins/plugin_exp_pubsub_schema.py	Fri Oct 06 08:52:51 2017 +0200
+++ b/src/plugins/plugin_exp_pubsub_schema.py	Fri Oct 06 10:55:51 2017 +0200
@@ -30,6 +30,7 @@
 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 @@
 
         @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 @@
             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 @@
 
         @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 @@
                     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 @@
             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 @@
             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)