Mercurial > libervia-backend
comparison src/core/xmpp.py @ 587:952322b1d490
Remove trailing whitespaces.
author | Emmanuel Gil Peyrot <linkmauve@linkmauve.fr> |
---|---|
date | Fri, 18 Jan 2013 17:55:34 +0100 |
parents | ca13633d3b6b |
children | d1b4805124a1 |
comparison
equal
deleted
inserted
replaced
586:6a718ede8be1 | 587:952322b1d490 |
---|---|
26 from sat.core import exceptions | 26 from sat.core import exceptions |
27 from calendar import timegm | 27 from calendar import timegm |
28 | 28 |
29 | 29 |
30 class SatXMPPClient(client.XMPPClient): | 30 class SatXMPPClient(client.XMPPClient): |
31 | 31 |
32 def __init__(self, host_app, profile, user_jid, password, host=None, port=5222): | 32 def __init__(self, host_app, profile, user_jid, password, host=None, port=5222): |
33 client.XMPPClient.__init__(self, user_jid, password, host, port) | 33 client.XMPPClient.__init__(self, user_jid, password, host, port) |
34 self.factory.clientConnectionLost = self.connectionLost | 34 self.factory.clientConnectionLost = self.connectionLost |
35 self.__connected=False | 35 self.__connected=False |
36 self.profile = profile | 36 self.profile = profile |
37 self.host_app = host_app | 37 self.host_app = host_app |
38 self.client_initialized = defer.Deferred() | 38 self.client_initialized = defer.Deferred() |
39 self.conn_deferred = defer.Deferred() | 39 self.conn_deferred = defer.Deferred() |
40 self._waiting_conf = {} #callback called when a confirmation is received | 40 self._waiting_conf = {} #callback called when a confirmation is received |
41 self._progress_cb_map = {} #callback called when a progress is requested (key = progress id) | 41 self._progress_cb_map = {} #callback called when a progress is requested (key = progress id) |
42 | 42 |
43 | 43 |
44 def getConnectionDeferred(self): | 44 def getConnectionDeferred(self): |
45 """Return a deferred which fire when the client is connected""" | 45 """Return a deferred which fire when the client is connected""" |
46 return self.conn_deferred | 46 return self.conn_deferred |
47 | 47 |
51 client.XMPPClient._authd(self, xmlstream) | 51 client.XMPPClient._authd(self, xmlstream) |
52 self.__connected=True | 52 self.__connected=True |
53 info (_("********** [%s] CONNECTED **********") % self.profile) | 53 info (_("********** [%s] CONNECTED **********") % self.profile) |
54 self.streamInitialized() | 54 self.streamInitialized() |
55 self.host_app.bridge.connected(self.profile) #we send the signal to the clients | 55 self.host_app.bridge.connected(self.profile) #we send the signal to the clients |
56 | 56 |
57 | 57 |
58 def streamInitialized(self): | 58 def streamInitialized(self): |
59 """Called after _authd""" | 59 """Called after _authd""" |
60 debug (_("XML stream is initialized")) | 60 debug (_("XML stream is initialized")) |
61 self.keep_alife = task.LoopingCall(self.xmlstream.send, " ") #Needed to avoid disconnection (specially with openfire) | 61 self.keep_alife = task.LoopingCall(self.xmlstream.send, " ") #Needed to avoid disconnection (specially with openfire) |
62 self.keep_alife.start(180) | 62 self.keep_alife.start(180) |
63 | 63 |
64 self.disco = SatDiscoProtocol(self) | 64 self.disco = SatDiscoProtocol(self) |
65 self.disco.setHandlerParent(self) | 65 self.disco.setHandlerParent(self) |
66 self.discoHandler = disco.DiscoHandler() | 66 self.discoHandler = disco.DiscoHandler() |
67 self.discoHandler.setHandlerParent(self) | 67 self.discoHandler.setHandlerParent(self) |
68 | 68 |
69 if not self.host_app.trigger.point("Disco Handled", self.profile): | 69 if not self.host_app.trigger.point("Disco Handled", self.profile): |
70 return | 70 return |
71 | 71 |
72 self.roster.requestRoster() | 72 self.roster.requestRoster() |
73 | 73 |
74 self.presence.available() | 74 self.presence.available() |
75 | 75 |
76 self.disco.requestInfo(jid.JID(self.jid.host)).addCallback(self.host_app.serverDisco, self.profile) #FIXME: use these informations | 76 self.disco.requestInfo(jid.JID(self.jid.host)).addCallback(self.host_app.serverDisco, self.profile) #FIXME: use these informations |
77 | 77 |
78 self.disco.requestItems(jid.JID(self.jid.host)).addCallback(self.host_app.serverDiscoItems, self.disco, self.profile, self.client_initialized) | 78 self.disco.requestItems(jid.JID(self.jid.host)).addCallback(self.host_app.serverDiscoItems, self.disco, self.profile, self.client_initialized) |
79 self.conn_deferred.callback(None) | 79 self.conn_deferred.callback(None) |
80 | 80 |
81 def initializationFailed(self, reason): | 81 def initializationFailed(self, reason): |
82 print ("initializationFailed: %s" % reason) | 82 print ("initializationFailed: %s" % reason) |
88 pass | 88 pass |
89 self.conn_deferred.errback() | 89 self.conn_deferred.errback() |
90 | 90 |
91 def isConnected(self): | 91 def isConnected(self): |
92 return self.__connected | 92 return self.__connected |
93 | 93 |
94 def connectionLost(self, connector, unused_reason): | 94 def connectionLost(self, connector, unused_reason): |
95 self.__connected=False | 95 self.__connected=False |
96 info (_("********** [%s] DISCONNECTED **********") % self.profile) | 96 info (_("********** [%s] DISCONNECTED **********") % self.profile) |
97 try: | 97 try: |
98 self.keep_alife.stop() | 98 self.keep_alife.stop() |
101 self.host_app.bridge.disconnected(self.profile) #we send the signal to the clients | 101 self.host_app.bridge.disconnected(self.profile) #we send the signal to the clients |
102 self.host_app.purgeClient(self.profile) #and we remove references to this client | 102 self.host_app.purgeClient(self.profile) #and we remove references to this client |
103 | 103 |
104 | 104 |
105 class SatMessageProtocol(xmppim.MessageProtocol): | 105 class SatMessageProtocol(xmppim.MessageProtocol): |
106 | 106 |
107 def __init__(self, host): | 107 def __init__(self, host): |
108 xmppim.MessageProtocol.__init__(self) | 108 xmppim.MessageProtocol.__init__(self) |
109 self.host = host | 109 self.host = host |
110 | 110 |
111 def onMessage(self, message): | 111 def onMessage(self, message): |
126 except IndexError: | 126 except IndexError: |
127 extra = {} | 127 extra = {} |
128 self.host.memory.addToHistory(jid.JID(message["from"]), jid.JID(message["to"]), mess_body, mess_type, profile=self.parent.profile) | 128 self.host.memory.addToHistory(jid.JID(message["from"]), jid.JID(message["to"]), mess_body, mess_type, profile=self.parent.profile) |
129 self.host.bridge.newMessage(message["from"], mess_body, mess_type, message['to'], extra, profile=self.parent.profile) | 129 self.host.bridge.newMessage(message["from"], mess_body, mess_type, message['to'], extra, profile=self.parent.profile) |
130 break | 130 break |
131 | 131 |
132 class SatRosterProtocol(xmppim.RosterClientProtocol): | 132 class SatRosterProtocol(xmppim.RosterClientProtocol): |
133 | 133 |
134 def __init__(self, host): | 134 def __init__(self, host): |
135 xmppim.RosterClientProtocol.__init__(self) | 135 xmppim.RosterClientProtocol.__init__(self) |
136 self.host = host | 136 self.host = host |
137 self.got_roster = defer.Deferred() | 137 self.got_roster = defer.Deferred() |
138 #XXX: the two following dicts keep a local copy of the roster | 138 #XXX: the two following dicts keep a local copy of the roster |
139 self._groups = {} #map from groups to bare jids: key=group value=set of bare jids | 139 self._groups = {} #map from groups to bare jids: key=group value=set of bare jids |
140 self._jids = {} #map from bare jids to RosterItem: key=jid value=RosterItem | 140 self._jids = {} #map from bare jids to RosterItem: key=jid value=RosterItem |
141 | 141 |
142 def rosterCb(self, roster): | 142 def rosterCb(self, roster): |
143 for raw_jid, item in roster.iteritems(): | 143 for raw_jid, item in roster.iteritems(): |
144 self.onRosterSet(item) | 144 self.onRosterSet(item) |
145 | 145 |
146 def requestRoster(self): | 146 def requestRoster(self): |
151 | 151 |
152 def removeItem(self, to): | 152 def removeItem(self, to): |
153 """Remove a contact from roster list""" | 153 """Remove a contact from roster list""" |
154 xmppim.RosterClientProtocol.removeItem(self, to) | 154 xmppim.RosterClientProtocol.removeItem(self, to) |
155 #TODO: check IQ result | 155 #TODO: check IQ result |
156 | 156 |
157 #XXX: disabled (cf http://wokkel.ik.nu/ticket/56)) | 157 #XXX: disabled (cf http://wokkel.ik.nu/ticket/56)) |
158 #def addItem(self, to): | 158 #def addItem(self, to): |
159 #"""Add a contact to roster list""" | 159 #"""Add a contact to roster list""" |
160 #xmppim.RosterClientProtocol.addItem(self, to) | 160 #xmppim.RosterClientProtocol.addItem(self, to) |
161 #TODO: check IQ result""" | 161 #TODO: check IQ result""" |
185 'ask': unicode(item.ask) | 185 'ask': unicode(item.ask) |
186 } | 186 } |
187 if item.name: | 187 if item.name: |
188 item_attr['name'] = item.name | 188 item_attr['name'] = item.name |
189 return item_attr | 189 return item_attr |
190 | 190 |
191 def onRosterSet(self, item): | 191 def onRosterSet(self, item): |
192 """Called when a new/update roster item is received""" | 192 """Called when a new/update roster item is received""" |
193 #TODO: send a signal to frontends | 193 #TODO: send a signal to frontends |
194 if not item.subscriptionTo and not item.subscriptionFrom and not item.ask: | 194 if not item.subscriptionTo and not item.subscriptionFrom and not item.ask: |
195 #XXX: current behaviour: we don't want contact in our roster list | 195 #XXX: current behaviour: we don't want contact in our roster list |
197 #may change in the future | 197 #may change in the future |
198 self.removeItem(item.jid) | 198 self.removeItem(item.jid) |
199 return | 199 return |
200 info (_("new contact in roster list: %s"), item.jid.full()) | 200 info (_("new contact in roster list: %s"), item.jid.full()) |
201 #self.host.memory.addContact(item.jid, item_attr, item.groups, self.parent.profile) | 201 #self.host.memory.addContact(item.jid, item_attr, item.groups, self.parent.profile) |
202 | 202 |
203 bare_jid = item.jid.userhost() | 203 bare_jid = item.jid.userhost() |
204 self._jids[bare_jid] = item | 204 self._jids[bare_jid] = item |
205 for group in item.groups: | 205 for group in item.groups: |
206 self._groups.setdefault(group,set()).add(bare_jid) | 206 self._groups.setdefault(group,set()).add(bare_jid) |
207 self.host.bridge.newContact(item.jid.full(), self.getAttributes(item), item.groups, self.parent.profile) | 207 self.host.bridge.newContact(item.jid.full(), self.getAttributes(item), item.groups, self.parent.profile) |
208 | 208 |
209 def onRosterRemove(self, entity): | 209 def onRosterRemove(self, entity): |
210 """Called when a roster removal event is received""" | 210 """Called when a roster removal event is received""" |
211 print _("removing %s from roster list") % entity.full() | 211 print _("removing %s from roster list") % entity.full() |
212 bare_jid = entity.userhost() | 212 bare_jid = entity.userhost() |
213 | 213 |
224 if not jids_set: | 224 if not jids_set: |
225 del self._groups[group] | 225 del self._groups[group] |
226 except KeyError: | 226 except KeyError: |
227 log.warning("there is not cache for the group [%(groups)s] of the removed roster item [%(jid)s]" % | 227 log.warning("there is not cache for the group [%(groups)s] of the removed roster item [%(jid)s]" % |
228 {"group": group, "jid": bare_jid}) | 228 {"group": group, "jid": bare_jid}) |
229 | 229 |
230 #then we send the bridge signal | 230 #then we send the bridge signal |
231 self.host.bridge.contactDeleted(entity.userhost(), self.parent.profile) | 231 self.host.bridge.contactDeleted(entity.userhost(), self.parent.profile) |
232 | 232 |
233 def getGroups(self): | 233 def getGroups(self): |
234 """Return a list of groups""" | 234 """Return a list of groups""" |
245 return self._jids.keys() | 245 return self._jids.keys() |
246 | 246 |
247 def isJidInRoster(self, entity_jid): | 247 def isJidInRoster(self, entity_jid): |
248 """Return True if jid is in roster""" | 248 """Return True if jid is in roster""" |
249 return entity_jid.userhost() in self._jids | 249 return entity_jid.userhost() in self._jids |
250 | 250 |
251 def getItems(self): | 251 def getItems(self): |
252 """Return all items of the roster""" | 252 """Return all items of the roster""" |
253 return self._jids.values() | 253 return self._jids.values() |
254 | 254 |
255 def getJidsFromGroup(self, group): | 255 def getJidsFromGroup(self, group): |
256 try: | 256 try: |
257 return self._groups[group] | 257 return self._groups[group] |
258 except KeyError: | 258 except KeyError: |
259 return exceptions.UnknownGroupError | 259 return exceptions.UnknownGroupError |
260 | 260 |
261 | 261 |
262 class SatPresenceProtocol(xmppim.PresenceClientProtocol): | 262 class SatPresenceProtocol(xmppim.PresenceClientProtocol): |
263 | 263 |
264 def __init__(self, host): | 264 def __init__(self, host): |
265 xmppim.PresenceClientProtocol.__init__(self) | 265 xmppim.PresenceClientProtocol.__init__(self) |
266 self.host = host | 266 self.host = host |
267 | 267 |
268 def availableReceived(self, entity, show=None, statuses=None, priority=0): | 268 def availableReceived(self, entity, show=None, statuses=None, priority=0): |
269 debug (_("presence update for [%(entity)s] (available, show=%(show)s statuses=%(statuses)s priority=%(priority)d)") % {'entity':entity, 'show':show, 'statuses':statuses, 'priority':priority}) | 269 debug (_("presence update for [%(entity)s] (available, show=%(show)s statuses=%(statuses)s priority=%(priority)d)") % {'entity':entity, 'show':show, 'statuses':statuses, 'priority':priority}) |
270 | 270 |
271 if not statuses: | 271 if not statuses: |
272 statuses = {} | 272 statuses = {} |
273 | 273 |
274 if statuses.has_key(None): #we only want string keys | 274 if statuses.has_key(None): #we only want string keys |
275 statuses["default"] = statuses[None] | 275 statuses["default"] = statuses[None] |
276 del statuses[None] | 276 del statuses[None] |
277 | 277 |
278 self.host.memory.setPresenceStatus(entity, show or "", | 278 self.host.memory.setPresenceStatus(entity, show or "", |
279 int(priority), statuses, self.parent.profile) | 279 int(priority), statuses, self.parent.profile) |
280 | 280 |
281 #now it's time to notify frontends | 281 #now it's time to notify frontends |
282 self.host.bridge.presenceUpdate(entity.full(), show or "", | 282 self.host.bridge.presenceUpdate(entity.full(), show or "", |
283 int(priority), statuses, self.parent.profile) | 283 int(priority), statuses, self.parent.profile) |
284 | 284 |
285 def unavailableReceived(self, entity, statuses=None): | 285 def unavailableReceived(self, entity, statuses=None): |
286 debug (_("presence update for [%(entity)s] (unavailable, statuses=%(statuses)s)") % {'entity':entity, 'statuses':statuses}) | 286 debug (_("presence update for [%(entity)s] (unavailable, statuses=%(statuses)s)") % {'entity':entity, 'statuses':statuses}) |
287 | 287 |
288 if not statuses: | 288 if not statuses: |
289 statuses = {} | 289 statuses = {} |
290 | 290 |
291 if statuses.has_key(None): #we only want string keys | 291 if statuses.has_key(None): #we only want string keys |
292 statuses["default"] = statuses[None] | 292 statuses["default"] = statuses[None] |
293 del statuses[None] | 293 del statuses[None] |
294 self.host.memory.setPresenceStatus(entity, "unavailable", 0, statuses, self.parent.profile) | 294 self.host.memory.setPresenceStatus(entity, "unavailable", 0, statuses, self.parent.profile) |
295 | 295 |
296 #now it's time to notify frontends | 296 #now it's time to notify frontends |
297 self.host.bridge.presenceUpdate(entity.full(), "unavailable", 0, statuses, self.parent.profile) | 297 self.host.bridge.presenceUpdate(entity.full(), "unavailable", 0, statuses, self.parent.profile) |
298 | 298 |
299 | 299 |
300 def available(self, entity=None, show=None, statuses=None, priority=0): | 300 def available(self, entity=None, show=None, statuses=None, priority=0): |
301 if not statuses: | 301 if not statuses: |
302 statuses = {} | 302 statuses = {} |
303 # default for us is None for wokkel | 303 # default for us is None for wokkel |
304 # so we must temporarily switch to wokkel's convention... | 304 # so we must temporarily switch to wokkel's convention... |
305 if 'default' in statuses: | 305 if 'default' in statuses: |
306 statuses[None] = statuses['default'] | 306 statuses[None] = statuses['default'] |
307 | 307 |
308 xmppim.PresenceClientProtocol.available(self, entity, show, statuses, priority) | 308 xmppim.PresenceClientProtocol.available(self, entity, show, statuses, priority) |
309 presence_elt = xmppim.AvailablePresence(entity, show, statuses, priority) | 309 presence_elt = xmppim.AvailablePresence(entity, show, statuses, priority) |
378 self.user_pass = user_pass | 378 self.user_pass = user_pass |
379 self.user_email = email | 379 self.user_email = email |
380 self.answer_id = answer_id | 380 self.answer_id = answer_id |
381 self.profile = profile | 381 self.profile = profile |
382 print _("Registration asked for"),user_login, user_pass, jabber_host | 382 print _("Registration asked for"),user_login, user_pass, jabber_host |
383 | 383 |
384 def connectionMade(self): | 384 def connectionMade(self): |
385 print "connectionMade" | 385 print "connectionMade" |
386 | 386 |
387 self.xmlstream.namespace = "jabber:client" | 387 self.xmlstream.namespace = "jabber:client" |
388 self.xmlstream.sendHeader() | 388 self.xmlstream.sendHeader() |
389 | 389 |
390 iq = compat.IQ(self.xmlstream, 'set') | 390 iq = compat.IQ(self.xmlstream, 'set') |
391 iq["to"] = self.jabber_host | 391 iq["to"] = self.jabber_host |
403 debug (_("registration answer: %s") % answer.toXml()) | 403 debug (_("registration answer: %s") % answer.toXml()) |
404 answer_type = "SUCCESS" | 404 answer_type = "SUCCESS" |
405 answer_data={"message":_("Registration successfull")} | 405 answer_data={"message":_("Registration successfull")} |
406 self.host.bridge.actionResult(answer_type, self.answer_id, answer_data, self.profile) | 406 self.host.bridge.actionResult(answer_type, self.answer_id, answer_data, self.profile) |
407 self.xmlstream.sendFooter() | 407 self.xmlstream.sendFooter() |
408 | 408 |
409 def registrationFailure(self, failure): | 409 def registrationFailure(self, failure): |
410 info (_("Registration failure: %s") % str(failure.value)) | 410 info (_("Registration failure: %s") % str(failure.value)) |
411 answer_type = "ERROR" | 411 answer_type = "ERROR" |
412 answer_data = {} | 412 answer_data = {} |
413 if failure.value.condition == 'conflict': | 413 if failure.value.condition == 'conflict': |