Mercurial > libervia-backend
diff src/sat.tac @ 330:608a4a2ba94e
Core: created a new core module where xmpp classes are put
author | Goffi <goffi@goffi.org> |
---|---|
date | Mon, 23 May 2011 21:18:58 +0200 |
parents | b069055320b1 |
children | 0a8eb0461f31 |
line wrap: on
line diff
--- a/src/sat.tac Mon May 23 01:01:44 2011 +0200 +++ b/src/sat.tac Mon May 23 21:18:58 2011 +0200 @@ -48,6 +48,7 @@ import signal, sys import os.path +from sat.core.xmpp import SatXMPPClient, SatMessageProtocol, SatRosterProtocol, SatPresenceProtocol, SatDiscoProtocol, SatFallbackHandler, RegisteringAuthenticator, SatVersionHandler from sat.tools.memory import Memory from sat.tools.xml_tools import tupleList2dataForm from sat.tools.misc import TriggerManager @@ -72,264 +73,6 @@ sat_id+=1 return "sat_id_"+str(sat_id) -class SatXMPPClient(client.XMPPClient): - - def __init__(self, host_app, 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.profile = profile - self.host_app = host_app - self.client_initialized = defer.Deferred() - - def _authd(self, xmlstream): - if not self.host_app.trigger.point("XML Initialized", xmlstream, self.profile): - return - client.XMPPClient._authd(self, xmlstream) - self.__connected=True - info (_("********** [%s] CONNECTED **********") % self.profile) - self.streamInitialized() - self.host_app.bridge.connected(self.profile) #we send the signal to the clients - - - 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) - - if not self.host_app.trigger.point("Disco Handled", self.profile): - return - - self.roster.requestRoster() - - self.presence.available() - - self.disco.requestInfo(jid.JID(self.host_app.memory.getParamA("Server", "Connection", profile_key=self.profile))).addCallback(self.host_app.serverDisco, self.profile) #FIXME: use these informations - self.disco.requestItems(jid.JID(self.host_app.memory.getParamA("Server", "Connection", profile_key=self.profile))).addCallback(self.host_app.serverDiscoItems, self.disco, self.profile, self.client_initialized) - - def initializationFailed(self, reason): - print ("initializationFailed: %s" % reason) - self.host_app.bridge.connectionError("AUTH_ERROR", self.profile) - try: - client.XMPPClient.initializationFailed(self, reason) - except: - #we already send an error signal, no need to raise an exception - pass - - def isConnected(self): - return self.__connected - - def connectionLost(self, connector, unused_reason): - self.__connected=False - info (_("********** [%s] DISCONNECTED **********") % self.profile) - try: - self.keep_alife.stop() - except AttributeError: - debug (_("No keep_alife")) - self.host_app.bridge.disconnected(self.profile) #we send the signal to the clients - - -class SatMessageProtocol(xmppim.MessageProtocol): - - def __init__(self, host): - xmppim.MessageProtocol.__init__(self) - self.host = host - - def onMessage(self, message): - debug (_(u"got message from: %s"), message["from"]) - if not self.host.trigger.point("MessageReceived",message, profile=self.parent.profile): - return - for e in message.elements(): - if e.name == "body": - mess_type = message['type'] if message.hasAttribute('type') else 'normal' - self.host.bridge.newMessage(message["from"], e.children[0], mess_type, message['to'], profile=self.parent.profile) - self.host.memory.addToHistory(self.parent.jid, jid.JID(message["from"]), self.parent.jid, "chat", e.children[0]) - break - -class SatRosterProtocol(xmppim.RosterClientProtocol): - - def __init__(self, host): - xmppim.RosterClientProtocol.__init__(self) - self.host = host - self._groups=set() - - def rosterCb(self, roster): - for raw_jid, item in roster.iteritems(): - self.onRosterSet(item) - - def requestRoster(self): - """ ask the server for Roster list """ - debug("requestRoster") - self.getRoster().addCallback(self.rosterCb) - - def removeItem(self, to): - """Remove a contact from roster list""" - xmppim.RosterClientProtocol.removeItem(self, to) - #TODO: check IQ result - - #XXX: disabled (cf http://wokkel.ik.nu/ticket/56)) - #def addItem(self, to): - #"""Add a contact to roster list""" - #xmppim.RosterClientProtocol.addItem(self, to) - #TODO: check IQ result""" - - def onRosterSet(self, item): - """Called when a new/update roster item is received""" - #TODO: send a signal to frontends - item_attr = {'to': str(item.subscriptionTo), - 'from': str(item.subscriptionFrom), - 'ask': str(item.ask) - } - if item.name: - item_attr['name'] = item.name - info (_("new contact in roster list: %s"), item.jid.full()) - self.host.memory.addContact(item.jid, item_attr, item.groups, self.parent.profile) - self.host.bridge.newContact(item.jid.full(), item_attr, item.groups, self.parent.profile) - self._groups.update(item.groups) - - def onRosterRemove(self, entity): - """Called when a roster removal event is received""" - #TODO: send a signal to frontends - print _("removing %s from roster list") % entity.full() - self.host.memory.delContact(entity, self.parent.profile) - - def getGroups(self): - """Return a set of groups""" - return self._groups - -class SatPresenceProtocol(xmppim.PresenceClientProtocol): - - def __init__(self, host): - xmppim.PresenceClientProtocol.__init__(self) - self.host = host - - def availableReceived(self, entity, show=None, statuses=None, priority=0): - debug (_("presence update for [%(entity)s] (available, show=%(show)s statuses=%(statuses)s priority=%(priority)d)") % {'entity':entity, 'show':show, 'statuses':statuses, 'priority':priority}) - - if statuses.has_key(None): #we only want string keys - statuses["default"] = statuses[None] - del statuses[None] - - self.host.memory.addPresenceStatus(entity, show or "", - int(priority), statuses, self.parent.profile) - - #now it's time to notify frontends - self.host.bridge.presenceUpdate(entity.full(), show or "", - int(priority), statuses, self.parent.profile) - - def unavailableReceived(self, entity, statuses=None): - debug (_("presence update for [%(entity)s] (unavailable, statuses=%(statuses)s)") % {'entity':entity, 'statuses':statuses}) - if statuses and statuses.has_key(None): #we only want string keys - statuses["default"] = statuses[None] - del statuses[None] - self.host.memory.addPresenceStatus(entity, "unavailable", 0, statuses, self.parent.profile) - - #now it's time to notify frontends - self.host.bridge.presenceUpdate(entity.full(), "unavailable", 0, statuses, self.parent.profile) - - - def available(self, entity=None, show=None, statuses=None, priority=0): - if statuses and statuses.has_key('default'): - statuses[None] = statuses['default'] - del statuses['default'] - xmppim.PresenceClientProtocol.available(self, entity, show, statuses, priority) - - def subscribedReceived(self, entity): - debug (_("subscription approved for [%s]") % entity.userhost()) - self.host.memory.delWaitingSub(entity.userhost(), self.parent.profile) - self.host.bridge.subscribe('subscribed', entity.userhost(), self.parent.profile) - - def unsubscribedReceived(self, entity): - debug (_("unsubscription confirmed for [%s]") % entity.userhost()) - self.host.memory.delWaitingSub(entity.userhost(), self.parent.profile) - self.host.bridge.subscribe('unsubscribed', entity.userhost(), self.parent.profile) - - def subscribeReceived(self, entity): - debug (_("subscription request for [%s]") % entity.userhost()) - self.host.memory.addWaitingSub('subscribe', entity.userhost(), self.parent.profile) - self.host.bridge.subscribe('subscribe', entity.userhost(), self.parent.profile) - - def unsubscribeReceived(self, entity): - debug (_("unsubscription asked for [%s]") % entity.userhost()) - self.host.memory.addWaitingSub('unsubscribe', entity.userhost(), self.parent.profile) - self.host.bridge.subscribe('unsubscribe', entity.userhost(), self.parent.profile) - -class SatDiscoProtocol(disco.DiscoClientProtocol): - def __init__(self, host): - disco.DiscoClientProtocol.__init__(self) - -class SatFallbackHandler(generic.FallbackHandler): - def __init__(self, host): - generic.FallbackHandler.__init__(self) - - def iqFallback(self, iq): - if iq.handled == True: - return - debug (u"iqFallback: xml = [%s]" % (iq.toXml())) - generic.FallbackHandler.iqFallback(self, iq) - -class RegisteringAuthenticator(xmlstream.ConnectAuthenticator): - - def __init__(self, host, jabber_host, user_login, user_pass, answer_id): - xmlstream.ConnectAuthenticator.__init__(self, jabber_host) - self.host = host - self.jabber_host = jabber_host - self.user_login = user_login - self.user_pass = user_pass - self.answer_id = answer_id - print _("Registration asked for"),user_login, user_pass, jabber_host - - def connectionMade(self): - print "connectionMade" - - self.xmlstream.namespace = "jabber:client" - self.xmlstream.sendHeader() - - iq = compat.IQ(self.xmlstream, 'set') - iq["to"] = self.jabber_host - query = iq.addElement(('jabber:iq:register', 'query')) - _user = query.addElement('username') - _user.addContent(self.user_login) - _pass = query.addElement('password') - _pass.addContent(self.user_pass) - reg = iq.send(self.jabber_host).addCallbacks(self.registrationAnswer, self.registrationFailure) - - def registrationAnswer(self, answer): - 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.xmlstream.sendFooter() - - def registrationFailure(self, failure): - info (_("Registration failure: %s") % str(failure.value)) - answer_type = "ERROR" - answer_data = {} - if failure.value.condition == 'conflict': - answer_data['reason'] = 'conflict' - answer_data={"message":_("Username already exists, please choose an other one")} - 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.xmlstream.sendFooter() - -class SatVersionHandler(generic.VersionHandler): - - def getDiscoInfo(self, requestor, target, node): - #XXX: We need to work around wokkel's behavious (namespace not added if there is a - # node) as it cause issues with XEP-0115 & PEP (XEP-0163): there is a node when server - # ask for disco info, and not when we generate the key, so the hash is used with different - # disco features, and when the server (seen on ejabberd) generate its own hash for security check - # it reject our features (resulting in e.g. no notification on PEP) - return generic.VersionHandler.getDiscoInfo(self, requestor, target, None) - class SAT(service.Service): def get_next_id(self):