From b1ab06ba6ae357abb1ecb7a3e45744bb3a2ce90c Mon Sep 17 00:00:00 2001 From: souliane Date: Fri, 6 Feb 2015 22:28:00 +0100 Subject: [PATCH 1/3] quick_frontend: fixes hash setting for QuickWidget --- frontends/src/quick_frontend/quick_widgets.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontends/src/quick_frontend/quick_widgets.py b/frontends/src/quick_frontend/quick_widgets.py index 5cc9b9e9..72f42175 100644 --- a/frontends/src/quick_frontend/quick_widgets.py +++ b/frontends/src/quick_frontend/quick_widgets.py @@ -195,7 +195,7 @@ class QuickWidgetsManager(object): new_kwargs['on_existing_widget'] = C.WIDGET_RAISE hash_idx = 1 while True: - new_kwargs['force_hash'] = hash_ + "_new_instance_{}".format(hash_idx) + new_kwargs['force_hash'] = "{}_new_instance_{}".format(hash_, hash_idx) try: widget = self.getOrCreateWidget(class_, target, *args, **new_kwargs) except WidgetAlreadyExistsError: From 5b0a210faba561319423969d0a2e9c6a7a5ae633 Mon Sep 17 00:00:00 2001 From: souliane Date: Sat, 7 Feb 2015 14:47:23 +0100 Subject: [PATCH 2/3] frontends (tools): Pyjamas's JID implementation can be compared to an object of a different type: - always return False if the other object is not a JID - to not fake list membership's test, hash(jid) now differs from hash(unicode(jid)) --- frontends/src/tools/jid.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/frontends/src/tools/jid.py b/frontends/src/tools/jid.py index 40facee7..c7b4cd86 100644 --- a/frontends/src/tools/jid.py +++ b/frontends/src/tools/jid.py @@ -58,12 +58,14 @@ except (TypeError, AttributeError): # Error raised is not the same depending on return getattr(self.__internal_str, name) def __eq__(self, other): + if not isinstance(other, JID): + return False return (self.node == other.node and self.domain == other.domain and self.resource == other.resource) def __hash__(self): - return hash(self.__internal_str) + return hash('JID<{}>'.format(self.__internal_str)) def find(self, *args): return self.__internal_str.find(*args) @@ -75,7 +77,7 @@ except (TypeError, AttributeError): # Error raised is not the same depending on node_end = 0 domain_end = self.__internal_str.find('/') if domain_end == 0: - raise ValueError("a jid can't start with '/'") + raise ValueError("a jid can't start with '/'") if domain_end == -1: domain_end = len(self.__internal_str) self.node = self.__internal_str[:node_end] or None From 902616219a1fcdee566ac23f3c7137f339ecd6eb Mon Sep 17 00:00:00 2001 From: souliane Date: Mon, 9 Feb 2015 09:19:30 +0100 Subject: [PATCH 3/3] quick_frontend: getOrCreateWidget callbacks can return another widget --- frontends/src/quick_frontend/quick_widgets.py | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/frontends/src/quick_frontend/quick_widgets.py b/frontends/src/quick_frontend/quick_widgets.py index 72f42175..cb9c74d0 100644 --- a/frontends/src/quick_frontend/quick_widgets.py +++ b/frontends/src/quick_frontend/quick_widgets.py @@ -100,18 +100,20 @@ class QuickWidgetsManager(object): @param class_(class): class of the widget to create @param target: target depending of the widget, usually a JID instance @param args(list): optional args to create a new instance of class_ - @param kwargs(list): optional kwargs to create anew instance of class_ + @param kwargs(dict): optional kwargs to create a new instance of class_ if 'profile' key is present, it will be popped and put in 'profiles' if there is neither 'profile' nor 'profiles', None will be used for 'profiles' if 'on_new_widget' is present it can have the following values: C.WIDGET_NEW [default]: self.host.newWidget will be called on widget creation - [callable]: this method will be called instead of self.host.newWidget + [callable]: this method will be called instead of self.host.newWidget, + and can return another widget to modify the result of the present method None: do nothing if 'on_existing_widget' is present it can have the following values: C.WIDGET_KEEP [default]: return the existing widget C.WIDGET_RAISE: raise WidgetAlreadyExistsError C.WIDGET_RECREATE: create a new widget *WITH A NEW HASH* - [callable]: this method will be called with existing widget as argument + [callable]: this method will be called with existing widget as argument, + and can return another widget to modify the result of the present method if 'force_hash' is present, the hash given in value will be used instead of the one returned by class_.getWidgetHash other keys will be used to instanciate class_ if the case happen (e.g. if type_ is present and class_ is a QuickChat subclass, it will be used to create a new QuickChat instance). @@ -169,7 +171,9 @@ class QuickWidgetsManager(object): if on_new_widget == C.WIDGET_NEW: self.host.newWidget(widget) elif callable(on_new_widget): - on_new_widget(widget) + result = on_new_widget(widget) + if isinstance(result, QuickWidget): + widget = result else: assert on_new_widget is None else: @@ -204,7 +208,9 @@ class QuickWidgetsManager(object): log.debug(u"Widget already exists, a new one has been recreated with hash {}".format(new_kwargs['force_hash'])) break elif callable(on_existing_widget): - on_existing_widget(widget) + result = on_existing_widget(widget) + if isinstance(result, QuickWidget): + widget = result else: raise exceptions.InternalError("Unexpected on_existing_widget value ({})".format(on_existing_widget))