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:
parent
7b520ddc93
commit
656bea30dd
10 changed files with 175 additions and 109 deletions
|
|
@ -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'):
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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 []
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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 []
|
||||
|
||||
|
|
|
|||
|
|
@ -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
53
sat.tac
|
|
@ -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]
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
|
|
|||
Loading…
Reference in a new issue