SàT multi-profile: connection using profiles

- /!\ plugins are temporarly deactivated
This commit is contained in:
Goffi 2010-01-29 13:55:41 +11:00
commit 714cf1ed2f
2 changed files with 76 additions and 63 deletions

130
sat.tac
View file

@ -70,11 +70,12 @@ def sat_next_id():
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 @@ class SatXMPPClient(client.XMPPClient):
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 @@ class SatMessageProtocol(xmppim.MessageProtocol):
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 @@ class SAT(service.Service):
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 @@ class SAT(service.Service):
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 @@ class SAT(service.Service):
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
self.messageProt = SatMessageProtocol(self)
self.messageProt.setHandlerParent(self.xmppclient)
#current.client.streamInitialized = self.streamInitialized #gof:
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 @@ class SAT(service.Service):
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 @@ class SAT(service.Service):
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 @@ class SAT(service.Service):
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 @@ class SAT(service.Service):
## 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

View file

@ -364,8 +364,6 @@ class Memory:
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 @@ class Memory:
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