changeset 1754:f4e9f2f7fe0f

plugin XEP-0166: jingleTerminate is called (if present) on applications and transports plugins on session-terminate action, can be used to do some cleaning
author Goffi <goffi@goffi.org>
date Thu, 17 Dec 2015 22:08:11 +0100
parents 27a140aa5023
children d2e023da2983
files src/plugins/plugin_xep_0166.py
diffstat 1 files changed, 24 insertions(+), 6 deletions(-) [+]
line wrap: on
line diff
--- a/src/plugins/plugin_xep_0166.py	Thu Dec 17 22:02:52 2015 +0100
+++ b/src/plugins/plugin_xep_0166.py	Thu Dec 17 22:08:11 2015 +0100
@@ -208,6 +208,8 @@
                 - jingleSessionInit(self, session, content_name[, *args, **kwargs], profile): must return the domish.Element used for initial content
                 - jingleHandler(self, action, session, content_name, transport_elt, profile):
                     called on several action to negociate the application or transport
+                - jingleTerminate: called on session terminate, with reason_elt
+                    May be used to clean session
         """
         if namespace in self._applications:
             raise exceptions.ConflictError(u"Trying to register already registered namespace {}".format(namespace))
@@ -605,6 +607,13 @@
 
                 content_data['transport_elt'] = transport_elt
 
+    def _ignore(self, action, session, content_name, elt, profile):
+        """Dummy method used when not exception must be raised if a method is not implemented in _callPlugins
+
+        must be used as app_default_cb and/or transp_default_cb
+        """
+        return 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, force_element=None, profile=C.PROF_KEY_NONE):
@@ -624,7 +633,7 @@
             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 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
+        @param force_element(None, domish.Element, object): if elements is False, it is used as element parameter
             else it is ignored
         @param profile(unicode): %(doc_profile)s
         @return (list[defer.Deferred]): list of launched Deferred
@@ -643,10 +652,10 @@
                 try:
                     method = getattr(handler, method_name)
                 except AttributeError:
-                    if default_cb is not None:
+                    if default_cb is None:
+                        raise exceptions.NotFound(u'{} not implemented !'.format(method_name))
+                    else:
                         method = default_cb
-                    else:
-                        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:
@@ -751,7 +760,16 @@
     def onSessionTerminate(self, client, request, jingle_elt, session):
         # TODO: check reason, display a message to user if needed
         log.debug("Jingle Session {} terminated".format(session['id']))
-        self._delSession(client, session['id'])
+        try:
+            reason_elt = jingle_elt.elements(NS_JINGLE, 'reason').next()
+        except StopIteration:
+            log.warning(u"Not reason given for session termination")
+            reason_elt = jingle_elt.addElement('reason')
+
+        terminate_defers = self._callPlugins(XEP_0166.A_SESSION_TERMINATE, session, 'jingleTerminate', 'jingleTerminate', self._ignore, self._ignore, elements=False, force_element=reason_elt, profile=client.profile)
+        terminate_dlist = defer.DeferredList(terminate_defers)
+
+        terminate_dlist.addCallback(lambda dummy: self._delSession(client, session['id']))
         client.xmlstream.send(xmlstream.toResponse(request, 'result'))
 
     def onSessionAccept(self, client, request, jingle_elt, session):
@@ -828,7 +846,7 @@
         @param jingle_elt(domish.Element): the <jingle> element
         @param session(dict): session data
         """
-        log.debug(u"Other peer want to replace the transport")
+        log.debug(u"Other peer wants to replace the transport")
         try:
             self._parseElements(jingle_elt, session, request, client, with_application=False)
         except exceptions.CancelError: