core, frontends: refactoring to base Libervia on QuickFrontend (big mixed commit):

/!\ not finished, everything is still instable !
    - bridge: DBus bridge has been modified to allow blocking call to be called in the same way as asynchronous calls
    - bridge: calls with a callback and no errback are now possible, default errback log the error
    - constants: removed hack to manage presence without OrderedDict, as an OrderedDict like class has been implemented in Libervia
    - core: getLastResource has been removed and replaced by getMainResource (there is a global better management of resources)
    - various style improvments: use of constants when possible, fixed variable overlaps, import of module instead of direct class import
    - frontends: printInfo and printMessage methods in (Quick)Chat are more generic (use of extra instead of timestamp)
    - frontends: bridge creation and option parsing (command line arguments) are now specified by the frontend in QuickApp __init__
    - frontends: ProfileManager manage a more complete plug sequence (some stuff formerly manage in contact_list have moved to ProfileManager)
    - quick_frontend (quick_widgets): QuickWidgetsManager is now iterable (all widgets are then returned), or can return an iterator on a specific class (return all widgets of this class) with getWidgets
    - frontends: tools.jid can now be used in Pyjamas, with some care
    - frontends (XMLUI): profile is now managed
    - core (memory): big improvment on entities cache management (and specially resource management)
    - core (params/exceptions): added PermissionError
    - various fixes and improvments, check diff for more details
This commit is contained in:
Goffi 2015-01-24 01:00:29 +01:00
commit 8ce5c1862b

View file

@ -25,6 +25,13 @@ from sat.core import exceptions
classes_map = {}
try:
# FIXME: to be removed when an acceptable solution is here
unicode('') # XXX: unicode doesn't exist in pyjamas
except (TypeError, AttributeError): # Error raised is not the same depending on pyjsbuild options
unicode = str
def register(base_cls, child_cls=None):
"""Register a child class to use by default when a base class is needed
@ -43,6 +50,40 @@ class QuickWidgetsManager(object):
self.host = host
self._widgets = {}
def __iter__(self):
"""Iterate throught all widgets"""
for widget_map in self._widgets.itervalues():
for widget in widget_map.itervalues():
yield widget
def getRealClass(self, class_):
"""Return class registered for given class_
@param class_: subclass of QuickWidget
@return: class actually used to create widget
"""
try:
cls = classes_map[class_]
except KeyError:
cls = class_
if cls is None:
raise exceptions.InternalError("There is not class registered for {}".format(class_))
return cls
def getWidgets(self, class_):
"""Get all subclassed widgets
@param class_: subclass of QuickWidget, same parameter as used in [getOrCreateWidget]
@return: iterator on widgets
"""
class_ = self.getRealClass(class_)
try:
widgets_map = self._widgets[class_]
except KeyError:
return iter([])
else:
return widgets_map.itervalues()
def getOrCreateWidget(self, class_, target, *args, **kwargs):
"""Get an existing widget or create a new one when necessary
@ -60,13 +101,7 @@ class QuickWidgetsManager(object):
if 'force_hash' is present, the hash given in value will be used instead of the one returned by class_.getWidgetHash
@return: a class_ instance, either new or already existing
"""
# class management
try:
cls = classes_map[class_]
except KeyError:
cls = class_
if cls is None:
raise exceptions.InternalError("There is not class registered for {}".format(class_))
cls = self.getRealClass(class_)
# arguments management
_args = [self.host, target] + list(args) or [] # FIXME: check if it's really necessary to use optional args
@ -86,12 +121,12 @@ class QuickWidgetsManager(object):
hash_ = cls.getWidgetHash(target, _kwargs['profiles'])
# widget creation or retrieval
widgets_list = self._widgets.setdefault(cls, {}) # we sorts widgets by classes
widgets_map = self._widgets.setdefault(cls, {}) # we sorts widgets by classes
if not cls.SINGLE:
widget = None # if the class is not SINGLE, we always create a new widget
else:
try:
widget = widgets_list[hash_]
widget = widgets_map[hash_]
widget.addTarget(target)
except KeyError:
widget = None
@ -106,7 +141,7 @@ class QuickWidgetsManager(object):
log.debug(u"Creating new widget for target {} {}".format(target, cls))
widget = cls(*_args, **_kwargs)
widgets_list[hash_] = widget
widgets_map[hash_] = widget
if on_new_widget == 'NEW_WIDGET':
self.host.newWidget(widget)