changeset 2364:918e38622a48

core (xmlui): added method to convert data form result to XMLUI: - former method was misnamed as it was used to convert data form element to XMLUI, so it has been renamed to dataFormEltResult2XMLUI - dataFormResult2XMLUI is now use to convert wokkel.data_form.Form instances to XMLUI
author Goffi <goffi@goffi.org>
date Sun, 01 Oct 2017 12:21:23 +0200
parents 41c7717b52cd
children 318f0434d830
files src/plugins/plugin_xep_0050.py src/plugins/plugin_xep_0055.py src/tools/xml_tools.py
diffstat 3 files changed, 32 insertions(+), 7 deletions(-) [+]
line wrap: on
line diff
--- a/src/plugins/plugin_xep_0050.py	Sun Oct 01 12:21:21 2017 +0200
+++ b/src/plugins/plugin_xep_0050.py	Sun Oct 01 12:21:23 2017 +0200
@@ -324,7 +324,7 @@
                                   )
 
         if session_id is None:
-            return xml_tools.dataFormResult2XMLUI(data_elt)
+            return xml_tools.dataFormEltResult2XMLUI(data_elt)
         form = data_form.Form.fromElement(data_elt)
         # we add any present note to the instructions
         form.instructions.extend(self._mergeNotes(notes))
--- a/src/plugins/plugin_xep_0055.py	Sun Oct 01 12:21:21 2017 +0200
+++ b/src/plugins/plugin_xep_0055.py	Sun Oct 01 12:21:23 2017 +0200
@@ -270,7 +270,7 @@
         @param elt (domish.Element):  form result element
         """
         if [child for child in elt.children if child.name == "item"]:
-            headers, xmlui_data = xml_tools.dataFormResult2XMLUIData(elt)
+            headers, xmlui_data = xml_tools.dataFormEltResult2XMLUIData(elt)
             if "jid" in headers:  # use XMLUI JidsListWidget to display the results
                 values = {}
                 for i in range(len(xmlui_data)):
@@ -297,7 +297,7 @@
         @return: a deferred XMLUI instance
         """
         d = self.getFieldsUI(jid.JID(to_jid_s), profile_key)
-        d.addCallback(lambda form: xml_tools.dataFormResult2XMLUI(form).toXml())
+        d.addCallback(lambda form: xml_tools.dataFormEltResult2XMLUI(form).toXml())
         return d
 
     def getFieldsUI(self, to_jid, profile_key):
@@ -356,7 +356,7 @@
         @return: a deferred XMLUI string representation
         """
         d = self.searchRequest(jid.JID(to_jid_s), search_data, profile_key)
-        d.addCallback(lambda form: xml_tools.dataFormResult2XMLUI(form).toXml())
+        d.addCallback(lambda form: xml_tools.dataFormEltResult2XMLUI(form).toXml())
         return d
 
     def searchRequest(self, to_jid, search_data, profile_key):
--- a/src/tools/xml_tools.py	Sun Oct 01 12:21:21 2017 +0200
+++ b/src/tools/xml_tools.py	Sun Oct 01 12:21:23 2017 +0200
@@ -29,6 +29,7 @@
 from twisted.internet import defer
 from sat.core import exceptions
 from collections import OrderedDict
+from copy import deepcopy
 import htmlentitydefs
 import re
 
@@ -40,6 +41,7 @@
 XML_ENTITIES = ('quot', 'amp', 'apos', 'lt', 'gt')
 
 # TODO: move XMLUI stuff in a separate module
+# TODO: rewrite this with lxml or ElementTree or domish.Element: it's complicated and difficult to maintain with current minidom implementation
 
 # Helper functions
 
@@ -139,7 +141,7 @@
     return dataForm2Widgets(form_ui, form, read_only=read_only)
 
 
-def dataFormResult2XMLUIData(form_xml):
+def dataFormEltResult2XMLUIData(form_xml):
     """Parse a data form result (not parsed by Wokkel's XEP-0004 implementation).
 
     The raw data form is used because Wokkel doesn't manage result items parsing yet.
@@ -206,11 +208,11 @@
     @param form_xml (domish.Element): element of the data form
     @return: the completed XMLUI instance
     """
-    headers, xmlui_data = dataFormResult2XMLUIData(form_xml)
+    headers, xmlui_data = dataFormEltResult2XMLUIData(form_xml)
     XMLUIData2AdvancedList(xmlui, headers, xmlui_data)
 
 
-def dataFormResult2XMLUI(form_elt, session_id=None):
+def dataFormEltResult2XMLUI(form_elt, session_id=None):
     """Take a raw data form (not parsed by XEP-0004) and convert it to a SàT XMLUI.
 
     The raw data form is used because Wokkel doesn't manage result items parsing yet.
@@ -226,6 +228,26 @@
         dataForm2Widgets(xml_ui, parsed_form, read_only=True)
     return xml_ui
 
+def dataFormResult2XMLUI(result_form, base_form, session_id=None):
+    """Convert data form result to SàT XMLUI.
+
+    @param result_form (data_form.Form): result form to convert
+    @param base_form (data_form.Form): initial form (i.e. of form type "form")
+        this one is necessary to reconstruct options when needed (e.g. list elements)
+    @param session_id (unicode): session id to return with the data
+    @return: XMLUI instance
+    """
+    form = deepcopy(result_form)
+    for name, field in form.fields.iteritems():
+        try:
+            base_field = base_form.fields[name]
+        except KeyError:
+            continue
+        field.options = base_field.options
+    xml_ui = XMLUI("window", "vertical", session_id=session_id)
+    dataForm2Widgets(xml_ui, form, read_only=True)
+    return xml_ui
+
 
 def _cleanValue(value):
     """Workaround method to avoid DBus types with D-Bus bridge.
@@ -928,6 +950,9 @@
         else:
             styles = set(styles)
         if not options:
+            # we can have no options if we get a submitted data form
+            # but we can't use submitted values directly,
+            # because we would not have the labels
             log.warning(_('empty "options" list'))
         if not styles.issubset(['multi']):
             raise exceptions.DataError(_("invalid styles"))