From df038ad3d4f6ef954fad277227b7113509944a8e Mon Sep 17 00:00:00 2001 From: Goffi Date: Sun, 1 Oct 2017 12:21:23 +0200 Subject: [PATCH] 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 --- src/plugins/plugin_xep_0050.py | 2 +- src/plugins/plugin_xep_0055.py | 6 +++--- src/tools/xml_tools.py | 31 ++++++++++++++++++++++++++++--- 3 files changed, 32 insertions(+), 7 deletions(-) diff --git a/src/plugins/plugin_xep_0050.py b/src/plugins/plugin_xep_0050.py index d869024a..f5b2bf00 100644 --- a/src/plugins/plugin_xep_0050.py +++ b/src/plugins/plugin_xep_0050.py @@ -324,7 +324,7 @@ class XEP_0050(object): ) 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)) diff --git a/src/plugins/plugin_xep_0055.py b/src/plugins/plugin_xep_0055.py index 2fe98452..c94a26e6 100644 --- a/src/plugins/plugin_xep_0055.py +++ b/src/plugins/plugin_xep_0055.py @@ -270,7 +270,7 @@ class XEP_0055(object): @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 @@ class XEP_0055(object): @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 @@ class XEP_0055(object): @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): diff --git a/src/tools/xml_tools.py b/src/tools/xml_tools.py index d419197c..30527a2e 100644 --- a/src/tools/xml_tools.py +++ b/src/tools/xml_tools.py @@ -29,6 +29,7 @@ from twisted.words.protocols.jabber import jid 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 @@ html_entity_re = re.compile(r'&([a-zA-Z]+?);') 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 @@ def dataForm2XMLUI(form, submit_id, session_id=None, read_only=False): 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 @@ def dataFormResult2AdvancedList(xmlui, form_xml): @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 @@ def dataFormResult2XMLUI(form_elt, session_id=None): 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 @@ class ListWidget(InputWidget): 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"))