diff sat.tac @ 22:bb72c29f3432

added action cb mechanism for buttons. Tested with a temporary new user registration button.
author Goffi <goffi@goffi.org>
date Tue, 01 Dec 2009 04:56:08 +0100
parents 6928e3cb73a8
children 925ab466c5ec
line wrap: on
line diff
--- a/sat.tac	Sun Nov 08 01:49:08 2009 +0100
+++ b/sat.tac	Tue Dec 01 04:56:08 2009 +0100
@@ -205,6 +205,7 @@
         self.user_login = user_login
         self.user_pass = user_pass
         self.answer_id = answer_id
+        print "Registration asked for",user_login, user_pass, jabber_host
     
     def connectionMade(self):
         print "connectionMade"
@@ -223,34 +224,38 @@
 
     def registrationAnswer(self, answer):
         debug ("registration answer: %s" % answer.toXml())
-        answer_type = "success"
-        answer_data={"human":"Registration successfull"}
-        self.host.bridge.sendAnswer(answer_type, self.answer_id, answer_data)
+        answer_type = "SUCCESS"
+        answer_data={"message":"Registration successfull"}
+        self.host.bridge.actionResult(answer_type, self.answer_id, answer_data)
         self.xmlstream.sendFooter()
         
     def registrationFailure(self, error):
-        info ("Registration failure: %s" %str(error))
-        answer_type = "error"
-        answer_data={"human":"Registration failed"}
+        info ("Registration failure: %s" % str(error.value))
+        answer_type = "ERROR"
+        answer_data = {}
         if error.value.condition == 'conflict':
             answer_data['reason'] = 'conflict'
+            answer_data={"message":"Username already exists, please choose an other one"}
         else:
             answer_data['reason'] = 'unknown'
-        self.host.bridge.sendAnswer(answer_type, self.answer_id, answer_data)
+            answer_data={"message":"Registration failed"}
+        self.host.bridge.actionResult(answer_type, self.answer_id, answer_data)
         self.xmlstream.sendFooter()
         
 
 class SAT(service.Service):
     
     def __init__(self):
-        #self.reactor=reactor
-        self.memory=Memory()
+        #TODO: standardize callback system
+        self.__waiting_conf = {}  #callback called when a confirmation is received
+        self.__progress_cb_map = {}  #callback called when a progress is requested (key = progress id)
+        self.__general_cb_map = {}  #callback called for general reasons (key = name) 
+        self.__private_data = {}  #used for internal callbacks (key = id)
+        self.plugins = {}
+        
+        self.memory=Memory(self)
         self.server_features=[]  #XXX: temp dic, need to be transfered into self.memory in the future
 
-        self._waiting_conf = {}  #callback called when a confirmation is received
-        self._progress_cb_map = {}  #callback called when a progress is requested (key = progress id)
-        self.plugins = {}
-
         self.bridge=DBusBridge()
         self.bridge.register("registerNewAccount", self.registerNewAccount)
         self.bridge.register("connect", self.connect)
@@ -259,7 +264,7 @@
         self.bridge.register("getPresenceStatus", self.memory.getPresenceStatus)
         self.bridge.register("sendMessage", self.sendMessage)
         self.bridge.register("setParam", self.setParam)
-        self.bridge.register("getParamV", self.memory.getParamV)
+        self.bridge.register("getParamA", self.memory.getParamA)
         self.bridge.register("getParams", self.memory.getParams)
         self.bridge.register("getParamsForCategory", self.memory.getParamsForCategory)
         self.bridge.register("getParamsCategories", self.memory.getParamsCategories)
@@ -268,6 +273,7 @@
         self.bridge.register("addContact", self.addContact)
         self.bridge.register("delContact", self.delContact)
         self.bridge.register("isConnected", self.isConnected)
+        self.bridge.register("launchAction", self.launchAction)
         self.bridge.register("confirmationAnswer", self.confirmationAnswer)
         self.bridge.register("getProgress", self.getProgress)
 
@@ -295,9 +301,9 @@
             info("already connected !")
             return
         print "connecting..."
-        self.me = jid.JID(self.memory.getParamV("JabberID", "Connection"))
-        self.xmppclient = SatXMPPClient(self.me, self.memory.getParamV("Password", "Connection"),
-            self.memory.getParamV("Server", "Connection"), 5222)
+        self.me = jid.JID(self.memory.getParamA("JabberID", "Connection"))
+        self.xmppclient = SatXMPPClient(self.me, self.memory.getParamA("Password", "Connection"),
+            self.memory.getParamA("Server", "Connection"), 5222)
         self.xmppclient.streamInitialized = self.streamInitialized
 
         self.messageProt = SatMessageProtocol(self)
@@ -362,27 +368,52 @@
         
         self.presence.available()
         
-        self.disco.requestInfo(jid.JID(self.memory.getParamV("Server", "Connection"))).addCallback(self.serverDisco)
+        self.disco.requestInfo(jid.JID(self.memory.getParamA("Server", "Connection"))).addCallback(self.serverDisco)
     
    ## Misc methods ##
    
-    def registerNewAccount(self, login, password, server, port = 5222):
+    def registerNewAccount(self, login, password, server, port = 5222, id = None):
         """Connect to a server and create a new account using in-band registration"""
 
-        next_id = sat_next_id()  #the id is used to send server's answer
+        next_id = id or sat_next_id()  #the id is used to send server's answer
         serverRegistrer = xmlstream.XmlStreamFactory(RegisteringAuthenticator(self, server, login, password, next_id))
         connector = reactor.connectTCP(server, port, serverRegistrer)
         serverRegistrer.clientConnectionLost = lambda conn, reason: connector.disconnect()
         
         return next_id 
 
