# HG changeset patch # User Goffi # Date 1264733741 -39600 # Node ID 93cb45a7420ff35f37a30d0cd03999826bcb7c23 # Parent 58d49fc19639cd9733a55993663dbd7f15ca508b SàT multi-profile: connection using profiles - /!\ plugins are temporarly deactivated diff -r 58d49fc19639 -r 93cb45a7420f sat.tac --- a/sat.tac Thu Jan 28 12:38:12 2010 +1100 +++ b/sat.tac Fri Jan 29 13:55:41 2010 +1100 @@ -70,11 +70,12 @@ class SatXMPPClient(client.XMPPClient): - def __init__(self, bridge, user_jid, password, host=None, port=5222): + def __init__(self, bridge, profile, user_jid, password, host=None, port=5222): client.XMPPClient.__init__(self, user_jid, password, host, port) self.factory.clientConnectionLost = self.connectionLost self.__connected=False self.bridge = bridge + self.profile = profile def _authd(self, xmlstream): print "SatXMPPClient" @@ -86,8 +87,21 @@ def streamInitialized(self): """Called after _authd""" + debug ("XML stream is initialized") self.keep_alife = task.LoopingCall(self.xmlstream.send, " ") #Needed to avoid disconnection (specially with openfire) self.keep_alife.start(180) + + self.disco = SatDiscoProtocol(self) + self.disco.setHandlerParent(self) + self.discoHandler = disco.DiscoHandler() + self.discoHandler.setHandlerParent(self) + + self.roster.requestRoster() + + self.presence.available() + + #self.disco.requestInfo(jid.JID(self.memory.getParamA("Server", "Connection"))).addCallback(self.host.serverDisco) #gof: FIXME + def isConnected(self): return self.__connected @@ -113,7 +127,7 @@ for e in message.elements(): if e.name == "body": self.host.bridge.newMessage(message["from"], e.children[0]) - self.host.memory.addToHistory(self.host.me, jid.JID(message["from"]), self.host.me, "chat", e.children[0]) + self.host.memory.addToHistory(self.parent.jid, jid.JID(message["from"]), self.parent.jid, "chat", e.children[0]) break class SatRosterProtocol(xmppim.RosterClientProtocol): @@ -306,6 +320,7 @@ 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 = {} self.plugins = {} self.memory=Memory(self) @@ -336,7 +351,7 @@ self.bridge.register("confirmationAnswer", self.confirmationAnswer) self.bridge.register("getProgress", self.getProgress) - self._import_plugins() + #self._import_plugins() #gof: def _import_plugins(self): @@ -353,45 +368,50 @@ self.plugins[plug_info['import_name']] = getattr(mod, plug_info['main'])(self) #TODO: test xmppclient presence and register handler parent - def getJidFrProfile(self, profile): - """Return jid from source""" - if profile == "@DEFAULT@": - return jid.JID(self.memory.getParamA("JabberID", "Connection")) - - def connect(self, profile = '@DEFAULT@'): + def connect(self, profile_key = '@DEFAULT@'): """Connect to jabber server""" + + profile = self.memory.getProfileName(profile_key) + if not profile_key: + error ('Trying to connect a non-exsitant profile') + return + if (self.isConnected()): info("already connected !") return print "connecting..." - self.me = self.getJidFrProfile(profile) - self.xmppclient = SatXMPPClient(self.bridge, self.me, self.memory.getParamA("Password", "Connection"), + current = self.profiles[profile] = SatXMPPClient(self.bridge, profile, + jid.JID(self.memory.getParamA("JabberID", "Connection"), profile), + self.memory.getParamA("Password", "Connection"), self.memory.getParamA("Server", "Connection"), 5222) - self.xmppclient.streamInitialized = self.streamInitialized + + #current.client.streamInitialized = self.streamInitialized #gof: - self.messageProt = SatMessageProtocol(self) - self.messageProt.setHandlerParent(self.xmppclient) + current.messageProt = SatMessageProtocol(self) + current.messageProt.setHandlerParent(current) - self.roster = SatRosterProtocol(self) - self.roster.setHandlerParent(self.xmppclient) + current.roster = SatRosterProtocol(self) + current.roster.setHandlerParent(current) - self.presence = SatPresenceProtocol(self) - self.presence.setHandlerParent(self.xmppclient) + current.presence = SatPresenceProtocol(self) + current.presence.setHandlerParent(current) - self.fallBack = SatFallbackHandler(self) - self.fallBack.setHandlerParent(self.xmppclient) + current.fallBack = SatFallbackHandler(self) + current.fallBack.setHandlerParent(current) - self.versionHandler = generic.VersionHandler(self.get_const('client_name'), + current.versionHandler = generic.VersionHandler(self.get_const('client_name'), self.get_const('client_version')) - self.versionHandler.setHandlerParent(self.xmppclient) + current.versionHandler.setHandlerParent(current) debug ("setting plugins parents") + + #FIXME: gof for plugin in self.plugins.iteritems(): if isinstance(plugin[1], XMPPHandler): - plugin[1].setHandlerParent(self.xmppclient) + plugin[1].setHandlerParent(current) - self.xmppclient.startService() + current.startService() def disconnect(self): """disconnect from jabber server""" @@ -417,24 +437,6 @@ debug("stopping app") reactor.stop() - def streamInitialized(self): - """Called when xmlstream is OK""" - SatXMPPClient.streamInitialized(self.xmppclient) - debug ("XML stream is initialized") - self.xmlstream = self.xmppclient.xmlstream - self.me = self.xmppclient.jid #in case of the ressource has changed - - self.disco = SatDiscoProtocol(self) - self.disco.setHandlerParent(self.xmppclient) - self.discoHandler = disco.DiscoHandler() - self.discoHandler.setHandlerParent(self.xmppclient) - - self.roster.requestRoster() - - self.presence.available() - - self.disco.requestInfo(jid.JID(self.memory.getParamA("Server", "Connection"))).addCallback(self.serverDisco) - ## Misc methods ## def registerNewAccount(self, login, password, server, port = 5222, id = None): @@ -480,17 +482,20 @@ else: self.actionResult(action_id, "SUPPRESS", {}) - def submitForm(self, action, target, fields): + def submitForm(self, action, target, fields, profile_key='@DEFAULT@'): """submit a form @param target: target jid where we are submitting @param fields: list of tuples (name, value) @return: tuple: (id, deferred) """ + + profile = self.memory.getProfileName(profile_key) + assert(profile) to_jid = jid.JID(target) - iq = compat.IQ(self.xmlstream, 'set') + iq = compat.IQ(self.profiles[profile].xmlstream, 'set') iq["to"] = target - iq["from"] = self.me.full() + iq["from"] = self.profiles[profile].jid.full() query = iq.addElement(('jabber:iq:register', 'query')) if action=='SUBMIT': form = XMLTools.tupleList2dataForm(fields) @@ -511,18 +516,18 @@ info ("setting param: %s=%s in category %s", name, value, category) self.memory.setParam(name, value, category) - def failed(self,xmlstream): - debug("failed: %s", xmlstream.getErrorMessage()) - debug("failed: %s", dir(xmlstream)) - - def isConnected(self): - try: - if self.xmppclient.isConnected(): - return True - except AttributeError: - #xmppclient not available - pass - return False + def isConnected(self, profile_key='@DEFAULT@'): + """Return connection status of profile + @param profile_key: key_word or profile name to determine profile name + @return True if connected + """ + profile = self.memory.getProfileName(profile_key) + if not profile: + error ('asking connection status for a non-existant profile') + raise Exception #TODO: raise a proper exception + if not self.profiles.has_key(profile): + return False + return self.profiles[profile].isConnected() def launchAction(self, type, data): """Launch a specific action asked by client @@ -547,16 +552,19 @@ ## jabber methods ## - def sendMessage(self,to,msg,type='chat'): + def sendMessage(self,to,msg,type='chat', profile_key='@DEFAULT@'): #FIXME: check validity of recipient + profile = self.memory.getProfileName(profile_key) + assert(profile) + current_jid = self.profiles[profile].jid debug("Sending jabber message to %s...", to) message = domish.Element(('jabber:client','message')) message["to"] = jid.JID(to).full() - message["from"] = self.me.full() + message["from"] = current_jid.full() message["type"] = type message.addElement("body", "jabber:client", msg) - self.xmlstream.send(message) - self.memory.addToHistory(self.me, self.me, jid.JID(to), message["type"], unicode(msg)) + self.profiles[profile].xmlstream.send(message) + self.memory.addToHistory(current_jid, current_jid, jid.JID(to), message["type"], unicode(msg)) self.bridge.newMessage(message['from'], unicode(msg), to=message['to']) #We send back the message, so all clients are aware of it diff -r 58d49fc19639 -r 93cb45a7420f tools/memory.py --- a/tools/memory.py Thu Jan 28 12:38:12 2010 +1100 +++ b/tools/memory.py Fri Jan 29 13:55:41 2010 +1100 @@ -364,8 +364,6 @@ self.params=Param(host) self.history={} #used to store chat history (key: short jid) self.private={} #used to store private value - self.disco={} #XXX: maybe best in a separate class - self.features={} host.set_const('savefile_history', SAVEFILE_HISTORY) host.set_const('savefile_private', SAVEFILE_PRIVATE) self.load() @@ -442,6 +440,13 @@ def getProfilesList(self): return self.params.getProfilesList() + + def getProfileName(self, profile_key): + """Return name of profile from keyword + @param profile_key: can be the profile name or a keywork (like @DEFAULT@) + @return: profile name or None if it doesn't exist""" + return self.params.getProfileName(profile_key) + def createProfile(self, name, default=False): """Create a new profile @param name: Profile name