comparison 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
comparison
equal deleted inserted replaced
21:633c5ed65701 22:bb72c29f3432
203 self.host = host 203 self.host = host
204 self.jabber_host = jabber_host 204 self.jabber_host = jabber_host
205 self.user_login = user_login 205 self.user_login = user_login
206 self.user_pass = user_pass 206 self.user_pass = user_pass
207 self.answer_id = answer_id 207 self.answer_id = answer_id
208 print "Registration asked for",user_login, user_pass, jabber_host
208 209
209 def connectionMade(self): 210 def connectionMade(self):
210 print "connectionMade" 211 print "connectionMade"
211 212
212 self.xmlstream.namespace = "jabber:client" 213 self.xmlstream.namespace = "jabber:client"
221 _pass.addContent(self.user_pass) 222 _pass.addContent(self.user_pass)
222 reg = iq.send(self.jabber_host).addCallbacks(self.registrationAnswer, self.registrationFailure) 223 reg = iq.send(self.jabber_host).addCallbacks(self.registrationAnswer, self.registrationFailure)
223 224
224 def registrationAnswer(self, answer): 225 def registrationAnswer(self, answer):
225 debug ("registration answer: %s" % answer.toXml()) 226 debug ("registration answer: %s" % answer.toXml())
226 answer_type = "success" 227 answer_type = "SUCCESS"
227 answer_data={"human":"Registration successfull"} 228 answer_data={"message":"Registration successfull"}
228 self.host.bridge.sendAnswer(answer_type, self.answer_id, answer_data) 229 self.host.bridge.actionResult(answer_type, self.answer_id, answer_data)
229 self.xmlstream.sendFooter() 230 self.xmlstream.sendFooter()
230 231
231 def registrationFailure(self, error): 232 def registrationFailure(self, error):
232 info ("Registration failure: %s" %str(error)) 233 info ("Registration failure: %s" % str(error.value))
233 answer_type = "error" 234 answer_type = "ERROR"
234 answer_data={"human":"Registration failed"} 235 answer_data = {}
235 if error.value.condition == 'conflict': 236 if error.value.condition == 'conflict':
236 answer_data['reason'] = 'conflict' 237 answer_data['reason'] = 'conflict'
238 answer_data={"message":"Username already exists, please choose an other one"}
237 else: 239 else:
238 answer_data['reason'] = 'unknown' 240 answer_data['reason'] = 'unknown'
239 self.host.bridge.sendAnswer(answer_type, self.answer_id, answer_data) 241 answer_data={"message":"Registration failed"}
242 self.host.bridge.actionResult(answer_type, self.answer_id, answer_data)
240 self.xmlstream.sendFooter() 243 self.xmlstream.sendFooter()
241 244
242 245
243 class SAT(service.Service): 246 class SAT(service.Service):
244 247
245 def __init__(self): 248 def __init__(self):
246 #self.reactor=reactor 249 #TODO: standardize callback system
247 self.memory=Memory() 250 self.__waiting_conf = {} #callback called when a confirmation is received
251 self.__progress_cb_map = {} #callback called when a progress is requested (key = progress id)
252 self.__general_cb_map = {} #callback called for general reasons (key = name)
253 self.__private_data = {} #used for internal callbacks (key = id)
254 self.plugins = {}
255
256 self.memory=Memory(self)
248 self.server_features=[] #XXX: temp dic, need to be transfered into self.memory in the future 257 self.server_features=[] #XXX: temp dic, need to be transfered into self.memory in the future
249
250 self._waiting_conf = {} #callback called when a confirmation is received
251 self._progress_cb_map = {} #callback called when a progress is requested (key = progress id)
252 self.plugins = {}
253 258
254 self.bridge=DBusBridge() 259 self.bridge=DBusBridge()
255 self.bridge.register("registerNewAccount", self.registerNewAccount) 260 self.bridge.register("registerNewAccount", self.registerNewAccount)
256 self.bridge.register("connect", self.connect) 261 self.bridge.register("connect", self.connect)
257 self.bridge.register("disconnect", self.disconnect) 262 self.bridge.register("disconnect", self.disconnect)
258 self.bridge.register("getContacts", self.memory.getContacts) 263 self.bridge.register("getContacts", self.memory.getContacts)
259 self.bridge.register("getPresenceStatus", self.memory.getPresenceStatus) 264 self.bridge.register("getPresenceStatus", self.memory.getPresenceStatus)
260 self.bridge.register("sendMessage", self.sendMessage) 265 self.bridge.register("sendMessage", self.sendMessage)
261 self.bridge.register("setParam", self.setParam) 266 self.bridge.register("setParam", self.setParam)
262 self.bridge.register("getParamV", self.memory.getParamV) 267 self.bridge.register("getParamA", self.memory.getParamA)
263 self.bridge.register("getParams", self.memory.getParams) 268 self.bridge.register("getParams", self.memory.getParams)
264 self.bridge.register("getParamsForCategory", self.memory.getParamsForCategory) 269 self.bridge.register("getParamsForCategory", self.memory.getParamsForCategory)
265 self.bridge.register("getParamsCategories", self.memory.getParamsCategories) 270 self.bridge.register("getParamsCategories", self.memory.getParamsCategories)
266 self.bridge.register("getHistory", self.memory.getHistory) 271 self.bridge.register("getHistory", self.memory.getHistory)
267 self.bridge.register("setPresence", self.setPresence) 272 self.bridge.register("setPresence", self.setPresence)
268 self.bridge.register("addContact", self.addContact) 273 self.bridge.register("addContact", self.addContact)
269 self.bridge.register("delContact", self.delContact) 274 self.bridge.register("delContact", self.delContact)
270 self.bridge.register("isConnected", self.isConnected) 275 self.bridge.register("isConnected", self.isConnected)
276 self.bridge.register("launchAction", self.launchAction)
271 self.bridge.register("confirmationAnswer", self.confirmationAnswer) 277 self.bridge.register("confirmationAnswer", self.confirmationAnswer)
272 self.bridge.register("getProgress", self.getProgress) 278 self.bridge.register("getProgress", self.getProgress)
273 279
274 self._import_plugins() 280 self._import_plugins()
275 281
293 299
294 if (self.isConnected()): 300 if (self.isConnected()):
295 info("already connected !") 301 info("already connected !")
296 return 302 return
297 print "connecting..." 303 print "connecting..."
298 self.me = jid.JID(self.memory.getParamV("JabberID", "Connection")) 304 self.me = jid.JID(self.memory.getParamA("JabberID", "Connection"))
299 self.xmppclient = SatXMPPClient(self.me, self.memory.getParamV("Password", "Connection"), 305 self.xmppclient = SatXMPPClient(self.me, self.memory.getParamA("Password", "Connection"),
300 self.memory.getParamV("Server", "Connection"), 5222) 306 self.memory.getParamA("Server", "Connection"), 5222)
301 self.xmppclient.streamInitialized = self.streamInitialized 307 self.xmppclient.streamInitialized = self.streamInitialized
302 308
303 self.messageProt = SatMessageProtocol(self) 309 self.messageProt = SatMessageProtocol(self)
304 self.messageProt.setHandlerParent(self.xmppclient) 310 self.messageProt.setHandlerParent(self.xmppclient)
305 311
360 366
361 self.roster.requestRoster() 367 self.roster.requestRoster()
362 368
363 self.presence.available() 369 self.presence.available()
364 370
365 self.disco.requestInfo(jid.JID(self.memory.getParamV("Server", "Connection"))).addCallback(self.serverDisco) 371 self.disco.requestInfo(jid.JID(self.memory.getParamA("Server", "Connection"))).addCallback(self.serverDisco)
366 372
367 ## Misc methods ## 373 ## Misc methods ##
368 374
369 def registerNewAccount(self, login, password, server, port = 5222): 375 def registerNewAccount(self, login, password, server, port = 5222, id = None):
370 """Connect to a server and create a new account using in-band registration""" 376 """Connect to a server and create a new account using in-band registration"""
371 377
372 next_id = sat_next_id() #the id is used to send server's answer 378 next_id = id or sat_next_id() #the id is used to send server's answer
373 serverRegistrer = xmlstream.XmlStreamFactory(RegisteringAuthenticator(self, server, login, password, next_id)) 379 serverRegistrer = xmlstream.XmlStreamFactory(RegisteringAuthenticator(self, server, login, password, next_id))
374 connector = reactor.connectTCP(server, port, serverRegistrer) 380 connector = reactor.connectTCP(server, port, serverRegistrer)
375 serverRegistrer.clientConnectionLost = lambda conn, reason: connector.disconnect() 381 serverRegistrer.clientConnectionLost = lambda conn, reason: connector.disconnect()
376 382
377 return next_id 383 return next_id
384
385 def registerNewAccountCB(self, id, data):
386 user = jid.parse(self.memory.getParamA("JabberID", "Connection"))[0]
387 server = self.memory.getParamA("Server", "Connection")
388
389 confirm_id = sat_next_id()
390 self.__private_data[confirm_id]=id
391
392 self.askConfirmation(confirm_id, "YES/NO",
393 {"message":"Are you sure to register new account [%s] to server %s ?" % (user, server)},
394 self.regisConfirmCB)
395 print ("===============+++++++++++ REGISTER NEW ACCOUNT++++++++++++++============")
396 print "id=",id
397 print "data=",data
398
399 def regisConfirmCB(self, id, accepted, data):
400 print "register Confirmation CB ! (%s)" % str(accepted)
401 action_id = self.__private_data[id]
402 del self.__private_data[id]
403 user = jid.parse(self.memory.getParamA("JabberID", "Connection"))[0]
404 password = self.memory.getParamA("Password", "Connection")
405 server = self.memory.getParamA("Server", "Connection")
406 if accepted:
407 self.registerNewAccount(user, password, server, id=action_id)
408 else:
409 self.actionResult(action_id, "SUPPRESS", {})
378 410
379 ## Client management ## 411 ## Client management ##
380 412
381 def setParam(self, name, value, category): 413 def setParam(self, name, value, category):
382 """set wanted paramater and notice observers""" 414 """set wanted paramater and notice observers"""
383 info ("setting param: %s=%s in category %s", name, value, category) 415 info ("setting param: %s=%s in category %s", name, value, category)
384 self.memory.setParam(name, value, category) 416 self.memory.setParam(name, value, category)
385 self.bridge.paramUpdate(name, value, category)
386 417
387 def failed(self,xmlstream): 418 def failed(self,xmlstream):
388 debug("failed: %s", xmlstream.getErrorMessage()) 419 debug("failed: %s", xmlstream.getErrorMessage())
389 debug("failed: %s", dir(xmlstream)) 420 debug("failed: %s", dir(xmlstream))
390 421
394 return True 425 return True
395 except AttributeError: 426 except AttributeError:
396 #xmppclient not available 427 #xmppclient not available
397 pass 428 pass
398 return False 429 return False
430
431 def launchAction(self, type, data):
432 """Launch a specific action asked by client
433 @param type: action type (button)
434 @data: needed data to launch the action
435
436 @return: action id for result, or empty string in case or error
437 """
438 if type=="button":
439 try:
440 cb_name = self.memory.getParamA(data["name"], data["category"], "callback")
441 except KeyError:
442 error ("Incomplete data")
443 return ""
444 id = sat_next_id()
445 self.callGeneralCB(cb_name, id, data)
446 return id
447 else:
448 error ("Unknown action type")
449 return ""
450
399 451
400 ## jabber methods ## 452 ## jabber methods ##
401 453
402 def sendMessage(self,to,msg,type='chat'): 454 def sendMessage(self,to,msg,type='chat'):
403 #FIXME: check validity of recipient 455 #FIXME: check validity of recipient
455 self.server_features.append(feature) 507 self.server_features.append(feature)
456 for cat, type in disco.identities: 508 for cat, type in disco.identities:
457 debug ("Identity found: [%s/%s] %s" % (cat, type, disco.identities[(cat,type)])) 509 debug ("Identity found: [%s/%s] %s" % (cat, type, disco.identities[(cat,type)]))
458 510
459 ## Generic HMI ## 511 ## Generic HMI ##
512
513 def actionResult(self, id, type, data):
514 """Send the result of an action
515 @param id: same id used with action
516 @type: result type ("PARAM", "SUCCESS", "ERROR")
517 @data: data (depend of result type)
518 """
519 self.bridge.actionResult(type, id, data)
520
521
460 522
461 def askConfirmation(self, id, type, data, cb): 523 def askConfirmation(self, id, type, data, cb):
462 """Add a confirmation callback""" 524 """Add a confirmation callback
463 if self._waiting_conf.has_key(id): 525 @param id: id used to get answer
526 @type: confirmation type ("YES/NO", "FILE_TRANSFERT")
527 @data: data (depend of confirmation type)
528 @cb: callback called with the answer
529 """
530 if self.__waiting_conf.has_key(id):
464 error ("Attempt to register two callbacks for the same confirmation") 531 error ("Attempt to register two callbacks for the same confirmation")
465 else: 532 else:
466 self._waiting_conf[id] = cb 533 self.__waiting_conf[id] = cb
467 self.bridge.askConfirmation(type, id, data) 534 self.bridge.askConfirmation(type, id, data)
468 535
469 536
470 def confirmationAnswer(self, id, accepted, data): 537 def confirmationAnswer(self, id, accepted, data):
471 """Called by frontends to answer confirmation requests""" 538 """Called by frontends to answer confirmation requests"""
472 debug ("Received confirmation answer for id [%s]: %s", id, "accepted" if accepted else "refused") 539 debug ("Received confirmation answer for id [%s]: %s", id, "accepted" if accepted else "refused")
473 if not self._waiting_conf.has_key(id): 540 if not self.__waiting_conf.has_key(id):
474 error ("Received an unknown confirmation") 541 error ("Received an unknown confirmation")
475 else: 542 else:
476 cb = self._waiting_conf[id] 543 cb = self.__waiting_conf[id]
477 del self._waiting_conf[id] 544 del self.__waiting_conf[id]
478 cb(id, accepted, data) 545 cb(id, accepted, data)
479 546
480 def registerProgressCB(self, id, CB): 547 def registerProgressCB(self, id, CB):
481 """Register a callback called when progress is requested for id""" 548 """Register a callback called when progress is requested for id"""
482 self._progress_cb_map[id] = CB 549 self.__progress_cb_map[id] = CB
483 550
484 def removeProgressCB(self, id): 551 def removeProgressCB(self, id):
485 """Remove a progress callback""" 552 """Remove a progress callback"""
486 if not self._progress_cb_map.has_key(id): 553 if not self.__progress_cb_map.has_key(id):
487 error ("Trying to remove an unknow progress callback") 554 error ("Trying to remove an unknow progress callback")
488 else: 555 else:
489 del self._progress_cb_map[id] 556 del self.__progress_cb_map[id]
490 557
491 def getProgress(self, id): 558 def getProgress(self, id):
492 """Return a dict with progress information 559 """Return a dict with progress information
493 data['position'] : current possition 560 data['position'] : current possition
494 data['size'] : end_position 561 data['size'] : end_position
495 """ 562 """
496 data = {} 563 data = {}
497 try: 564 try:
498 self._progress_cb_map[id](data) 565 self.__progress_cb_map[id](data)
499 except KeyError: 566 except KeyError:
500 pass 567 pass
501 #debug("Requested progress for unknown id") 568 #debug("Requested progress for unknown id")
502 return data 569 return data
503 570
571 def registerGeneralCB(self, name, CB):
572 """Register a callback called for general reason"""
573 self.__general_cb_map[name] = CB
574
575 def removeGeneralCB(self, name):
576 """Remove a general callback"""
577 if not self.__general_cb_map.has_key(name):
578 error ("Trying to remove an unknow general callback")
579 else:
580 del self.__general_cb_map[name]
581
582 def callGeneralCB(self, name, *args, **kwargs):
583 """Call general function back"""
584 try:
585 return self.__general_cb_map[name](*args, **kwargs)
586 except KeyError:
587 error("Trying to call unknown function")
588 return None
504 589
505 application = service.Application('SàT') 590 application = service.Application('SàT')
506 service = SAT() 591 service = SAT()
507 service.setServiceParent(application) 592 service.setServiceParent(application)