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
This commit is contained in:
Goffi 2012-11-10 16:38:16 +01:00
commit fa38394401
3 changed files with 570 additions and 400 deletions

View file

@ -33,3 +33,6 @@ class UnknownEntityError(Exception):
class UnknownGroupError(Exception):
pass
class NotFound(Exception):
pass

View file

@ -44,7 +44,7 @@ import sys
import os.path
from sat.core import xmpp
from sat.core.exceptions import ProfileUnknownError, UnknownEntityError
from sat.core.exceptions import ProfileUnknownError, UnknownEntityError, ProfileNotInCacheError
from sat.memory.memory import Memory
from sat.tools.xml_tools import tupleList2dataForm
from sat.tools.misc import TriggerManager
@ -98,8 +98,6 @@ class SAT(service.Service):
def __init__(self):
#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.profiles = {}
@ -134,8 +132,8 @@ class SAT(service.Service):
self.bridge.register("sendMessage", self.sendMessage)
self.bridge.register("getConfig", self.memory.getConfig)
self.bridge.register("setParam", self.setParam)
self.bridge.register("getParamA", self.memory.getParamA)
self.bridge.register("asyncGetParamA", self.memory.asyncGetParamA)
self.bridge.register("getParamA", self.memory.getStringParamA)
self.bridge.register("asyncGetParamA", self.memory.asyncGetStringParamA)
self.bridge.register("getParamsUI", self.memory.getParamsUI)
self.bridge.register("getParams", self.memory.getParams)
self.bridge.register("getParamsForCategory", self.memory.getParamsForCategory)
@ -336,11 +334,13 @@ class SAT(service.Service):
return None
return self.profiles[profile]
def registerNewAccount(self, login, password, email, server, port = 5222, id = None):
def registerNewAccount(self, login, password, email, server, port = 5222, id = None, profile_key = '@DEFAULT@'):
"""Connect to a server and create a new account using in-band registration"""
profile = self.memory.getProfileName(profile_key)
assert(profile)
next_id = id or sat_next_id() #the id is used to send server's answer
serverRegistrer = xmlstream.XmlStreamFactory(xmpp.RegisteringAuthenticator(self, server, login, password, email, next_id))
serverRegistrer = xmlstream.XmlStreamFactory(xmpp.RegisteringAuthenticator(self, server, login, password, email, next_id, profile))
connector = reactor.connectTCP(server, port, serverRegistrer)
serverRegistrer.clientConnectionLost = lambda conn, reason: connector.disconnect()
@ -354,7 +354,7 @@ class SAT(service.Service):
if not user or not password or not server:
info (_('No user or server given'))
#TODO: a proper error message must be sent to frontend
self.actionResult(id, "ERROR", {'message':_("No user, password or server given, can't register new account.")})
self.actionResult(id, "ERROR", {'message':_("No user, password or server given, can't register new account.")}, profile)
return
confirm_id = sat_next_id()
@ -362,12 +362,12 @@ class SAT(service.Service):
self.askConfirmation(confirm_id, "YES/NO",
{"message":_("Are you sure to register new account [%(user)s] to server %(server)s ?") % {'user':user, 'server':server, 'profile':profile}},
self.regisConfirmCB)
self.regisConfirmCB, profile)
print ("===============+++++++++++ REGISTER NEW ACCOUNT++++++++++++++============")
print "id=",id
print "data=",data
def regisConfirmCB(self, id, accepted, data):
def regisConfirmCB(self, id, accepted, data, profile):
print _("register Confirmation CB ! (%s)") % str(accepted)
action_id,profile = self.__private_data[id]
del self.__private_data[id]
@ -377,7 +377,7 @@ class SAT(service.Service):
server = self.memory.getParamA("Server", "Connection", profile_key=profile)
self.registerNewAccount(user, password, None, server, id=action_id)
else:
self.actionResult(action_id, "SUPPRESS", {})
self.actionResult(action_id, "SUPPRESS", {}, profile)
def submitForm(self, action, target, fields, profile_key):
"""submit a form
@ -601,73 +601,88 @@ class SAT(service.Service):
## Generic HMI ##
def actionResult(self, id, type, data):
def actionResult(self, action_id, action_type, data, profile):
"""Send the result of an action
@param id: same id used with action
@param type: result type ("PARAM", "SUCCESS", "ERROR", "XMLUI")
@param action_id: same action_id used with action
@param action_type: result action_type ("PARAM", "SUCCESS", "ERROR", "XMLUI")
@param data: dictionary
"""
self.bridge.actionResult(type, id, data)
self.bridge.actionResult(action_type, action_id, data, profile)
def actionResultExt(self, id, type, data):
def actionResultExt(self, action_id, action_type, data, profile):
"""Send the result of an action, extended version
@param id: same id used with action
@param type: result type /!\ only "DICT_DICT" for this method
@param action_id: same action_id used with action
@param action_type: result action_type /!\ only "DICT_DICT" for this method
@param data: dictionary of dictionaries
"""
if type != "DICT_DICT":
error(_("type for actionResultExt must be DICT_DICT, fixing it"))
type = "DICT_DICT"
self.bridge.actionResultExt(type, id, data)
if action_type != "DICT_DICT":
error(_("action_type for actionResultExt must be DICT_DICT, fixing it"))
action_type = "DICT_DICT"
self.bridge.actionResultExt(action_type, action_id, data, profile)
def askConfirmation(self, id, type, data, cb):
def askConfirmation(self, conf_id, conf_type, data, cb, profile):
"""Add a confirmation callback
@param id: id used to get answer
@param type: confirmation type ("YES/NO", "FILE_TRANSFER")
@param data: data (depend of confirmation type)
@param conf_id: conf_id used to get answer
@param conf_type: confirmation conf_type ("YES/NO", "FILE_TRANSFER")
@param data: data (depend of confirmation conf_type)
@param cb: callback called with the answer
"""
if self.__waiting_conf.has_key(id):
client = self.getClient(profile)
if not client:
raise ProfileUnknownError(_("Asking confirmation a non-existant profile"))
if client._waiting_conf.has_key(conf_id):
error (_("Attempt to register two callbacks for the same confirmation"))
else:
self.__waiting_conf[id] = cb
self.bridge.askConfirmation(type, id, data)
client._waiting_conf[conf_id] = cb
self.bridge.askConfirmation(conf_type, conf_id, data, profile)
def confirmationAnswer(self, id, accepted, data):
def confirmationAnswer(self, conf_id, accepted, data, profile):
"""Called by frontends to answer confirmation requests"""
debug (_("Received confirmation answer for id [%(id)s]: %(success)s") % {'id': id, 'success':_("accepted") if accepted else _("refused")})
if not self.__waiting_conf.has_key(id):
client = self.getClient(profile)
if not client:
raise ProfileUnknownError(_("Confirmation answer from a non-existant profile"))
debug (_("Received confirmation answer for conf_id [%(conf_id)s]: %(success)s") % {'conf_id': conf_id, 'success':_("accepted") if accepted else _("refused")})
if not client._waiting_conf.has_key(conf_id):
error (_("Received an unknown confirmation"))
else:
cb = self.__waiting_conf[id]
del self.__waiting_conf[id]
cb(id, accepted, data)
cb = client._waiting_conf[conf_id]
del client._waiting_conf[conf_id]
cb(conf_id, accepted, data, profile)
def registerProgressCB(self, id, CB):
def registerProgressCB(self, progress_id, CB, profile):
"""Register a callback called when progress is requested for id"""
self.__progress_cb_map[id] = CB
client = self.getClient(profile)
if not client:
raise ProfileUnknownError
client._progress_cb_map[progress_id] = CB
def removeProgressCB(self, id):
def removeProgressCB(self, progress_id, profile):
"""Remove a progress callback"""
if not self.__progress_cb_map.has_key(id):
client = self.getClient(profile)
if not client:
raise ProfileUnknownError
if not client._progress_cb_map.has_key(progress_id):
error (_("Trying to remove an unknow progress callback"))
else:
del self.__progress_cb_map[id]
del client._progress_cb_map[progress_id]
def getProgress(self, id):
def getProgress(self, progress_id, profile):
"""Return a dict with progress information
data['position'] : current possition
data['size'] : end_position
"""
client = self.getClient(profile)
if not profile:
raise ProfileNotInCacheError
data = {}
try:
self.__progress_cb_map[id](id, data)
client._progress_cb_map[progress_id](progress_id, data, profile)
except KeyError:
pass
#debug("Requested progress for unknown id")
#debug("Requested progress for unknown progress_id")
return data
def registerGeneralCB(self, name, CB):

View file

@ -37,6 +37,9 @@ class SatXMPPClient(client.XMPPClient):
self.host_app = host_app
self.client_initialized = defer.Deferred()
self.conn_deferred = defer.Deferred()
self._waiting_conf = {} #callback called when a confirmation is received
self._progress_cb_map = {} #callback called when a progress is requested (key = progress id)
def getConnectionDeferred(self):
"""Return a deferred which fire when the client is connected"""
@ -360,7 +363,7 @@ class SatFallbackHandler(generic.FallbackHandler):
class RegisteringAuthenticator(xmlstream.ConnectAuthenticator):
def __init__(self, host, jabber_host, user_login, user_pass, email, answer_id):
def __init__(self, host, jabber_host, user_login, user_pass, email, answer_id, profile):
xmlstream.ConnectAuthenticator.__init__(self, jabber_host)
self.host = host
self.jabber_host = jabber_host
@ -368,6 +371,7 @@ class RegisteringAuthenticator(xmlstream.ConnectAuthenticator):
self.user_pass = user_pass
self.user_email = email
self.answer_id = answer_id
self.profile = profile
print _("Registration asked for"),user_login, user_pass, jabber_host
def connectionMade(self):
@ -392,7 +396,7 @@ class RegisteringAuthenticator(xmlstream.ConnectAuthenticator):
debug (_("registration answer: %s") % answer.toXml())
answer_type = "SUCCESS"
answer_data={"message":_("Registration successfull")}
self.host.bridge.actionResult(answer_type, self.answer_id, answer_data)
self.host.bridge.actionResult(answer_type, self.answer_id, answer_data, self.profile)
self.xmlstream.sendFooter()
def registrationFailure(self, failure):
@ -405,7 +409,7 @@ class RegisteringAuthenticator(xmlstream.ConnectAuthenticator):
else:
answer_data['reason'] = 'unknown'
answer_data={"message":_("Registration failed (%s)") % str(failure.value.condition)}
self.host.bridge.actionResult(answer_type, self.answer_id, answer_data)
self.host.bridge.actionResult(answer_type, self.answer_id, answer_data, self.profile)
self.xmlstream.sendFooter()
class SatVersionHandler(generic.VersionHandler):