comparison src/plugins/plugin_xep_0166.py @ 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 c25f63215632
children d17772b0fe22
comparison
equal deleted inserted replaced
1753:27a140aa5023 1754:f4e9f2f7fe0f
206 A Deferred can be returned 206 A Deferred can be returned
207 - if not present, a generic accept dialog will be used 207 - if not present, a generic accept dialog will be used
208 - jingleSessionInit(self, session, content_name[, *args, **kwargs], profile): must return the domish.Element used for initial content 208 - jingleSessionInit(self, session, content_name[, *args, **kwargs], profile): must return the domish.Element used for initial content
209 - jingleHandler(self, action, session, content_name, transport_elt, profile): 209 - jingleHandler(self, action, session, content_name, transport_elt, profile):
210 called on several action to negociate the application or transport 210 called on several action to negociate the application or transport
211 - jingleTerminate: called on session terminate, with reason_elt
212 May be used to clean session
211 """ 213 """
212 if namespace in self._applications: 214 if namespace in self._applications:
213 raise exceptions.ConflictError(u"Trying to register already registered namespace {}".format(namespace)) 215 raise exceptions.ConflictError(u"Trying to register already registered namespace {}".format(namespace))
214 self._applications[namespace] = ApplicationData(namespace=namespace, handler=handler) 216 self._applications[namespace] = ApplicationData(namespace=namespace, handler=handler)
215 log.debug(u"new jingle application registered") 217 log.debug(u"new jingle application registered")
603 if 'transport_elt' in content_data: 605 if 'transport_elt' in content_data:
604 raise exceptions.InternalError(u"transport_elt should not exist at this point") 606 raise exceptions.InternalError(u"transport_elt should not exist at this point")
605 607
606 content_data['transport_elt'] = transport_elt 608 content_data['transport_elt'] = transport_elt
607 609
610 def _ignore(self, action, session, content_name, elt, profile):
611 """Dummy method used when not exception must be raised if a method is not implemented in _callPlugins
612
613 must be used as app_default_cb and/or transp_default_cb
614 """
615 return elt
616
608 def _callPlugins(self, action, session, app_method_name='jingleHandler', transp_method_name='jingleHandler', 617 def _callPlugins(self, action, session, app_method_name='jingleHandler', transp_method_name='jingleHandler',
609 app_default_cb=None, transp_default_cb=None, delete=True, 618 app_default_cb=None, transp_default_cb=None, delete=True,
610 elements=True, force_element=None, profile=C.PROF_KEY_NONE): 619 elements=True, force_element=None, profile=C.PROF_KEY_NONE):
611 """Call application and transport plugin methods for all contents 620 """Call application and transport plugin methods for all contents
612 621
622 None to raise an exception instead 631 None to raise an exception instead
623 @param delete(bool): if True, remove desc_elt and transport_elt from session 632 @param delete(bool): if True, remove desc_elt and transport_elt from session
624 ignored if elements is False 633 ignored if elements is False
625 @param elements(bool): True if elements(desc_elt and tranport_elt) must be managed 634 @param elements(bool): True if elements(desc_elt and tranport_elt) must be managed
626 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) 635 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)
627 @param force_element(None, domish.Element, object): if elements is None, it is used as element parameter 636 @param force_element(None, domish.Element, object): if elements is False, it is used as element parameter
628 else it is ignored 637 else it is ignored
629 @param profile(unicode): %(doc_profile)s 638 @param profile(unicode): %(doc_profile)s
630 @return (list[defer.Deferred]): list of launched Deferred 639 @return (list[defer.Deferred]): list of launched Deferred
631 @raise exceptions.NotFound: method is not implemented 640 @raise exceptions.NotFound: method is not implemented
632 """ 641 """
641 650
642 handler = content_data[handler_key].handler 651 handler = content_data[handler_key].handler
643 try: 652 try:
644 method = getattr(handler, method_name) 653 method = getattr(handler, method_name)
645 except AttributeError: 654 except AttributeError:
646 if default_cb is not None: 655 if default_cb is None:
656 raise exceptions.NotFound(u'{} not implemented !'.format(method_name))
657 else:
647 method = default_cb 658 method = default_cb
648 else:
649 raise exceptions.NotFound(u'{} not implemented !'.format(method_name))
650 if elements: 659 if elements:
651 elt = content_data.pop(elt_name) if delete else content_data[elt_name] 660 elt = content_data.pop(elt_name) if delete else content_data[elt_name]
652 else: 661 else:
653 elt = force_element 662 elt = force_element
654 d = defer.maybeDeferred(method, action, session, content_name, elt, profile) 663 d = defer.maybeDeferred(method, action, session, content_name, elt, profile)
749 return d_list 758 return d_list
750 759
751 def onSessionTerminate(self, client, request, jingle_elt, session): 760 def onSessionTerminate(self, client, request, jingle_elt, session):
752 # TODO: check reason, display a message to user if needed 761 # TODO: check reason, display a message to user if needed
753 log.debug("Jingle Session {} terminated".format(session['id'])) 762 log.debug("Jingle Session {} terminated".format(session['id']))
754 self._delSession(client, session['id']) 763 try:
764 reason_elt = jingle_elt.elements(NS_JINGLE, 'reason').next()
765 except StopIteration:
766 log.warning(u"Not reason given for session termination")
767 reason_elt = jingle_elt.addElement('reason')
768
769 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)
770 terminate_dlist = defer.DeferredList(terminate_defers)
771
772 terminate_dlist.addCallback(lambda dummy: self._delSession(client, session['id']))
755 client.xmlstream.send(xmlstream.toResponse(request, 'result')) 773 client.xmlstream.send(xmlstream.toResponse(request, 'result'))
756 774
757 def onSessionAccept(self, client, request, jingle_elt, session): 775 def onSessionAccept(self, client, request, jingle_elt, session):
758 """Method called once session is accepted 776 """Method called once session is accepted
759 777
826 @param client: %(doc_client)s 844 @param client: %(doc_client)s
827 @param request(domish.Element): full <iq> request 845 @param request(domish.Element): full <iq> request
828 @param jingle_elt(domish.Element): the <jingle> element 846 @param jingle_elt(domish.Element): the <jingle> element
829 @param session(dict): session data 847 @param session(dict): session data
830 """ 848 """
831 log.debug(u"Other peer want to replace the transport") 849 log.debug(u"Other peer wants to replace the transport")
832 try: 850 try:
833 self._parseElements(jingle_elt, session, request, client, with_application=False) 851 self._parseElements(jingle_elt, session, request, client, with_application=False)
834 except exceptions.CancelError: 852 except exceptions.CancelError:
835 defer.returnValue(None) 853 defer.returnValue(None)
836 854