comparison sat_frontends/quick_frontend/quick_widgets.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 e3803ae89fbc
children 07aac71ea31f
comparison
equal deleted inserted replaced
3027:ff5bcb12ae60 3028:ab2696e34d29
27 classes_map = {} 27 classes_map = {}
28 28
29 29
30 try: 30 try:
31 # FIXME: to be removed when an acceptable solution is here 31 # FIXME: to be removed when an acceptable solution is here
32 unicode("") # XXX: unicode doesn't exist in pyjamas 32 str("") # XXX: unicode doesn't exist in pyjamas
33 except ( 33 except (
34 TypeError, 34 TypeError,
35 AttributeError, 35 AttributeError,
36 ): # Error raised is not the same depending on pyjsbuild options 36 ): # Error raised is not the same depending on pyjsbuild options
37 unicode = str 37 str = str
38 38
39 39
40 def register(base_cls, child_cls=None): 40 def register(base_cls, child_cls=None):
41 """Register a child class to use by default when a base class is needed 41 """Register a child class to use by default when a base class is needed
42 42
61 self.host = host 61 self.host = host
62 self._widgets = {} 62 self._widgets = {}
63 63
64 def __iter__(self): 64 def __iter__(self):
65 """Iterate throught all widgets""" 65 """Iterate throught all widgets"""
66 for widget_map in self._widgets.itervalues(): 66 for widget_map in self._widgets.values():
67 for widget_instances in widget_map.itervalues(): 67 for widget_instances in widget_map.values():
68 for widget in widget_instances: 68 for widget in widget_instances:
69 yield widget 69 yield widget
70 70
71 def getRealClass(self, class_): 71 def getRealClass(self, class_):
72 """Return class registered for given class_ 72 """Return class registered for given class_
112 widgets_map = self._widgets[class_.__name__] 112 widgets_map = self._widgets[class_.__name__]
113 except KeyError: 113 except KeyError:
114 return 114 return
115 else: 115 else:
116 if target is not None: 116 if target is not None:
117 filter_hash = unicode(class_.getWidgetHash(target, profiles)) 117 filter_hash = str(class_.getWidgetHash(target, profiles))
118 else: 118 else:
119 filter_hash = None 119 filter_hash = None
120 if filter_hash is not None: 120 if filter_hash is not None:
121 for widget in widgets_map.get(filter_hash, []): 121 for widget in widgets_map.get(filter_hash, []):
122 yield widget 122 yield widget
123 else: 123 else:
124 for widget_instances in widgets_map.itervalues(): 124 for widget_instances in widgets_map.values():
125 for widget in widget_instances: 125 for widget in widget_instances:
126 yield widget 126 yield widget
127 127
128 def getWidget(self, class_, target=None, profiles=None): 128 def getWidget(self, class_, target=None, profiles=None):
129 """Get a widget without creating it if it doesn't exist. 129 """Get a widget without creating it if it doesn't exist.
134 @param profiles (unicode, iterable[unicode], None): profile(s) to use (may or may not be 134 @param profiles (unicode, iterable[unicode], None): profile(s) to use (may or may not be
135 used, depending of the widget class) 135 used, depending of the widget class)
136 @return: a class_ instance or None if the widget doesn't exist 136 @return: a class_ instance or None if the widget doesn't exist
137 """ 137 """
138 assert (target is not None) or (profiles is not None) 138 assert (target is not None) or (profiles is not None)
139 if profiles is not None and isinstance(profiles, unicode): 139 if profiles is not None and isinstance(profiles, str):
140 profiles = [profiles] 140 profiles = [profiles]
141 class_ = self.getRealClass(class_) 141 class_ = self.getRealClass(class_)
142 hash_ = class_.getWidgetHash(target, profiles) 142 hash_ = class_.getWidgetHash(target, profiles)
143 try: 143 try:
144 return self._widgets[class_.__name__][hash_][0] 144 return self._widgets[class_.__name__][hash_][0]
221 else: 221 else:
222 widget.addTarget(target) 222 widget.addTarget(target)
223 223
224 if widget is None: 224 if widget is None:
225 # we need to create a new widget 225 # we need to create a new widget
226 log.debug(u"Creating new widget for target {} {}".format(target, cls)) 226 log.debug("Creating new widget for target {} {}".format(target, cls))
227 widget = cls(*_args, **_kwargs) 227 widget = cls(*_args, **_kwargs)
228 widgets_map[hash_] = [widget] 228 widgets_map[hash_] = [widget]
229 229
230 if on_new_widget == C.WIDGET_NEW: 230 if on_new_widget == C.WIDGET_NEW:
231 self.host.newWidget(widget) 231 self.host.newWidget(widget)
246 pass 246 pass
247 else: 247 else:
248 recreateArgs(_args, _kwargs) 248 recreateArgs(_args, _kwargs)
249 widget = cls(*_args, **_kwargs) 249 widget = cls(*_args, **_kwargs)
250 widgets_map[hash_].append(widget) 250 widgets_map[hash_].append(widget)
251 log.debug(u"widget <{wid}> already exists, a new one has been recreated" 251 log.debug("widget <{wid}> already exists, a new one has been recreated"
252 .format(wid=widget)) 252 .format(wid=widget))
253 elif callable(on_existing_widget): 253 elif callable(on_existing_widget):
254 widget = on_existing_widget(widget) 254 widget = on_existing_widget(widget)
255 if widget is None: 255 if widget is None:
256 raise exceptions.InternalError( 256 raise exceptions.InternalError(
257 u"on_existing_widget method must return the widget to use") 257 "on_existing_widget method must return the widget to use")
258 else: 258 else:
259 raise exceptions.InternalError( 259 raise exceptions.InternalError(
260 "Unexpected on_existing_widget value ({})".format(on_existing_widget)) 260 "Unexpected on_existing_widget value ({})".format(on_existing_widget))
261 261
262 return widget 262 return widget
293 293
294 class_ = self.getRealClass(widget_to_delete.__class__) 294 class_ = self.getRealClass(widget_to_delete.__class__)
295 try: 295 try:
296 widgets_map = self._widgets[class_.__name__] 296 widgets_map = self._widgets[class_.__name__]
297 except KeyError: 297 except KeyError:
298 log.error(u"no widgets_map found for class {cls}".format(cls=class_)) 298 log.error("no widgets_map found for class {cls}".format(cls=class_))
299 return 299 return
300 widget_hash = unicode(class_.getWidgetHash(widget_to_delete.target, 300 widget_hash = str(class_.getWidgetHash(widget_to_delete.target,
301 widget_to_delete.profiles)) 301 widget_to_delete.profiles))
302 widget_instances = widgets_map[widget_hash] 302 widget_instances = widgets_map[widget_hash]
303 if all_instances: 303 if all_instances:
304 widget_instances.clear() 304 widget_instances.clear()
305 else: 305 else:
306 try: 306 try:
307 widget_instances.remove(widget_to_delete) 307 widget_instances.remove(widget_to_delete)
308 except ValueError: 308 except ValueError:
309 log.error(u"widget_to_delete not found in widget instances") 309 log.error("widget_to_delete not found in widget instances")
310 return 310 return
311 311
312 log.debug(u"widget {} deleted".format(widget_to_delete)) 312 log.debug("widget {} deleted".format(widget_to_delete))
313 313
314 if not widget_instances: 314 if not widget_instances:
315 # all instances with this hash have been deleted 315 # all instances with this hash have been deleted
316 # we remove the hash itself 316 # we remove the hash itself
317 del widgets_map[widget_hash] 317 del widgets_map[widget_hash]
318 log.debug(u"All instances of {cls} with hash {widget_hash} have been deleted" 318 log.debug("All instances of {cls} with hash {widget_hash} have been deleted"
319 .format(cls=class_, widget_hash=widget_hash)) 319 .format(cls=class_, widget_hash=widget_hash))
320 320
321 321
322 class QuickWidget(object): 322 class QuickWidget(object):
323 """generic widget base""" 323 """generic widget base"""
343 self.host = host 343 self.host = host
344 self.targets = set() 344 self.targets = set()
345 self.addTarget(target) 345 self.addTarget(target)
346 self.profiles = set() 346 self.profiles = set()
347 self._sync = True 347 self._sync = True
348 if isinstance(profiles, basestring): 348 if isinstance(profiles, str):
349 self.addProfile(profiles) 349 self.addProfile(profiles)
350 elif profiles is None: 350 elif profiles is None:
351 if not self.PROFILES_ALLOW_NONE: 351 if not self.PROFILES_ALLOW_NONE:
352 raise ValueError("profiles can't have a value of None") 352 raise ValueError("profiles can't have a value of None")
353 else: 353 else:
428 428
429 @param target: target to check 429 @param target: target to check
430 @param profiles: profile(s) associated to target, see __init__ docstring 430 @param profiles: profile(s) associated to target, see __init__ docstring
431 @return: a hash (can correspond to one or many targets or profiles, depending of widget class) 431 @return: a hash (can correspond to one or many targets or profiles, depending of widget class)
432 """ 432 """
433 return unicode(target) # by defaut, there is one hash for one target 433 return str(target) # by defaut, there is one hash for one target
434 434
435 # widget life events 435 # widget life events
436 436
437 def onDelete(self, *args, **kwargs): 437 def onDelete(self, *args, **kwargs):
438 """Called when a widget is being deleted 438 """Called when a widget is being deleted