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
This commit is contained in:
Goffi 2010-01-30 16:17:33 +11:00
commit 656bea30dd
10 changed files with 175 additions and 109 deletions

View file

@ -133,7 +133,7 @@ class QuickApp():
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'):

View file

@ -58,23 +58,23 @@ class DBusBridgeFrontend(BridgeFrontend):
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)

View file

@ -521,7 +521,7 @@ class MainWindow(wx.Frame, QuickApp):
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

View file

@ -58,11 +58,11 @@ PLUGIN_INFO = {
"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 @@ class XEP_0054(XMPPHandler):
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 @@ class XEP_0054(XMPPHandler):
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 <PHOTO> elem and save the picture"""
for elem in photo_xml.elements():
@ -177,14 +171,18 @@ class XEP_0054(XMPPHandler):
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 @@ class XEP_0054(XMPPHandler):
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 @@ class XEP_0054(XMPPHandler):
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 @@ class XEP_0054(XMPPHandler):
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)

View file

@ -85,6 +85,7 @@ PLUGIN_INFO = {
"type": "XEP",
"protocols": ["XEP-0065"],
"main": "XEP_0065",
"handler": "yes",
"description": """Implementation of SOCKS5 Bytestreams"""
}
@ -312,7 +313,7 @@ class SOCKSv5(protocol.Protocol, FileSender):
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 @@ class Socks5ClientFactory(protocol.ClientFactory):
debug ("Socks 5 client connection lost (reason: %s)", reason)
class XEP_0065(XMPPHandler):
implements(iwokkel.IDisco)
class XEP_0065():
params = """
<params>
@ -480,20 +480,12 @@ class XEP_0065(XMPPHandler):
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 @@ class XEP_0065(XMPPHandler):
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 @@ class XEP_0065(XMPPHandler):
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 @@ class XEP_0065(XMPPHandler):
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 []

View file

@ -20,7 +20,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
"""
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 @@ class XEP_0077():
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 @@ class XEP_0077():
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)

View file

@ -22,7 +22,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
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 @@ PLUGIN_INFO = {
"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 @@ class XEP_0096(XMPPHandler):
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 @@ class XEP_0096(XMPPHandler):
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 @@ class XEP_0096(XMPPHandler):
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 @@ class XEP_0096(XMPPHandler):
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 []

View file

@ -21,7 +21,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
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 @@ class XEP_0100():
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 @@ class XEP_0100():
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 @@ class XEP_0100():
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

53
sat.tac
View file

@ -70,12 +70,12 @@ def sat_next_id():
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 @@ class SatXMPPClient(client.XMPPClient):
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 @@ class SatXMPPClient(client.XMPPClient):
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 @@ class SatXMPPClient(client.XMPPClient):
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 @@ class SAT(service.Service):
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 @@ class SAT(service.Service):
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 @@ class SAT(service.Service):
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 @@ class SAT(service.Service):
#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 @@ class SAT(service.Service):
## 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 @@ class SAT(service.Service):
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 @@ class SAT(service.Service):
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]

View file

@ -224,7 +224,10 @@ class Param():
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 @@ class Memory:
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()