Mercurial > libervia-backend
view libervia/cli/output_std.py @ 4231:e11b13418ba6
plugin XEP-0353, XEP-0234, jingle: WebRTC data channel signaling implementation:
Implement XEP-0343: Signaling WebRTC Data Channels in Jingle. The current version of the
XEP (0.3.1) has no implementation and contains some flaws. After discussing this on xsf@,
Daniel (from Conversations) mentioned that they had a sprint with Larma (from Dino) to
work on another version and provided me with this link:
https://gist.github.com/iNPUTmice/6c56f3e948cca517c5fb129016d99e74 . I have used it for my
implementation.
This implementation reuses work done on Jingle A/V call (notably XEP-0176 and XEP-0167
plugins), with adaptations. When used, XEP-0234 will not handle the file itself as it
normally does. This is because WebRTC has several implementations (browser for web
interface, GStreamer for others), and file/data must be handled directly by the frontend.
This is particularly important for web frontends, as the file is not sent from the backend
but from the end-user's browser device.
Among the changes, there are:
- XEP-0343 implementation.
- `file_send` bridge method now use serialised dict as output.
- New `BaseTransportHandler.is_usable` method which get content data and returns a boolean
(default to `True`) to tell if this transport can actually be used in this context (when
we are initiator). Used in webRTC case to see if call data are available.
- Support of `application` media type, and everything necessary to handle data channels.
- Better confirmation message, with file name, size and description when available.
- When file is accepted in preflight, it is specified in following `action_new` signal for
actual file transfer. This way, frontend can avoid the display or 2 confirmation
messages.
- XEP-0166: when not specified, default `content` name is now its index number instead of
a UUID. This follows the behaviour of browsers.
- XEP-0353: better handling of events such as call taken by another device.
- various other updates.
rel 441
author | Goffi <goffi@goffi.org> |
---|---|
date | Sat, 06 Apr 2024 12:57:23 +0200 |
parents | 47401850dec6 |
children | 0d7bb4df2343 |
line wrap: on
line source
#! /usr/bin/env python3 # Libervia CLI # 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/>. """Standard outputs""" from libervia.cli.constants import Const as C from libervia.frontends.tools import jid from libervia.backend.tools.common.ansi import ANSI as A from libervia.backend.tools.common import date_utils import json __outputs__ = ["Simple", "Json"] class Simple(object): """Default outputs""" def __init__(self, host): self.host = host host.register_output(C.OUTPUT_TEXT, C.OUTPUT_NAME_SIMPLE, self.simple_print) host.register_output(C.OUTPUT_LIST, C.OUTPUT_NAME_SIMPLE, self.list) host.register_output(C.OUTPUT_DICT, C.OUTPUT_NAME_SIMPLE, self.dict) host.register_output(C.OUTPUT_LIST_DICT, C.OUTPUT_NAME_SIMPLE, self.list_dict) host.register_output(C.OUTPUT_DICT_DICT, C.OUTPUT_NAME_SIMPLE, self.dict_dict) host.register_output(C.OUTPUT_MESS, C.OUTPUT_NAME_SIMPLE, self.messages) host.register_output(C.OUTPUT_COMPLEX, C.OUTPUT_NAME_SIMPLE, self.simple_print) def simple_print(self, data): self.host.disp(str(data)) def list(self, data): self.host.disp("\n".join(data)) def dict(self, data, indent=0, header_color=C.A_HEADER): options = self.host.parse_output_options() self.host.check_output_options({"no-header"}, options) show_header = not "no-header" in options for k, v in data.items(): if show_header: header = A.color(header_color, k) + ": " else: header = "" self.host.disp( ( "{indent}{header}{value}".format( indent=indent * " ", header=header, value=v ) ) ) def list_dict(self, data): for idx, datum in enumerate(data): if idx: self.host.disp("\n") self.dict(datum) def dict_dict(self, data): for key, sub_dict in data.items(): self.host.disp(A.color(C.A_HEADER, key)) self.dict(sub_dict, indent=4, header_color=C.A_SUBHEADER) def messages(self, data): # TODO: handle lang, and non chat message (normal, headline) for mess_data in data: (uid, timestamp, from_jid, to_jid, message, subject, mess_type, extra) = mess_data time_str = date_utils.date_fmt(timestamp, "auto_day", tz_info=date_utils.TZ_LOCAL) from_jid = jid.JID(from_jid) if mess_type == C.MESS_TYPE_GROUPCHAT: nick = from_jid.resource else: nick = from_jid.node if self.host.own_jid is not None and self.host.own_jid.bare == from_jid.bare: nick_color = A.BOLD + A.FG_BLUE else: nick_color = A.BOLD + A.FG_YELLOW message = list(message.values())[0] if message else "" self.host.disp(A.color( A.FG_CYAN, '['+time_str+'] ', nick_color, nick, A.RESET, A.BOLD, '> ', A.RESET, message)) class Json(object): """outputs in json format""" def __init__(self, host): self.host = host host.register_output(C.OUTPUT_TEXT, C.OUTPUT_NAME_JSON, self.dump) host.register_output(C.OUTPUT_LIST, C.OUTPUT_NAME_JSON, self.dump_pretty) host.register_output(C.OUTPUT_LIST, C.OUTPUT_NAME_JSON_RAW, self.dump) host.register_output(C.OUTPUT_DICT, C.OUTPUT_NAME_JSON, self.dump_pretty) host.register_output(C.OUTPUT_DICT, C.OUTPUT_NAME_JSON_RAW, self.dump) host.register_output(C.OUTPUT_LIST_DICT, C.OUTPUT_NAME_JSON, self.dump_pretty) host.register_output(C.OUTPUT_LIST_DICT, C.OUTPUT_NAME_JSON_RAW, self.dump) host.register_output(C.OUTPUT_DICT_DICT, C.OUTPUT_NAME_JSON, self.dump_pretty) host.register_output(C.OUTPUT_DICT_DICT, C.OUTPUT_NAME_JSON_RAW, self.dump) host.register_output(C.OUTPUT_MESS, C.OUTPUT_NAME_JSON, self.dump_pretty) host.register_output(C.OUTPUT_MESS, C.OUTPUT_NAME_JSON_RAW, self.dump) host.register_output(C.OUTPUT_COMPLEX, C.OUTPUT_NAME_JSON, self.dump_pretty) host.register_output(C.OUTPUT_COMPLEX, C.OUTPUT_NAME_JSON_RAW, self.dump) def dump(self, data): self.host.disp(json.dumps(data, default=str)) def dump_pretty(self, data): self.host.disp(json.dumps(data, indent=4, default=str))