Mercurial > libervia-backend
diff sat/plugins/plugin_xep_0166.py @ 3404:26a0af6e32c1
plugin XEP-0166: new trigger point + coroutines + helper methods:
- a new `XEP-0166_initiate` async trigger point is available
- `initate` is now a coroutine
- `jingleSessionInit` in applications and transports handlers are now called using
`utils.adDeferred`
- new `getApplication` helper method, to retrieve application from its namespace
- new `getContentData` helper method to retrieve application and its argument from content
author | Goffi <goffi@goffi.org> |
---|---|
date | Thu, 12 Nov 2020 14:53:15 +0100 |
parents | ac9342f359e9 |
children | be6d91572633 |
line wrap: on
line diff
--- a/sat/plugins/plugin_xep_0166.py Thu Nov 12 14:53:15 2020 +0100 +++ b/sat/plugins/plugin_xep_0166.py Thu Nov 12 14:53:15 2020 +0100 @@ -19,6 +19,7 @@ import uuid import time +from typing import Tuple from collections import namedtuple from zope.interface import implementer from twisted.words.protocols.jabber import jid @@ -336,8 +337,34 @@ """ return self._buildJingleElt(client, session, XEP_0166.A_SESSION_INFO) - @defer.inlineCallbacks - def initiate(self, client, peer_jid, contents): + def getApplication(self, namespace: str) -> object: + """Retreive application corresponding to a namespace + + @raise exceptions.NotFound if application can't be found + """ + try: + return self._applications[namespace] + except KeyError: + raise exceptions.NotFound( + f"No application registered for {namespace}" + ) + + def getContentData(self, content: dict) -> Tuple[object, list, dict, str]: + """"Retrieve application and its argument from content""" + app_ns = content["app_ns"] + try: + application = self.getApplication(app_ns) + except exceptions.NotFound as e: + raise exceptions.InternalError(str(e)) + app_args = content.get("app_args", []) + app_kwargs = content.get("app_kwargs", {}) + try: + content_name = content["name"] + except KeyError: + content_name = content["name"] = str(uuid.uuid4()) + return application, app_args, app_kwargs, content_name + + async def initiate(self, client, peer_jid, contents): """Send a session initiation request @param peer_jid(jid.JID): jid to establith session with @@ -352,7 +379,7 @@ default to BOTH (see XEP-0166 ยง7.3) - app_args(list): args to pass to the application plugin - app_kwargs(dict): keyword args to pass to the application plugin - @return D(unicode): jingle session id + @return (unicode): jingle session id """ assert contents # there must be at least one content if (peer_jid == client.jid @@ -371,6 +398,13 @@ "started": time.time(), "contents": {}, } + + if not await self.host.trigger.asyncPoint( + "XEP-0166_initiate", + client, session, contents + ): + return + iq_elt, jingle_elt = self._buildJingleElt( client, session, XEP_0166.A_SESSION_INITIATE ) @@ -380,13 +414,7 @@ for content in contents: # we get the application plugin - app_ns = content["app_ns"] - try: - application = self._applications[app_ns] - except KeyError: - raise exceptions.InternalError( - "No application registered for {}".format(app_ns) - ) + application, app_args, app_kwargs, content_name = self.getContentData(content) # and the transport plugin transport_type = content.get("transport_type", XEP_0166.TRANSPORT_STREAMING) @@ -406,15 +434,10 @@ "creator": XEP_0166.ROLE_INITIATOR, "senders": content.get("senders", "both"), } - try: - content_name = content["name"] - except KeyError: - content_name = str(uuid.uuid4()) - else: - if content_name in contents_dict: - raise exceptions.InternalError( - "There is already a content with this name" - ) + if content_name in contents_dict: + raise exceptions.InternalError( + "There is already a content with this name" + ) contents_dict[content_name] = content_data # we construct the content element @@ -427,21 +450,21 @@ pass # then the description element - app_args = content.get("app_args", []) - app_kwargs = content.get("app_kwargs", {}) - desc_elt = yield application.handler.jingleSessionInit( + desc_elt = await utils.asDeferred( + application.handler.jingleSessionInit, client, session, content_name, *app_args, **app_kwargs ) content_elt.addChild(desc_elt) # and the transport one - transport_elt = yield transport.handler.jingleSessionInit( + transport_elt = await utils.asDeferred( + transport.handler.jingleSessionInit, client, session, content_name ) content_elt.addChild(transport_elt) try: - yield iq_elt.send() + await iq_elt.send() except Exception as e: failure_ = failure.Failure(e) self._iqError(failure_, sid, client)