comparison sat_frontends/quick_frontend/quick_widgets.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 003b8b4b56a7
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.core import exceptions 23 from sat.core import exceptions
23 from sat_frontends.quick_frontend.constants import Const as C 24 from sat_frontends.quick_frontend.constants import Const as C
24 25
25 26
26 NEW_INSTANCE_SUFF = '_new_instance_' 27 NEW_INSTANCE_SUFF = "_new_instance_"
27 classes_map = {} 28 classes_map = {}
28 29
29 30
30 try: 31 try:
31 # FIXME: to be removed when an acceptable solution is here 32 # FIXME: to be removed when an acceptable solution is here
32 unicode('') # XXX: unicode doesn't exist in pyjamas 33 unicode("") # XXX: unicode doesn't exist in pyjamas
33 except (TypeError, AttributeError): # Error raised is not the same depending on pyjsbuild options 34 except (
35 TypeError,
36 AttributeError,
37 ): # Error raised is not the same depending on pyjsbuild options
34 unicode = str 38 unicode = str
35 39
36 40
37 def register(base_cls, child_cls=None): 41 def register(base_cls, child_cls=None):
38 """Register a child class to use by default when a base class is needed 42 """Register a child class to use by default when a base class is needed
75 # in the second case 79 # in the second case
76 cls = classes_map[class_.__name__] 80 cls = classes_map[class_.__name__]
77 except KeyError: 81 except KeyError:
78 cls = class_ 82 cls = class_
79 if cls is None: 83 if cls is None:
80 raise exceptions.InternalError("There is not class registered for {}".format(class_)) 84 raise exceptions.InternalError(
85 "There is not class registered for {}".format(class_)
86 )
81 return cls 87 return cls
82 88
83 def getRootHash(self, hash_): 89 def getRootHash(self, hash_):
84 """Return root hash (i.e. hash without new instance suffix for recreated widgets 90 """Return root hash (i.e. hash without new instance suffix for recreated widgets
85 91
107 filter_hash = unicode(class_.getWidgetHash(target, profiles)) 113 filter_hash = unicode(class_.getWidgetHash(target, profiles))
108 else: 114 else:
109 filter_hash = None 115 filter_hash = None
110 for w_hash, w in widgets_map.iteritems(): 116 for w_hash, w in widgets_map.iteritems():
111 if profiles is None or w.profiles.intersection(profiles): 117 if profiles is None or w.profiles.intersection(profiles):
112 if filter_hash is not None and self.getRootHash(w_hash) != filter_hash: 118 if (
119 filter_hash is not None
120 and self.getRootHash(w_hash) != filter_hash
121 ):
113 continue 122 continue
114 yield w 123 yield w
115 124
116 def getWidget(self, class_, target=None, profiles=None): 125 def getWidget(self, class_, target=None, profiles=None):
117 """Get a widget without creating it if it doesn't exist. 126 """Get a widget without creating it if it doesn't exist.
159 @return: a class_ instance, either new or already existing 168 @return: a class_ instance, either new or already existing
160 """ 169 """
161 cls = self.getRealClass(class_) 170 cls = self.getRealClass(class_)
162 171
163 ## arguments management ## 172 ## arguments management ##
164 _args = [self.host, target] + list(args) or [] # FIXME: check if it's really necessary to use optional args 173 _args = [self.host, target] + list(
174 args
175 ) or [] # FIXME: check if it's really necessary to use optional args
165 _kwargs = kwargs or {} 176 _kwargs = kwargs or {}
166 if 'profiles' in _kwargs and 'profile' in _kwargs: 177 if "profiles" in _kwargs and "profile" in _kwargs:
167 raise ValueError("You can't have 'profile' and 'profiles' keys at the same time") 178 raise ValueError(
168 try: 179 "You can't have 'profile' and 'profiles' keys at the same time"
169 _kwargs['profiles'] = [_kwargs.pop('profile')] 180 )
170 except KeyError: 181 try:
171 if not 'profiles' in _kwargs: 182 _kwargs["profiles"] = [_kwargs.pop("profile")]
172 _kwargs['profiles'] = None 183 except KeyError:
173 184 if not "profiles" in _kwargs:
174 #on_new_widget tell what to do for the new widget creation 185 _kwargs["profiles"] = None
175 try: 186
176 on_new_widget = _kwargs.pop('on_new_widget') 187 # on_new_widget tell what to do for the new widget creation
188 try:
189 on_new_widget = _kwargs.pop("on_new_widget")
177 except KeyError: 190 except KeyError:
178 on_new_widget = C.WIDGET_NEW 191 on_new_widget = C.WIDGET_NEW
179 192
180 #on_existing_widget tell what to do when the widget already exists 193 # on_existing_widget tell what to do when the widget already exists
181 try: 194 try:
182 on_existing_widget = _kwargs.pop('on_existing_widget') 195 on_existing_widget = _kwargs.pop("on_existing_widget")
183 except KeyError: 196 except KeyError:
184 on_existing_widget = C.WIDGET_KEEP 197 on_existing_widget = C.WIDGET_KEEP
185 198
186 ## we get the hash ## 199 ## we get the hash ##
187 try: 200 try:
188 hash_ = _kwargs.pop('force_hash') 201 hash_ = _kwargs.pop("force_hash")
189 except KeyError: 202 except KeyError:
190 hash_ = cls.getWidgetHash(target, _kwargs['profiles']) 203 hash_ = cls.getWidgetHash(target, _kwargs["profiles"])
191 204
192 ## widget creation or retrieval ## 205 ## widget creation or retrieval ##
193 206
194 widgets_map = self._widgets.setdefault(cls.__name__, {}) # we sorts widgets by classes 207 widgets_map = self._widgets.setdefault(
208 cls.__name__, {}
209 ) # we sorts widgets by classes
195 if not cls.SINGLE: 210 if not cls.SINGLE:
196 widget = None # if the class is not SINGLE, we always create a new widget 211 widget = None # if the class is not SINGLE, we always create a new widget
197 else: 212 else:
198 try: 213 try:
199 widget = widgets_map[hash_] 214 widget = widgets_map[hash_]
200 widget.addTarget(target) 215 widget.addTarget(target)
201 except KeyError: 216 except KeyError:
223 # we use getOrCreateWidget to recreate the new widget 238 # we use getOrCreateWidget to recreate the new widget
224 # /!\ we use args and kwargs and not _args and _kwargs because we need the original args 239 # /!\ we use args and kwargs and not _args and _kwargs because we need the original args
225 # we need to get rid of kwargs special options 240 # we need to get rid of kwargs special options
226 new_kwargs = kwargs.copy() 241 new_kwargs = kwargs.copy()
227 try: 242 try:
228 new_kwargs.pop('force_hash') # FIXME: we use pop instead of del here because pyjamas doesn't raise error on del 243 new_kwargs.pop(
244 "force_hash"
245 ) # FIXME: we use pop instead of del here because pyjamas doesn't raise error on del
229 except KeyError: 246 except KeyError:
230 pass 247 pass
231 else: 248 else:
232 raise ValueError("force_hash option can't be used with on_existing_widget=RECREATE") 249 raise ValueError(
233 250 "force_hash option can't be used with on_existing_widget=RECREATE"
234 new_kwargs['on_new_widget'] = on_new_widget 251 )
252
253 new_kwargs["on_new_widget"] = on_new_widget
235 254
236 # XXX: keep up-to-date if new special kwargs are added (i.e.: delete these keys here) 255 # XXX: keep up-to-date if new special kwargs are added (i.e.: delete these keys here)
237 new_kwargs['on_existing_widget'] = C.WIDGET_RAISE 256 new_kwargs["on_existing_widget"] = C.WIDGET_RAISE
238 try: 257 try:
239 recreateArgs = widget.recreateArgs 258 recreateArgs = widget.recreateArgs
240 except AttributeError: 259 except AttributeError:
241 pass 260 pass
242 else: 261 else:
243 recreateArgs(args, new_kwargs) 262 recreateArgs(args, new_kwargs)
244 hash_idx = 1 263 hash_idx = 1
245 while True: 264 while True:
246 new_kwargs['force_hash'] = "{}{}{}".format(hash_, NEW_INSTANCE_SUFF, hash_idx) 265 new_kwargs["force_hash"] = "{}{}{}".format(
266 hash_, NEW_INSTANCE_SUFF, hash_idx
267 )
247 try: 268 try:
248 widget = self.getOrCreateWidget(class_, target, *args, **new_kwargs) 269 widget = self.getOrCreateWidget(
270 class_, target, *args, **new_kwargs
271 )
249 except WidgetAlreadyExistsError: 272 except WidgetAlreadyExistsError:
250 hash_idx += 1 273 hash_idx += 1
251 else: 274 else:
252 log.debug(u"Widget already exists, a new one has been recreated with hash {}".format(new_kwargs['force_hash'])) 275 log.debug(
276 u"Widget already exists, a new one has been recreated with hash {}".format(
277 new_kwargs["force_hash"]
278 )
279 )
253 break 280 break
254 elif callable(on_existing_widget): 281 elif callable(on_existing_widget):
255 on_existing_widget(widget) 282 on_existing_widget(widget)
256 else: 283 else:
257 raise exceptions.InternalError("Unexpected on_existing_widget value ({})".format(on_existing_widget)) 284 raise exceptions.InternalError(
285 "Unexpected on_existing_widget value ({})".format(on_existing_widget)
286 )
258 287
259 return widget 288 return widget
260 289
261 def deleteWidget(self, widget_to_delete, *args, **kwargs): 290 def deleteWidget(self, widget_to_delete, *args, **kwargs):
262 """Delete a widget 291 """Delete a widget
284 del widget_map[hash_] 313 del widget_map[hash_]
285 314
286 315
287 class QuickWidget(object): 316 class QuickWidget(object):
288 """generic widget base""" 317 """generic widget base"""
289 SINGLE=True # if True, there can be only one widget per target(s) 318
290 PROFILES_MULTIPLE=False # If True, this widget can handle several profiles at once 319 SINGLE = True # if True, there can be only one widget per target(s)
291 PROFILES_ALLOW_NONE=False # If True, this widget can be used without profile 320 PROFILES_MULTIPLE = False # If True, this widget can handle several profiles at once
321 PROFILES_ALLOW_NONE = False # If True, this widget can be used without profile
292 322
293 def __init__(self, host, target, profiles=None): 323 def __init__(self, host, target, profiles=None):
294 """ 324 """
295 @param host: %(doc_host)s 325 @param host: %(doc_host)s
296 @param target: target specific for this widget class 326 @param target: target specific for this widget class
315 if not self.profiles: 345 if not self.profiles:
316 raise ValueError("no profile found, use None for no profile classes") 346 raise ValueError("no profile found, use None for no profile classes")
317 347
318 @property 348 @property
319 def profile(self): 349 def profile(self):
320 assert len(self.profiles) == 1 and not self.PROFILES_MULTIPLE and not self.PROFILES_ALLOW_NONE 350 assert (
351 len(self.profiles) == 1
352 and not self.PROFILES_MULTIPLE
353 and not self.PROFILES_ALLOW_NONE
354 )
321 return list(self.profiles)[0] 355 return list(self.profiles)[0]
322 356
323 def addTarget(self, target): 357 def addTarget(self, target):
324 """Add a target if it doesn't already exists 358 """Add a target if it doesn't already exists
325 359
348 382
349 @param target: target to check 383 @param target: target to check
350 @param profiles: profile(s) associated to target, see __init__ docstring 384 @param profiles: profile(s) associated to target, see __init__ docstring
351 @return: a hash (can correspond to one or many targets or profiles, depending of widget class) 385 @return: a hash (can correspond to one or many targets or profiles, depending of widget class)
352 """ 386 """
353 return unicode(target) # by defaut, there is one hash for one target 387 return unicode(target) # by defaut, there is one hash for one target
354 388
355 def onDelete(self, *args, **kwargs): 389 def onDelete(self, *args, **kwargs):
356 """Called when a widget is being deleted 390 """Called when a widget is being deleted
357 391
358 @return (boot, None): False to cancel deletion 392 @return (boot, None): False to cancel deletion
359 all other value continue deletion 393 all other value continue deletion
360 """ 394 """
361 log.debug(u"widget {} deleted".format(self)) 395 log.debug(u"widget {} deleted".format(self))
362 return True 396 return True
363