Mercurial > libervia-backend
comparison sat_frontends/jp/xmlui_manager.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 | 620bbcec884c |
children | fee60f17ebac |
comparison
equal
deleted
inserted
replaced
3027:ff5bcb12ae60 | 3028:ab2696e34d29 |
---|---|
58 def disp(self, *args, **kwargs): | 58 def disp(self, *args, **kwargs): |
59 self.host.disp(*args, **kwargs) | 59 self.host.disp(*args, **kwargs) |
60 | 60 |
61 | 61 |
62 class Widget(Base): | 62 class Widget(Base): |
63 category = u"widget" | 63 category = "widget" |
64 enabled = True | 64 enabled = True |
65 | 65 |
66 @property | 66 @property |
67 def name(self): | 67 def name(self): |
68 return self._xmlui_name | 68 return self._xmlui_name |
87 if value is None: | 87 if value is None: |
88 value = self.name | 88 value = self.name |
89 if self.host.verbosity: | 89 if self.host.verbosity: |
90 to_disp = [ | 90 to_disp = [ |
91 A.FG_MAGENTA, | 91 A.FG_MAGENTA, |
92 u" " if elems else u"", | 92 " " if elems else "", |
93 u"({})".format(value), | 93 "({})".format(value), |
94 A.RESET, | 94 A.RESET, |
95 ] | 95 ] |
96 if elems is None: | 96 if elems is None: |
97 self.host.disp(A.color(*to_disp)) | 97 self.host.disp(A.color(*to_disp)) |
98 else: | 98 else: |
164 if no_select or value in self.selected: | 164 if no_select or value in self.selected: |
165 yield value, label | 165 yield value, label |
166 | 166 |
167 @property | 167 @property |
168 def inline(self): | 168 def inline(self): |
169 return u"inline" in self.style | 169 return "inline" in self.style |
170 | 170 |
171 @property | 171 @property |
172 def no_select(self): | 172 def no_select(self): |
173 return u"noselect" in self.style | 173 return "noselect" in self.style |
174 | 174 |
175 | 175 |
176 class EmptyWidget(xmlui_base.EmptyWidget, Widget): | 176 class EmptyWidget(xmlui_base.EmptyWidget, Widget): |
177 | 177 |
178 def __init__(self, xmlui_parent): | 178 def __init__(self, xmlui_parent): |
179 Widget.__init__(self, xmlui_parent) | 179 Widget.__init__(self, xmlui_parent) |
180 | 180 |
181 def show(self): | 181 def show(self): |
182 self.host.disp(u'') | 182 self.host.disp('') |
183 | 183 |
184 | 184 |
185 class TextWidget(xmlui_base.TextWidget, ValueWidget): | 185 class TextWidget(xmlui_base.TextWidget, ValueWidget): |
186 type = u"text" | 186 type = "text" |
187 | 187 |
188 def show(self): | 188 def show(self): |
189 self.host.disp(self.value) | 189 self.host.disp(self.value) |
190 | 190 |
191 | 191 |
192 class LabelWidget(xmlui_base.LabelWidget, ValueWidget): | 192 class LabelWidget(xmlui_base.LabelWidget, ValueWidget): |
193 type = u"label" | 193 type = "label" |
194 | 194 |
195 @property | 195 @property |
196 def for_name(self): | 196 def for_name(self): |
197 try: | 197 try: |
198 return self._xmlui_for_name | 198 return self._xmlui_for_name |
199 except AttributeError: | 199 except AttributeError: |
200 return None | 200 return None |
201 | 201 |
202 def show(self, no_lf=False, ansi=u""): | 202 def show(self, no_lf=False, ansi=""): |
203 """show label | 203 """show label |
204 | 204 |
205 @param no_lf(bool): same as for [JP.disp] | 205 @param no_lf(bool): same as for [JP.disp] |
206 @param ansi(unicode): ansi escape code to print before label | 206 @param ansi(unicode): ansi escape code to print before label |
207 """ | 207 """ |
208 self.disp(A.color(ansi, self.value), no_lf=no_lf) | 208 self.disp(A.color(ansi, self.value), no_lf=no_lf) |
209 | 209 |
210 | 210 |
211 class JidWidget(xmlui_base.JidWidget, TextWidget): | 211 class JidWidget(xmlui_base.JidWidget, TextWidget): |
212 type = u"jid" | 212 type = "jid" |
213 | 213 |
214 class StringWidget(xmlui_base.StringWidget, InputWidget): | 214 class StringWidget(xmlui_base.StringWidget, InputWidget): |
215 type = u"string" | 215 type = "string" |
216 | 216 |
217 def show(self): | 217 def show(self): |
218 if self.read_only or self.root.read_only: | 218 if self.read_only or self.root.read_only: |
219 self.disp(self.value) | 219 self.disp(self.value) |
220 else: | 220 else: |
221 elems = [] | 221 elems = [] |
222 self.verboseName(elems) | 222 self.verboseName(elems) |
223 if self.value: | 223 if self.value: |
224 elems.append(_(u"(enter: {default})").format(default=self.value)) | 224 elems.append(_("(enter: {default})").format(default=self.value)) |
225 elems.extend([C.A_HEADER, u"> "]) | 225 elems.extend([C.A_HEADER, "> "]) |
226 value = raw_input(A.color(*elems).encode('utf-8')) | 226 value = input(A.color(*elems).encode('utf-8')) |
227 if value: | 227 if value: |
228 # TODO: empty value should be possible | 228 # TODO: empty value should be possible |
229 # an escape key should be used for default instead of enter with empty value | 229 # an escape key should be used for default instead of enter with empty value |
230 self.value = value | 230 self.value = value |
231 | 231 |
232 | 232 |
233 class JidInputWidget(xmlui_base.JidInputWidget, StringWidget): | 233 class JidInputWidget(xmlui_base.JidInputWidget, StringWidget): |
234 type = u"jid_input" | 234 type = "jid_input" |
235 | 235 |
236 | 236 |
237 class TextBoxWidget(xmlui_base.TextWidget, StringWidget): | 237 class TextBoxWidget(xmlui_base.TextWidget, StringWidget): |
238 type = u"textbox" | 238 type = "textbox" |
239 # TODO: use a more advanced input method | 239 # TODO: use a more advanced input method |
240 | 240 |
241 def show(self): | 241 def show(self): |
242 self.verboseName() | 242 self.verboseName() |
243 if self.read_only or self.root.read_only: | 243 if self.read_only or self.root.read_only: |
244 self.disp(self.value) | 244 self.disp(self.value) |
245 else: | 245 else: |
246 if self.value: | 246 if self.value: |
247 self.disp(A.color(C.A_HEADER, u"↓ current value ↓\n", A.FG_CYAN, self.value, | 247 self.disp(A.color(C.A_HEADER, "↓ current value ↓\n", A.FG_CYAN, self.value, |
248 "")) | 248 "")) |
249 | 249 |
250 values = [] | 250 values = [] |
251 while True: | 251 while True: |
252 try: | 252 try: |
253 if not values: | 253 if not values: |
254 line = raw_input(A.color(C.A_HEADER, u"[Ctrl-D to finish]> ")) | 254 line = input(A.color(C.A_HEADER, "[Ctrl-D to finish]> ")) |
255 else: | 255 else: |
256 line = raw_input() | 256 line = input() |
257 values.append(line) | 257 values.append(line) |
258 except EOFError: | 258 except EOFError: |
259 break | 259 break |
260 | 260 |
261 self.value = u'\n'.join(values).rstrip() | 261 self.value = '\n'.join(values).rstrip() |
262 | 262 |
263 | 263 |
264 class XHTMLBoxWidget(xmlui_base.XHTMLBoxWidget, StringWidget): | 264 class XHTMLBoxWidget(xmlui_base.XHTMLBoxWidget, StringWidget): |
265 type = u"xhtmlbox" | 265 type = "xhtmlbox" |
266 | 266 |
267 def show(self): | 267 def show(self): |
268 # FIXME: we use bridge in a blocking way as permitted by python-dbus | 268 # FIXME: we use bridge in a blocking way as permitted by python-dbus |
269 # this only for now to make it simpler, it must be refactored | 269 # this only for now to make it simpler, it must be refactored |
270 # to use async when jp will be fully async (expected for 0.8) | 270 # to use async when jp will be fully async (expected for 0.8) |
272 self.value, C.SYNTAX_XHTML, "markdown", False, self.host.profile) | 272 self.value, C.SYNTAX_XHTML, "markdown", False, self.host.profile) |
273 super(XHTMLBoxWidget, self).show() | 273 super(XHTMLBoxWidget, self).show() |
274 | 274 |
275 | 275 |
276 class ListWidget(xmlui_base.ListWidget, OptionsWidget): | 276 class ListWidget(xmlui_base.ListWidget, OptionsWidget): |
277 type = u"list" | 277 type = "list" |
278 # TODO: handle flags, notably multi | 278 # TODO: handle flags, notably multi |
279 | 279 |
280 def show(self): | 280 def show(self): |
281 if self.root.values_only: | 281 if self.root.values_only: |
282 for value in self.values: | 282 for value in self.values: |
289 self.verboseName() | 289 self.verboseName() |
290 | 290 |
291 for idx, (value, label) in enumerate(self.options): | 291 for idx, (value, label) in enumerate(self.options): |
292 elems = [] | 292 elems = [] |
293 if not self.root.read_only: | 293 if not self.root.read_only: |
294 elems.extend([C.A_SUBHEADER, unicode(idx), A.RESET, u": "]) | 294 elems.extend([C.A_SUBHEADER, str(idx), A.RESET, ": "]) |
295 elems.append(label) | 295 elems.append(label) |
296 self.verboseName(elems, value) | 296 self.verboseName(elems, value) |
297 self.disp(A.color(*elems)) | 297 self.disp(A.color(*elems)) |
298 | 298 |
299 if self.root.read_only: | 299 if self.root.read_only: |
306 | 306 |
307 # we ask use to choose an option | 307 # we ask use to choose an option |
308 choice = None | 308 choice = None |
309 limit_max = len(self.options) - 1 | 309 limit_max = len(self.options) - 1 |
310 while choice is None or choice < 0 or choice > limit_max: | 310 while choice is None or choice < 0 or choice > limit_max: |
311 choice = raw_input( | 311 choice = input( |
312 A.color(C.A_HEADER, _(u"your choice (0-{max}): ").format(max=limit_max)) | 312 A.color(C.A_HEADER, _("your choice (0-{max}): ").format(max=limit_max)) |
313 ) | 313 ) |
314 try: | 314 try: |
315 choice = int(choice) | 315 choice = int(choice) |
316 except ValueError: | 316 except ValueError: |
317 choice = None | 317 choice = None |
318 self.value = self.options[choice][0] | 318 self.value = self.options[choice][0] |
319 self.disp("") | 319 self.disp("") |
320 | 320 |
321 | 321 |
322 class BoolWidget(xmlui_base.BoolWidget, InputWidget): | 322 class BoolWidget(xmlui_base.BoolWidget, InputWidget): |
323 type = u"bool" | 323 type = "bool" |
324 | 324 |
325 def show(self): | 325 def show(self): |
326 disp_true = A.color(A.FG_GREEN, u"TRUE") | 326 disp_true = A.color(A.FG_GREEN, "TRUE") |
327 disp_false = A.color(A.FG_RED, u"FALSE") | 327 disp_false = A.color(A.FG_RED, "FALSE") |
328 if self.read_only or self.root.read_only: | 328 if self.read_only or self.root.read_only: |
329 self.disp(disp_true if self.value else disp_false) | 329 self.disp(disp_true if self.value else disp_false) |
330 else: | 330 else: |
331 self.disp(A.color(C.A_HEADER, u"0: ", | 331 self.disp(A.color(C.A_HEADER, "0: ", |
332 disp_false, A.RESET, | 332 disp_false, A.RESET, |
333 u" *" if not self.value else u"")) | 333 " *" if not self.value else "")) |
334 self.disp(A.color(C.A_HEADER, u"1: ", | 334 self.disp(A.color(C.A_HEADER, "1: ", |
335 disp_true, A.RESET, | 335 disp_true, A.RESET, |
336 u" *" if self.value else u"")) | 336 " *" if self.value else "")) |
337 choice = None | 337 choice = None |
338 while choice not in ("0", "1"): | 338 while choice not in ("0", "1"): |
339 elems = [C.A_HEADER, _(u"your choice (0,1): ")] | 339 elems = [C.A_HEADER, _("your choice (0,1): ")] |
340 self.verboseName(elems) | 340 self.verboseName(elems) |
341 choice = raw_input(A.color(*elems)) | 341 choice = input(A.color(*elems)) |
342 self.value = bool(int(choice)) | 342 self.value = bool(int(choice)) |
343 self.disp("") | 343 self.disp("") |
344 | 344 |
345 def _xmluiGetValue(self): | 345 def _xmluiGetValue(self): |
346 return C.boolConst(self.value) | 346 return C.boolConst(self.value) |
348 | 348 |
349 ## Containers ## | 349 ## Containers ## |
350 | 350 |
351 | 351 |
352 class Container(Base): | 352 class Container(Base): |
353 category = u"container" | 353 category = "container" |
354 | 354 |
355 def __init__(self, xmlui_parent): | 355 def __init__(self, xmlui_parent): |
356 super(Container, self).__init__(xmlui_parent) | 356 super(Container, self).__init__(xmlui_parent) |
357 self.children = [] | 357 self.children = [] |
358 | 358 |
369 for child in self.children: | 369 for child in self.children: |
370 child.show() | 370 child.show() |
371 | 371 |
372 | 372 |
373 class VerticalContainer(xmlui_base.VerticalContainer, Container): | 373 class VerticalContainer(xmlui_base.VerticalContainer, Container): |
374 type = u"vertical" | 374 type = "vertical" |
375 | 375 |
376 | 376 |
377 class PairsContainer(xmlui_base.PairsContainer, Container): | 377 class PairsContainer(xmlui_base.PairsContainer, Container): |
378 type = u"pairs" | 378 type = "pairs" |
379 | 379 |
380 | 380 |
381 class LabelContainer(xmlui_base.PairsContainer, Container): | 381 class LabelContainer(xmlui_base.PairsContainer, Container): |
382 type = u"label" | 382 type = "label" |
383 | 383 |
384 def show(self): | 384 def show(self): |
385 for child in self.children: | 385 for child in self.children: |
386 no_lf = False | 386 no_lf = False |
387 # we check linked widget type | 387 # we check linked widget type |
388 # to see if we want the label on the same line or not | 388 # to see if we want the label on the same line or not |
389 if child.type == u"label": | 389 if child.type == "label": |
390 for_name = child.for_name | 390 for_name = child.for_name |
391 if for_name: | 391 if for_name: |
392 for_widget = self.root.widgets[for_name] | 392 for_widget = self.root.widgets[for_name] |
393 wid_type = for_widget.type | 393 wid_type = for_widget.type |
394 if self.root.values_only or wid_type in ( | 394 if self.root.values_only or wid_type in ( |
533 pass | 533 pass |
534 | 534 |
535 def _launchActionCb(self, data): | 535 def _launchActionCb(self, data): |
536 XMLUIPanel._actions -= 1 | 536 XMLUIPanel._actions -= 1 |
537 assert XMLUIPanel._actions >= 0 | 537 assert XMLUIPanel._actions >= 0 |
538 if u"xmlui" in data: | 538 if "xmlui" in data: |
539 xmlui_raw = data["xmlui"] | 539 xmlui_raw = data["xmlui"] |
540 xmlui = create(self.host, xmlui_raw) | 540 xmlui = create(self.host, xmlui_raw) |
541 xmlui.show() | 541 xmlui.show() |
542 if xmlui.submit_id: | 542 if xmlui.submit_id: |
543 xmlui.onFormSubmitted() | 543 xmlui.onFormSubmitted() |
555 data, | 555 data, |
556 self.profile, | 556 self.profile, |
557 callback=self._launchActionCb, | 557 callback=self._launchActionCb, |
558 errback=partial( | 558 errback=partial( |
559 self.command.errback, | 559 self.command.errback, |
560 msg=_(u"can't launch XMLUI action: {}"), | 560 msg=_("can't launch XMLUI action: {}"), |
561 exit_code=C.EXIT_BRIDGE_ERRBACK, | 561 exit_code=C.EXIT_BRIDGE_ERRBACK, |
562 ), | 562 ), |
563 ) | 563 ) |
564 | 564 |
565 | 565 |