Mercurial > libervia-backend
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) |