diff --git a/src/tools/xml_tools.py b/src/tools/xml_tools.py
index 37f5ab6d..111e50f8 100644
--- a/src/tools/xml_tools.py
+++ b/src/tools/xml_tools.py
@@ -21,27 +21,29 @@ from sat.core.i18n import _
from sat.core.constants import Const as C
from sat.core.log import getLogger
log = getLogger(__name__)
+
from xml.dom import minidom, NotFoundErr
from wokkel import data_form
from twisted.words.xish import domish
from sat.core import exceptions
-"""This library help manage XML used in SàT (parameters, registration, etc) """
+"""This library help manage XML used in SàT (parameters, registration, etc)"""
SAT_FORM_PREFIX = "SAT_FORM_"
-SAT_PARAM_SEPARATOR = "_XMLUI_PARAM_" # used to have unique elements names
+SAT_PARAM_SEPARATOR = "_XMLUI_PARAM_" # used to have unique elements names
# Helper functions
def _dataFormField2XMLUIData(field, read_only=False):
- """ Get data needed to create an XMLUI's Widget from Wokkel's data_form's Field
- field can be modified (if it's fixed and it has no value)
- @param field: data_form.Field (it uses field.value, field.fieldType, field.label and field.var)
- @param read_only: if True and it make sens, create a read only input widget
- @return: widget_type, widget_args, widget_kwargs
+ """Get data needed to create an XMLUI's Widget from Wokkel's data_form's Field.
+ The attribute field can be modified (if it's fixed and it has no value).
+
+ @param field (data_form.Field): a field with attributes "value", "fieldType", "label" and "var"
+ @param read_only (bool): if True and it makes sense, create a read only input widget
+ @return: a tuple (widget_type, widget_args, widget_kwargs)
"""
widget_args = [field.value]
widget_kwargs = {}
@@ -88,12 +90,14 @@ def _dataFormField2XMLUIData(field, read_only=False):
return widget_type, widget_args, widget_kwargs
-def dataForm2Widgets(form_ui, form, read_only=False):
- """Complete an existing XMLUI with widget converted frot XEP-0004 data forms
- @param form_ui: XMLUI instance
- @param form: Wokkel's implementation of data form
- @return: completed xml_ui
+def dataForm2Widgets(form_ui, form, read_only=False):
+ """Complete an existing XMLUI with widget converted from XEP-0004 data forms.
+
+ @param form_ui (XMLUI): XMLUI instance
+ @param form (data_form.Form): Wokkel's implementation of data form
+ @param read_only (bool): if True and it makes sense, create a read only input widget
+ @return: the completed XMLUI instance
"""
if form.instructions:
form_ui.addText('\n'.join(form.instructions), 'instructions')
@@ -112,20 +116,26 @@ def dataForm2Widgets(form_ui, form, read_only=False):
return form_ui
-def dataForm2XMLUI(form, submit_id, session_id=None, read_only=False):
- """Take a data form (xep-0004, Wokkel's implementation) and convert it to a SàT XML
- @param submit_id: callback id to call when submitting form
- @param session_id: id to return with the data
+def dataForm2XMLUI(form, submit_id, session_id=None, read_only=False):
+ """Take a data form (XEP-0004, Wokkel's implementation) and convert it to a SàT XMLUI.
+
+ @param form (data_form.Form): a Form instance
+ @param submit_id (unicode): callback id to call when submitting form
+ @param session_id (unicode): session id to return with the data
+ @param read_only (bool): if True and it makes sense, create a read only input widget
+ @return: XMLUI instance
"""
form_ui = XMLUI("form", "vertical", submit_id=submit_id, session_id=session_id)
return dataForm2Widgets(form_ui, form, read_only=read_only)
+
def dataFormResult2AdvancedList(xmlui, form_xml):
- """Take a raw data form (not parsed by XEP-0004) and convert it to an advanced list
- raw data form is used because Wokkel doesn't manage result items parsing yet
- @param xmlui: the XMLUI where the AdvancedList will be added
- @param form_xml: domish.Element of the data form
+ """Take a raw data form (not parsed by XEP-0004) and convert it to an advanced list.
+
+ The raw data form is used because Wokkel doesn't manage result items parsing yet.
+ @param xmlui (XMLUI): the XMLUI where the AdvancedList will be added
+ @param form_xml (domish.Element): element of the data form
@return: AdvancedList element
"""
headers = {}
@@ -138,7 +148,7 @@ def dataFormResult2AdvancedList(xmlui, form_xml):
if elt.name != "field":
raise exceptions.DataError("Unexpected tag")
name = elt["var"]
- label = elt.attributes.get('label','')
+ label = elt.attributes.get('label', '')
type_ = elt.attributes.get('type')
headers[name] = (label, type_)
@@ -162,13 +172,15 @@ def dataFormResult2AdvancedList(xmlui, form_xml):
return xmlui
-def dataFormResult2XMLUI(form_elt, session_id=None):
- """Take a raw data form (not parsed by XEP-0004) and convert it to a SàT XMLUI
- raw data form is used because Wokkel doesn't manage result items parsing yet
- @param form_elt: domish.Element of the data form
- @return: XMLUI interface
- """
+def dataFormResult2XMLUI(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.
+ @param form_elt (domish.Element): element of the data form
+ @param session_id (unicode): session id to return with the data
+ @return: XMLUI instance
+ """
xml_ui = XMLUI("window", "vertical", session_id=session_id)
try:
dataFormResult2AdvancedList(xml_ui, form_elt)
@@ -177,8 +189,9 @@ def dataFormResult2XMLUI(form_elt, session_id=None):
dataForm2Widgets(xml_ui, parsed_form, read_only=True)
return xml_ui
+
def _cleanValue(value):
- """Workaround method to avoid DBus types with D-Bus bridge
+ """Workaround method to avoid DBus types with D-Bus bridge.
@param value: value to clean
@return: value in a non DBus type (only clean string yet)
@@ -189,27 +202,42 @@ def _cleanValue(value):
return unicode(value)
return value
+
def XMLUIResult2DataFormResult(xmlui_data):
- """ Extract form data from a XMLUI return
- @xmlui_data: data returned by frontends for XMLUI form
- @return: dict of data usable by Wokkel's dataform
+ """ Extract form data from a XMLUI return.
+
+ @param xmlui_data (dict): data returned by frontends for XMLUI form
+ @return: dict of data usable by Wokkel's data form
"""
return {key[len(SAT_FORM_PREFIX):]: _cleanValue(value) for key, value in xmlui_data.iteritems() if key.startswith(SAT_FORM_PREFIX)}
+
def formEscape(name):
- """ Return escaped name for forms """
- return u"%s%s" % (SAT_FORM_PREFIX, name)
+ """Return escaped name for forms.
+
+ @param name (unicode): form name
+ @return: unicode
+ """
+ return u"%s%s" % (SAT_FORM_PREFIX, name)
+
def XMLUIResultToElt(xmlui_data):
- """ Construct result domish.Element from XMLUI result
- @xmlui_data: data returned by frontends for XMLUI form
+ """Construct result domish.Element from XMLUI result.
+
+ @param xmlui_data (dict): data returned by frontends for XMLUI form
+ @return: domish.Element
"""
form = data_form.Form('submit')
form.makeFields(XMLUIResult2DataFormResult(xmlui_data))
return form.toElement()
+
def tupleList2dataForm(values):
- """convert a list of tuples (name,value) to a wokkel submit data form"""
+ """Convert a list of tuples (name, value) to a wokkel submit data form.
+
+ @param values (list): list of tuples
+ @return: data_form.Form
+ """
form = data_form.Form('submit')
for value in values:
field = data_form.Field(var=value[0], value=value[1])
@@ -217,8 +245,13 @@ def tupleList2dataForm(values):
return form
+
def paramsXML2XMLUI(xml):
- """Convert the xml for parameter to a SàT XML User Interface"""
+ """Convert the XML for parameter to a SàT XML User Interface.
+
+ @param xml (unicode)
+ @return: XMLUI
+ """
params_doc = minidom.parseString(xml.encode('utf-8'))
top = params_doc.documentElement
if top.nodeName != 'params':
@@ -274,8 +307,12 @@ def paramsXML2XMLUI(xml):
def _getParamListOptions(param):
- """Retrieve the options for list element. The tags
- must be direct children of ."""
+ """Retrieve the options for list element.
+
+ The tags must be direct children of .
+ @param param (domish.Element): element
+ @return: a tuple (options, selected_value)
+ """
if len(param.getElementsByTagName("options")) > 0:
raise exceptions.DataError(_("The 'options' tag is not allowed in parameter of type 'list'!"))
elems = param.getElementsByTagName("option")
@@ -283,7 +320,7 @@ def _getParamListOptions(param):
return []
options = [elem.getAttribute("value") for elem in elems]
selected = [elem.getAttribute("value") for elem in elems if elem.getAttribute("selected") == 'true']
- return (options, selected)
+ return (options, selected)
## XMLUI Elements
@@ -295,6 +332,7 @@ class Element(object):
def __init__(self, xmlui, parent=None):
"""Create a container element
+
@param xmlui: XMLUI instance
@parent: parent element
"""
@@ -321,7 +359,7 @@ class TopElement(Element):
class TabElement(Element):
- """ Used by TabsContainer to give name and label to tabs """
+ """ Used by TabsContainer to give name and label to tabs."""
type = 'tab'
def __init__(self, parent, name, label):
@@ -447,6 +485,7 @@ class Container(Element):
current = current.parent
return current
+
class VerticalContainer(Container):
type = "vertical"
@@ -482,7 +521,7 @@ class TabsContainer(Container):
class AdvancedListContainer(Container):
type = "advanced_list"
- def __init__(self, xmlui, callback_id=None, name=None, headers=None, items=None, columns=None, selectable = 'no', auto_index = False, parent=None):
+ def __init__(self, xmlui, callback_id=None, name=None, headers=None, items=None, columns=None, selectable='no', auto_index=False, parent=None):
"""Create an advanced list
@param headers: optional headers information
@param callback_id: id of the method to call when selection is done
@@ -527,7 +566,7 @@ class AdvancedListContainer(Container):
self.addHeader(header)
def addHeader(self, header):
- pass # TODO
+ pass # TODO
def addItems(self, items):
for item in items:
@@ -623,7 +662,7 @@ class LabelWidget(Widget):
"""Used for one line blob of text,
most of time to display the desciption or name of the next widget
"""
- type='label'
+ type = 'label'
def __init__(self, xmlui, label, name=None, parent=None):
super(LabelWidget, self).__init__(xmlui, name, parent)
@@ -632,7 +671,7 @@ class LabelWidget(Widget):
class JidWidget(Widget):
"""Used to display a Jabber ID, some specific methods can be added"""
- type='jid'
+ type = 'jid'
def __init__(self, xmlui, jid, name=None, parent=None):
super(JidWidget, self).__init__(xmlui, name, parent)
@@ -905,7 +944,7 @@ class XMLUI(object):
dialog_opt = {}
self._createDialog(dialog_opt)
return
- self.main_container = self._createContainer(container, TopElement(self))
+ self.main_container = self._createContainer(container, TopElement(self))
self.current_container = self.main_container
def _introspect(self):
@@ -929,17 +968,17 @@ class XMLUI(object):
self.doc.unlink()
def __getattr__(self, name):
- if name.startswith("add") and name not in ('addWidget',): # addWidgetName(...) create an instance of WidgetName
+ if name.startswith("add") and name not in ('addWidget',): # addWidgetName(...) create an instance of WidgetName
if self.type == C.XMLUI_DIALOG:
raise exceptions.InternalError(_("addXXX can't be used with dialogs"))
- class_name = name[3:]+"Widget"
+ class_name = name[3:] + "Widget"
if class_name in globals():
cls = globals()[class_name]
if issubclass(cls, Widget):
def createWidget(*args, **kwargs):
if "parent" not in kwargs:
kwargs["parent"] = self.current_container
- if "name" not in kwargs and issubclass(cls, InputWidget): # name can be given as first argument or in keyword arguments for InputWidgets
+ if "name" not in kwargs and issubclass(cls, InputWidget): # name can be given as first argument or in keyword arguments for InputWidgets
args = list(args)
kwargs["name"] = args.pop(0)
return cls(self, *args, **kwargs)
@@ -960,7 +999,7 @@ class XMLUI(object):
top_element.removeAttribute("submit")
except NotFoundErr:
pass
- elif value: # submit_id can be the empty string to bypass form restriction
+ elif value: # submit_id can be the empty string to bypass form restriction
top_element.setAttribute("submit", value)
@property
@@ -1050,12 +1089,12 @@ def note(message, title='', level=C.XMLUI_DATA_LVL_INFO):
@param title: title of the note
@param level: one of C.XMLUI_DATA_LVL_*
"""
- note_xmlui = XMLUI(C.XMLUI_DIALOG, dialog_opt = {
+ note_xmlui = XMLUI(C.XMLUI_DIALOG, dialog_opt={
C.XMLUI_DATA_TYPE: C.XMLUI_DIALOG_NOTE,
C.XMLUI_DATA_MESS: message,
C.XMLUI_DATA_LVL: level},
title=title
- )
+ )
return note_xmlui
# Misc other funtions