# HG changeset patch # User Goffi # Date 1264828653 -39600 # Node ID d46f849664aaed0528746eea44468f741fefc003 # Parent 0db25931b60d1488bcaae6eadd1aad66b310674e SàT: multi-profile, plugins updated - core: 2 new convenient methods: getJidNStream and getClient - new param in plugin info: "handler" to know if there is a handler to plug on profiles clients - plugins with handler now use an other class which is returned to profile client with the new method "getHandler" and pluged when connecting diff -r 0db25931b60d -r d46f849664aa frontends/quick_frontend/quick_app.py --- a/frontends/quick_frontend/quick_app.py Fri Jan 29 14:17:15 2010 +1100 +++ b/frontends/quick_frontend/quick_app.py Sat Jan 30 16:17:33 2010 +1100 @@ -133,7 +133,7 @@ self.CM.update(from_jid, 'show', show) self.CM.update(from_jid, 'statuses', statuses) self.CM.update(from_jid, 'groups', groups) - cache = self.bridge.getProfileCache(from_jid) + cache = self.bridge.getCardCache(from_jid) if cache.has_key('nick'): self.CM.update(from_jid, 'nick', cache['nick']) if cache.has_key('avatar'): diff -r 0db25931b60d -r d46f849664aa frontends/sat_bridge_frontend/DBus.py --- a/frontends/sat_bridge_frontend/DBus.py Fri Jan 29 14:17:15 2010 +1100 +++ b/frontends/sat_bridge_frontend/DBus.py Sat Jan 30 16:17:33 2010 +1100 @@ -58,23 +58,23 @@ def sendMessage(self, to, message): return self.db_comm_iface.sendMessage(to, message) - def sendFile(self, to, path): - return self.db_comm_iface.sendFile(to, path) + def sendFile(self, to, path, profile_key='@DEFAULT@'): + return self.db_comm_iface.sendFile(to, path, profile_key) def findGateways(self, target): return self.db_comm_iface.findGateways(target) - def getProfile(self, target): - return self.db_comm_iface.getProfile(target) + def getCard(self, target, profile_key='@DEFAULT@'): + return self.db_comm_iface.getCard(target, profile_key) - def getProfileCache(self, target): - return self.db_comm_iface.getProfileCache(target) + def getCardCache(self, target): + return self.db_comm_iface.getCardCache(target) def getAvatarFile(self, hash): return self.db_comm_iface.getAvatarFile(hash) - def in_band_register(self, target): - return self.db_comm_iface.in_band_register(target) + def in_band_register(self, target, profile_key='@DEFAULT@'): + return self.db_comm_iface.in_band_register(target, profile_key) def setPresence(self, to="", show="", priority=0, statuses={}): return self.db_comm_iface.setPresence(to, show, priority, statuses) diff -r 0db25931b60d -r d46f849664aa frontends/wix/main_window.py --- a/frontends/wix/main_window.py Fri Jan 29 14:17:15 2010 +1100 +++ b/frontends/wix/main_window.py Sat Jan 30 16:17:33 2010 +1100 @@ -521,7 +521,7 @@ dlg.ShowModal() dlg.Destroy() return - id = self.bridge.getProfile(target.short) + id = self.bridge.getCard(target.short) self.current_action_ids.add(id) self.current_action_ids_cb[id] = self.onProfileReceived diff -r 0db25931b60d -r d46f849664aa plugins/plugin_xep_0054.py --- a/plugins/plugin_xep_0054.py Fri Jan 29 14:17:15 2010 +1100 +++ b/plugins/plugin_xep_0054.py Sat Jan 30 16:17:33 2010 +1100 @@ -58,11 +58,11 @@ "protocols": ["XEP-0054", "XEP-0153"], "dependencies": [], "main": "XEP_0054", +"handler": "yes", "description": """Implementation of vcard-temp""" } -class XEP_0054(XMPPHandler): - implements(iwokkel.IDisco) +class XEP_0054(): def __init__(self, host): info("Plugin XEP_0054 initialization") @@ -71,9 +71,12 @@ self.vcard_cache = host.memory.getPrivate("vcard_cache") or {} #used to store nicknames and avatar, key = jid if not os.path.exists(self.avatar_path): os.makedirs(self.avatar_path) - host.bridge.addMethod("getProfile", ".communication", in_sign='s', out_sign='s', method=self.getProfile) + host.bridge.addMethod("getCard", ".communication", in_sign='ss', out_sign='s', method=self.getCard) host.bridge.addMethod("getAvatarFile", ".communication", in_sign='s', out_sign='s', method=self.getAvatarFile) - host.bridge.addMethod("getProfileCache", ".communication", in_sign='s', out_sign='a{ss}', method=self.getProfileCache) + host.bridge.addMethod("getCardCache", ".communication", in_sign='s', out_sign='a{ss}', method=self.getCardCache) + + def getHandler(self): + return XEP_0054_handler(self) def update_cache(self, jid, name, value): """update cache value @@ -101,15 +104,6 @@ return None - def connectionInitialized(self): - self.xmlstream.addObserver(VCARD_UPDATE, self.update) - - def getDiscoInfo(self, requestor, target, nodeIdentifier=''): - return [disco.DiscoFeature(NS_VCARD)] - - def getDiscoItems(self, requestor, target, nodeIdentifier=''): - return [] - def save_photo(self, photo_xml): """Parse a elem and save the picture""" for elem in photo_xml.elements(): @@ -177,14 +171,18 @@ error ("Can't find VCard of %s" % failure.value.stanza['from']) self.host.bridge.actionResult("SUPPRESS", failure.value.stanza['id'], {}) #FIXME: maybe an error message would be best - def getProfile(self, target): + def getCard(self, target, profile_key='@DEFAULT@'): """Ask server for VCard @param target: jid from which we want the VCard @result: id to retrieve the profile""" + current_jid, xmlstream = self.host.getJidNStream(profile_key) + if not xmlstream: + error ('Asking profile for an non-existant or not connected profile') + return "" to_jid = jid.JID(target) debug("Asking for %s's VCard" % to_jid.userhost()) - reg_request=IQ(self.host.xmlstream,'get') - reg_request["from"]=self.host.me.full() + reg_request=IQ(xmlstream,'get') + reg_request["from"]=current_jid.full() reg_request["to"] = to_jid.userhost() query=reg_request.addElement('vCard', NS_VCARD) reg_request.send(to_jid.userhost()).addCallbacks(self.vcard_ok, self.vcard_err) @@ -201,7 +199,7 @@ return "" return filename - def getProfileCache(self, target): + def getCardCache(self, target): """Request for cached values of profile return the cached nickname and avatar if exists, else get VCard """ @@ -215,6 +213,24 @@ result['avatar'] = avatar return result + + +class XEP_0054_handler(XMPPHandler): + implements(iwokkel.IDisco) + + def __init__(self, plugin_parent): + self.plugin_parent = plugin_parent + self.host = plugin_parent.host + + def connectionInitialized(self): + self.xmlstream.addObserver(VCARD_UPDATE, self.update) + + def getDiscoInfo(self, requestor, target, nodeIdentifier=''): + return [disco.DiscoFeature(NS_VCARD)] + + def getDiscoItems(self, requestor, target, nodeIdentifier=''): + return [] + def update(self, presence): """Request for VCard's nickname return the cached nickname if exists, else get VCard @@ -224,8 +240,7 @@ for elem in x_elem.elements(): if elem.name == 'photo': hash = str(elem) - old_avatar = self.get_cache(to_jid, 'avatar') + old_avatar = self.plugin_parent.get_cache(to_jid, 'avatar') if not old_avatar or old_avatar != hash: debug('New avatar found, requesting vcard') - self.getProfile(to_jid.userhost()) - + self.plugin_parent.getCard(to_jid.userhost(), self.parent.profile) diff -r 0db25931b60d -r d46f849664aa plugins/plugin_xep_0065.py --- a/plugins/plugin_xep_0065.py Fri Jan 29 14:17:15 2010 +1100 +++ b/plugins/plugin_xep_0065.py Sat Jan 30 16:17:33 2010 +1100 @@ -85,6 +85,7 @@ "type": "XEP", "protocols": ["XEP-0065"], "main": "XEP_0065", +"handler": "yes", "description": """Implementation of SOCKS5 Bytestreams""" } @@ -312,7 +313,7 @@ debug("Saving file in %s.", self.data["dest_path"]) self.dest_file = open(self.data["dest_path"], 'w') self.state = STATE_TARGET_READY - self.activateCB(self.target_jid, self.initiator_jid, self.sid, self.IQ_id) + self.activateCB(self.target_jid, self.initiator_jid, self.sid, self.IQ_id, self.xmlstream) except struct.error, why: @@ -450,8 +451,7 @@ debug ("Socks 5 client connection lost (reason: %s)", reason) -class XEP_0065(XMPPHandler): - implements(iwokkel.IDisco) +class XEP_0065(): params = """ @@ -480,20 +480,12 @@ info("Launching Socks5 Stream server on port %d", port) reactor.listenTCP(port, self.server_factory) + def getHandler(self): + return XEP_0065_handler(self) + def getExternalIP(self): """Return IP visible from outside, by asking to a website""" return getPage("http://www.goffi.org/sat_tools/get_ip.php") - - def connectionInitialized(self): - self.xmlstream.addObserver(BS_REQUEST, self.getFile) - - - def getDiscoInfo(self, requestor, target, nodeIdentifier=''): - return [disco.DiscoFeature(NS_BS)] - - def getDiscoItems(self, requestor, target, nodeIdentifier=''): - return [] - def setData(self, data, id): self.data = data @@ -507,8 +499,10 @@ self.server_factory.protocol.filesize = size self.server_factory.protocol.transfert_id = id - def getFile(self, iq): + def getFile(self, iq, profile_key='@DEFAULT@'): """Get file using byte stream""" + client = self.host.getClient(profile_key) + assert(client) iq.handled = True SI_elem = iq.firstChildElement() IQ_id = iq['id'] @@ -518,17 +512,18 @@ factory = self.client_factory self.server_factory.protocol.mode = "target" factory.protocol.host = self.host #needed for progress CB + factory.protocol.xmlstream = client.xmlstream factory.protocol.data = self.data factory.protocol.transfert_id = self.transfert_id factory.protocol.filesize = self.data["size"] factory.protocol.sid = SI_elem['sid'] factory.protocol.initiator_jid = element['jid'] - factory.protocol.target_jid = self.host.me.full() + factory.protocol.target_jid = client.jid.full() factory.protocol.IQ_id = IQ_id factory.protocol.activateCB = self.activateStream reactor.connectTCP(element['host'], int(element['port']), factory) - def activateStream(self, from_jid, to_jid, sid, IQ_id): + def activateStream(self, from_jid, to_jid, sid, IQ_id, xmlstream): debug("activating stream") result = domish.Element(('', 'iq')) result['type'] = 'result' @@ -539,5 +534,21 @@ query['sid'] = sid streamhost = query.addElement('streamhost-used') streamhost['jid'] = to_jid #FIXME: use real streamhost - self.host.xmlstream.send(result) + xmlstream.send(result) +class XEP_0065_handler(XMPPHandler): + implements(iwokkel.IDisco) + + def __init__(self, plugin_parent): + self.plugin_parent = plugin_parent + self.host = plugin_parent.host + + def connectionInitialized(self): + self.xmlstream.addObserver(BS_REQUEST, self.plugin_parent.getFile) + + + def getDiscoInfo(self, requestor, target, nodeIdentifier=''): + return [disco.DiscoFeature(NS_BS)] + + def getDiscoItems(self, requestor, target, nodeIdentifier=''): + return [] diff -r 0db25931b60d -r d46f849664aa plugins/plugin_xep_0077.py --- a/plugins/plugin_xep_0077.py Fri Jan 29 14:17:15 2010 +1100 +++ b/plugins/plugin_xep_0077.py Sat Jan 30 16:17:33 2010 +1100 @@ -20,7 +20,7 @@ """ from logging import debug, info, error -from twisted.words.protocols.jabber import client, jid, xmlstream +from twisted.words.protocols.jabber import client, jid from twisted.words.protocols.jabber import error as jab_error from twisted.words.protocols.jabber.xmlstream import IQ from twisted.internet import reactor @@ -47,7 +47,7 @@ info("Plugin XEP_0077 initialization") self.host = host self.triggers = {} #used by other protocol (e.g. XEP-0100) to finish registration. key = target_jid - host.bridge.addMethod("in_band_register", ".communication", in_sign='s', out_sign='s', method=self.in_band_register) + host.bridge.addMethod("in_band_register", ".communication", in_sign='ss', out_sign='s', method=self.in_band_register) host.bridge.addMethod("in_band_submit", ".request", in_sign='sa(ss)', out_sign='s', method=self.in_band_submit) def addTrigger(self, target, cb): @@ -127,12 +127,16 @@ deferred.addCallbacks(self.registrationAnswer, self.registrationFailure) return id - def in_band_register(self, target): + def in_band_register(self, target, profile_key='@DEFAULT@'): """register to a target JID""" + current_jid, xmlstream = self.host.getJidNStream(profile_key) + if not xmlstream: + error ('Asking profile for an non-existant or not connected profile') + return "" to_jid = jid.JID(target) debug("Asking registration for [%s]" % to_jid.full()) - reg_request=IQ(self.host.xmlstream,'get') - reg_request["from"]=self.host.me.full() + reg_request=IQ(xmlstream,'get') + reg_request["from"]=current_jid.full() reg_request["to"] = to_jid.full() query=reg_request.addElement('query', NS_REG) reg_request.send(to_jid.full()).addCallbacks(self.reg_ok, self.reg_err) diff -r 0db25931b60d -r d46f849664aa plugins/plugin_xep_0096.py --- a/plugins/plugin_xep_0096.py Fri Jan 29 14:17:15 2010 +1100 +++ b/plugins/plugin_xep_0096.py Sat Jan 30 16:17:33 2010 +1100 @@ -22,7 +22,7 @@ from logging import debug, info, error from twisted.words.xish import domish from twisted.internet import protocol -from twisted.words.protocols.jabber import client, jid, xmlstream +from twisted.words.protocols.jabber import client, jid from twisted.words.protocols.jabber import error as jab_error import os.path from twisted.internet import reactor #FIXME best way ??? @@ -48,29 +48,22 @@ "protocols": ["XEP-0096"], "dependencies": ["XEP_0065"], "main": "XEP_0096", +"handler": "yes", "description": """Implementation of SI File Transfert""" } -class XEP_0096(XMPPHandler): - implements(iwokkel.IDisco) +class XEP_0096(): def __init__(self, host): info("Plugin XEP_0096 initialization") self.host = host self._waiting_for_approval = {} - host.bridge.addMethod("sendFile", ".communication", in_sign='ss', out_sign='s', method=self.sendFile) + host.bridge.addMethod("sendFile", ".communication", in_sign='sss', out_sign='s', method=self.sendFile) - def connectionInitialized(self): - self.xmlstream.addObserver(SI_REQUEST, self.xep_96) - + def getHandler(self): + return XEP_0096_handler(self) - def getDiscoInfo(self, requestor, target, nodeIdentifier=''): - return [disco.DiscoFeature(NS_SI)] - - def getDiscoItems(self, requestor, target, nodeIdentifier=''): - return [] - - def xep_96(self, IQ): + def xep_96(self, IQ, profile): info ("XEP-0096 management") IQ.handled=True SI_elem = IQ.firstChildElement() @@ -84,7 +77,7 @@ file_size = element["size"] elif element.name == "feature": from_jid = IQ["from"] - self._waiting_for_approval[IQ["id"]] = (element, from_jid, file_size) + self._waiting_for_approval[IQ["id"]] = (element, from_jid, file_size, profile) data={ "filename":filename, "from":from_jid, "size":file_size } self.host.askConfirmation(IQ["id"], "FILE_TRANSFERT", data, self.confirmationCB) @@ -106,13 +99,15 @@ error ("Approved unknow id !") #TODO: manage this (maybe approved by several frontends) else: - element, from_id, size = self._waiting_for_approval[id] + element, from_id, size, profile = self._waiting_for_approval[id] del(self._waiting_for_approval[id]) - self.negociate(element, id, from_id) + self.negociate(element, id, from_id, profile) - def negociate(self, feat_elem, id, to_jid): + def negociate(self, feat_elem, id, to_jid, profile): #TODO: put this in a plugin #FIXME: over ultra mega ugly, need to be generic + client = self.host.getClient(profile) + assert(client) info ("Feature negociation") data = feat_elem.firstChildElement() field = data.firstChildElement() @@ -134,40 +129,41 @@ field['var'] = 'stream-method' value = field.addElement('value') value.addContent('http://jabber.org/protocol/bytestreams') - self.host.xmlstream.send(result) + client.xmlstream.send(result) - def fileCB(self, answer): + def fileCB(self, answer, xmlstream, current_jid): if answer['type']=="result": #FIXME FIXME FIXME ugly ugly ugly ! and temp FIXME FIXME FIXME info("SENDING UGLY ANSWER") - offer=client.IQ(self.host.xmlstream,'set') - offer["from"]=self.host.me.full() + offer=client.IQ(xmlstream,'set') + offer["from"]=current_jid.full() offer["to"]=answer['from'] query=offer.addElement('query', 'http://jabber.org/protocol/bytestreams') query['mode']='tcp' streamhost=query.addElement('streamhost') streamhost['host']=self.host.memory.getParamA("IP", "File Transfert") streamhost['port']=self.host.memory.getParamA("Port", "File Transfert") - streamhost['jid']=self.host.me.full() + streamhost['jid']=current_jid.full() offer.send() - - - - def sendFile(self, to, filepath): + def sendFile(self, to, filepath, profile_key='@DEFAULT@'): """send a file using XEP-0096 Return an unique id to identify the transfert """ + current_jid, xmlstream = self.host.getJidNStream(profile_key) + if not xmlstream: + error ('Asking profile for an non-existant or not connected profile') + return "" debug ("sendfile (%s) to %s", filepath, to ) print type(filepath), type(to) statinfo = os.stat(filepath) - offer=client.IQ(self.host.xmlstream,'set') + offer=client.IQ(xmlstream,'set') debug ("Transfert ID: %s", offer["id"]) self.host.plugins["XEP_0065"].sendFile(offer["id"], filepath, str(statinfo.st_size)) - offer["from"]=self.host.me.full() + offer["from"]=current_jid.full() offer["to"]=jid.JID(to).full() si=offer.addElement('si','http://jabber.org/protocol/si') si["mime-type"]='text/plain' @@ -190,7 +186,23 @@ option = field.addElement('option') value = option.addElement('value', content='http://jabber.org/protocol/bytestreams') - offer.addCallback(self.fileCB) + offer.addCallback(self.fileCB, current_jid = current_jid, xmlstream = xmlstream) offer.send() return offer["id"] #XXX: using IQ id as file transfert id seems OK as IQ id are required +class XEP_0096_handler(XMPPHandler): + implements(iwokkel.IDisco) + + def __init__(self, plugin_parent): + self.plugin_parent = plugin_parent + self.host = plugin_parent.host + + def connectionInitialized(self): + self.xmlstream.addObserver(SI_REQUEST, self.plugin_parent.xep_96, profile = self.parent.profile) + + def getDiscoInfo(self, requestor, target, nodeIdentifier=''): + return [disco.DiscoFeature(NS_SI)] + + def getDiscoItems(self, requestor, target, nodeIdentifier=''): + return [] + diff -r 0db25931b60d -r d46f849664aa plugins/plugin_xep_0100.py --- a/plugins/plugin_xep_0100.py Fri Jan 29 14:17:15 2010 +1100 +++ b/plugins/plugin_xep_0100.py Sat Jan 30 16:17:33 2010 +1100 @@ -21,7 +21,7 @@ from logging import debug, info, error from twisted.internet import protocol -from twisted.words.protocols.jabber import client, jid, xmlstream +from twisted.words.protocols.jabber import client, jid from twisted.words.protocols.jabber import error as jab_error import pdb @@ -76,7 +76,7 @@ self.__inc_handled_items(request_id) - def discoItems(self, disco, request_id, target): + def discoItems(self, disco, request_id, target, client): """Look for items with disco protocol, and ask infos for each one""" #FIXME: target is used as we can't find the original iq node (parent is None) # an other way would avoid this useless parameter (is there a way with wokkel ?) @@ -88,8 +88,8 @@ self.__gateways[request_id] = {'__total_items':len(disco._items), '__handled_items':0, '__private__':{'target':target.full()}} for item in disco._items: debug ("item found: %s", item.name) - self.host.disco.requestInfo(item.entity).addCallback(self.discoInfo, entity=item.entity, request_id=request_id) - self.host.disco.requestInfo(item.entity).addErrback(self.discoInfoErr, entity=item.entity, request_id=request_id) + client.disco.requestInfo(item.entity).addCallback(self.discoInfo, entity=item.entity, request_id=request_id) + client.disco.requestInfo(item.entity).addErrback(self.discoInfoErr, entity=item.entity, request_id=request_id) def registrationSuccessful(self, target): """Called when in_band registration is ok, we must now follow the rest of procedure""" @@ -103,12 +103,14 @@ self.host.plugins["XEP_0077"].addTrigger(target, self.registrationSuccessful) return self.host.plugins["XEP_0077"].in_band_submit(action, target, fields) - def findGateways(self, target): + def findGateways(self, target, profile_key='@DEFAULT@'): """Find gateways in the target JID, using discovery protocol Return an id used for retrieving the list of gateways """ + client = self.host.getClient(profile_key) + assert(client) to_jid = jid.JID(target) debug ("find gateways (target = %s)" % to_jid.full()) request_id = self.host.get_next_id() - self.host.disco.requestItems(to_jid).addCallback(self.discoItems, request_id=request_id, target = to_jid) + client.disco.requestItems(to_jid).addCallback(self.discoItems, request_id=request_id, target = to_jid, client = client) return request_id diff -r 0db25931b60d -r d46f849664aa sat.tac --- a/sat.tac Fri Jan 29 14:17:15 2010 +1100 +++ b/sat.tac Sat Jan 30 16:17:33 2010 +1100 @@ -70,12 +70,12 @@ class SatXMPPClient(client.XMPPClient): - def __init__(self, bridge, profile, user_jid, password, host=None, port=5222): + 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.bridge = bridge self.profile = profile + self.host_app = host_app def _authd(self, xmlstream): print "SatXMPPClient" @@ -83,7 +83,7 @@ self.__connected=True print "********** CONNECTED **********" self.streamInitialized() - self.bridge.connected() #we send the signal to the clients + self.host_app.bridge.connected() #we send the signal to the clients def streamInitialized(self): """Called after _authd""" @@ -99,9 +99,8 @@ self.roster.requestRoster() self.presence.available() - - #self.disco.requestInfo(jid.JID(self.memory.getParamA("Server", "Connection"))).addCallback(self.host.serverDisco) #gof: FIXME - + + self.disco.requestInfo(jid.JID(self.host_app.memory.getParamA("Server", "Connection", profile_key=self.profile))).addCallback(self.host_app.serverDisco) #FIXME: use these informations def isConnected(self): return self.__connected @@ -113,7 +112,7 @@ self.keep_alife.stop() except AttributeError: debug("No keep_alife") - self.bridge.disconnected() #we send the signal to the clients + self.host_app.bridge.disconnected() #we send the signal to the clients class SatMessageProtocol(xmppim.MessageProtocol): @@ -351,14 +350,14 @@ self.bridge.register("confirmationAnswer", self.confirmationAnswer) self.bridge.register("getProgress", self.getProgress) - #self._import_plugins() #gof: + self._import_plugins() def _import_plugins(self): """Import all plugins found in plugins directory""" #TODO: manage dependencies plug_lst = [os.path.splitext(plugin)[0] for plugin in map(os.path.basename,glob ("plugins/plugin*.py"))] - + for plug in plug_lst: plug_path = 'plugins.'+plug __import__(plug_path) @@ -366,6 +365,10 @@ plug_info = mod.PLUGIN_INFO info ("importing plugin: %s", plug_info['name']) self.plugins[plug_info['import_name']] = getattr(mod, plug_info['main'])(self) + if plug_info.has_key('handler') and plug_info['handler'] == 'yes': + self.plugins[plug_info['import_name']].is_handler = True + else: + self.plugins[plug_info['import_name']].is_handler = False #TODO: test xmppclient presence and register handler parent def connect(self, profile_key = '@DEFAULT@'): @@ -381,12 +384,10 @@ info("already connected !") return print "connecting..." - 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) - - #current.client.streamInitialized = self.streamInitialized #gof: + current = self.profiles[profile] = SatXMPPClient(self, profile, + jid.JID(self.memory.getParamA("JabberID", "Connection", profile_key = profile_key), profile), + self.memory.getParamA("Password", "Connection", profile_key = profile_key), + self.memory.getParamA("Server", "Connection", profile_key = profile_key), 5222) current.messageProt = SatMessageProtocol(self) current.messageProt.setHandlerParent(current) @@ -408,8 +409,8 @@ #FIXME: gof for plugin in self.plugins.iteritems(): - if isinstance(plugin[1], XMPPHandler): - plugin[1].setHandlerParent(current) + if plugin[1].is_handler: + plugin[1].getHandler().setHandlerParent(current) current.startService() @@ -440,6 +441,22 @@ ## Misc methods ## + def getJidNStream(self, profile_key): + """Convenient method to get jid and stream from profile key + @return: tuple (jid, xmlstream) from profile, can be None""" + profile = self.memory.getProfileName(profile_key) + if not profile or not self.profiles[profile].isConnected(): + return (None, None) + return (self.profiles[profile].jid, self.profiles[profile].xmlstream) + + def getClient(self, profile_key): + """Convenient method to get client from profile key + @return: client or None if it doesn't exist""" + profile = self.memory.getProfileName(profile_key) + if not profile: + return None + return self.profiles[profile] + def registerNewAccount(self, login, password, server, port = 5222, id = None): """Connect to a server and create a new account using in-band registration""" @@ -451,6 +468,7 @@ return next_id def registerNewAccountCB(self, id, data): + #FIXME: gof: profile not managed here ! user = jid.parse(self.memory.getParamA("JabberID", "Connection"))[0] password = self.memory.getParamA("Password", "Connection") server = self.memory.getParamA("Server", "Connection") @@ -472,6 +490,7 @@ print "data=",data def regisConfirmCB(self, id, accepted, data): + #FIXME: gof: profile not managed here ! print "register Confirmation CB ! (%s)" % str(accepted) action_id = self.__private_data[id] del self.__private_data[id] diff -r 0db25931b60d -r d46f849664aa tools/memory.py --- a/tools/memory.py Fri Jan 29 14:17:15 2010 +1100 +++ b/tools/memory.py Sat Jan 30 16:17:33 2010 +1100 @@ -224,7 +224,10 @@ error('Requesting a param for an non-existant profile') return None - return self.__getParam(profile, category, name) or node[1].getAttribute(attr) + if attr == "value": + return self.__getParam(profile, category, name) or node[1].getAttribute(attr) + else: + return node[1].getAttribute(attr) def __getParam(self, profile, category, name, type='individual'): @@ -550,8 +553,8 @@ debug ("Memory getPresenceStatus (%s)", self.presenceStatus) return self.presenceStatus - def getParamA(self, name, category, attr="value"): - return self.params.getParamA(name, category, attr) + def getParamA(self, name, category, attr="value", profile_key="@DEFAULT@"): + return self.params.getParamA(name, category, attr, profile_key) def getParams(self): return self.params.getParams()