quick_frontend (app): progress callbacks handling:

in addition to listeners, a frontend can now register progression callback and errback which are called when the given progressing action is finished.
Those callbacks can be registered using registerProgressCbs or specified in actionManager.
This commit is contained in:
Goffi 2019-03-20 09:08:47 +01:00
commit 1b312477b1

View file

@ -313,7 +313,7 @@ class QuickApp(object):
# widget currently selected (must be filled by frontend)
self.selected_widget = None
# listeners
# listeners are callable watching events
self._listeners = {} # key: listener type ("avatar", "selected", etc),
# value: list of callbacks
@ -328,12 +328,20 @@ class QuickApp(object):
if connect_bridge:
self.connectBridge()
# frontend notifications
self._notif_id = 0
self._notifications = OrderedDict()
# watched progresses and associated callbacks
self._progress_ids = {}
# available features
# FIXME: features are profile specific, to be checked
self.features = None
self.ns_map = {} # map of short name to namespaces
#: map of short name to namespaces
self.ns_map = {}
#: available encryptions
self.encryption_plugins = []
self._sync = True # state of synchronisation with backend
# state of synchronisation with backend
self._sync = True
def connectBridge(self):
self.bridge.bridgeConnect(callback=self._bridgeCb, errback=self._bridgeEb)
@ -436,7 +444,7 @@ class QuickApp(object):
@property
def sync(self):
"""Get synchronization flag
"""Synchronization flag
True if this frontend is synchronised with backend
"""
@ -1042,15 +1050,44 @@ class QuickApp(object):
else:
log.warning("Unmanaged PubSub event type {}".format(event_type))
def registerProgressCbs(self, progress_id, callback, errback):
"""Register progression callbacks
@param progress_id(unicode): id of the progression to check
@param callback(callable, None): method to call when progressing action
successfuly finished.
None to ignore
@param errback(callable, None): method to call when progressions action failed
None to ignore
"""
callbacks = self._progress_ids.setdefault(progress_id, [])
callbacks.append((callback, errback))
def progressStartedHandler(self, pid, metadata, profile):
log.info(u"Progress {} started".format(pid))
def progressFinishedHandler(self, pid, metadata, profile):
log.info(u"Progress {} finished".format(pid))
try:
callbacks = self._progress_ids.pop(pid)
except KeyError:
pass
else:
for callback, __ in callbacks:
if callback is not None:
callback(metadata, profile=profile)
self.callListeners("progressFinished", pid, metadata, profile=profile)
def progressErrorHandler(self, pid, err_msg, profile):
log.warning(u"Progress {pid} error: {err_msg}".format(pid=pid, err_msg=err_msg))
try:
callbacks = self._progress_ids.pop(pid)
except KeyError:
pass
else:
for __, errback in callbacks:
if errback is not None:
errback(err_msg, profile=profile)
self.callListeners("progressError", pid, err_msg, profile=profile)
def _subscribe_cb(self, answer, data):
@ -1166,7 +1203,7 @@ class QuickApp(object):
self.getAvatar(entity, ignore_cache=True, profile=profile)
def actionManager(self, action_data, callback=None, ui_show_cb=None, user_action=True,
profile=C.PROF_KEY_NONE):
progress_cb=None, progress_eb=None, profile=C.PROF_KEY_NONE):
"""Handle backend action
@param action_data(dict): action dict as sent by launchAction or returned by an
@ -1174,7 +1211,14 @@ class QuickApp(object):
@param callback(None, callback): if not None, callback to use on XMLUI answer
@param ui_show_cb(None, callback): if not None, method to call to show the XMLUI
@param user_action(bool): if True, the action is a result of a user interaction
else the action come from backend direclty (i.e. actionNew)
else the action come from backend direclty (i.e. actionNew).
This is useful to know if the frontend can display a popup immediately (if
True) or if it should add it to a queue that the user can activate later.
@param progress_cb(None, callable): method to call when progression is finished.
Only make sense if a progress is expected in this action
@param progress_eb(None, callable): method to call when something went wrong
during progression.
Only make sense if a progress is expected in this action
"""
try:
xmlui = action_data.pop("xmlui")
@ -1198,6 +1242,8 @@ class QuickApp(object):
except KeyError:
pass
else:
if progress_cb or progress_eb:
self.registerProgressCbs(progress_id, progress_cb, progress_eb)
self.progressIdHandler(progress_id, profile)
# we ignore metadata