Mercurial > libervia-backend
view libervia/backend/plugins/plugin_xep_0092.py @ 4240:79c8a70e1813
backend, frontend: prepare remote control:
This is a series of changes necessary to prepare the implementation of remote control
feature:
- XEP-0166: add a `priority` attribute to `ApplicationData`: this is needed when several
applications are working in a same session, to know which one must be handled first.
Will be used to make Remote Control have precedence over Call content.
- XEP-0166: `_call_plugins` is now async and is not used with `DeferredList` anymore: the
benefit to have methods called in parallels is very low, and it cause a lot of trouble
as we can't predict order. Methods are now called sequentially so workflow can be
predicted.
- XEP-0167: fix `senders` XMPP attribute <=> SDP mapping
- XEP-0234: preflight acceptance key is now `pre-accepted` instead of `file-accepted`, so
the same key can be used with other jingle applications.
- XEP-0167, XEP-0343: move some method to XEP-0167
- XEP-0353: use new `priority` feature to call preflight methods of applications according
to it.
- frontend (webrtc): refactor the sources/sink handling with a more flexible mechanism
based on Pydantic models. It is now possible to have has many Data Channel as necessary,
to have them in addition to A/V streams, to specify manually GStreamer sources and
sinks, etc.
- frontend (webrtc): rework of the pipeline to reduce latency.
- frontend: new `portal_desktop` method. Screenshare portal handling has been moved there,
and RemoteDesktop portal has been added.
- frontend (webrtc): fix `extract_ufrag_pwd` method.
rel 436
author | Goffi <goffi@goffi.org> |
---|---|
date | Sat, 11 May 2024 13:52:41 +0200 |
parents | 4b842c1fb686 |
children |
line wrap: on
line source
#!/usr/bin/env python3 # SàT plugin for Software Version (XEP-0092) # Copyright (C) 2009-2021 Jérôme Poisson (goffi@goffi.org) # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU Affero General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU Affero General Public License for more details. # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see <http://www.gnu.org/licenses/>. from typing import Tuple from twisted.internet import defer, reactor from twisted.words.protocols.jabber import jid from wokkel import compat from libervia.backend.core import exceptions from libervia.backend.core.constants import Const as C from libervia.backend.core.core_types import SatXMPPEntity from libervia.backend.core.i18n import _ from libervia.backend.core.log import getLogger log = getLogger(__name__) NS_VERSION = "jabber:iq:version" TIMEOUT = 10 PLUGIN_INFO = { C.PI_NAME: "Software Version Plugin", C.PI_IMPORT_NAME: "XEP-0092", C.PI_TYPE: "XEP", C.PI_PROTOCOLS: ["XEP-0092"], C.PI_DEPENDENCIES: [], C.PI_RECOMMENDATIONS: [C.TEXT_CMDS], C.PI_MAIN: "XEP_0092", C.PI_HANDLER: "no", # version is already handler in core.xmpp module C.PI_DESCRIPTION: _("""Implementation of Software Version"""), } class XEP_0092(object): def __init__(self, host): log.info(_("Plugin XEP_0092 initialization")) self.host = host host.bridge.add_method( "software_version_get", ".plugin", in_sign="ss", out_sign="(sss)", method=self._get_version, async_=True, ) try: self.host.plugins[C.TEXT_CMDS].add_who_is_cb(self._whois, 50) except KeyError: log.info(_("Text commands not available")) def _get_version(self, entity_jid_s, profile_key): def prepare_for_bridge(data): name, version, os = data return (name or "", version or "", os or "") client = self.host.get_client(profile_key) d = self.version_get(client, jid.JID(entity_jid_s)) d.addCallback(prepare_for_bridge) return d def version_get( self, client: SatXMPPEntity, jid_: jid.JID, ) -> Tuple[str, str, str]: """Ask version of the client that jid_ is running @param jid_: jid from who we want to know client's version @return: a defered which fire a tuple with the following data (None if not available): - name: Natural language name of the software - version: specific version of the software - os: operating system of the queried entity """ def do_version_get(__): iq_elt = compat.IQ(client.xmlstream, "get") iq_elt["to"] = jid_.full() iq_elt.addElement("query", NS_VERSION) d = iq_elt.send() d.addCallback(self._got_version) return d d = self.host.check_feature(client, NS_VERSION, jid_) d.addCallback(do_version_get) reactor.callLater( TIMEOUT, d.cancel ) # XXX: timeout needed because some clients don't answer the IQ return d def _got_version(self, iq_elt): try: query_elt = next(iq_elt.elements(NS_VERSION, "query")) except StopIteration: raise exceptions.DataError ret = [] for name in ("name", "version", "os"): try: data_elt = next(query_elt.elements(NS_VERSION, name)) ret.append(str(data_elt)) except StopIteration: ret.append(None) return tuple(ret) def _whois(self, client, whois_msg, mess_data, target_jid): """Add software/OS information to whois""" def version_cb(version_data): name, version, os = version_data if name: whois_msg.append(_("Client name: %s") % name) if version: whois_msg.append(_("Client version: %s") % version) if os: whois_msg.append(_("Operating system: %s") % os) def version_eb(failure): failure.trap(exceptions.FeatureNotFound, defer.CancelledError) if failure.check(failure, exceptions.FeatureNotFound): whois_msg.append(_("Software version not available")) else: whois_msg.append(_("Client software version request timeout")) d = self.version_get(client, target_jid) d.addCallbacks(version_cb, version_eb) return d