diff src/core/sat_main.py @ 1622:5b24d6bf5d15

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
author Goffi <goffi@goffi.org>
date Tue, 17 Nov 2015 21:28:58 +0100
parents 2b82d846848e
children 7e749e8eefd0
line wrap: on
line diff
--- a/src/core/sat_main.py	Tue Nov 17 20:18:51 2015 +0100
+++ b/src/core/sat_main.py	Tue Nov 17 21:28:58 2015 +0100
@@ -102,6 +102,7 @@
         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 @@
             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 @@
                 - 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 @@
                 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):