comparison src/core/sat_main.py @ 538:2c4016921403

core, frontends, bridgen plugins: fixed methods which were unproperly managing multi-profiles - added profile argument to askConfirmation, actionResult, actionResultExt, entityDataUpdated, confirmationAnswer, getProgress - core, frontends: fixed calls/signals according to new bridge API - user of proper profile namespace for progression indicators and dialogs - memory: getParam* now return bool when param type is bool - memory: added getStringParam* to return string instead of typed value - core, memory, storage, quick_frontend: getHistory now manage properly multi-profiles - plugins XEP-0047, XEP-0054, XEP-0065, XEP-0077, XEP-0096; multi-profiles proper handling
author Goffi <goffi@goffi.org>
date Sat, 10 Nov 2012 16:38:16 +0100
parents a31abb97310d
children 8b116fa42a31
comparison
equal deleted inserted replaced
537:28cddc96c4ed 538:2c4016921403
42 42
43 import sys 43 import sys
44 import os.path 44 import os.path
45 45
46 from sat.core import xmpp 46 from sat.core import xmpp
47 from sat.core.exceptions import ProfileUnknownError, UnknownEntityError 47 from sat.core.exceptions import ProfileUnknownError, UnknownEntityError, ProfileNotInCacheError
48 from sat.memory.memory import Memory 48 from sat.memory.memory import Memory
49 from sat.tools.xml_tools import tupleList2dataForm 49 from sat.tools.xml_tools import tupleList2dataForm
50 from sat.tools.misc import TriggerManager 50 from sat.tools.misc import TriggerManager
51 from glob import glob 51 from glob import glob
52 52
96 CONST[name] = value 96 CONST[name] = value
97 97
98 def __init__(self): 98 def __init__(self):
99 #TODO: standardize callback system 99 #TODO: standardize callback system
100 100
101 self.__waiting_conf = {} #callback called when a confirmation is received
102 self.__progress_cb_map = {} #callback called when a progress is requested (key = progress id)
103 self.__general_cb_map = {} #callback called for general reasons (key = name) 101 self.__general_cb_map = {} #callback called for general reasons (key = name)
104 self.__private_data = {} #used for internal callbacks (key = id) 102 self.__private_data = {} #used for internal callbacks (key = id)
105 self.profiles = {} 103 self.profiles = {}
106 self.plugins = {} 104 self.plugins = {}
107 self.menus = {} #used to know which new menus are wanted by plugins 105 self.menus = {} #used to know which new menus are wanted by plugins
132 self.bridge.register("getPresenceStatus", self.memory.getPresenceStatus) 130 self.bridge.register("getPresenceStatus", self.memory.getPresenceStatus)
133 self.bridge.register("getWaitingSub", self.memory.getWaitingSub) 131 self.bridge.register("getWaitingSub", self.memory.getWaitingSub)
134 self.bridge.register("sendMessage", self.sendMessage) 132 self.bridge.register("sendMessage", self.sendMessage)
135 self.bridge.register("getConfig", self.memory.getConfig) 133 self.bridge.register("getConfig", self.memory.getConfig)
136 self.bridge.register("setParam", self.setParam) 134 self.bridge.register("setParam", self.setParam)
137 self.bridge.register("getParamA", self.memory.getParamA) 135 self.bridge.register("getParamA", self.memory.getStringParamA)
138 self.bridge.register("asyncGetParamA", self.memory.asyncGetParamA) 136 self.bridge.register("asyncGetParamA", self.memory.asyncGetStringParamA)
139 self.bridge.register("getParamsUI", self.memory.getParamsUI) 137 self.bridge.register("getParamsUI", self.memory.getParamsUI)
140 self.bridge.register("getParams", self.memory.getParams) 138 self.bridge.register("getParams", self.memory.getParams)
141 self.bridge.register("getParamsForCategory", self.memory.getParamsForCategory) 139 self.bridge.register("getParamsForCategory", self.memory.getParamsForCategory)
142 self.bridge.register("getParamsCategories", self.memory.getParamsCategories) 140 self.bridge.register("getParamsCategories", self.memory.getParamsCategories)
143 self.bridge.register("getHistory", self.memory.getHistory) 141 self.bridge.register("getHistory", self.memory.getHistory)
334 profile = self.memory.getProfileName(profile_key) 332 profile = self.memory.getProfileName(profile_key)
335 if not profile: 333 if not profile:
336 return None 334 return None
337 return self.profiles[profile] 335 return self.profiles[profile]
338 336
339 def registerNewAccount(self, login, password, email, server, port = 5222, id = None): 337 def registerNewAccount(self, login, password, email, server, port = 5222, id = None, profile_key = '@DEFAULT@'):
340 """Connect to a server and create a new account using in-band registration""" 338 """Connect to a server and create a new account using in-band registration"""
339 profile = self.memory.getProfileName(profile_key)
340 assert(profile)
341 341
342 next_id = id or sat_next_id() #the id is used to send server's answer 342 next_id = id or sat_next_id() #the id is used to send server's answer
343 serverRegistrer = xmlstream.XmlStreamFactory(xmpp.RegisteringAuthenticator(self, server, login, password, email, next_id)) 343 serverRegistrer = xmlstream.XmlStreamFactory(xmpp.RegisteringAuthenticator(self, server, login, password, email, next_id, profile))
344 connector = reactor.connectTCP(server, port, serverRegistrer) 344 connector = reactor.connectTCP(server, port, serverRegistrer)
345 serverRegistrer.clientConnectionLost = lambda conn, reason: connector.disconnect() 345 serverRegistrer.clientConnectionLost = lambda conn, reason: connector.disconnect()
346 346
347 return next_id 347 return next_id
348 348
352 server = self.memory.getParamA("Server", "Connection", profile_key=profile) 352 server = self.memory.getParamA("Server", "Connection", profile_key=profile)
353 353
354 if not user or not password or not server: 354 if not user or not password or not server:
355 info (_('No user or server given')) 355 info (_('No user or server given'))
356 #TODO: a proper error message must be sent to frontend 356 #TODO: a proper error message must be sent to frontend
357 self.actionResult(id, "ERROR", {'message':_("No user, password or server given, can't register new account.")}) 357 self.actionResult(id, "ERROR", {'message':_("No user, password or server given, can't register new account.")}, profile)
358 return 358 return
359 359
360 confirm_id = sat_next_id() 360 confirm_id = sat_next_id()
361 self.__private_data[confirm_id]=(id,profile) 361 self.__private_data[confirm_id]=(id,profile)
362 362
363 self.askConfirmation(confirm_id, "YES/NO", 363 self.askConfirmation(confirm_id, "YES/NO",
364 {"message":_("Are you sure to register new account [%(user)s] to server %(server)s ?") % {'user':user, 'server':server, 'profile':profile}}, 364 {"message":_("Are you sure to register new account [%(user)s] to server %(server)s ?") % {'user':user, 'server':server, 'profile':profile}},
365 self.regisConfirmCB) 365 self.regisConfirmCB, profile)
366 print ("===============+++++++++++ REGISTER NEW ACCOUNT++++++++++++++============") 366 print ("===============+++++++++++ REGISTER NEW ACCOUNT++++++++++++++============")
367 print "id=",id 367 print "id=",id
368 print "data=",data 368 print "data=",data
369 369
370 def regisConfirmCB(self, id, accepted, data): 370 def regisConfirmCB(self, id, accepted, data, profile):
371 print _("register Confirmation CB ! (%s)") % str(accepted) 371 print _("register Confirmation CB ! (%s)") % str(accepted)
372 action_id,profile = self.__private_data[id] 372 action_id,profile = self.__private_data[id]
373 del self.__private_data[id] 373 del self.__private_data[id]
374 if accepted: 374 if accepted:
375 user = jid.parse(self.memory.getParamA("JabberID", "Connection", profile_key=profile))[0] 375 user = jid.parse(self.memory.getParamA("JabberID", "Connection", profile_key=profile))[0]
376 password = self.memory.getParamA("Password", "Connection", profile_key=profile) 376 password = self.memory.getParamA("Password", "Connection", profile_key=profile)
377 server = self.memory.getParamA("Server", "Connection", profile_key=profile) 377 server = self.memory.getParamA("Server", "Connection", profile_key=profile)
378 self.registerNewAccount(user, password, None, server, id=action_id) 378 self.registerNewAccount(user, password, None, server, id=action_id)
379 else: 379 else:
380 self.actionResult(action_id, "SUPPRESS", {}) 380 self.actionResult(action_id, "SUPPRESS", {}, profile)
381 381
382 def submitForm(self, action, target, fields, profile_key): 382 def submitForm(self, action, target, fields, profile_key):
383 """submit a form 383 """submit a form
384 @param target: target jid where we are submitting 384 @param target: target jid where we are submitting
385 @param fields: list of tuples (name, value) 385 @param fields: list of tuples (name, value)
599 defer.DeferredList(defer_list).chainDeferred(initialized) 599 defer.DeferredList(defer_list).chainDeferred(initialized)
600 600
601 601
602 ## Generic HMI ## 602 ## Generic HMI ##
603 603
604 def actionResult(self, id, type, data): 604 def actionResult(self, action_id, action_type, data, profile):
605 """Send the result of an action 605 """Send the result of an action
606 @param id: same id used with action 606 @param action_id: same action_id used with action
607 @param type: result type ("PARAM", "SUCCESS", "ERROR", "XMLUI") 607 @param action_type: result action_type ("PARAM", "SUCCESS", "ERROR", "XMLUI")
608 @param data: dictionary 608 @param data: dictionary
609 """ 609 """
610 self.bridge.actionResult(type, id, data) 610 self.bridge.actionResult(action_type, action_id, data, profile)
611 611
612 def actionResultExt(self, id, type, data): 612 def actionResultExt(self, action_id, action_type, data, profile):
613 """Send the result of an action, extended version 613 """Send the result of an action, extended version
614 @param id: same id used with action 614 @param action_id: same action_id used with action
615 @param type: result type /!\ only "DICT_DICT" for this method 615 @param action_type: result action_type /!\ only "DICT_DICT" for this method
616 @param data: dictionary of dictionaries 616 @param data: dictionary of dictionaries
617 """ 617 """
618 if type != "DICT_DICT": 618 if action_type != "DICT_DICT":
619 error(_("type for actionResultExt must be DICT_DICT, fixing it")) 619 error(_("action_type for actionResultExt must be DICT_DICT, fixing it"))
620 type = "DICT_DICT" 620 action_type = "DICT_DICT"
621 self.bridge.actionResultExt(type, id, data) 621 self.bridge.actionResultExt(action_type, action_id, data, profile)
622 622
623 623
624 624
625 def askConfirmation(self, id, type, data, cb): 625 def askConfirmation(self, conf_id, conf_type, data, cb, profile):
626 """Add a confirmation callback 626 """Add a confirmation callback
627 @param id: id used to get answer 627 @param conf_id: conf_id used to get answer
628 @param type: confirmation type ("YES/NO", "FILE_TRANSFER") 628 @param conf_type: confirmation conf_type ("YES/NO", "FILE_TRANSFER")
629 @param data: data (depend of confirmation type) 629 @param data: data (depend of confirmation conf_type)
630 @param cb: callback called with the answer 630 @param cb: callback called with the answer
631 """ 631 """
632 if self.__waiting_conf.has_key(id): 632 client = self.getClient(profile)
633 if not client:
634 raise ProfileUnknownError(_("Asking confirmation a non-existant profile"))
635 if client._waiting_conf.has_key(conf_id):
633 error (_("Attempt to register two callbacks for the same confirmation")) 636 error (_("Attempt to register two callbacks for the same confirmation"))
634 else: 637 else:
635 self.__waiting_conf[id] = cb 638 client._waiting_conf[conf_id] = cb
636 self.bridge.askConfirmation(type, id, data) 639 self.bridge.askConfirmation(conf_type, conf_id, data, profile)
637 640
638 641
639 def confirmationAnswer(self, id, accepted, data): 642 def confirmationAnswer(self, conf_id, accepted, data, profile):
640 """Called by frontends to answer confirmation requests""" 643 """Called by frontends to answer confirmation requests"""
641 debug (_("Received confirmation answer for id [%(id)s]: %(success)s") % {'id': id, 'success':_("accepted") if accepted else _("refused")}) 644 client = self.getClient(profile)
642 if not self.__waiting_conf.has_key(id): 645 if not client:
646 raise ProfileUnknownError(_("Confirmation answer from a non-existant profile"))
647 debug (_("Received confirmation answer for conf_id [%(conf_id)s]: %(success)s") % {'conf_id': conf_id, 'success':_("accepted") if accepted else _("refused")})
648 if not client._waiting_conf.has_key(conf_id):
643 error (_("Received an unknown confirmation")) 649 error (_("Received an unknown confirmation"))
644 else: 650 else:
645 cb = self.__waiting_conf[id] 651 cb = client._waiting_conf[conf_id]
646 del self.__waiting_conf[id] 652 del client._waiting_conf[conf_id]
647 cb(id, accepted, data) 653 cb(conf_id, accepted, data, profile)
648 654
649 def registerProgressCB(self, id, CB): 655 def registerProgressCB(self, progress_id, CB, profile):
650 """Register a callback called when progress is requested for id""" 656 """Register a callback called when progress is requested for id"""
651 self.__progress_cb_map[id] = CB 657 client = self.getClient(profile)
652 658 if not client:
653 def removeProgressCB(self, id): 659 raise ProfileUnknownError
660 client._progress_cb_map[progress_id] = CB
661
662 def removeProgressCB(self, progress_id, profile):
654 """Remove a progress callback""" 663 """Remove a progress callback"""
655 if not self.__progress_cb_map.has_key(id): 664 client = self.getClient(profile)
665 if not client:
666 raise ProfileUnknownError
667 if not client._progress_cb_map.has_key(progress_id):
656 error (_("Trying to remove an unknow progress callback")) 668 error (_("Trying to remove an unknow progress callback"))
657 else: 669 else:
658 del self.__progress_cb_map[id] 670 del client._progress_cb_map[progress_id]
659 671
660 def getProgress(self, id): 672 def getProgress(self, progress_id, profile):
661 """Return a dict with progress information 673 """Return a dict with progress information
662 data['position'] : current possition 674 data['position'] : current possition
663 data['size'] : end_position 675 data['size'] : end_position
664 """ 676 """
677 client = self.getClient(profile)
678 if not profile:
679 raise ProfileNotInCacheError
665 data = {} 680 data = {}
666 try: 681 try:
667 self.__progress_cb_map[id](id, data) 682 client._progress_cb_map[progress_id](progress_id, data, profile)
668 except KeyError: 683 except KeyError:
669 pass 684 pass
670 #debug("Requested progress for unknown id") 685 #debug("Requested progress for unknown progress_id")
671 return data 686 return data
672 687
673 def registerGeneralCB(self, name, CB): 688 def registerGeneralCB(self, name, CB):
674 """Register a callback called for general reason""" 689 """Register a callback called for general reason"""
675 self.__general_cb_map[name] = CB 690 self.__general_cb_map[name] = CB