Mercurial > libervia-backend
comparison libervia/backend/plugins/plugin_xep_0298.py @ 4294:a0ed5c976bf8
component conferences, plugin XEP-0167, XEP-0298: add stream user metadata:
A/V conference now adds user metadata about the stream it is forwarding through XEP-0298.
This is parsed and added to metadata during confirmation on client side.
rel 448
author | Goffi <goffi@goffi.org> |
---|---|
date | Tue, 06 Aug 2024 23:43:11 +0200 |
parents | dd0891d0b22b |
children |
comparison
equal
deleted
inserted
replaced
4293:9447796408f6 | 4294:a0ed5c976bf8 |
---|---|
18 # along with this program. If not, see <http://www.gnu.org/licenses/>. | 18 # along with this program. If not, see <http://www.gnu.org/licenses/>. |
19 | 19 |
20 from urllib.parse import quote, unquote | 20 from urllib.parse import quote, unquote |
21 from twisted.words.protocols.jabber import jid | 21 from twisted.words.protocols.jabber import jid |
22 from twisted.words.xish import domish | 22 from twisted.words.xish import domish |
23 from libervia.backend.core.core_types import SatXMPPEntity | |
23 from libervia.backend.core.i18n import _ | 24 from libervia.backend.core.i18n import _ |
24 from libervia.backend.core.constants import Const as C | 25 from libervia.backend.core.constants import Const as C |
25 from libervia.backend.core.log import getLogger | 26 from libervia.backend.core.log import getLogger |
26 from wokkel import disco, iwokkel | 27 from wokkel import disco, iwokkel |
27 from zope.interface import implementer | 28 from zope.interface import implementer |
28 from twisted.words.protocols.jabber.xmlstream import XMPPHandler | 29 from twisted.words.protocols.jabber.xmlstream import XMPPHandler |
30 | |
31 from libervia.backend.plugins.plugin_xep_0166 import XEP_0166 | |
29 | 32 |
30 log = getLogger(__name__) | 33 log = getLogger(__name__) |
31 | 34 |
32 | 35 |
33 PLUGIN_INFO = { | 36 PLUGIN_INFO = { |
34 C.PI_NAME: "Events", | 37 C.PI_NAME: "Events", |
35 C.PI_IMPORT_NAME: "XEP-0298", | 38 C.PI_IMPORT_NAME: "XEP-0298", |
36 C.PI_TYPE: "XEP", | 39 C.PI_TYPE: "XEP", |
37 C.PI_MODES: C.PLUG_MODE_BOTH, | 40 C.PI_MODES: C.PLUG_MODE_BOTH, |
38 C.PI_PROTOCOLS: [], | 41 C.PI_PROTOCOLS: [], |
39 C.PI_DEPENDENCIES: [], | 42 C.PI_DEPENDENCIES: ["XEP-0167"], |
40 C.PI_MAIN: "XEP_0298", | 43 C.PI_MAIN: "XEP_0298", |
41 C.PI_HANDLER: "yes", | 44 C.PI_HANDLER: "yes", |
42 C.PI_DESCRIPTION: _( | 45 C.PI_DESCRIPTION: _( |
43 "Delivering Conference Information to Jingle Participants (Coin). This plugin " | 46 "Delivering Conference Information to Jingle Participants (Coin). This plugin " |
44 "is used to associate metadata about uses an call states in multi-party calls." | 47 "is used to associate metadata about uses an call states in multi-party calls." |
53 namespace = NS_COIN | 56 namespace = NS_COIN |
54 | 57 |
55 def __init__(self, host): | 58 def __init__(self, host): |
56 log.info(f"plugin {PLUGIN_INFO[C.PI_NAME]!r} initialization") | 59 log.info(f"plugin {PLUGIN_INFO[C.PI_NAME]!r} initialization") |
57 self.host = host | 60 self.host = host |
61 self._j: XEP_0166 = host.plugins["XEP-0166"] | |
62 host.trigger.add( | |
63 "XEP-0167_jingle_session_init", self._jingle_session_init_trigger | |
64 ) | |
65 host.trigger.add("XEP-0167_jingle_handler", self._jingle_handler_trigger) | |
58 | 66 |
59 def get_handler(self, client): | 67 def get_handler(self, client): |
60 return CoinHandler(self) | 68 return CoinHandler(self) |
69 | |
70 def _jingle_session_init_trigger( | |
71 self, | |
72 client: SatXMPPEntity, | |
73 session: dict, | |
74 content_name: str, | |
75 media: str, | |
76 media_data: dict, | |
77 desc_elt: domish.Element, | |
78 ) -> None: | |
79 """Check for the presence of "user" metadata, and add relevant elements.""" | |
80 if client.profile == "conferences": | |
81 if content_name != next(iter(session["contents"].keys())): | |
82 # We only apply metadata for the first content, as it is global. | |
83 return | |
84 try: | |
85 user = session["metadata"]["user"] | |
86 except KeyError: | |
87 return | |
88 jingle_elt = session["jingle_elt"] | |
89 conference_info_elt = self.add_conference_info(jingle_elt, True) | |
90 self.add_user(conference_info_elt, user) | |
91 | |
92 async def _jingle_handler_trigger( | |
93 self, | |
94 client: SatXMPPEntity, | |
95 action: str, | |
96 session: dict, | |
97 content_name: str, | |
98 desc_elt: domish.Element, | |
99 ) -> None: | |
100 # this is a session metadata, so we only generate it on the first content | |
101 if action == self._j.A_PREPARE_CONFIRMATION and content_name == next( | |
102 iter(session["contents"]) | |
103 ): | |
104 jingle_elt = session["jingle_elt"] | |
105 infos = self.parse(jingle_elt) | |
106 try: | |
107 user = infos["info"]["users"][0] | |
108 except (KeyError, IndexError): | |
109 pass | |
110 else: | |
111 session.setdefault("metadata", {})["peer_user"] = user | |
61 | 112 |
62 def add_conference_info( | 113 def add_conference_info( |
63 self, jingle_elt: domish.Element, is_focus: bool = False, **kwargs | 114 self, jingle_elt: domish.Element, is_focus: bool = False, **kwargs |
64 ) -> domish.Element: | 115 ) -> domish.Element: |
65 """Create and return a <conference_info> element | 116 """Create and return a <conference_info> element |
102 @param jingle_elt: Jingle element to parse. | 153 @param jingle_elt: Jingle element to parse. |
103 @return: Dictionary with "info" key if conference info is found. | 154 @return: Dictionary with "info" key if conference info is found. |
104 """ | 155 """ |
105 try: | 156 try: |
106 conference_info_elt = next( | 157 conference_info_elt = next( |
107 jingle_elt.elements((NS_CONFERENCE_INFO, "conference-info")) | 158 jingle_elt.elements(NS_CONFERENCE_INFO, "conference-info") |
108 ) | 159 ) |
109 except StopIteration: | 160 except StopIteration: |
110 return {} | 161 return {} |
111 | 162 |
112 users = [] | 163 users = [] |