+    def registerNewAccountCB(self, id, data):
+        user = jid.parse(self.memory.getParamA("JabberID", "Connection"))[0]
+        server = self.memory.getParamA("Server", "Connection")
+
+        confirm_id = sat_next_id()
+        self.__private_data[confirm_id]=id
+    
+        self.askConfirmation(confirm_id, "YES/NO",
+            {"message":"Are you sure to register new account [%s] to server %s ?" % (user, server)},
+            self.regisConfirmCB)
+        print ("===============+++++++++++ REGISTER NEW ACCOUNT++++++++++++++============")
+        print "id=",id
+        print "data=",data
+
+    def regisConfirmCB(self, id, accepted, data):
+        print "register Confirmation CB ! (%s)" % str(accepted)
+        action_id = self.__private_data[id]
+        del self.__private_data[id]
+        user = jid.parse(self.memory.getParamA("JabberID", "Connection"))[0]
+        password = self.memory.getParamA("Password", "Connection")
+        server = self.memory.getParamA("Server", "Connection")
+        if accepted:
+            self.registerNewAccount(user, password, server, id=action_id)
+        else:
+            self.actionResult(action_id, "SUPPRESS", {})
+
     ## Client management ##
 
     def setParam(self, name, value, category):
         """set wanted paramater and notice observers"""
         info ("setting param: %s=%s in category %s", name, value, category)
         self.memory.setParam(name, value, category)
-        self.bridge.paramUpdate(name, value, category)
 
     def failed(self,xmlstream):
         debug("failed: %s", xmlstream.getErrorMessage())
@@ -397,6 +428,27 @@
             pass
         return False
 
+    def launchAction(self, type, data):
+        """Launch a specific action asked by client
+        @param type: action type (button)
+        @data: needed data to launch the action
+
+        @return: action id for result, or empty string in case or error
+        """
+        if type=="button":
+            try:
+                cb_name = self.memory.getParamA(data["name"], data["category"], "callback")
+            except KeyError:
+                error ("Incomplete data")
+                return ""
+            id = sat_next_id()
+            self.callGeneralCB(cb_name, id, data)
+            return id
+        else:
+            error ("Unknown action type")
+            return ""
+
+
     ## jabber methods ##
     
     def sendMessage(self,to,msg,type='chat'):
@@ -457,36 +509,51 @@
             debug ("Identity found: [%s/%s] %s" % (cat, type, disco.identities[(cat,type)]))
 
     ## Generic HMI ## 
+    
+    def actionResult(self, id, type, data):
+        """Send the result of an action
+        @param id: same id used with action
+        @type: result type ("PARAM", "SUCCESS", "ERROR")
+        @data: data (depend of result type)
+        """
+        self.bridge.actionResult(type, id, data)
+
+
 
     def askConfirmation(self, id, type, data, cb):
-        """Add a confirmation callback"""
-        if self._waiting_conf.has_key(id):
+        """Add a confirmation callback
+        @param id: id used to get answer
+        @type: confirmation type ("YES/NO", "FILE_TRANSFERT")
+        @data: data (depend of confirmation type)
+        @cb: callback called with the answer
+        """
+        if self.__waiting_conf.has_key(id):
             error ("Attempt to register two callbacks for the same confirmation")
         else:
-            self._waiting_conf[id] = cb
+            self.__waiting_conf[id] = cb
             self.bridge.askConfirmation(type, id, data)
 
 
     def confirmationAnswer(self, id, accepted, data):
         """Called by frontends to answer confirmation requests"""
         debug ("Received confirmation answer for id [%s]: %s", id, "accepted" if accepted else "refused")
-        if not self._waiting_conf.has_key(id):
+        if not self.__waiting_conf.has_key(id):
             error ("Received an unknown confirmation")
         else:
-            cb = self._waiting_conf[id]
-            del self._waiting_conf[id]
+            cb = self.__waiting_conf[id]
+            del self.__waiting_conf[id]
             cb(id, accepted, data)
 
     def registerProgressCB(self, id, CB):
         """Register a callback called when progress is requested for id"""
-        self._progress_cb_map[id] = CB
+        self.__progress_cb_map[id] = CB
 
     def removeProgressCB(self, id):
         """Remove a progress callback"""
-        if not self._progress_cb_map.has_key(id):
+        if not self.__progress_cb_map.has_key(id):
             error ("Trying to remove an unknow progress callback")
         else:
-            del self._progress_cb_map[id]
+            del self.__progress_cb_map[id]
 
     def getProgress(self, id):
         """Return a dict with progress information
@@ -495,12 +562,30 @@
         """
         data = {}
         try:
-            self._progress_cb_map[id](data)
+            self.__progress_cb_map[id](data)
         except KeyError:
             pass
             #debug("Requested progress for unknown id")
         return data
 
+    def registerGeneralCB(self, name, CB):
+        """Register a callback called for general reason"""
+        self.__general_cb_map[name] = CB
+
+    def removeGeneralCB(self, name):
+        """Remove a general callback"""
+        if not self.__general_cb_map.has_key(name):
+            error ("Trying to remove an unknow general callback")
+        else:
+            del self.__general_cb_map[name]
+
+    def callGeneralCB(self, name, *args, **kwargs):
+        """Call general function back"""
+        try:
+            return self.__general_cb_map[name](*args, **kwargs)
+        except KeyError:
+            error("Trying to call unknown function")
+            return None
 
 application = service.Application('SàT')
 service = SAT()