comparison sat_frontends/tools/xmlui.py @ 3028:ab2696e34d29

Python 3 port: /!\ this is a huge commit /!\ starting from this commit, SàT is needs Python 3.6+ /!\ SàT maybe be instable or some feature may not work anymore, this will improve with time This patch port backend, bridge and frontends to Python 3. Roughly this has been done this way: - 2to3 tools has been applied (with python 3.7) - all references to python2 have been replaced with python3 (notably shebangs) - fixed files not handled by 2to3 (notably the shell script) - several manual fixes - fixed issues reported by Python 3 that where not handled in Python 2 - replaced "async" with "async_" when needed (it's a reserved word from Python 3.7) - replaced zope's "implements" with @implementer decorator - temporary hack to handle data pickled in database, as str or bytes may be returned, to be checked later - fixed hash comparison for password - removed some code which is not needed anymore with Python 3 - deactivated some code which needs to be checked (notably certificate validation) - tested with jp, fixed reported issues until some basic commands worked - ported Primitivus (after porting dependencies like urwid satext) - more manual fixes
author Goffi <goffi@goffi.org>
date Tue, 13 Aug 2019 19:08:41 +0200
parents 5ecce65631a2
children fee60f17ebac
comparison
equal deleted inserted replaced
3027:ff5bcb12ae60 3028:ab2696e34d29
49 """ 49 """
50 data = [] 50 data = []
51 for child in node.childNodes: 51 for child in node.childNodes:
52 if child.nodeType == child.TEXT_NODE: 52 if child.nodeType == child.TEXT_NODE:
53 data.append(child.wholeText) 53 data.append(child.wholeText)
54 return u"".join(data) 54 return "".join(data)
55 55
56 56
57 class Widget(object): 57 class Widget(object):
58 """base Widget""" 58 """base Widget"""
59 59
293 """ 293 """
294 self.host = host 294 self.host = host
295 top = parsed_dom.documentElement 295 top = parsed_dom.documentElement
296 self.session_id = top.getAttribute("session_id") or None 296 self.session_id = top.getAttribute("session_id") or None
297 self.submit_id = top.getAttribute("submit") or None 297 self.submit_id = top.getAttribute("submit") or None
298 self.xmlui_title = title or top.getAttribute("title") or u"" 298 self.xmlui_title = title or top.getAttribute("title") or ""
299 self.hidden = {} 299 self.hidden = {}
300 if flags is None: 300 if flags is None:
301 flags = [] 301 flags = []
302 self.flags = flags 302 self.flags = flags
303 self.callback = callback or self._defaultCb 303 self.callback = callback or self._defaultCb
340 self._xmluiClose() 340 self._xmluiClose()
341 if self.submit_id is None: 341 if self.submit_id is None:
342 raise ValueError("Can't submit is self.submit_id is not set") 342 raise ValueError("Can't submit is self.submit_id is not set")
343 if "session_id" in data: 343 if "session_id" in data:
344 raise ValueError( 344 raise ValueError(
345 u"session_id must no be used in data, it is automaticaly filled with " 345 "session_id must no be used in data, it is automaticaly filled with "
346 u"self.session_id if present" 346 "self.session_id if present"
347 ) 347 )
348 if self.session_id is not None: 348 if self.session_id is not None:
349 data["session_id"] = self.session_id 349 data["session_id"] = self.session_id
350 self._xmluiLaunchAction(self.submit_id, data) 350 self._xmluiLaunchAction(self.submit_id, data)
351 351
374 374
375 def __getattr__(self, name): 375 def __getattr__(self, name):
376 return self.__getitem__(name) 376 return self.__getitem__(name)
377 377
378 def keys(self): 378 def keys(self):
379 return self.widgets.keys() 379 return list(self.widgets.keys())
380 380
381 381
382 class XMLUIPanel(XMLUIBase): 382 class XMLUIPanel(XMLUIBase):
383 """XMLUI Panel 383 """XMLUI Panel
384 384
418 self.constructUI(parsed_dom) 418 self.constructUI(parsed_dom)
419 419
420 @staticmethod 420 @staticmethod
421 def escape(name): 421 def escape(name):
422 """Return escaped name for forms""" 422 """Return escaped name for forms"""
423 return u"%s%s" % (C.SAT_FORM_PREFIX, name) 423 return "%s%s" % (C.SAT_FORM_PREFIX, name)
424 424
425 @property 425 @property
426 def main_cont(self): 426 def main_cont(self):
427 return self._main_cont 427 return self._main_cont
428 428
554 value_elt = self._getChildNode(node, "value") 554 value_elt = self._getChildNode(node, "value")
555 if value_elt is not None: 555 if value_elt is not None:
556 value = getText(value_elt) 556 value = getText(value_elt)
557 else: 557 else:
558 value = ( 558 value = (
559 node.getAttribute("value") if node.hasAttribute("value") else u"" 559 node.getAttribute("value") if node.hasAttribute("value") else ""
560 ) 560 )
561 if type_ == "empty": 561 if type_ == "empty":
562 ctrl = self.widget_factory.createEmptyWidget(_xmlui_parent) 562 ctrl = self.widget_factory.createEmptyWidget(_xmlui_parent)
563 if CURRENT_LABEL in data: 563 if CURRENT_LABEL in data:
564 data[CURRENT_LABEL] = None 564 data[CURRENT_LABEL] = None
567 elif type_ == "label": 567 elif type_ == "label":
568 ctrl = self.widget_factory.createLabelWidget(_xmlui_parent, value) 568 ctrl = self.widget_factory.createLabelWidget(_xmlui_parent, value)
569 data[CURRENT_LABEL] = ctrl 569 data[CURRENT_LABEL] = ctrl
570 elif type_ == "hidden": 570 elif type_ == "hidden":
571 if name in self.hidden: 571 if name in self.hidden:
572 raise exceptions.ConflictError(u"Conflict on hidden value with " 572 raise exceptions.ConflictError("Conflict on hidden value with "
573 u"name {name}".format(name=name)) 573 "name {name}".format(name=name))
574 self.hidden[name] = value 574 self.hidden[name] = value
575 continue 575 continue
576 elif type_ == "jid": 576 elif type_ == "jid":
577 ctrl = self.widget_factory.createJidWidget(_xmlui_parent, value) 577 ctrl = self.widget_factory.createJidWidget(_xmlui_parent, value)
578 elif type_ == "divider": 578 elif type_ == "divider":
615 _xmlui_parent, value, self._isAttrSet("read_only", node) 615 _xmlui_parent, value, self._isAttrSet("read_only", node)
616 ) 616 )
617 self.ctrl_list[name] = {"type": type_, "control": ctrl} 617 self.ctrl_list[name] = {"type": type_, "control": ctrl}
618 elif type_ == "list": 618 elif type_ == "list":
619 style = [] if node.getAttribute("multi") == "yes" else ["single"] 619 style = [] if node.getAttribute("multi") == "yes" else ["single"]
620 for attr in (u"noselect", u"extensible", u"reducible", u"inline"): 620 for attr in ("noselect", "extensible", "reducible", "inline"):
621 if node.getAttribute(attr) == "yes": 621 if node.getAttribute(attr) == "yes":
622 style.append(attr) 622 style.append(attr)
623 _options = [ 623 _options = [
624 (option.getAttribute("value"), option.getAttribute("label")) 624 (option.getAttribute("value"), option.getAttribute("label"))
625 for option in node.getElementsByTagName("option") 625 for option in node.getElementsByTagName("option")
776 data = {} 776 data = {}
777 for field in fields: 777 for field in fields:
778 escaped = self.escape(field) 778 escaped = self.escape(field)
779 ctrl = self.ctrl_list[field] 779 ctrl = self.ctrl_list[field]
780 if isinstance(ctrl["control"], ListWidget): 780 if isinstance(ctrl["control"], ListWidget):
781 data[escaped] = u"\t".join(ctrl["control"]._xmluiGetSelectedValues()) 781 data[escaped] = "\t".join(ctrl["control"]._xmluiGetSelectedValues())
782 else: 782 else:
783 data[escaped] = ctrl["control"]._xmluiGetValue() 783 data[escaped] = ctrl["control"]._xmluiGetValue()
784 self._xmluiLaunchAction(callback_id, data) 784 self._xmluiLaunchAction(callback_id, data)
785 785
786 def onChangeInternal(self, ctrl): 786 def onChangeInternal(self, ctrl):
808 values = [value for value in values if value] 808 values = [value for value in values if value]
809 if values: 809 if values:
810 target._xmluiAddValues(values, select=True) 810 target._xmluiAddValues(values, select=True)
811 else: 811 else:
812 if isinstance(source, ListWidget): 812 if isinstance(source, ListWidget):
813 value = u", ".join(source._xmluiGetSelectedValues()) 813 value = ", ".join(source._xmluiGetSelectedValues())
814 else: 814 else:
815 value = source._xmluiGetValue() 815 value = source._xmluiGetValue()
816 if action == "move": 816 if action == "move":
817 source._xmluiSetValue("") 817 source._xmluiSetValue("")
818 target._xmluiSetValue(value) 818 target._xmluiSetValue(value)
875 for ctrl_name in self.ctrl_list: 875 for ctrl_name in self.ctrl_list:
876 escaped = self.escape(ctrl_name) 876 escaped = self.escape(ctrl_name)
877 ctrl = self.ctrl_list[ctrl_name] 877 ctrl = self.ctrl_list[ctrl_name]
878 if isinstance(ctrl["control"], ListWidget): 878 if isinstance(ctrl["control"], ListWidget):
879 selected_values.append( 879 selected_values.append(
880 (escaped, u"\t".join(ctrl["control"]._xmluiGetSelectedValues())) 880 (escaped, "\t".join(ctrl["control"]._xmluiGetSelectedValues()))
881 ) 881 )
882 else: 882 else:
883 selected_values.append((escaped, ctrl["control"]._xmluiGetValue())) 883 selected_values.append((escaped, ctrl["control"]._xmluiGetValue()))
884 data = dict(selected_values) 884 data = dict(selected_values)
885 for key, value in self.hidden.iteritems(): 885 for key, value in self.hidden.items():
886 data[self.escape(key)] = value 886 data[self.escape(key)] = value
887 887
888 if self.submit_id is not None: 888 if self.submit_id is not None:
889 self.submit(data) 889 self.submit(data)
890 else: 890 else:
911 self.type must be param 911 self.type must be param
912 """ 912 """
913 assert self.type == "param" 913 assert self.type == "param"
914 for ctrl in self.param_changed: 914 for ctrl in self.param_changed:
915 if isinstance(ctrl, ListWidget): 915 if isinstance(ctrl, ListWidget):
916 value = u"\t".join(ctrl._xmluiGetSelectedValues()) 916 value = "\t".join(ctrl._xmluiGetSelectedValues())
917 else: 917 else:
918 value = ctrl._xmluiGetValue() 918 value = ctrl._xmluiGetValue()
919 param_name = ctrl._xmlui_name.split(C.SAT_PARAM_SEPARATOR)[1] 919 param_name = ctrl._xmlui_name.split(C.SAT_PARAM_SEPARATOR)[1]
920 self._xmluiSetParam(param_name, value, ctrl._param_category) 920 self._xmluiSetParam(param_name, value, ctrl._param_category)
921 921
1010 @param class_: the class to use to instanciate given type 1010 @param class_: the class to use to instanciate given type
1011 """ 1011 """
1012 # TODO: remove this method, as there are seme use cases where different XMLUI 1012 # TODO: remove this method, as there are seme use cases where different XMLUI
1013 # classes can be used in the same frontend, so a global value is not good 1013 # classes can be used in the same frontend, so a global value is not good
1014 assert type_ in (CLASS_PANEL, CLASS_DIALOG) 1014 assert type_ in (CLASS_PANEL, CLASS_DIALOG)
1015 log.warning(u"registerClass for XMLUI is deprecated, please use partial with " 1015 log.warning("registerClass for XMLUI is deprecated, please use partial with "
1016 u"xmlui.create and class_map instead") 1016 "xmlui.create and class_map instead")
1017 if type_ in _class_map: 1017 if type_ in _class_map:
1018 log.debug(_(u"XMLUI class already registered for {type_}, ignoring").format( 1018 log.debug(_("XMLUI class already registered for {type_}, ignoring").format(
1019 type_=type_)) 1019 type_=type_))
1020 return 1020 return
1021 1021
1022 _class_map[type_] = class_ 1022 _class_map[type_] = class_
1023 1023