plugin XEP-0166: session-info action handling
This commit is contained in:
parent
ee65aa7f3c
commit
a66843a884
1 changed files with 61 additions and 10 deletions
|
|
@ -25,7 +25,6 @@ log = getLogger(__name__)
|
|||
from sat.core import exceptions
|
||||
from twisted.words.protocols.jabber import jid
|
||||
from twisted.internet import defer
|
||||
# from wokkel import disco, iwokkel, data_form, compat
|
||||
from wokkel import disco, iwokkel
|
||||
from twisted.words.protocols.jabber import error
|
||||
from twisted.words.protocols.jabber import xmlstream
|
||||
|
|
@ -74,6 +73,7 @@ class XEP_0166(object):
|
|||
A_SESSION_INITIATE = "session-initiate"
|
||||
A_SESSION_ACCEPT = "session-accept"
|
||||
A_SESSION_TERMINATE = "session-terminate"
|
||||
A_SESSION_INFO = "session-info"
|
||||
A_TRANSPORT_INFO = "transport-info"
|
||||
# non standard actions
|
||||
A_PREPARE_INITIATOR = "prepare-initiator" # initiator must prepare tranfer
|
||||
|
|
@ -257,6 +257,16 @@ class XEP_0166(object):
|
|||
|
||||
return iq_elt, context_elt
|
||||
|
||||
def buildSessionInfo(self, session, profile=C.PROF_KEY_NONE):
|
||||
"""Build a session-info action
|
||||
|
||||
@param session(dict): jingle session data
|
||||
@param profile: %(doc_profile)s
|
||||
@return (tuple[domish.Element, domish.Element]): parent <iq> element, <jingle> element
|
||||
"""
|
||||
client = self.host.getClient(profile)
|
||||
return self._buildJingleElt(client, session, XEP_0166.A_SESSION_INFO)
|
||||
|
||||
@defer.inlineCallbacks
|
||||
def initiate(self, peer_jid, contents, profile=C.PROF_KEY_NONE):
|
||||
"""Send a session initiation request
|
||||
|
|
@ -439,6 +449,8 @@ class XEP_0166(object):
|
|||
self.onSessionTerminate(client, request, jingle_elt, session)
|
||||
elif action == XEP_0166.A_SESSION_ACCEPT:
|
||||
self.onSessionAccept(client, request, jingle_elt, session)
|
||||
elif action == XEP_0166.A_SESSION_INFO:
|
||||
self.onSessionInfo(client, request, jingle_elt, session)
|
||||
elif action == XEP_0166.A_TRANSPORT_INFO:
|
||||
self.onTransportInfo(client, request, jingle_elt, session)
|
||||
else:
|
||||
|
|
@ -541,7 +553,9 @@ class XEP_0166(object):
|
|||
|
||||
content_data['transport_elt'] = transport_elt
|
||||
|
||||
def _callPlugins(self, action, session, app_method_name='jingleHandler', transp_method_name='jingleHandler', app_default_cb=None, transp_default_cb=None, delete=True, elements=True, profile=C.PROF_KEY_NONE):
|
||||
def _callPlugins(self, action, session, app_method_name='jingleHandler', transp_method_name='jingleHandler',
|
||||
app_default_cb=None, transp_default_cb=None, delete=True,
|
||||
elements=True, force_element=None, profile=C.PROF_KEY_NONE):
|
||||
"""Call application and transport plugin methods for all contents
|
||||
|
||||
@param action(unicode): jingle action name
|
||||
|
|
@ -557,9 +571,12 @@ class XEP_0166(object):
|
|||
@param delete(bool): if True, remove desc_elt and transport_elt from session
|
||||
ignored if elements is False
|
||||
@param elements(bool): True if elements(desc_elt and tranport_elt) must be managed
|
||||
must be True if _callPlugins is use in a request, and False if it used after a request (i.e. on <iq> result or error)
|
||||
must be True if _callPlugins is used in a request, and False if it used after a request (i.e. on <iq> result or error)
|
||||
@param force_element(None, domish.Element, object): if elements is None, it is used as element parameter
|
||||
else it is ignored
|
||||
@param profile(unicode): %(doc_profile)s
|
||||
@return (list[defer.Deferred]): list of launched Deferred
|
||||
@raise exceptions.NotFound: method is not implemented
|
||||
"""
|
||||
contents_dict = session['contents']
|
||||
defers_list = []
|
||||
|
|
@ -577,13 +594,12 @@ class XEP_0166(object):
|
|||
if default_cb is not None:
|
||||
method = default_cb
|
||||
else:
|
||||
raise exceptions.InternalError(u'{} not implemented !'.format(method_name))
|
||||
finally:
|
||||
if elements:
|
||||
elt = content_data.pop(elt_name) if delete else content_data[elt_name]
|
||||
else:
|
||||
elt = None
|
||||
d = defer.maybeDeferred(method, action, session, content_name, elt, profile)
|
||||
raise exceptions.NotFound(u'{} not implemented !'.format(method_name))
|
||||
if elements:
|
||||
elt = content_data.pop(elt_name) if delete else content_data[elt_name]
|
||||
else:
|
||||
elt = force_element
|
||||
d = defer.maybeDeferred(method, action, session, content_name, elt, profile)
|
||||
defers_list.append(d)
|
||||
|
||||
return defers_list
|
||||
|
|
@ -715,6 +731,41 @@ class XEP_0166(object):
|
|||
# after negociations we start the transfer
|
||||
negociate_dlist.addCallback(lambda dummy: self._callPlugins(XEP_0166.A_START, session, app_method_name=None, elements=False, profile=client.profile))
|
||||
|
||||
def _onSessionCb(self, result, client, request, jingle_elt, session):
|
||||
client.xmlstream.send(xmlstream.toResponse(request, 'result'))
|
||||
|
||||
def _onSessionEb(self, failure_, client, request, jingle_elt, session):
|
||||
log.error(u"Error while handling onSessionInfo: {}".format(failure_.value))
|
||||
# XXX: only error managed so far, maybe some applications/transports need more
|
||||
self.sendError('feature-not-implemented', None, request, 'unsupported-info', client.profile)
|
||||
|
||||
def onSessionInfo(self, client, request, jingle_elt, session):
|
||||
"""Method called when a session-info action is received from other peer
|
||||
|
||||
This method is only called for initiator
|
||||
@param client: %(doc_client)s
|
||||
@param request(domish.Element): full <iq> request
|
||||
@param jingle_elt(domish.Element): the <jingle> element
|
||||
@param session(dict): session data
|
||||
"""
|
||||
if not jingle_elt.children:
|
||||
# this is a session ping, see XEP-0166 §6.8
|
||||
client.xmlstream.send(xmlstream.toResponse(request, 'result'))
|
||||
return
|
||||
|
||||
try:
|
||||
# XXX: session-info is most likely only used for application, so we don't call transport plugins
|
||||
# if a future transport use it, this behaviour must be adapted
|
||||
defers = self._callPlugins(XEP_0166.A_SESSION_INFO, session, 'jingleSessionInfo', None,
|
||||
elements=False, force_element=jingle_elt, profile=client.profile)
|
||||
except exceptions.NotFound as e:
|
||||
self._onSessionEb(failure.Failure(e), client, request, jingle_elt, session)
|
||||
return
|
||||
|
||||
dlist = defer.DeferredList(defers, fireOnOneErrback=True)
|
||||
dlist.addCallback(self._onSessionCb, client, request, jingle_elt, session)
|
||||
dlist.addErrback(self._onSessionCb, client, request, jingle_elt, session)
|
||||
|
||||
def onTransportInfo(self, client, request, jingle_elt, session):
|
||||
"""Method called when a transport-info action is received from other peer
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue