comparison src/tools/xml_tools.py @ 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 5defafc8ede6
children 318f0434d830
comparison
equal deleted inserted replaced
2363:41c7717b52cd 2364:918e38622a48
27 from twisted.words.xish import domish 27 from twisted.words.xish import domish
28 from twisted.words.protocols.jabber import jid 28 from twisted.words.protocols.jabber import jid
29 from twisted.internet import defer 29 from twisted.internet import defer
30 from sat.core import exceptions 30 from sat.core import exceptions
31 from collections import OrderedDict 31 from collections import OrderedDict
32 from copy import deepcopy
32 import htmlentitydefs 33 import htmlentitydefs
33 import re 34 import re
34 35
35 """This library help manage XML used in SàT (parameters, registration, etc)""" 36 """This library help manage XML used in SàT (parameters, registration, etc)"""
36 37
38 SAT_PARAM_SEPARATOR = "_XMLUI_PARAM_" # used to have unique elements names 39 SAT_PARAM_SEPARATOR = "_XMLUI_PARAM_" # used to have unique elements names
39 html_entity_re = re.compile(r'&([a-zA-Z]+?);') 40 html_entity_re = re.compile(r'&([a-zA-Z]+?);')
40 XML_ENTITIES = ('quot', 'amp', 'apos', 'lt', 'gt') 41 XML_ENTITIES = ('quot', 'amp', 'apos', 'lt', 'gt')
41 42
42 # TODO: move XMLUI stuff in a separate module 43 # TODO: move XMLUI stuff in a separate module
44 # TODO: rewrite this with lxml or ElementTree or domish.Element: it's complicated and difficult to maintain with current minidom implementation
43 45
44 # Helper functions 46 # Helper functions
45 47
46 def _dataFormField2XMLUIData(field, read_only=False): 48 def _dataFormField2XMLUIData(field, read_only=False):
47 """Get data needed to create an XMLUI's Widget from Wokkel's data_form's Field. 49 """Get data needed to create an XMLUI's Widget from Wokkel's data_form's Field.
137 """ 139 """
138 form_ui = XMLUI("form", "vertical", submit_id=submit_id, session_id=session_id) 140 form_ui = XMLUI("form", "vertical", submit_id=submit_id, session_id=session_id)
139 return dataForm2Widgets(form_ui, form, read_only=read_only) 141 return dataForm2Widgets(form_ui, form, read_only=read_only)
140 142
141 143
142 def dataFormResult2XMLUIData(form_xml): 144 def dataFormEltResult2XMLUIData(form_xml):
143 """Parse a data form result (not parsed by Wokkel's XEP-0004 implementation). 145 """Parse a data form result (not parsed by Wokkel's XEP-0004 implementation).
144 146
145 The raw data form is used because Wokkel doesn't manage result items parsing yet. 147 The raw data form is used because Wokkel doesn't manage result items parsing yet.
146 @param form_xml (domish.Element): element of the data form 148 @param form_xml (domish.Element): element of the data form
147 @return: a couple (headers, result_list): 149 @return: a couple (headers, result_list):
204 The raw data form is used because Wokkel doesn't manage result items parsing yet. 206 The raw data form is used because Wokkel doesn't manage result items parsing yet.
205 @param xmlui (XMLUI): the XMLUI where the AdvancedList will be added 207 @param xmlui (XMLUI): the XMLUI where the AdvancedList will be added
206 @param form_xml (domish.Element): element of the data form 208 @param form_xml (domish.Element): element of the data form
207 @return: the completed XMLUI instance 209 @return: the completed XMLUI instance
208 """ 210 """
209 headers, xmlui_data = dataFormResult2XMLUIData(form_xml) 211 headers, xmlui_data = dataFormEltResult2XMLUIData(form_xml)
210 XMLUIData2AdvancedList(xmlui, headers, xmlui_data) 212 XMLUIData2AdvancedList(xmlui, headers, xmlui_data)
211 213
212 214
213 def dataFormResult2XMLUI(form_elt, session_id=None): 215 def dataFormEltResult2XMLUI(form_elt, session_id=None):
214 """Take a raw data form (not parsed by XEP-0004) and convert it to a SàT XMLUI. 216 """Take a raw data form (not parsed by XEP-0004) and convert it to a SàT XMLUI.
215 217
216 The raw data form is used because Wokkel doesn't manage result items parsing yet. 218 The raw data form is used because Wokkel doesn't manage result items parsing yet.
217 @param form_elt (domish.Element): element of the data form 219 @param form_elt (domish.Element): element of the data form
218 @param session_id (unicode): session id to return with the data 220 @param session_id (unicode): session id to return with the data
222 try: 224 try:
223 dataFormResult2AdvancedList(xml_ui, form_elt) 225 dataFormResult2AdvancedList(xml_ui, form_elt)
224 except exceptions.DataError: 226 except exceptions.DataError:
225 parsed_form = data_form.Form.fromElement(form_elt) 227 parsed_form = data_form.Form.fromElement(form_elt)
226 dataForm2Widgets(xml_ui, parsed_form, read_only=True) 228 dataForm2Widgets(xml_ui, parsed_form, read_only=True)
229 return xml_ui
230
231 def dataFormResult2XMLUI(result_form, base_form, session_id=None):
232 """Convert data form result to SàT XMLUI.
233
234 @param result_form (data_form.Form): result form to convert
235 @param base_form (data_form.Form): initial form (i.e. of form type "form")
236 this one is necessary to reconstruct options when needed (e.g. list elements)
237 @param session_id (unicode): session id to return with the data
238 @return: XMLUI instance
239 """
240 form = deepcopy(result_form)
241 for name, field in form.fields.iteritems():
242 try:
243 base_field = base_form.fields[name]
244 except KeyError:
245 continue
246 field.options = base_field.options
247 xml_ui = XMLUI("window", "vertical", session_id=session_id)
248 dataForm2Widgets(xml_ui, form, read_only=True)
227 return xml_ui 249 return xml_ui
228 250
229 251
230 def _cleanValue(value): 252 def _cleanValue(value):
231 """Workaround method to avoid DBus types with D-Bus bridge. 253 """Workaround method to avoid DBus types with D-Bus bridge.
926 if styles is None: 948 if styles is None:
927 styles = set() 949 styles = set()
928 else: 950 else:
929 styles = set(styles) 951 styles = set(styles)
930 if not options: 952 if not options:
953 # we can have no options if we get a submitted data form
954 # but we can't use submitted values directly,
955 # because we would not have the labels
931 log.warning(_('empty "options" list')) 956 log.warning(_('empty "options" list'))
932 if not styles.issubset(['multi']): 957 if not styles.issubset(['multi']):
933 raise exceptions.DataError(_("invalid styles")) 958 raise exceptions.DataError(_("invalid styles"))
934 super(ListWidget, self).__init__(xmlui, name, parent) 959 super(ListWidget, self).__init__(xmlui, name, parent)
935 self.addOptions(options, selected) 960 self.addOptions(options, selected)