SàT multi-profile: connection using profiles
- /!\ plugins are temporarly deactivated
This commit is contained in:
parent
d6b6f77bec
commit
714cf1ed2f
2 changed files with 76 additions and 63 deletions
130
sat.tac
130
sat.tac
|
|
@ -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
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Reference in a new issue