core, bridge: actionsGet:
- added a new mechanism to keep actions until they are answered (or timeout-ed)
- keep_id must be explicitly used on actionNew
- actionsGet is used to retrive these actions
- the mechanism is used in deferXMLUI
This commit is contained in:
parent
c0b1f1a86e
commit
a42452ff57
6 changed files with 63 additions and 7 deletions
|
|
@ -123,6 +123,20 @@ class DBusBridgeFrontend(BridgeFrontend):
|
|||
|
||||
return getPluginMethod
|
||||
|
||||
def actionsGet(self, profile_key="@DEFAULT@", callback=None, errback=None):
|
||||
if callback is None:
|
||||
error_handler = None
|
||||
else:
|
||||
if errback is None:
|
||||
errback = log.error
|
||||
error_handler = lambda err:errback(dbus_to_bridge_exception(err))
|
||||
kwargs={}
|
||||
if callback is not None:
|
||||
kwargs['timeout'] = const_TIMEOUT
|
||||
kwargs['reply_handler'] = callback
|
||||
kwargs['error_handler'] = error_handler
|
||||
return self.db_core_iface.actionsGet(profile_key, **kwargs)
|
||||
|
||||
def addContact(self, entity_jid, profile_key="@DEFAULT@", callback=None, errback=None):
|
||||
if callback is None:
|
||||
error_handler = None
|
||||
|
|
|
|||
|
|
@ -212,6 +212,12 @@ class DbusObject(dbus.service.Object):
|
|||
|
||||
### methods ###
|
||||
|
||||
@dbus.service.method(const_INT_PREFIX+const_CORE_SUFFIX,
|
||||
in_signature='s', out_signature='a(a{ss}si)',
|
||||
async_callbacks=None)
|
||||
def actionsGet(self, profile_key="@DEFAULT@"):
|
||||
return self._callback("actionsGet", unicode(profile_key))
|
||||
|
||||
@dbus.service.method(const_INT_PREFIX+const_CORE_SUFFIX,
|
||||
in_signature='ss', out_signature='',
|
||||
async_callbacks=None)
|
||||
|
|
|
|||
|
|
@ -632,6 +632,16 @@ doc_param_2=%(doc_profile_key)s
|
|||
doc_return=dict where key can be:
|
||||
- xmlui: a XMLUI need to be displayed
|
||||
|
||||
[actionsGet]
|
||||
type=method
|
||||
category=core
|
||||
sig_in=s
|
||||
sig_out=a(a{ss}si)
|
||||
param_0_default="@DEFAULT@"
|
||||
doc=Get all not yet answered actions
|
||||
doc_param_0=%(doc_profile_key)s
|
||||
doc_return=list of data as for [actionNew] (without the profile)
|
||||
|
||||
[confirmationAnswer]
|
||||
deprecated=
|
||||
type=method
|
||||
|
|
|
|||
|
|
@ -102,6 +102,7 @@ class SAT(service.Service):
|
|||
self.bridge.register("delContact", self._delContact)
|
||||
self.bridge.register("isConnected", self.isConnected)
|
||||
self.bridge.register("launchAction", self.launchCallback)
|
||||
self.bridge.register("actionsGet", self.actionsGet)
|
||||
self.bridge.register("confirmationAnswer", self.confirmationAnswer)
|
||||
self.bridge.register("progressGet", self._progressGet)
|
||||
self.bridge.register("progressGetAll", self._progressGetAll)
|
||||
|
|
@ -785,16 +786,36 @@ class SAT(service.Service):
|
|||
del client._waiting_conf[conf_id]
|
||||
cb(conf_id, accepted, data, profile)
|
||||
|
||||
def actionNew(self, action_data, security_limit=C.NO_SECURITY_LIMIT, profile=C.PROF_KEY_NONE):
|
||||
"""Shortcut to bridge.actionNew which generate and id
|
||||
def _killAction(self, keep_id, client):
|
||||
log.debug(u"Killing action {} for timeout".format(keep_id))
|
||||
client.actions[keep_id]
|
||||
|
||||
def actionNew(self, action_data, security_limit=C.NO_SECURITY_LIMIT, keep_id=None, profile=C.PROF_KEY_NONE):
|
||||
"""Shortcut to bridge.actionNew which generate and id and keep for retrieval
|
||||
|
||||
@param action_data(dict): action data (see bridge documentation)
|
||||
@param security_limit: %(doc_security_limit)s
|
||||
@param keep_id(None, unicode): if not None, used to keep action for differed retrieval
|
||||
must be set to the callback_id
|
||||
action will be deleted after 30 min.
|
||||
@param profile: %(doc_profile)s
|
||||
"""
|
||||
id_ = unicode(uuid.uuid4())
|
||||
if keep_id is not None:
|
||||
client = self.getClient(profile)
|
||||
action_timer = reactor.callLater(60*30, self._killAction)
|
||||
client.actions[keep_id] = (action_data, id_, security_limit, action_timer)
|
||||
|
||||
self.bridge.actionNew(action_data, id_, security_limit, profile)
|
||||
|
||||
def actionsGet(self, profile):
|
||||
"""Return current non answered actions
|
||||
|
||||
@param profile: %(doc_profile)s
|
||||
"""
|
||||
client = self.getClient(profile)
|
||||
return [action_tuple[:-1] for action_tuple in client.actions.itervalues()]
|
||||
|
||||
def registerProgressCb(self, progress_id, callback, profile):
|
||||
"""Register a callback called when progress is requested for id"""
|
||||
client = self.getClient(profile)
|
||||
|
|
@ -904,9 +925,13 @@ class SAT(service.Service):
|
|||
- C.BOOL_TRUE
|
||||
- C.BOOL_FALSE
|
||||
"""
|
||||
profile = self.memory.getProfileName(profile_key)
|
||||
if not profile:
|
||||
raise exceptions.ProfileUnknownError(_('trying to launch action with a non-existant profile'))
|
||||
client = self.getClient(profile_key)
|
||||
try:
|
||||
action_tuple = client.actions[callback_id]
|
||||
except KeyError:
|
||||
pass
|
||||
else:
|
||||
action_tuple[-1].cancel() # the last item is the action timer
|
||||
|
||||
try:
|
||||
callback, args, kwargs = self._cb_map[callback_id]
|
||||
|
|
@ -918,7 +943,7 @@ class SAT(service.Service):
|
|||
raise exceptions.DataError("Required data for this callback is missing")
|
||||
args,kwargs=list(args)[:],kwargs.copy() # we don't want to modify the original (kw)args
|
||||
args.insert(0, data)
|
||||
kwargs["profile"] = profile
|
||||
kwargs["profile"] = client.profile
|
||||
del kwargs["with_data"]
|
||||
|
||||
if kwargs.pop('one_shot', False):
|
||||
|
|
|
|||
|
|
@ -45,6 +45,7 @@ class SatXMPPClient(client.XMPPClient):
|
|||
self.conn_deferred = defer.Deferred()
|
||||
self._waiting_conf = {} # callback called when a confirmation is received
|
||||
self._progress_cb = {} # callback called when a progress is requested (key = progress id)
|
||||
self.actions = {} # used to keep track of actions for retrieval (key = action_id)
|
||||
|
||||
def getConnectionDeferred(self):
|
||||
"""Return a deferred which fire when the client is connected"""
|
||||
|
|
|
|||
|
|
@ -1271,7 +1271,7 @@ def deferXMLUI(host, xmlui, action_extra=None, security_limit=C.NO_SECURITY_LIMI
|
|||
action_data = {'xmlui': xmlui.toXml()}
|
||||
if action_extra is not None:
|
||||
action_data.update(action_extra)
|
||||
host.actionNew(action_data, profile=profile)
|
||||
host.actionNew(action_data, keep_id=xmlui.submit_id, profile=profile)
|
||||
return xmlui_d
|
||||
|
||||
def deferDialog(host, message, title=u'Please confirm', type_=C.XMLUI_DIALOG_CONFIRM, options=None,
|
||||
|
|
|
|||
Loading…
Reference in a new issue