Mercurial > libervia-backend
comparison sat.tac @ 62:93cb45a7420f
SàT multi-profile: connection using profiles
- /!\ plugins are temporarly deactivated
author | Goffi <goffi@goffi.org> |
---|---|
date | Fri, 29 Jan 2010 13:55:41 +1100 |
parents | 9764e027ecc0 |
children | 0db25931b60d |
comparison
equal
deleted
inserted
replaced
61:58d49fc19639 | 62:93cb45a7420f |
---|---|
68 sat_id+=1 | 68 sat_id+=1 |
69 return "sat_id_"+str(sat_id) | 69 return "sat_id_"+str(sat_id) |
70 | 70 |
71 class SatXMPPClient(client.XMPPClient): | 71 class SatXMPPClient(client.XMPPClient): |
72 | 72 |
73 def __init__(self, bridge, user_jid, password, host=None, port=5222): | 73 def __init__(self, bridge, profile, user_jid, password, host=None, port=5222): |
74 client.XMPPClient.__init__(self, user_jid, password, host, port) | 74 client.XMPPClient.__init__(self, user_jid, password, host, port) |
75 self.factory.clientConnectionLost = self.connectionLost | 75 self.factory.clientConnectionLost = self.connectionLost |
76 self.__connected=False | 76 self.__connected=False |
77 self.bridge = bridge | 77 self.bridge = bridge |
78 self.profile = profile | |
78 | 79 |
79 def _authd(self, xmlstream): | 80 def _authd(self, xmlstream): |
80 print "SatXMPPClient" | 81 print "SatXMPPClient" |
81 client.XMPPClient._authd(self, xmlstream) | 82 client.XMPPClient._authd(self, xmlstream) |
82 self.__connected=True | 83 self.__connected=True |
84 self.streamInitialized() | 85 self.streamInitialized() |
85 self.bridge.connected() #we send the signal to the clients | 86 self.bridge.connected() #we send the signal to the clients |
86 | 87 |
87 def streamInitialized(self): | 88 def streamInitialized(self): |
88 """Called after _authd""" | 89 """Called after _authd""" |
90 debug ("XML stream is initialized") | |
89 self.keep_alife = task.LoopingCall(self.xmlstream.send, " ") #Needed to avoid disconnection (specially with openfire) | 91 self.keep_alife = task.LoopingCall(self.xmlstream.send, " ") #Needed to avoid disconnection (specially with openfire) |
90 self.keep_alife.start(180) | 92 self.keep_alife.start(180) |
93 | |
94 self.disco = SatDiscoProtocol(self) | |
95 self.disco.setHandlerParent(self) | |
96 self.discoHandler = disco.DiscoHandler() | |
97 self.discoHandler.setHandlerParent(self) | |
98 | |
99 self.roster.requestRoster() | |
100 | |
101 self.presence.available() | |
102 | |
103 #self.disco.requestInfo(jid.JID(self.memory.getParamA("Server", "Connection"))).addCallback(self.host.serverDisco) #gof: FIXME | |
104 | |
91 | 105 |
92 def isConnected(self): | 106 def isConnected(self): |
93 return self.__connected | 107 return self.__connected |
94 | 108 |
95 def connectionLost(self, connector, unused_reason): | 109 def connectionLost(self, connector, unused_reason): |
111 def onMessage(self, message): | 125 def onMessage(self, message): |
112 debug (u"got_message from: %s", message["from"]) | 126 debug (u"got_message from: %s", message["from"]) |
113 for e in message.elements(): | 127 for e in message.elements(): |
114 if e.name == "body": | 128 if e.name == "body": |
115 self.host.bridge.newMessage(message["from"], e.children[0]) | 129 self.host.bridge.newMessage(message["from"], e.children[0]) |
116 self.host.memory.addToHistory(self.host.me, jid.JID(message["from"]), self.host.me, "chat", e.children[0]) | 130 self.host.memory.addToHistory(self.parent.jid, jid.JID(message["from"]), self.parent.jid, "chat", e.children[0]) |
117 break | 131 break |
118 | 132 |
119 class SatRosterProtocol(xmppim.RosterClientProtocol): | 133 class SatRosterProtocol(xmppim.RosterClientProtocol): |
120 | 134 |
121 def __init__(self, host): | 135 def __init__(self, host): |
304 | 318 |
305 self.__waiting_conf = {} #callback called when a confirmation is received | 319 self.__waiting_conf = {} #callback called when a confirmation is received |
306 self.__progress_cb_map = {} #callback called when a progress is requested (key = progress id) | 320 self.__progress_cb_map = {} #callback called when a progress is requested (key = progress id) |
307 self.__general_cb_map = {} #callback called for general reasons (key = name) | 321 self.__general_cb_map = {} #callback called for general reasons (key = name) |
308 self.__private_data = {} #used for internal callbacks (key = id) | 322 self.__private_data = {} #used for internal callbacks (key = id) |
323 self.profiles = {} | |
309 self.plugins = {} | 324 self.plugins = {} |
310 | 325 |
311 self.memory=Memory(self) | 326 self.memory=Memory(self) |
312 self.server_features=[] #XXX: temp dic, need to be transfered into self.memory in the future | 327 self.server_features=[] #XXX: temp dic, need to be transfered into self.memory in the future |
313 | 328 |
334 self.bridge.register("isConnected", self.isConnected) | 349 self.bridge.register("isConnected", self.isConnected) |
335 self.bridge.register("launchAction", self.launchAction) | 350 self.bridge.register("launchAction", self.launchAction) |
336 self.bridge.register("confirmationAnswer", self.confirmationAnswer) | 351 self.bridge.register("confirmationAnswer", self.confirmationAnswer) |
337 self.bridge.register("getProgress", self.getProgress) | 352 self.bridge.register("getProgress", self.getProgress) |
338 | 353 |
339 self._import_plugins() | 354 #self._import_plugins() #gof: |
340 | 355 |
341 | 356 |
342 def _import_plugins(self): | 357 def _import_plugins(self): |
343 """Import all plugins found in plugins directory""" | 358 """Import all plugins found in plugins directory""" |
344 #TODO: manage dependencies | 359 #TODO: manage dependencies |
351 plug_info = mod.PLUGIN_INFO | 366 plug_info = mod.PLUGIN_INFO |
352 info ("importing plugin: %s", plug_info['name']) | 367 info ("importing plugin: %s", plug_info['name']) |
353 self.plugins[plug_info['import_name']] = getattr(mod, plug_info['main'])(self) | 368 self.plugins[plug_info['import_name']] = getattr(mod, plug_info['main'])(self) |
354 #TODO: test xmppclient presence and register handler parent | 369 #TODO: test xmppclient presence and register handler parent |
355 | 370 |
356 def getJidFrProfile(self, profile): | 371 def connect(self, profile_key = '@DEFAULT@'): |
357 """Return jid from source""" | |
358 if profile == "@DEFAULT@": | |
359 return jid.JID(self.memory.getParamA("JabberID", "Connection")) | |
360 | |
361 def connect(self, profile = '@DEFAULT@'): | |
362 """Connect to jabber server""" | 372 """Connect to jabber server""" |
363 | 373 |
374 | |
375 profile = self.memory.getProfileName(profile_key) | |
376 if not profile_key: | |
377 error ('Trying to connect a non-exsitant profile') | |
378 return | |
379 | |
364 if (self.isConnected()): | 380 if (self.isConnected()): |
365 info("already connected !") | 381 info("already connected !") |
366 return | 382 return |
367 print "connecting..." | 383 print "connecting..." |
368 self.me = self.getJidFrProfile(profile) | 384 current = self.profiles[profile] = SatXMPPClient(self.bridge, profile, |
369 self.xmppclient = SatXMPPClient(self.bridge, self.me, self.memory.getParamA("Password", "Connection"), | 385 jid.JID(self.memory.getParamA("JabberID", "Connection"), profile), |
386 self.memory.getParamA("Password", "Connection"), | |
370 self.memory.getParamA("Server", "Connection"), 5222) | 387 self.memory.getParamA("Server", "Connection"), 5222) |
371 self.xmppclient.streamInitialized = self.streamInitialized | 388 |
372 | 389 #current.client.streamInitialized = self.streamInitialized #gof: |
373 self.messageProt = SatMessageProtocol(self) | 390 |
374 self.messageProt.setHandlerParent(self.xmppclient) | 391 current.messageProt = SatMessageProtocol(self) |
375 | 392 current.messageProt.setHandlerParent(current) |
376 self.roster = SatRosterProtocol(self) | 393 |
377 self.roster.setHandlerParent(self.xmppclient) | 394 current.roster = SatRosterProtocol(self) |
378 | 395 current.roster.setHandlerParent(current) |
379 self.presence = SatPresenceProtocol(self) | 396 |
380 self.presence.setHandlerParent(self.xmppclient) | 397 current.presence = SatPresenceProtocol(self) |
381 | 398 current.presence.setHandlerParent(current) |
382 self.fallBack = SatFallbackHandler(self) | 399 |
383 self.fallBack.setHandlerParent(self.xmppclient) | 400 current.fallBack = SatFallbackHandler(self) |
384 | 401 current.fallBack.setHandlerParent(current) |
385 self.versionHandler = generic.VersionHandler(self.get_const('client_name'), | 402 |
403 current.versionHandler = generic.VersionHandler(self.get_const('client_name'), | |
386 self.get_const('client_version')) | 404 self.get_const('client_version')) |
387 self.versionHandler.setHandlerParent(self.xmppclient) | 405 current.versionHandler.setHandlerParent(current) |
388 | 406 |
389 debug ("setting plugins parents") | 407 debug ("setting plugins parents") |
408 | |
409 #FIXME: gof | |
390 for plugin in self.plugins.iteritems(): | 410 for plugin in self.plugins.iteritems(): |
391 if isinstance(plugin[1], XMPPHandler): | 411 if isinstance(plugin[1], XMPPHandler): |
392 plugin[1].setHandlerParent(self.xmppclient) | 412 plugin[1].setHandlerParent(current) |
393 | 413 |
394 self.xmppclient.startService() | 414 current.startService() |
395 | 415 |
396 def disconnect(self): | 416 def disconnect(self): |
397 """disconnect from jabber server""" | 417 """disconnect from jabber server""" |
398 if (not self.isConnected()): | 418 if (not self.isConnected()): |
399 info("not connected !") | 419 info("not connected !") |
415 | 435 |
416 def stop(self): | 436 def stop(self): |
417 debug("stopping app") | 437 debug("stopping app") |
418 reactor.stop() | 438 reactor.stop() |
419 | 439 |
420 def streamInitialized(self): | |
421 """Called when xmlstream is OK""" | |
422 SatXMPPClient.streamInitialized(self.xmppclient) | |
423 debug ("XML stream is initialized") | |
424 self.xmlstream = self.xmppclient.xmlstream | |
425 self.me = self.xmppclient.jid #in case of the ressource has changed | |
426 | |
427 self.disco = SatDiscoProtocol(self) | |
428 self.disco.setHandlerParent(self.xmppclient) | |
429 self.discoHandler = disco.DiscoHandler() | |
430 self.discoHandler.setHandlerParent(self.xmppclient) | |
431 | |
432 self.roster.requestRoster() | |
433 | |
434 self.presence.available() | |
435 | |
436 self.disco.requestInfo(jid.JID(self.memory.getParamA("Server", "Connection"))).addCallback(self.serverDisco) | |
437 | |
438 ## Misc methods ## | 440 ## Misc methods ## |
439 | 441 |
440 def registerNewAccount(self, login, password, server, port = 5222, id = None): | 442 def registerNewAccount(self, login, password, server, port = 5222, id = None): |
441 """Connect to a server and create a new account using in-band registration""" | 443 """Connect to a server and create a new account using in-band registration""" |
442 | 444 |
478 if accepted: | 480 if accepted: |
479 self.registerNewAccount(user, password, server, id=action_id) | 481 self.registerNewAccount(user, password, server, id=action_id) |
480 else: | 482 else: |
481 self.actionResult(action_id, "SUPPRESS", {}) | 483 self.actionResult(action_id, "SUPPRESS", {}) |
482 | 484 |
483 def submitForm(self, action, target, fields): | 485 def submitForm(self, action, target, fields, profile_key='@DEFAULT@'): |
484 """submit a form | 486 """submit a form |
485 @param target: target jid where we are submitting | 487 @param target: target jid where we are submitting |
486 @param fields: list of tuples (name, value) | 488 @param fields: list of tuples (name, value) |
487 @return: tuple: (id, deferred) | 489 @return: tuple: (id, deferred) |
488 """ | 490 """ |
491 | |
492 profile = self.memory.getProfileName(profile_key) | |
493 assert(profile) | |
489 to_jid = jid.JID(target) | 494 to_jid = jid.JID(target) |
490 | 495 |
491 iq = compat.IQ(self.xmlstream, 'set') | 496 iq = compat.IQ(self.profiles[profile].xmlstream, 'set') |
492 iq["to"] = target | 497 iq["to"] = target |
493 iq["from"] = self.me.full() | 498 iq["from"] = self.profiles[profile].jid.full() |
494 query = iq.addElement(('jabber:iq:register', 'query')) | 499 query = iq.addElement(('jabber:iq:register', 'query')) |
495 if action=='SUBMIT': | 500 if action=='SUBMIT': |
496 form = XMLTools.tupleList2dataForm(fields) | 501 form = XMLTools.tupleList2dataForm(fields) |
497 query.addChild(form.toElement()) | 502 query.addChild(form.toElement()) |
498 elif action=='CANCEL': | 503 elif action=='CANCEL': |
509 def setParam(self, name, value, category): | 514 def setParam(self, name, value, category): |
510 """set wanted paramater and notice observers""" | 515 """set wanted paramater and notice observers""" |
511 info ("setting param: %s=%s in category %s", name, value, category) | 516 info ("setting param: %s=%s in category %s", name, value, category) |
512 self.memory.setParam(name, value, category) | 517 self.memory.setParam(name, value, category) |
513 | 518 |
514 def failed(self,xmlstream): | 519 def isConnected(self, profile_key='@DEFAULT@'): |
515 debug("failed: %s", xmlstream.getErrorMessage()) | 520 """Return connection status of profile |
516 debug("failed: %s", dir(xmlstream)) | 521 @param profile_key: key_word or profile name to determine profile name |
517 | 522 @return True if connected |
518 def isConnected(self): | 523 """ |
519 try: | 524 profile = self.memory.getProfileName(profile_key) |
520 if self.xmppclient.isConnected(): | 525 if not profile: |
521 return True | 526 error ('asking connection status for a non-existant profile') |
522 except AttributeError: | 527 raise Exception #TODO: raise a proper exception |
523 #xmppclient not available | 528 if not self.profiles.has_key(profile): |
524 pass | 529 return False |
525 return False | 530 return self.profiles[profile].isConnected() |
526 | 531 |
527 def launchAction(self, type, data): | 532 def launchAction(self, type, data): |
528 """Launch a specific action asked by client | 533 """Launch a specific action asked by client |
529 @param type: action type (button) | 534 @param type: action type (button) |
530 @param data: needed data to launch the action | 535 @param data: needed data to launch the action |
545 return "" | 550 return "" |
546 | 551 |
547 | 552 |
548 ## jabber methods ## | 553 ## jabber methods ## |
549 | 554 |
550 def sendMessage(self,to,msg,type='chat'): | 555 def sendMessage(self,to,msg,type='chat', profile_key='@DEFAULT@'): |
551 #FIXME: check validity of recipient | 556 #FIXME: check validity of recipient |
557 profile = self.memory.getProfileName(profile_key) | |
558 assert(profile) | |
559 current_jid = self.profiles[profile].jid | |
552 debug("Sending jabber message to %s...", to) | 560 debug("Sending jabber message to %s...", to) |
553 message = domish.Element(('jabber:client','message')) | 561 message = domish.Element(('jabber:client','message')) |
554 message["to"] = jid.JID(to).full() | 562 message["to"] = jid.JID(to).full() |
555 message["from"] = self.me.full() | 563 message["from"] = current_jid.full() |
556 message["type"] = type | 564 message["type"] = type |
557 message.addElement("body", "jabber:client", msg) | 565 message.addElement("body", "jabber:client", msg) |
558 self.xmlstream.send(message) | 566 self.profiles[profile].xmlstream.send(message) |
559 self.memory.addToHistory(self.me, self.me, jid.JID(to), message["type"], unicode(msg)) | 567 self.memory.addToHistory(current_jid, current_jid, jid.JID(to), message["type"], unicode(msg)) |
560 self.bridge.newMessage(message['from'], unicode(msg), to=message['to']) #We send back the message, so all clients are aware of it | 568 self.bridge.newMessage(message['from'], unicode(msg), to=message['to']) #We send back the message, so all clients are aware of it |
561 | 569 |
562 | 570 |
563 def setPresence(self, to="", show="", priority = 0, statuses={}): | 571 def setPresence(self, to="", show="", priority = 0, statuses={}): |
564 """Send our presence information""" | 572 """Send our presence information""" |