Mercurial > libervia-backend
annotate sat_frontends/jp/cmd_info.py @ 3104:118d91c932a7
plugin XEP-0384: OMEMO for MUC implementation:
- encryption is now allowed for group chats
- when an encryption is requested for a MUC, real jids or all occupants are used to
encrypt the message
- a cache for plain text message sent to MUC is used, because for security reason we can't
encrypt message for our own device with OMEMO (that would prevent ratchet and break the
prefect forward secrecy). Thus, message sent in MUC are cached for 5 min, and the
decrypted version is used when found. We don't send immediately the plain text message
to frontends and history because we want to keep the same MUC behaviour as for plain
text, and receiving a message means that it was received and sent back by MUC service
- <origin-id> is used to identify messages sent by our device
- a feedback_jid is now use to use correct entity for feedback message in case of problem:
with a room we have to send feedback message to the room and not the the emitter
- encryptMessage now only accepts list in the renamed "entity_bare_jids" argument
author | Goffi <goffi@goffi.org> |
---|---|
date | Mon, 30 Dec 2019 20:59:46 +0100 |
parents | fee60f17ebac |
children | 9d0df638c8b4 |
rev | line source |
---|---|
1960 | 1 #!/usr/bin/env python2 |
966 | 2 # -*- coding: utf-8 -*- |
3 | |
4 # jp: a SAT command line tool | |
2771 | 5 # Copyright (C) 2009-2019 Jérôme Poisson (goffi@goffi.org) |
966 | 6 |
7 # This program is free software: you can redistribute it and/or modify | |
8 # it under the terms of the GNU Affero General Public License as published by | |
9 # the Free Software Foundation, either version 3 of the License, or | |
10 # (at your option) any later version. | |
11 | |
12 # This program is distributed in the hope that it will be useful, | |
13 # but WITHOUT ANY WARRANTY; without even the implied warranty of | |
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
15 # GNU Affero General Public License for more details. | |
16 | |
17 # You should have received a copy of the GNU Affero General Public License | |
18 # along with this program. If not, see <http://www.gnu.org/licenses/>. | |
19 | |
3028 | 20 from . import base |
966 | 21 from sat.core.i18n import _ |
2346
c903c259402a
jp (info/disco): type selection + output improvments:
Goffi <goffi@goffi.org>
parents:
2343
diff
changeset
|
22 from sat.tools.common.ansi import ANSI as A |
2600
947c4c4c5c53
jp (info/session): by default, display started as human readable date instead of Unix time
Goffi <goffi@goffi.org>
parents:
2562
diff
changeset
|
23 from sat.tools.common import date_utils |
2114
dc5d214f0a3b
jp (info/session): added a command to get data on current session
Goffi <goffi@goffi.org>
parents:
1960
diff
changeset
|
24 from sat_frontends.jp.constants import Const as C |
2346
c903c259402a
jp (info/disco): type selection + output improvments:
Goffi <goffi@goffi.org>
parents:
2343
diff
changeset
|
25 from sat_frontends.jp import common |
966 | 26 |
971
8ca5c990ed92
jp: "disco" subcommand, moved into a new "info" subcommand + added "version" subcommand which get software version
Goffi <goffi@goffi.org>
parents:
966
diff
changeset
|
27 __commands__ = ["Info"] |
8ca5c990ed92
jp: "disco" subcommand, moved into a new "info" subcommand + added "version" subcommand which get software version
Goffi <goffi@goffi.org>
parents:
966
diff
changeset
|
28 |
966 | 29 |
30 class Disco(base.CommandBase): | |
31 | |
32 def __init__(self, host): | |
2346
c903c259402a
jp (info/disco): type selection + output improvments:
Goffi <goffi@goffi.org>
parents:
2343
diff
changeset
|
33 extra_outputs = {'default': self.default_output} |
3040 | 34 super(Disco, self).__init__( |
35 host, 'disco', use_output='complex', extra_outputs=extra_outputs, | |
36 help=_('service discovery')) | |
966 | 37 |
38 def add_parser_options(self): | |
3028 | 39 self.parser.add_argument("jid", help=_("entity to discover")) |
3040 | 40 self.parser.add_argument( |
41 "-t", "--type", type=str, choices=('infos', 'items', 'both'), default='both', | |
42 help=_("type of data to discover")) | |
3028 | 43 self.parser.add_argument("-n", "--node", default='', help=_("node to use")) |
3040 | 44 self.parser.add_argument( |
45 "-C", "--no-cache", dest='use_cache', action="store_false", | |
46 help=_("ignore cache")) | |
2346
c903c259402a
jp (info/disco): type selection + output improvments:
Goffi <goffi@goffi.org>
parents:
2343
diff
changeset
|
47 |
c903c259402a
jp (info/disco): type selection + output improvments:
Goffi <goffi@goffi.org>
parents:
2343
diff
changeset
|
48 def default_output(self, data): |
3028 | 49 features = data.get('features', []) |
50 identities = data.get('identities', []) | |
51 extensions = data.get('extensions', {}) | |
52 items = data.get('items', []) | |
2346
c903c259402a
jp (info/disco): type selection + output improvments:
Goffi <goffi@goffi.org>
parents:
2343
diff
changeset
|
53 |
c903c259402a
jp (info/disco): type selection + output improvments:
Goffi <goffi@goffi.org>
parents:
2343
diff
changeset
|
54 identities_table = common.Table(self.host, |
c903c259402a
jp (info/disco): type selection + output improvments:
Goffi <goffi@goffi.org>
parents:
2343
diff
changeset
|
55 identities, |
3028 | 56 headers=(_('category'), |
57 _('type'), | |
58 _('name')), | |
2346
c903c259402a
jp (info/disco): type selection + output improvments:
Goffi <goffi@goffi.org>
parents:
2343
diff
changeset
|
59 use_buffer=True) |
c903c259402a
jp (info/disco): type selection + output improvments:
Goffi <goffi@goffi.org>
parents:
2343
diff
changeset
|
60 |
c903c259402a
jp (info/disco): type selection + output improvments:
Goffi <goffi@goffi.org>
parents:
2343
diff
changeset
|
61 extensions_tpl = [] |
3028 | 62 extensions_types = list(extensions.keys()) |
1414
159d16336f87
core, bridge, jp: management of service discovery extensions (XEP-0128)
Goffi <goffi@goffi.org>
parents:
1396
diff
changeset
|
63 extensions_types.sort() |
159d16336f87
core, bridge, jp: management of service discovery extensions (XEP-0128)
Goffi <goffi@goffi.org>
parents:
1396
diff
changeset
|
64 for type_ in extensions_types: |
159d16336f87
core, bridge, jp: management of service discovery extensions (XEP-0128)
Goffi <goffi@goffi.org>
parents:
1396
diff
changeset
|
65 fields = [] |
159d16336f87
core, bridge, jp: management of service discovery extensions (XEP-0128)
Goffi <goffi@goffi.org>
parents:
1396
diff
changeset
|
66 for field in extensions[type_]: |
159d16336f87
core, bridge, jp: management of service discovery extensions (XEP-0128)
Goffi <goffi@goffi.org>
parents:
1396
diff
changeset
|
67 field_lines = [] |
159d16336f87
core, bridge, jp: management of service discovery extensions (XEP-0128)
Goffi <goffi@goffi.org>
parents:
1396
diff
changeset
|
68 data, values = field |
3028 | 69 data_keys = list(data.keys()) |
1414
159d16336f87
core, bridge, jp: management of service discovery extensions (XEP-0128)
Goffi <goffi@goffi.org>
parents:
1396
diff
changeset
|
70 data_keys.sort() |
159d16336f87
core, bridge, jp: management of service discovery extensions (XEP-0128)
Goffi <goffi@goffi.org>
parents:
1396
diff
changeset
|
71 for key in data_keys: |
3028 | 72 field_lines.append(A.color('\t', C.A_SUBHEADER, key, A.RESET, ': ', |
2710
b6e16a89311b
jp (info/disco): better default output for extensions
Goffi <goffi@goffi.org>
parents:
2681
diff
changeset
|
73 data[key])) |
b6e16a89311b
jp (info/disco): better default output for extensions
Goffi <goffi@goffi.org>
parents:
2681
diff
changeset
|
74 if len(values) == 1: |
3028 | 75 field_lines.append(A.color('\t', C.A_SUBHEADER, "value", A.RESET, |
76 ': ', values[0] or (A.BOLD + "UNSET"))) | |
2710
b6e16a89311b
jp (info/disco): better default output for extensions
Goffi <goffi@goffi.org>
parents:
2681
diff
changeset
|
77 elif len(values) > 1: |
3028 | 78 field_lines.append(A.color('\t', C.A_SUBHEADER, "values", A.RESET, |
79 ': ')) | |
2710
b6e16a89311b
jp (info/disco): better default output for extensions
Goffi <goffi@goffi.org>
parents:
2681
diff
changeset
|
80 |
b6e16a89311b
jp (info/disco): better default output for extensions
Goffi <goffi@goffi.org>
parents:
2681
diff
changeset
|
81 for value in values: |
3028 | 82 field_lines.append(A.color('\t - ', A.BOLD, value)) |
83 fields.append('\n'.join(field_lines)) | |
3040 | 84 extensions_tpl.append('{type_}\n{fields}'.format( |
85 type_=type_, | |
86 fields='\n\n'.join(fields))) | |
966 | 87 |
3040 | 88 items_table = common.Table( |
89 self.host, | |
90 items, | |
91 headers=( | |
92 _('entity'), | |
93 _('node'), | |
94 _('name')), | |
95 use_buffer=True) | |
2346
c903c259402a
jp (info/disco): type selection + output improvments:
Goffi <goffi@goffi.org>
parents:
2343
diff
changeset
|
96 |
966 | 97 template = [] |
98 if features: | |
3028 | 99 template.append(A.color(C.A_HEADER, _("Features")) + "\n\n{features}") |
966 | 100 if identities: |
3028 | 101 template.append(A.color(C.A_HEADER, _("Identities")) + "\n\n{identities}") |
2346
c903c259402a
jp (info/disco): type selection + output improvments:
Goffi <goffi@goffi.org>
parents:
2343
diff
changeset
|
102 if extensions: |
3028 | 103 template.append(A.color(C.A_HEADER, _("Extensions")) + "\n\n{extensions}") |
966 | 104 if items: |
3028 | 105 template.append(A.color(C.A_HEADER, _("Items")) + "\n\n{items}") |
966 | 106 |
3040 | 107 print("\n\n".join(template).format( |
108 features = '\n'.join(features), | |
109 identities = identities_table.display().string, | |
110 extensions = '\n'.join(extensions_tpl), | |
111 items = items_table.display().string, | |
112 )) | |
113 | |
114 async def start(self): | |
115 infos_requested = self.args.type in ('infos', 'both') | |
116 items_requested = self.args.type in ('items', 'both') | |
117 jids = await self.host.check_jids([self.args.jid]) | |
118 jid = jids[0] | |
119 | |
120 # infos | |
121 if not infos_requested: | |
122 infos = None | |
123 else: | |
124 try: | |
125 infos = await self.host.bridge.discoInfos( | |
126 jid, | |
127 node=self.args.node, | |
128 use_cache=self.args.use_cache, | |
129 profile_key=self.host.profile | |
130 ) | |
131 except Exception as e: | |
132 self.disp(_(f"error while doing discovery: {e}"), error=True) | |
133 self.host.quit(C.EXIT_BRIDGE_ERRBACK) | |
971
8ca5c990ed92
jp: "disco" subcommand, moved into a new "info" subcommand + added "version" subcommand which get software version
Goffi <goffi@goffi.org>
parents:
966
diff
changeset
|
134 |
3040 | 135 # items |
136 if not items_requested: | |
137 items = None | |
138 else: | |
139 try: | |
140 items = await self.host.bridge.discoItems( | |
141 jid, | |
142 node=self.args.node, | |
143 use_cache=self.args.use_cache, | |
144 profile_key=self.host.profile | |
145 ) | |
146 except Exception as e: | |
147 self.disp(_(f"error while doing discovery: {e}"), error=True) | |
148 self.host.quit(C.EXIT_BRIDGE_ERRBACK) | |
149 | |
150 # output | |
151 data = {} | |
152 | |
153 if infos_requested: | |
154 features, identities, extensions = infos | |
155 features.sort() | |
156 identities.sort(key=lambda identity: identity[2]) | |
157 data.update({ | |
158 'features': features, | |
159 'identities': identities, | |
160 'extensions': extensions}) | |
161 | |
162 if items_requested: | |
163 items.sort(key=lambda item: item[2]) | |
164 data['items'] = items | |
165 | |
166 await self.output(data) | |
167 self.host.quit() | |
971
8ca5c990ed92
jp: "disco" subcommand, moved into a new "info" subcommand + added "version" subcommand which get software version
Goffi <goffi@goffi.org>
parents:
966
diff
changeset
|
168 |
8ca5c990ed92
jp: "disco" subcommand, moved into a new "info" subcommand + added "version" subcommand which get software version
Goffi <goffi@goffi.org>
parents:
966
diff
changeset
|
169 class Version(base.CommandBase): |
8ca5c990ed92
jp: "disco" subcommand, moved into a new "info" subcommand + added "version" subcommand which get software version
Goffi <goffi@goffi.org>
parents:
966
diff
changeset
|
170 |
8ca5c990ed92
jp: "disco" subcommand, moved into a new "info" subcommand + added "version" subcommand which get software version
Goffi <goffi@goffi.org>
parents:
966
diff
changeset
|
171 def __init__(self, host): |
2340
4fd499d14b27
jp (info): fixed help for version and session
Goffi <goffi@goffi.org>
parents:
2151
diff
changeset
|
172 super(Version, self).__init__(host, 'version', help=_('software version')) |
971
8ca5c990ed92
jp: "disco" subcommand, moved into a new "info" subcommand + added "version" subcommand which get software version
Goffi <goffi@goffi.org>
parents:
966
diff
changeset
|
173 |
8ca5c990ed92
jp: "disco" subcommand, moved into a new "info" subcommand + added "version" subcommand which get software version
Goffi <goffi@goffi.org>
parents:
966
diff
changeset
|
174 def add_parser_options(self): |
8ca5c990ed92
jp: "disco" subcommand, moved into a new "info" subcommand + added "version" subcommand which get software version
Goffi <goffi@goffi.org>
parents:
966
diff
changeset
|
175 self.parser.add_argument("jid", type=str, help=_("Entity to request")) |
8ca5c990ed92
jp: "disco" subcommand, moved into a new "info" subcommand + added "version" subcommand which get software version
Goffi <goffi@goffi.org>
parents:
966
diff
changeset
|
176 |
3040 | 177 async def start(self): |
178 jids = await self.host.check_jids([self.args.jid]) | |
971
8ca5c990ed92
jp: "disco" subcommand, moved into a new "info" subcommand + added "version" subcommand which get software version
Goffi <goffi@goffi.org>
parents:
966
diff
changeset
|
179 jid = jids[0] |
3040 | 180 try: |
181 data = await self.host.bridge.getSoftwareVersion(jid, self.host.profile) | |
182 except Exception as e: | |
183 self.disp(_(f"error while trying to get version: {e}"), error=True) | |
184 self.host.quit(C.EXIT_BRIDGE_ERRBACK) | |
185 else: | |
186 infos = [] | |
187 name, version, os = data | |
188 if name: | |
189 infos.append(_(f"Software name: {name}")) | |
190 if version: | |
191 infos.append(_(f"Software version: {version}")) | |
192 if os: | |
193 infos.append(_(f"Operating System: {os}")) | |
971
8ca5c990ed92
jp: "disco" subcommand, moved into a new "info" subcommand + added "version" subcommand which get software version
Goffi <goffi@goffi.org>
parents:
966
diff
changeset
|
194 |
3040 | 195 print("\n".join(infos)) |
196 self.host.quit() | |
971
8ca5c990ed92
jp: "disco" subcommand, moved into a new "info" subcommand + added "version" subcommand which get software version
Goffi <goffi@goffi.org>
parents:
966
diff
changeset
|
197 |
8ca5c990ed92
jp: "disco" subcommand, moved into a new "info" subcommand + added "version" subcommand which get software version
Goffi <goffi@goffi.org>
parents:
966
diff
changeset
|
198 |
2114
dc5d214f0a3b
jp (info/session): added a command to get data on current session
Goffi <goffi@goffi.org>
parents:
1960
diff
changeset
|
199 class Session(base.CommandBase): |
dc5d214f0a3b
jp (info/session): added a command to get data on current session
Goffi <goffi@goffi.org>
parents:
1960
diff
changeset
|
200 |
dc5d214f0a3b
jp (info/session): added a command to get data on current session
Goffi <goffi@goffi.org>
parents:
1960
diff
changeset
|
201 def __init__(self, host): |
2600
947c4c4c5c53
jp (info/session): by default, display started as human readable date instead of Unix time
Goffi <goffi@goffi.org>
parents:
2562
diff
changeset
|
202 extra_outputs = {'default': self.default_output} |
3040 | 203 super(Session, self).__init__( |
204 host, 'session', use_output='dict', extra_outputs=extra_outputs, | |
205 help=_('running session')) | |
2114
dc5d214f0a3b
jp (info/session): added a command to get data on current session
Goffi <goffi@goffi.org>
parents:
1960
diff
changeset
|
206 |
3040 | 207 def add_parser_options(self): |
208 pass | |
209 | |
210 async def default_output(self, data): | |
2600
947c4c4c5c53
jp (info/session): by default, display started as human readable date instead of Unix time
Goffi <goffi@goffi.org>
parents:
2562
diff
changeset
|
211 started = data['started'] |
3028 | 212 data['started'] = '{short} (UTC, {relative})'.format( |
2605
87f8cf51fca5
jp (info/session): show short + relative date by default for "started"
Goffi <goffi@goffi.org>
parents:
2600
diff
changeset
|
213 short=date_utils.date_fmt(started), |
87f8cf51fca5
jp (info/session): show short + relative date by default for "started"
Goffi <goffi@goffi.org>
parents:
2600
diff
changeset
|
214 relative=date_utils.date_fmt(started, 'relative')) |
3040 | 215 await self.host.output(C.OUTPUT_DICT, 'simple', {}, data) |
2114
dc5d214f0a3b
jp (info/session): added a command to get data on current session
Goffi <goffi@goffi.org>
parents:
1960
diff
changeset
|
216 |
3040 | 217 async def start(self): |
218 try: | |
219 data = await self.host.bridge.sessionInfosGet(self.host.profile) | |
220 except Exception as e: | |
221 self.disp(_(f'Error getting session infos: {e}'), error=True) | |
222 self.host.quit(C.EXIT_BRIDGE_ERRBACK) | |
223 else: | |
224 await self.output(data) | |
225 self.host.quit() | |
2114
dc5d214f0a3b
jp (info/session): added a command to get data on current session
Goffi <goffi@goffi.org>
parents:
1960
diff
changeset
|
226 |
dc5d214f0a3b
jp (info/session): added a command to get data on current session
Goffi <goffi@goffi.org>
parents:
1960
diff
changeset
|
227 |
971
8ca5c990ed92
jp: "disco" subcommand, moved into a new "info" subcommand + added "version" subcommand which get software version
Goffi <goffi@goffi.org>
parents:
966
diff
changeset
|
228 class Info(base.CommandBase): |
2114
dc5d214f0a3b
jp (info/session): added a command to get data on current session
Goffi <goffi@goffi.org>
parents:
1960
diff
changeset
|
229 subcommands = (Disco, Version, Session) |
971
8ca5c990ed92
jp: "disco" subcommand, moved into a new "info" subcommand + added "version" subcommand which get software version
Goffi <goffi@goffi.org>
parents:
966
diff
changeset
|
230 |
8ca5c990ed92
jp: "disco" subcommand, moved into a new "info" subcommand + added "version" subcommand which get software version
Goffi <goffi@goffi.org>
parents:
966
diff
changeset
|
231 def __init__(self, host): |
3040 | 232 super(Info, self).__init__( |
233 host, 'info', use_profile=False, | |
234 help=_('Get various pieces of information on entities')) |