comparison sat_frontends/jp/xmlui_manager.py @ 2624:56f94936df1e

code style reformatting using black
author Goffi <goffi@goffi.org>
date Wed, 27 Jun 2018 20:14:46 +0200
parents 26edcf3a30eb
children bdb8276fd2da
comparison
equal deleted inserted replaced
2623:49533de4540b 2624:56f94936df1e
16 16
17 # You should have received a copy of the GNU Affero General Public License 17 # You should have received a copy of the GNU Affero General Public License
18 # along with this program. If not, see <http://www.gnu.org/licenses/>. 18 # along with this program. If not, see <http://www.gnu.org/licenses/>.
19 19
20 from sat.core.log import getLogger 20 from sat.core.log import getLogger
21
21 log = getLogger(__name__) 22 log = getLogger(__name__)
22 from sat_frontends.tools import xmlui as xmlui_manager 23 from sat_frontends.tools import xmlui as xmlui_manager
23 from sat_frontends.jp.constants import Const as C 24 from sat_frontends.jp.constants import Const as C
24 from sat.tools.common.ansi import ANSI as A 25 from sat.tools.common.ansi import ANSI as A
25 from sat.core.i18n import _ 26 from sat.core.i18n import _
26 from functools import partial 27 from functools import partial
27 28
28 # workflow constants 29 # workflow constants
29 30
30 SUBMIT = 'SUBMIT' # submit form 31 SUBMIT = "SUBMIT" # submit form
31
32 32
33 33
34 ## Widgets ## 34 ## Widgets ##
35
35 36
36 class Base(object): 37 class Base(object):
37 """Base for Widget and Container""" 38 """Base for Widget and Container"""
39
38 type = None 40 type = None
39 _root = None 41 _root = None
40 42
41 def __init__(self, xmlui_parent): 43 def __init__(self, xmlui_parent):
42 self.xmlui_parent = xmlui_parent 44 self.xmlui_parent = xmlui_parent
56 def disp(self, *args, **kwargs): 58 def disp(self, *args, **kwargs):
57 self.host.disp(*args, **kwargs) 59 self.host.disp(*args, **kwargs)
58 60
59 61
60 class Widget(Base): 62 class Widget(Base):
61 category = u'widget' 63 category = u"widget"
62 enabled = True 64 enabled = True
63 65
64 @property 66 @property
65 def name(self): 67 def name(self):
66 return self._xmlui_name 68 return self._xmlui_name
83 use self.name if None 85 use self.name if None
84 """ 86 """
85 if value is None: 87 if value is None:
86 value = self.name 88 value = self.name
87 if self.host.verbosity: 89 if self.host.verbosity:
88 to_disp = [A.FG_MAGENTA, 90 to_disp = [
89 u' ' if elems else u'', 91 A.FG_MAGENTA,
90 u'({})'.format(value), A.RESET] 92 u" " if elems else u"",
93 u"({})".format(value),
94 A.RESET,
95 ]
91 if elems is None: 96 if elems is None:
92 self.host.disp(A.color(*to_disp)) 97 self.host.disp(A.color(*to_disp))
93 else: 98 else:
94 elems.extend(to_disp) 99 elems.extend(to_disp)
95 100
101
96 class ValueWidget(Widget): 102 class ValueWidget(Widget):
97
98 def __init__(self, xmlui_parent, value): 103 def __init__(self, xmlui_parent, value):
99 super(ValueWidget, self).__init__(xmlui_parent) 104 super(ValueWidget, self).__init__(xmlui_parent)
100 self.value = value 105 self.value = value
101 106
102 @property 107 @property
103 def values(self): 108 def values(self):
104 return [self.value] 109 return [self.value]
105 110
106 111
107 class InputWidget(ValueWidget): 112 class InputWidget(ValueWidget):
108
109 def __init__(self, xmlui_parent, value, read_only=False): 113 def __init__(self, xmlui_parent, value, read_only=False):
110 super(InputWidget, self).__init__(xmlui_parent, value) 114 super(InputWidget, self).__init__(xmlui_parent, value)
111 self.read_only = read_only 115 self.read_only = read_only
112 116
113 def _xmluiGetValue(self): 117 def _xmluiGetValue(self):
114 return self.value 118 return self.value
115 119
116 120
117 class OptionsWidget(Widget): 121 class OptionsWidget(Widget):
118
119 def __init__(self, xmlui_parent, options, selected, style): 122 def __init__(self, xmlui_parent, options, selected, style):
120 super(OptionsWidget, self).__init__(xmlui_parent) 123 super(OptionsWidget, self).__init__(xmlui_parent)
121 self.options = options 124 self.options = options
122 self.selected = selected 125 self.selected = selected
123 self.style = style 126 self.style = style
155 158
156 @property 159 @property
157 def items(self): 160 def items(self):
158 """return suitable items, according to style""" 161 """return suitable items, according to style"""
159 no_select = self.no_select 162 no_select = self.no_select
160 for value,label in self.options: 163 for value, label in self.options:
161 if no_select or value in self.selected: 164 if no_select or value in self.selected:
162 yield value,label 165 yield value, label
163 166
164 @property 167 @property
165 def inline(self): 168 def inline(self):
166 return u'inline' in self.style 169 return u"inline" in self.style
167 170
168 @property 171 @property
169 def no_select(self): 172 def no_select(self):
170 return u'noselect' in self.style 173 return u"noselect" in self.style
171 174
172 175
173 class EmptyWidget(xmlui_manager.EmptyWidget, Widget): 176 class EmptyWidget(xmlui_manager.EmptyWidget, Widget):
174
175 def __init__(self, _xmlui_parent): 177 def __init__(self, _xmlui_parent):
176 Widget.__init__(self) 178 Widget.__init__(self)
177 179
178 180
179 class TextWidget(xmlui_manager.TextWidget, ValueWidget): 181 class TextWidget(xmlui_manager.TextWidget, ValueWidget):
191 try: 193 try:
192 return self._xmlui_for_name 194 return self._xmlui_for_name
193 except AttributeError: 195 except AttributeError:
194 return None 196 return None
195 197
196 def show(self, no_lf=False, ansi=u''): 198 def show(self, no_lf=False, ansi=u""):
197 """show label 199 """show label
198 200
199 @param no_lf(bool): same as for [JP.disp] 201 @param no_lf(bool): same as for [JP.disp]
200 @param ansi(unicode): ansi escape code to print before label 202 @param ansi(unicode): ansi escape code to print before label
201 """ 203 """
210 self.disp(self.value) 212 self.disp(self.value)
211 else: 213 else:
212 elems = [] 214 elems = []
213 self.verboseName(elems) 215 self.verboseName(elems)
214 if self.value: 216 if self.value:
215 elems.append(_(u'(enter: {default})').format(default=self.value)) 217 elems.append(_(u"(enter: {default})").format(default=self.value))
216 elems.extend([C.A_HEADER, u'> ']) 218 elems.extend([C.A_HEADER, u"> "])
217 value = raw_input(A.color(*elems)) 219 value = raw_input(A.color(*elems))
218 if value: 220 if value:
219 # TODO: empty value should be possible 221 #  TODO: empty value should be possible
220 # an escape key should be used for default instead of enter with empty value 222 # an escape key should be used for default instead of enter with empty value
221 self.value = value 223 self.value = value
222 224
223 225
224
225 class JidInputWidget(xmlui_manager.JidInputWidget, StringWidget): 226 class JidInputWidget(xmlui_manager.JidInputWidget, StringWidget):
226 type = u'jid_input' 227 type = u"jid_input"
227 228
228 229
229 class TextBoxWidget(xmlui_manager.TextWidget, StringWidget): 230 class TextBoxWidget(xmlui_manager.TextWidget, StringWidget):
230 type = u"textbox" 231 type = u"textbox"
231 232
232 233
233 class ListWidget(xmlui_manager.ListWidget, OptionsWidget): 234 class ListWidget(xmlui_manager.ListWidget, OptionsWidget):
234 type = u'list' 235 type = u"list"
235 # TODO: handle flags, notably multi 236 # TODO: handle flags, notably multi
236 237
237 def show(self): 238 def show(self):
238 if self.root.values_only: 239 if self.root.values_only:
239 for value in self.values: 240 for value in self.values:
246 self.verboseName() 247 self.verboseName()
247 248
248 for idx, (value, label) in enumerate(self.options): 249 for idx, (value, label) in enumerate(self.options):
249 elems = [] 250 elems = []
250 if not self.root.read_only: 251 if not self.root.read_only:
251 elems.extend([C.A_SUBHEADER, unicode(idx), A.RESET, u': ']) 252 elems.extend([C.A_SUBHEADER, unicode(idx), A.RESET, u": "])
252 elems.append(label) 253 elems.append(label)
253 self.verboseName(elems, value) 254 self.verboseName(elems, value)
254 self.disp(A.color(*elems)) 255 self.disp(A.color(*elems))
255 256
256 if self.root.read_only: 257 if self.root.read_only:
259 if len(self.options) == 1: 260 if len(self.options) == 1:
260 # we have only one option, no need to ask 261 # we have only one option, no need to ask
261 self.value = self.options[0][0] 262 self.value = self.options[0][0]
262 return 263 return
263 264
264 # we ask use to choose an option 265 #  we ask use to choose an option
265 choice = None 266 choice = None
266 limit_max = len(self.options)-1 267 limit_max = len(self.options) - 1
267 while choice is None or choice<0 or choice>limit_max: 268 while choice is None or choice < 0 or choice > limit_max:
268 choice = raw_input(A.color(C.A_HEADER, _(u'your choice (0-{max}): ').format(max=limit_max))) 269 choice = raw_input(
270 A.color(C.A_HEADER, _(u"your choice (0-{max}): ").format(max=limit_max))
271 )
269 try: 272 try:
270 choice = int(choice) 273 choice = int(choice)
271 except ValueError: 274 except ValueError:
272 choice = None 275 choice = None
273 self.value = self.options[choice][0] 276 self.value = self.options[choice][0]
274 self.disp('') 277 self.disp("")
275 278
276 279
277 class BoolWidget(xmlui_manager.BoolWidget, InputWidget): 280 class BoolWidget(xmlui_manager.BoolWidget, InputWidget):
278 type = u'bool' 281 type = u"bool"
279 282
280 def show(self): 283 def show(self):
281 disp_true = A.color(A.FG_GREEN, u'TRUE') 284 disp_true = A.color(A.FG_GREEN, u"TRUE")
282 disp_false = A.color(A.FG_RED,u'FALSE') 285 disp_false = A.color(A.FG_RED, u"FALSE")
283 if self.read_only: 286 if self.read_only:
284 self.disp(disp_true if self.value else disp_false) 287 self.disp(disp_true if self.value else disp_false)
285 else: 288 else:
286 self.disp(A.color(C.A_HEADER, u'0: ', disp_false)) 289 self.disp(A.color(C.A_HEADER, u"0: ", disp_false))
287 self.disp(A.color(C.A_HEADER, u'1: ', disp_true)) 290 self.disp(A.color(C.A_HEADER, u"1: ", disp_true))
288 choice = None 291 choice = None
289 while choice not in ('0', '1'): 292 while choice not in ("0", "1"):
290 elems = [C.A_HEADER, _(u'your choice (0,1): ')] 293 elems = [C.A_HEADER, _(u"your choice (0,1): ")]
291 self.verboseName(elems) 294 self.verboseName(elems)
292 choice = raw_input(A.color(*elems)) 295 choice = raw_input(A.color(*elems))
293 self.value = bool(int(choice)) 296 self.value = bool(int(choice))
294 self.disp('') 297 self.disp("")
295 298
296 def _xmluiGetValue(self): 299 def _xmluiGetValue(self):
297 return C.boolConst(self.value) 300 return C.boolConst(self.value)
298 301
302
299 ## Containers ## 303 ## Containers ##
300 304
305
301 class Container(Base): 306 class Container(Base):
302 category = u'container' 307 category = u"container"
303 308
304 def __init__(self, xmlui_parent): 309 def __init__(self, xmlui_parent):
305 super(Container, self).__init__(xmlui_parent) 310 super(Container, self).__init__(xmlui_parent)
306 self.children = [] 311 self.children = []
307 312
318 for child in self.children: 323 for child in self.children:
319 child.show() 324 child.show()
320 325
321 326
322 class VerticalContainer(xmlui_manager.VerticalContainer, Container): 327 class VerticalContainer(xmlui_manager.VerticalContainer, Container):
323 type = u'vertical' 328 type = u"vertical"
324 329
325 330
326 class PairsContainer(xmlui_manager.PairsContainer, Container): 331 class PairsContainer(xmlui_manager.PairsContainer, Container):
327 type = u'pairs' 332 type = u"pairs"
328 333
329 334
330 class LabelContainer(xmlui_manager.PairsContainer, Container): 335 class LabelContainer(xmlui_manager.PairsContainer, Container):
331 type = u'label' 336 type = u"label"
332 337
333 def show(self): 338 def show(self):
334 for child in self.children: 339 for child in self.children:
335 no_lf = False 340 no_lf = False
336 # we check linked widget type 341 # we check linked widget type
337 # to see if we want the label on the same line or not 342 # to see if we want the label on the same line or not
338 if child.type == u'label': 343 if child.type == u"label":
339 for_name = child.for_name 344 for_name = child.for_name
340 if for_name is not None: 345 if for_name is not None:
341 for_widget = self.root.widgets[for_name] 346 for_widget = self.root.widgets[for_name]
342 wid_type = for_widget.type 347 wid_type = for_widget.type
343 if self.root.values_only or wid_type in ('text', 'string', 'jid_input'): 348 if self.root.values_only or wid_type in (
349 "text",
350 "string",
351 "jid_input",
352 ):
344 no_lf = True 353 no_lf = True
345 elif wid_type == 'bool' and for_widget.read_only: 354 elif wid_type == "bool" and for_widget.read_only:
346 no_lf = True 355 no_lf = True
347 child.show(no_lf=no_lf, ansi=A.FG_CYAN) 356 child.show(no_lf=no_lf, ansi=A.FG_CYAN)
348 else: 357 else:
349 child.show() 358 child.show()
350 359
360
351 ## Dialogs ## 361 ## Dialogs ##
352 362
353 363
354 class Dialog(object): 364 class Dialog(object):
355
356 def __init__(self, xmlui_parent): 365 def __init__(self, xmlui_parent):
357 self.xmlui_parent = xmlui_parent 366 self.xmlui_parent = xmlui_parent
358 self.host = self.xmlui_parent.host 367 self.host = self.xmlui_parent.host
359 368
360 def disp(self, *args, **kwargs): 369 def disp(self, *args, **kwargs):
367 """ 376 """
368 raise NotImplementedError(self.__class__) 377 raise NotImplementedError(self.__class__)
369 378
370 379
371 class NoteDialog(xmlui_manager.NoteDialog, Dialog): 380 class NoteDialog(xmlui_manager.NoteDialog, Dialog):
372
373 def show(self): 381 def show(self):
374 # TODO: handle title and level 382 # TODO: handle title and level
375 self.disp(self.message) 383 self.disp(self.message)
376 384
377 def __init__(self, _xmlui_parent, title, message, level): 385 def __init__(self, _xmlui_parent, title, message, level):
378 Dialog.__init__(self, _xmlui_parent) 386 Dialog.__init__(self, _xmlui_parent)
379 xmlui_manager.NoteDialog.__init__(self, _xmlui_parent) 387 xmlui_manager.NoteDialog.__init__(self, _xmlui_parent)
380 self.title, self.message, self.level = title, message, level 388 self.title, self.message, self.level = title, message, level
381 389
390
382 ## Factory ## 391 ## Factory ##
383 392
384 393
385 class WidgetFactory(object): 394 class WidgetFactory(object):
386
387 def __getattr__(self, attr): 395 def __getattr__(self, attr):
388 if attr.startswith("create"): 396 if attr.startswith("create"):
389 cls = globals()[attr[6:]] 397 cls = globals()[attr[6:]]
390 return cls 398 return cls
391 399
396 read_only = False 404 read_only = False
397 values_only = False 405 values_only = False
398 workflow = None 406 workflow = None
399 _submit_cb = None 407 _submit_cb = None
400 408
401 def __init__(self, host, parsed_dom, title=None, flags=None, callback=None, ignore=None, whitelist=None, profile=None): 409 def __init__(
402 xmlui_manager.XMLUIPanel.__init__(self, 410 self,
403 host, 411 host,
404 parsed_dom, 412 parsed_dom,
405 title = title, 413 title=None,
406 flags = flags, 414 flags=None,
407 ignore = ignore, 415 callback=None,
408 whitelist = whitelist, 416 ignore=None,
409 profile=host.profile) 417 whitelist=None,
418 profile=None,
419 ):
420 xmlui_manager.XMLUIPanel.__init__(
421 self,
422 host,
423 parsed_dom,
424 title=title,
425 flags=flags,
426 ignore=ignore,
427 whitelist=whitelist,
428 profile=host.profile,
429 )
410 self.submitted = False 430 self.submitted = False
411 431
412 @property 432 @property
413 def command(self): 433 def command(self):
414 return self.host.command 434 return self.host.command
453 self.submit_id = None # avoid double submit 473 self.submit_id = None # avoid double submit
454 return 474 return
455 elif isinstance(cmd, list): 475 elif isinstance(cmd, list):
456 name, value = cmd 476 name, value = cmd
457 widget = self.widgets[name] 477 widget = self.widgets[name]
458 if widget.type == 'bool': 478 if widget.type == "bool":
459 value = C.bool(value) 479 value = C.bool(value)
460 widget.value = value 480 widget.value = value
461 self.show() 481 self.show()
462 482
463 def submitForm(self, callback=None): 483 def submitForm(self, callback=None):
464 XMLUIPanel._submit_cb = callback 484 XMLUIPanel._submit_cb = callback
465 self.onFormSubmitted() 485 self.onFormSubmitted()
466 486
467 def onFormSubmitted(self, ignore=None): 487 def onFormSubmitted(self, ignore=None):
468 # self.submitted is a Q&D workaround to avoid 488 #  self.submitted is a Q&D workaround to avoid
469 # double submit when a workflow is set 489 # double submit when a workflow is set
470 if self.submitted: 490 if self.submitted:
471 return 491 return
472 self.submitted = True 492 self.submitted = True
473 super(XMLUIPanel, self).onFormSubmitted(ignore) 493 super(XMLUIPanel, self).onFormSubmitted(ignore)
476 pass 496 pass
477 497
478 def _launchActionCb(self, data): 498 def _launchActionCb(self, data):
479 XMLUIPanel._actions -= 1 499 XMLUIPanel._actions -= 1
480 assert XMLUIPanel._actions >= 0 500 assert XMLUIPanel._actions >= 0
481 if u'xmlui' in data: 501 if u"xmlui" in data:
482 xmlui_raw = data['xmlui'] 502 xmlui_raw = data["xmlui"]
483 xmlui = xmlui_manager.create(self.host, xmlui_raw) 503 xmlui = xmlui_manager.create(self.host, xmlui_raw)
484 xmlui.show() 504 xmlui.show()
485 if xmlui.submit_id: 505 if xmlui.submit_id:
486 xmlui.onFormSubmitted() 506 xmlui.onFormSubmitted()
487 # TODO: handle data other than XMLUI 507 # TODO: handle data other than XMLUI
496 self.host.bridge.launchAction( 516 self.host.bridge.launchAction(
497 action_id, 517 action_id,
498 data, 518 data,
499 self.profile, 519 self.profile,
500 callback=self._launchActionCb, 520 callback=self._launchActionCb,
501 errback=partial(self.command.errback, 521 errback=partial(
502 msg=_(u"can't launch XMLUI action: {}"), 522 self.command.errback,
503 exit_code=C.EXIT_BRIDGE_ERRBACK)) 523 msg=_(u"can't launch XMLUI action: {}"),
524 exit_code=C.EXIT_BRIDGE_ERRBACK,
525 ),
526 )
504 527
505 528
506 class XMLUIDialog(xmlui_manager.XMLUIDialog): 529 class XMLUIDialog(xmlui_manager.XMLUIDialog):
507 type = 'dialog' 530 type = "dialog"
508 dialog_factory = WidgetFactory() 531 dialog_factory = WidgetFactory()
509 read_only = False 532 read_only = False
510 533
511 def show(self, dummy=None): 534 def show(self, dummy=None):
512 self.dlg.show() 535 self.dlg.show()