Mercurial > libervia-backend
annotate sat_frontends/jp/base.py @ 3636:43542cf32e5a
cli: call `bridge.getReady()` after bridge connection
author | Goffi <goffi@goffi.org> |
---|---|
date | Wed, 01 Sep 2021 13:46:43 +0200 |
parents | 04283582966f |
children | 51983c55c5b6 c143e7f35074 |
rev | line source |
---|---|
3043
3df611adb598
jp: handle dbus bridge with asyncio:
Goffi <goffi@goffi.org>
parents:
3040
diff
changeset
|
1 #!/usr/bin/env python3 |
0 | 2 |
609
84a6e83157c2
fixed licences in docstrings (they are now in comments)
Goffi <goffi@goffi.org>
parents:
601
diff
changeset
|
3 # jp: a SAT command line tool |
3479 | 4 # Copyright (C) 2009-2021 Jérôme Poisson (goffi@goffi.org) |
0 | 5 |
609
84a6e83157c2
fixed licences in docstrings (they are now in comments)
Goffi <goffi@goffi.org>
parents:
601
diff
changeset
|
6 # This program is free software: you can redistribute it and/or modify |
84a6e83157c2
fixed licences in docstrings (they are now in comments)
Goffi <goffi@goffi.org>
parents:
601
diff
changeset
|
7 # it under the terms of the GNU Affero General Public License as published by |
84a6e83157c2
fixed licences in docstrings (they are now in comments)
Goffi <goffi@goffi.org>
parents:
601
diff
changeset
|
8 # the Free Software Foundation, either version 3 of the License, or |
84a6e83157c2
fixed licences in docstrings (they are now in comments)
Goffi <goffi@goffi.org>
parents:
601
diff
changeset
|
9 # (at your option) any later version. |
0 | 10 |
609
84a6e83157c2
fixed licences in docstrings (they are now in comments)
Goffi <goffi@goffi.org>
parents:
601
diff
changeset
|
11 # This program is distributed in the hope that it will be useful, |
84a6e83157c2
fixed licences in docstrings (they are now in comments)
Goffi <goffi@goffi.org>
parents:
601
diff
changeset
|
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of |
84a6e83157c2
fixed licences in docstrings (they are now in comments)
Goffi <goffi@goffi.org>
parents:
601
diff
changeset
|
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
84a6e83157c2
fixed licences in docstrings (they are now in comments)
Goffi <goffi@goffi.org>
parents:
601
diff
changeset
|
14 # GNU Affero General Public License for more details. |
0 | 15 |
609
84a6e83157c2
fixed licences in docstrings (they are now in comments)
Goffi <goffi@goffi.org>
parents:
601
diff
changeset
|
16 # You should have received a copy of the GNU Affero General Public License |
84a6e83157c2
fixed licences in docstrings (they are now in comments)
Goffi <goffi@goffi.org>
parents:
601
diff
changeset
|
17 # along with this program. If not, see <http://www.gnu.org/licenses/>. |
0 | 18 |
3040 | 19 import asyncio |
771 | 20 from sat.core.i18n import _ |
402
f03688bdb858
jp: use with statement to open fifo
Goffi <goffi@goffi.org>
parents:
401
diff
changeset
|
21 |
0 | 22 ### logging ### |
1605
0aded9648c5c
jp (base): added a self.disp method which manage verbosity and stderr + verbosity property
Goffi <goffi@goffi.org>
parents:
1604
diff
changeset
|
23 import logging as log |
3040 | 24 log.basicConfig(level=log.WARNING, |
25 format='[%(name)s] %(message)s') | |
0 | 26 ### |
27 | |
28 import sys | |
3040 | 29 import os |
817 | 30 import os.path |
31 import argparse | |
3040 | 32 import inspect |
3046 | 33 import tty |
34 import termios | |
3040 | 35 from pathlib import Path |
817 | 36 from glob import iglob |
37 from importlib import import_module | |
1139
75025461141f
move sat.tools.jid to sat_frontends.tools.jid
souliane <souliane@mailoo.org>
parents:
1033
diff
changeset
|
38 from sat_frontends.tools.jid import JID |
2098
e0066920a661
primitivus, jp: dynamic bridge + fixed D-Bus bridge:
Goffi <goffi@goffi.org>
parents:
2086
diff
changeset
|
39 from sat.tools import config |
e0066920a661
primitivus, jp: dynamic bridge + fixed D-Bus bridge:
Goffi <goffi@goffi.org>
parents:
2086
diff
changeset
|
40 from sat.tools.common import dynamic_import |
2532 | 41 from sat.tools.common import uri |
2704
ab37d1c7c38c
jp (base): new date_decoder to specify dates in arguments
Goffi <goffi@goffi.org>
parents:
2692
diff
changeset
|
42 from sat.tools.common import date_utils |
3046 | 43 from sat.tools.common import utils |
44 from sat.tools.common.ansi import ANSI as A | |
817 | 45 from sat.core import exceptions |
46 import sat_frontends.jp | |
3043
3df611adb598
jp: handle dbus bridge with asyncio:
Goffi <goffi@goffi.org>
parents:
3040
diff
changeset
|
47 from sat_frontends.jp.loops import QuitException, getJPLoop |
970
2e052998c7eb
jp: using C.APP_URL for application url
Goffi <goffi@goffi.org>
parents:
965
diff
changeset
|
48 from sat_frontends.jp.constants import Const as C |
3049
9839ce068140
jp: password is now prompted if needed:
Goffi <goffi@goffi.org>
parents:
3046
diff
changeset
|
49 from sat_frontends.bridge.bridge_frontend import BridgeException |
2532 | 50 from sat_frontends.tools import misc |
1840
9eabf7fadfdd
frontends (jp): onActionNew displays xmlui message if no meta_type is defined and xmlui is defined
souliane <souliane@mailoo.org>
parents:
1832
diff
changeset
|
51 import xml.etree.ElementTree as ET # FIXME: used temporarily to manage XMLUI |
1950 | 52 from collections import OrderedDict |
1872
df1ca137b0cb
jp (blog/edit): editor arguments can now be specified on sat.conf, and default on are applied for known editors:
Goffi <goffi@goffi.org>
parents:
1869
diff
changeset
|
53 |
2098
e0066920a661
primitivus, jp: dynamic bridge + fixed D-Bus bridge:
Goffi <goffi@goffi.org>
parents:
2086
diff
changeset
|
54 ## bridge handling |
e0066920a661
primitivus, jp: dynamic bridge + fixed D-Bus bridge:
Goffi <goffi@goffi.org>
parents:
2086
diff
changeset
|
55 # we get bridge name from conf and initialise the right class accordingly |
e0066920a661
primitivus, jp: dynamic bridge + fixed D-Bus bridge:
Goffi <goffi@goffi.org>
parents:
2086
diff
changeset
|
56 main_config = config.parseMainConf() |
e0066920a661
primitivus, jp: dynamic bridge + fixed D-Bus bridge:
Goffi <goffi@goffi.org>
parents:
2086
diff
changeset
|
57 bridge_name = config.getConfig(main_config, '', 'bridge', 'dbus') |
3043
3df611adb598
jp: handle dbus bridge with asyncio:
Goffi <goffi@goffi.org>
parents:
3040
diff
changeset
|
58 JPLoop = getJPLoop(bridge_name) |
2098
e0066920a661
primitivus, jp: dynamic bridge + fixed D-Bus bridge:
Goffi <goffi@goffi.org>
parents:
2086
diff
changeset
|
59 |
e0066920a661
primitivus, jp: dynamic bridge + fixed D-Bus bridge:
Goffi <goffi@goffi.org>
parents:
2086
diff
changeset
|
60 |
0 | 61 try: |
817 | 62 import progressbar |
63 except ImportError: | |
3040 | 64 msg = (_('ProgressBar not available, please download it at ' |
65 'http://pypi.python.org/pypi/progressbar\n' | |
66 'Progress bar deactivated\n--\n')) | |
67 print(msg, file=sys.stderr) | |
817 | 68 progressbar=None |
69 | |
70 #consts | |
1606
de785fcf9a7b
jp (base, file): file command and progress fixes and adaptation to new API:
Goffi <goffi@goffi.org>
parents:
1605
diff
changeset
|
71 DESCRIPTION = """This software is a command line tool for XMPP. |
970
2e052998c7eb
jp: using C.APP_URL for application url
Goffi <goffi@goffi.org>
parents:
965
diff
changeset
|
72 Get the latest version at """ + C.APP_URL |
817 | 73 |
3479 | 74 COPYLEFT = """Copyright (C) 2009-2021 Jérôme Poisson, Adrien Cossa |
817 | 75 This program comes with ABSOLUTELY NO WARRANTY; |
76 This is free software, and you are welcome to redistribute it under certain conditions. | |
77 """ | |
0 | 78 |
3040 | 79 PROGRESS_DELAY = 0.1 # the progression will be checked every PROGRESS_DELAY s |
1606
de785fcf9a7b
jp (base, file): file command and progress fixes and adaptation to new API:
Goffi <goffi@goffi.org>
parents:
1605
diff
changeset
|
80 |
0 | 81 |
2704
ab37d1c7c38c
jp (base): new date_decoder to specify dates in arguments
Goffi <goffi@goffi.org>
parents:
2692
diff
changeset
|
82 def date_decoder(arg): |
ab37d1c7c38c
jp (base): new date_decoder to specify dates in arguments
Goffi <goffi@goffi.org>
parents:
2692
diff
changeset
|
83 return date_utils.date_parse_ext(arg, default_tz=date_utils.TZ_LOCAL) |
ab37d1c7c38c
jp (base): new date_decoder to specify dates in arguments
Goffi <goffi@goffi.org>
parents:
2692
diff
changeset
|
84 |
ab37d1c7c38c
jp (base): new date_decoder to specify dates in arguments
Goffi <goffi@goffi.org>
parents:
2692
diff
changeset
|
85 |
3481
7892585b7e17
core (setup), jp, primitivus: update console scripts + classifiers:
Goffi <goffi@goffi.org>
parents:
3479
diff
changeset
|
86 class LiberviaCli: |
814 | 87 """ |
88 This class can be use to establish a connection with the | |
89 bridge. Moreover, it should manage a main loop. | |
90 | |
91 To use it, you mainly have to redefine the method run to perform | |
92 specify what kind of operation you want to perform. | |
93 | |
94 """ | |
817 | 95 def __init__(self): |
1606
de785fcf9a7b
jp (base, file): file command and progress fixes and adaptation to new API:
Goffi <goffi@goffi.org>
parents:
1605
diff
changeset
|
96 """ |
de785fcf9a7b
jp (base, file): file command and progress fixes and adaptation to new API:
Goffi <goffi@goffi.org>
parents:
1605
diff
changeset
|
97 |
3040 | 98 @attribute quit_on_progress_end (bool): set to False if you manage yourself |
99 exiting, or if you want the user to stop by himself | |
1606
de785fcf9a7b
jp (base, file): file command and progress fixes and adaptation to new API:
Goffi <goffi@goffi.org>
parents:
1605
diff
changeset
|
100 @attribute progress_success(callable): method to call when progress just started |
de785fcf9a7b
jp (base, file): file command and progress fixes and adaptation to new API:
Goffi <goffi@goffi.org>
parents:
1605
diff
changeset
|
101 by default display a message |
3040 | 102 @attribute progress_success(callable): method to call when progress is |
103 successfully finished by default display a message | |
1606
de785fcf9a7b
jp (base, file): file command and progress fixes and adaptation to new API:
Goffi <goffi@goffi.org>
parents:
1605
diff
changeset
|
104 @attribute progress_failure(callable): method to call when progress failed |
de785fcf9a7b
jp (base, file): file command and progress fixes and adaptation to new API:
Goffi <goffi@goffi.org>
parents:
1605
diff
changeset
|
105 by default display a message |
de785fcf9a7b
jp (base, file): file command and progress fixes and adaptation to new API:
Goffi <goffi@goffi.org>
parents:
1605
diff
changeset
|
106 """ |
3046 | 107 self.sat_conf = main_config |
108 self.set_color_theme() | |
2098
e0066920a661
primitivus, jp: dynamic bridge + fixed D-Bus bridge:
Goffi <goffi@goffi.org>
parents:
2086
diff
changeset
|
109 bridge_module = dynamic_import.bridge(bridge_name, 'sat_frontends.bridge') |
e0066920a661
primitivus, jp: dynamic bridge + fixed D-Bus bridge:
Goffi <goffi@goffi.org>
parents:
2086
diff
changeset
|
110 if bridge_module is None: |
3028 | 111 log.error("Can't import {} bridge".format(bridge_name)) |
165
8a2053de6f8c
Frontends: management of unlaunched SàT Backend (information message and exit)
Goffi <goffi@goffi.org>
parents:
156
diff
changeset
|
112 sys.exit(1) |
814 | 113 |
3040 | 114 self.bridge = bridge_module.AIOBridge() |
115 self._onQuitCallbacks = [] | |
2098
e0066920a661
primitivus, jp: dynamic bridge + fixed D-Bus bridge:
Goffi <goffi@goffi.org>
parents:
2086
diff
changeset
|
116 |
3555
53fec6309fa3
cli: update constants to use new name
Goffi <goffi@goffi.org>
parents:
3547
diff
changeset
|
117 def get_config(self, name, section=C.CONFIG_SECTION, default=None): |
3046 | 118 """Retrieve a setting value from sat.conf""" |
119 return config.getConfig(self.sat_conf, section, name, default=default) | |
120 | |
121 def guess_background(self): | |
3547
1ac5570fa998
jp: fix background guessing when stdin is redirected
Goffi <goffi@goffi.org>
parents:
3490
diff
changeset
|
122 if not sys.stdin.isatty() or not sys.stdout.isatty(): |
3378
67e306cae157
jp: don't guess background when stdout is not a tty
Goffi <goffi@goffi.org>
parents:
3136
diff
changeset
|
123 return 'dark' |
3046 | 124 stdin_fd = sys.stdin.fileno() |
125 old_settings = termios.tcgetattr(stdin_fd) | |
126 try: | |
127 tty.setraw(sys.stdin.fileno()) | |
128 # we request background color | |
129 sys.stdout.write("\033]11;?\a") | |
130 sys.stdout.flush() | |
131 expected = "\033]11;rgb:" | |
132 for c in expected: | |
133 ch = sys.stdin.read(1) | |
134 if ch != c: | |
3051
ee2654308a57
jp: default to "dark" if background is not set and can't be detected
Goffi <goffi@goffi.org>
parents:
3049
diff
changeset
|
135 # background id is not supported, we default to "dark" |
3046 | 136 # TODO: log something? |
3051
ee2654308a57
jp: default to "dark" if background is not set and can't be detected
Goffi <goffi@goffi.org>
parents:
3049
diff
changeset
|
137 return 'dark' |
3046 | 138 red, green, blue = [int(c, 16)/65535 for c in sys.stdin.read(14).split('/')] |
139 # '\a' is the last character | |
140 sys.stdin.read(1) | |
141 finally: | |
142 termios.tcsetattr(stdin_fd, termios.TCSADRAIN, old_settings) | |
143 | |
144 lum = utils.per_luminance(red, green, blue) | |
145 if lum <= 0.5: | |
146 return 'dark' | |
147 else: | |
148 return 'light' | |
149 | |
150 def set_color_theme(self): | |
151 background = self.get_config('background', default='auto') | |
152 if background == 'auto': | |
153 background = self.guess_background() | |
154 if background not in ('dark', 'light'): | |
155 raise exceptions.ConfigError(_( | |
3568
04283582966f
core, frontends: fix invalid translatable strings.
Goffi <goffi@goffi.org>
parents:
3555
diff
changeset
|
156 'Invalid value set for "background" ({background}), please check ' |
04283582966f
core, frontends: fix invalid translatable strings.
Goffi <goffi@goffi.org>
parents:
3555
diff
changeset
|
157 'your settings in libervia.conf').format( |
04283582966f
core, frontends: fix invalid translatable strings.
Goffi <goffi@goffi.org>
parents:
3555
diff
changeset
|
158 background=repr(background) |
04283582966f
core, frontends: fix invalid translatable strings.
Goffi <goffi@goffi.org>
parents:
3555
diff
changeset
|
159 )) |
3046 | 160 if background == 'light': |
161 C.A_HEADER = A.FG_MAGENTA | |
162 C.A_SUBHEADER = A.BOLD + A.FG_RED | |
163 C.A_LEVEL_COLORS = (C.A_HEADER, A.BOLD + A.FG_BLUE, A.FG_MAGENTA, A.FG_CYAN) | |
164 C.A_SUCCESS = A.FG_GREEN | |
165 C.A_FAILURE = A.BOLD + A.FG_RED | |
166 C.A_WARNING = A.FG_RED | |
167 C.A_PROMPT_PATH = A.FG_BLUE | |
168 C.A_PROMPT_SUF = A.BOLD | |
169 C.A_DIRECTORY = A.BOLD + A.FG_MAGENTA | |
170 C.A_FILE = A.FG_BLACK | |
171 | |
3040 | 172 def _bridgeConnected(self): |
173 self.parser = argparse.ArgumentParser( | |
174 formatter_class=argparse.RawDescriptionHelpFormatter, description=DESCRIPTION) | |
817 | 175 self._make_parents() |
176 self.add_parser_options() | |
3040 | 177 self.subparsers = self.parser.add_subparsers( |
178 title=_('Available commands'), dest='command', required=True) | |
1606
de785fcf9a7b
jp (base, file): file command and progress fixes and adaptation to new API:
Goffi <goffi@goffi.org>
parents:
1605
diff
changeset
|
179 |
de785fcf9a7b
jp (base, file): file command and progress fixes and adaptation to new API:
Goffi <goffi@goffi.org>
parents:
1605
diff
changeset
|
180 # progress attributes |
817 | 181 self._progress_id = None # TODO: manage several progress ids |
1606
de785fcf9a7b
jp (base, file): file command and progress fixes and adaptation to new API:
Goffi <goffi@goffi.org>
parents:
1605
diff
changeset
|
182 self.quit_on_progress_end = True |
817 | 183 |
1950 | 184 # outputs |
185 self._outputs = {} | |
186 for type_ in C.OUTPUT_TYPES: | |
187 self._outputs[type_] = OrderedDict() | |
2189
a25a256688e2
jp (base): output can now specify a default when registering
Goffi <goffi@goffi.org>
parents:
2188
diff
changeset
|
188 self.default_output = {} |
1950 | 189 |
2705
0bb811aaf11d
jp (base): new own_jid host attribute:
Goffi <goffi@goffi.org>
parents:
2704
diff
changeset
|
190 self.own_jid = None # must be filled at runtime if needed |
0bb811aaf11d
jp (base): new own_jid host attribute:
Goffi <goffi@goffi.org>
parents:
2704
diff
changeset
|
191 |
817 | 192 @property |
193 def progress_id(self): | |
194 return self._progress_id | |
195 | |
3040 | 196 async def set_progress_id(self, progress_id): |
197 # because we use async, we need an explicit setter | |
198 self._progress_id = progress_id | |
199 await self.replayCache('progress_ids_cache') | |
817 | 200 |
1606
de785fcf9a7b
jp (base, file): file command and progress fixes and adaptation to new API:
Goffi <goffi@goffi.org>
parents:
1605
diff
changeset
|
201 @property |
de785fcf9a7b
jp (base, file): file command and progress fixes and adaptation to new API:
Goffi <goffi@goffi.org>
parents:
1605
diff
changeset
|
202 def watch_progress(self): |
de785fcf9a7b
jp (base, file): file command and progress fixes and adaptation to new API:
Goffi <goffi@goffi.org>
parents:
1605
diff
changeset
|
203 try: |
de785fcf9a7b
jp (base, file): file command and progress fixes and adaptation to new API:
Goffi <goffi@goffi.org>
parents:
1605
diff
changeset
|
204 self.pbar |
de785fcf9a7b
jp (base, file): file command and progress fixes and adaptation to new API:
Goffi <goffi@goffi.org>
parents:
1605
diff
changeset
|
205 except AttributeError: |
de785fcf9a7b
jp (base, file): file command and progress fixes and adaptation to new API:
Goffi <goffi@goffi.org>
parents:
1605
diff
changeset
|
206 return False |
de785fcf9a7b
jp (base, file): file command and progress fixes and adaptation to new API:
Goffi <goffi@goffi.org>
parents:
1605
diff
changeset
|
207 else: |
de785fcf9a7b
jp (base, file): file command and progress fixes and adaptation to new API:
Goffi <goffi@goffi.org>
parents:
1605
diff
changeset
|
208 return True |
de785fcf9a7b
jp (base, file): file command and progress fixes and adaptation to new API:
Goffi <goffi@goffi.org>
parents:
1605
diff
changeset
|
209 |
de785fcf9a7b
jp (base, file): file command and progress fixes and adaptation to new API:
Goffi <goffi@goffi.org>
parents:
1605
diff
changeset
|
210 @watch_progress.setter |
de785fcf9a7b
jp (base, file): file command and progress fixes and adaptation to new API:
Goffi <goffi@goffi.org>
parents:
1605
diff
changeset
|
211 def watch_progress(self, watch_progress): |
de785fcf9a7b
jp (base, file): file command and progress fixes and adaptation to new API:
Goffi <goffi@goffi.org>
parents:
1605
diff
changeset
|
212 if watch_progress: |
de785fcf9a7b
jp (base, file): file command and progress fixes and adaptation to new API:
Goffi <goffi@goffi.org>
parents:
1605
diff
changeset
|
213 self.pbar = None |
1604
9ac78437000d
jp (base): added quitFromSignal method to quit from signal handler with errcode without traceback, and addOnQuitCallback to manage cleaning callbacks
Goffi <goffi@goffi.org>
parents:
1600
diff
changeset
|
214 |
1605
0aded9648c5c
jp (base): added a self.disp method which manage verbosity and stderr + verbosity property
Goffi <goffi@goffi.org>
parents:
1604
diff
changeset
|
215 @property |
0aded9648c5c
jp (base): added a self.disp method which manage verbosity and stderr + verbosity property
Goffi <goffi@goffi.org>
parents:
1604
diff
changeset
|
216 def verbosity(self): |
0aded9648c5c
jp (base): added a self.disp method which manage verbosity and stderr + verbosity property
Goffi <goffi@goffi.org>
parents:
1604
diff
changeset
|
217 try: |
0aded9648c5c
jp (base): added a self.disp method which manage verbosity and stderr + verbosity property
Goffi <goffi@goffi.org>
parents:
1604
diff
changeset
|
218 return self.args.verbose |
0aded9648c5c
jp (base): added a self.disp method which manage verbosity and stderr + verbosity property
Goffi <goffi@goffi.org>
parents:
1604
diff
changeset
|
219 except AttributeError: |
0aded9648c5c
jp (base): added a self.disp method which manage verbosity and stderr + verbosity property
Goffi <goffi@goffi.org>
parents:
1604
diff
changeset
|
220 return 0 |
0aded9648c5c
jp (base): added a self.disp method which manage verbosity and stderr + verbosity property
Goffi <goffi@goffi.org>
parents:
1604
diff
changeset
|
221 |
3040 | 222 async def replayCache(self, cache_attribute): |
1642
7ec7ce9cdc4c
jp (base): progressStarted signals are cached until progress_id is known, this avoid missing the progression if we have the signal before the id.
Goffi <goffi@goffi.org>
parents:
1641
diff
changeset
|
223 """Replay cached signals |
7ec7ce9cdc4c
jp (base): progressStarted signals are cached until progress_id is known, this avoid missing the progression if we have the signal before the id.
Goffi <goffi@goffi.org>
parents:
1641
diff
changeset
|
224 |
7ec7ce9cdc4c
jp (base): progressStarted signals are cached until progress_id is known, this avoid missing the progression if we have the signal before the id.
Goffi <goffi@goffi.org>
parents:
1641
diff
changeset
|
225 @param cache_attribute(str): name of the attribute containing the cache |
7ec7ce9cdc4c
jp (base): progressStarted signals are cached until progress_id is known, this avoid missing the progression if we have the signal before the id.
Goffi <goffi@goffi.org>
parents:
1641
diff
changeset
|
226 if the attribute doesn't exist, there is no cache and the call is ignored |
3040 | 227 else the cache must be a list of tuples containing the replay callback as |
228 first item, then the arguments to use | |
1642
7ec7ce9cdc4c
jp (base): progressStarted signals are cached until progress_id is known, this avoid missing the progression if we have the signal before the id.
Goffi <goffi@goffi.org>
parents:
1641
diff
changeset
|
229 """ |
7ec7ce9cdc4c
jp (base): progressStarted signals are cached until progress_id is known, this avoid missing the progression if we have the signal before the id.
Goffi <goffi@goffi.org>
parents:
1641
diff
changeset
|
230 try: |
7ec7ce9cdc4c
jp (base): progressStarted signals are cached until progress_id is known, this avoid missing the progression if we have the signal before the id.
Goffi <goffi@goffi.org>
parents:
1641
diff
changeset
|
231 cache = getattr(self, cache_attribute) |
7ec7ce9cdc4c
jp (base): progressStarted signals are cached until progress_id is known, this avoid missing the progression if we have the signal before the id.
Goffi <goffi@goffi.org>
parents:
1641
diff
changeset
|
232 except AttributeError: |
7ec7ce9cdc4c
jp (base): progressStarted signals are cached until progress_id is known, this avoid missing the progression if we have the signal before the id.
Goffi <goffi@goffi.org>
parents:
1641
diff
changeset
|
233 pass |
7ec7ce9cdc4c
jp (base): progressStarted signals are cached until progress_id is known, this avoid missing the progression if we have the signal before the id.
Goffi <goffi@goffi.org>
parents:
1641
diff
changeset
|
234 else: |
7ec7ce9cdc4c
jp (base): progressStarted signals are cached until progress_id is known, this avoid missing the progression if we have the signal before the id.
Goffi <goffi@goffi.org>
parents:
1641
diff
changeset
|
235 for cache_data in cache: |
3040 | 236 await cache_data[0](*cache_data[1:]) |
1642
7ec7ce9cdc4c
jp (base): progressStarted signals are cached until progress_id is known, this avoid missing the progression if we have the signal before the id.
Goffi <goffi@goffi.org>
parents:
1641
diff
changeset
|
237 |
3407
2f0be2b7de68
jp: replace `no_lf` argument by `end` in `disp` (same as in `print`)
Goffi <goffi@goffi.org>
parents:
3378
diff
changeset
|
238 def disp(self, msg, verbosity=0, error=False, end='\n'): |
1605
0aded9648c5c
jp (base): added a self.disp method which manage verbosity and stderr + verbosity property
Goffi <goffi@goffi.org>
parents:
1604
diff
changeset
|
239 """Print a message to user |
0aded9648c5c
jp (base): added a self.disp method which manage verbosity and stderr + verbosity property
Goffi <goffi@goffi.org>
parents:
1604
diff
changeset
|
240 |
0aded9648c5c
jp (base): added a self.disp method which manage verbosity and stderr + verbosity property
Goffi <goffi@goffi.org>
parents:
1604
diff
changeset
|
241 @param msg(unicode): message to print |
0aded9648c5c
jp (base): added a self.disp method which manage verbosity and stderr + verbosity property
Goffi <goffi@goffi.org>
parents:
1604
diff
changeset
|
242 @param verbosity(int): minimal verbosity to display the message |
0aded9648c5c
jp (base): added a self.disp method which manage verbosity and stderr + verbosity property
Goffi <goffi@goffi.org>
parents:
1604
diff
changeset
|
243 @param error(bool): if True, print to stderr instead of stdout |
3407
2f0be2b7de68
jp: replace `no_lf` argument by `end` in `disp` (same as in `print`)
Goffi <goffi@goffi.org>
parents:
3378
diff
changeset
|
244 @param end(str): string appended after the last value, default a newline |
1605
0aded9648c5c
jp (base): added a self.disp method which manage verbosity and stderr + verbosity property
Goffi <goffi@goffi.org>
parents:
1604
diff
changeset
|
245 """ |
0aded9648c5c
jp (base): added a self.disp method which manage verbosity and stderr + verbosity property
Goffi <goffi@goffi.org>
parents:
1604
diff
changeset
|
246 if self.verbosity >= verbosity: |
0aded9648c5c
jp (base): added a self.disp method which manage verbosity and stderr + verbosity property
Goffi <goffi@goffi.org>
parents:
1604
diff
changeset
|
247 if error: |
3407
2f0be2b7de68
jp: replace `no_lf` argument by `end` in `disp` (same as in `print`)
Goffi <goffi@goffi.org>
parents:
3378
diff
changeset
|
248 print(msg, end=end, file=sys.stderr) |
1605
0aded9648c5c
jp (base): added a self.disp method which manage verbosity and stderr + verbosity property
Goffi <goffi@goffi.org>
parents:
1604
diff
changeset
|
249 else: |
3407
2f0be2b7de68
jp: replace `no_lf` argument by `end` in `disp` (same as in `print`)
Goffi <goffi@goffi.org>
parents:
3378
diff
changeset
|
250 print(msg, end=end) |
1605
0aded9648c5c
jp (base): added a self.disp method which manage verbosity and stderr + verbosity property
Goffi <goffi@goffi.org>
parents:
1604
diff
changeset
|
251 |
3040 | 252 async def output(self, type_, name, extra_outputs, data): |
2155 | 253 if name in extra_outputs: |
3040 | 254 method = extra_outputs[name] |
2155 | 255 else: |
3040 | 256 method = self._outputs[type_][name]['callback'] |
257 | |
258 ret = method(data) | |
259 if inspect.isawaitable(ret): | |
260 await ret | |
1950 | 261 |
1604
9ac78437000d
jp (base): added quitFromSignal method to quit from signal handler with errcode without traceback, and addOnQuitCallback to manage cleaning callbacks
Goffi <goffi@goffi.org>
parents:
1600
diff
changeset
|
262 def addOnQuitCallback(self, callback, *args, **kwargs): |
9ac78437000d
jp (base): added quitFromSignal method to quit from signal handler with errcode without traceback, and addOnQuitCallback to manage cleaning callbacks
Goffi <goffi@goffi.org>
parents:
1600
diff
changeset
|
263 """Add a callback which will be called on quit command |
9ac78437000d
jp (base): added quitFromSignal method to quit from signal handler with errcode without traceback, and addOnQuitCallback to manage cleaning callbacks
Goffi <goffi@goffi.org>
parents:
1600
diff
changeset
|
264 |
9ac78437000d
jp (base): added quitFromSignal method to quit from signal handler with errcode without traceback, and addOnQuitCallback to manage cleaning callbacks
Goffi <goffi@goffi.org>
parents:
1600
diff
changeset
|
265 @param callback(callback): method to call |
9ac78437000d
jp (base): added quitFromSignal method to quit from signal handler with errcode without traceback, and addOnQuitCallback to manage cleaning callbacks
Goffi <goffi@goffi.org>
parents:
1600
diff
changeset
|
266 """ |
3040 | 267 self._onQuitCallbacks.append((callback, args, kwargs)) |
1604
9ac78437000d
jp (base): added quitFromSignal method to quit from signal handler with errcode without traceback, and addOnQuitCallback to manage cleaning callbacks
Goffi <goffi@goffi.org>
parents:
1600
diff
changeset
|
268 |
1950 | 269 def getOutputChoices(self, output_type): |
270 """Return valid output filters for output_type | |
271 | |
272 @param output_type: True for default, | |
273 else can be any registered type | |
274 """ | |
3028 | 275 return list(self._outputs[output_type].keys()) |
1950 | 276 |
817 | 277 def _make_parents(self): |
278 self.parents = {} | |
279 | |
3040 | 280 # we have a special case here as the start-session option is present only if |
281 # connection is not needed, so we create two similar parents, one with the | |
282 # option, the other one without it | |
1594
313f2bb7841b
jp: profile session can now be started without connection:
Goffi <goffi@goffi.org>
parents:
1588
diff
changeset
|
283 for parent_name in ('profile', 'profile_session'): |
313f2bb7841b
jp: profile session can now be started without connection:
Goffi <goffi@goffi.org>
parents:
1588
diff
changeset
|
284 parent = self.parents[parent_name] = argparse.ArgumentParser(add_help=False) |
3040 | 285 parent.add_argument( |
286 "-p", "--profile", action="store", type=str, default='@DEFAULT@', | |
287 help=_("Use PROFILE profile key (default: %(default)s)")) | |
288 parent.add_argument( | |
3049
9839ce068140
jp: password is now prompted if needed:
Goffi <goffi@goffi.org>
parents:
3046
diff
changeset
|
289 "--pwd", action="store", metavar='PASSWORD', |
3040 | 290 help=_("Password used to connect profile, if necessary")) |
1594
313f2bb7841b
jp: profile session can now be started without connection:
Goffi <goffi@goffi.org>
parents:
1588
diff
changeset
|
291 |
3040 | 292 profile_parent, profile_session_parent = (self.parents['profile'], |
293 self.parents['profile_session']) | |
1594
313f2bb7841b
jp: profile session can now be started without connection:
Goffi <goffi@goffi.org>
parents:
1588
diff
changeset
|
294 |
3040 | 295 connect_short, connect_long, connect_action, connect_help = ( |
296 "-c", "--connect", "store_true", | |
297 _("Connect the profile before doing anything else") | |
298 ) | |
299 profile_parent.add_argument( | |
300 connect_short, connect_long, action=connect_action, help=connect_help) | |
1594
313f2bb7841b
jp: profile session can now be started without connection:
Goffi <goffi@goffi.org>
parents:
1588
diff
changeset
|
301 |
313f2bb7841b
jp: profile session can now be started without connection:
Goffi <goffi@goffi.org>
parents:
1588
diff
changeset
|
302 profile_session_connect_group = profile_session_parent.add_mutually_exclusive_group() |
3040 | 303 profile_session_connect_group.add_argument( |
304 connect_short, connect_long, action=connect_action, help=connect_help) | |
305 profile_session_connect_group.add_argument( | |
306 "--start-session", action="store_true", | |
307 help=_("Start a profile session without connecting")) | |
817 | 308 |
3040 | 309 progress_parent = self.parents['progress'] = argparse.ArgumentParser( |
310 add_help=False) | |
817 | 311 if progressbar: |
3040 | 312 progress_parent.add_argument( |
313 "-P", "--progress", action="store_true", help=_("Show progress bar")) | |
0 | 314 |
1600 | 315 verbose_parent = self.parents['verbose'] = argparse.ArgumentParser(add_help=False) |
3040 | 316 verbose_parent.add_argument( |
317 '--verbose', '-v', action='count', default=0, | |
318 help=_("Add a verbosity level (can be used multiple times)")) | |
1600 | 319 |
3412
7b4ae3dbc041
jp (base, pubsub/set): new `--quiet` argument:
Goffi <goffi@goffi.org>
parents:
3409
diff
changeset
|
320 quiet_parent = self.parents['quiet'] = argparse.ArgumentParser(add_help=False) |
7b4ae3dbc041
jp (base, pubsub/set): new `--quiet` argument:
Goffi <goffi@goffi.org>
parents:
3409
diff
changeset
|
321 quiet_parent.add_argument( |
7b4ae3dbc041
jp (base, pubsub/set): new `--quiet` argument:
Goffi <goffi@goffi.org>
parents:
3409
diff
changeset
|
322 '--quiet', '-q', action='store_true', |
7b4ae3dbc041
jp (base, pubsub/set): new `--quiet` argument:
Goffi <goffi@goffi.org>
parents:
3409
diff
changeset
|
323 help=_("be quiet (only output machine readable data)")) |
7b4ae3dbc041
jp (base, pubsub/set): new `--quiet` argument:
Goffi <goffi@goffi.org>
parents:
3409
diff
changeset
|
324 |
2532 | 325 draft_parent = self.parents['draft'] = argparse.ArgumentParser(add_help=False) |
326 draft_group = draft_parent.add_argument_group(_('draft handling')) | |
3040 | 327 draft_group.add_argument( |
328 "-D", "--current", action="store_true", help=_("load current draft")) | |
329 draft_group.add_argument( | |
330 "-F", "--draft-path", type=Path, help=_("path to a draft file to retrieve")) | |
2532 | 331 |
332 | |
2547
2d69a0afe039
jp: new argument pubsub_default can be used in Commands to replace default value in help string
Goffi <goffi@goffi.org>
parents:
2539
diff
changeset
|
333 def make_pubsub_group(self, flags, defaults): |
2532 | 334 """generate pubsub options according to flags |
335 | |
336 @param flags(iterable[unicode]): see [CommandBase.__init__] | |
2547
2d69a0afe039
jp: new argument pubsub_default can be used in Commands to replace default value in help string
Goffi <goffi@goffi.org>
parents:
2539
diff
changeset
|
337 @param defaults(dict[unicode, unicode]): help text for default value |
2d69a0afe039
jp: new argument pubsub_default can be used in Commands to replace default value in help string
Goffi <goffi@goffi.org>
parents:
2539
diff
changeset
|
338 key can be "service" or "node" |
2d69a0afe039
jp: new argument pubsub_default can be used in Commands to replace default value in help string
Goffi <goffi@goffi.org>
parents:
2539
diff
changeset
|
339 value will be set in " (DEFAULT: {value})", or can be None to remove DEFAULT |
2532 | 340 @return (ArgumentParser): parser to add |
341 """ | |
342 flags = misc.FlagsHandler(flags) | |
343 parent = argparse.ArgumentParser(add_help=False) | |
344 pubsub_group = parent.add_argument_group('pubsub') | |
3028 | 345 pubsub_group.add_argument("-u", "--pubsub-url", |
346 help=_("Pubsub URL (xmpp or http)")) | |
2532 | 347 |
3028 | 348 service_help = _("JID of the PubSub service") |
2532 | 349 if not flags.service: |
3028 | 350 default = defaults.pop('service', _('PEP service')) |
2547
2d69a0afe039
jp: new argument pubsub_default can be used in Commands to replace default value in help string
Goffi <goffi@goffi.org>
parents:
2539
diff
changeset
|
351 if default is not None: |
3028 | 352 service_help += _(" (DEFAULT: {default})".format(default=default)) |
353 pubsub_group.add_argument("-s", "--service", default='', | |
2532 | 354 help=service_help) |
355 | |
3028 | 356 node_help = _("node to request") |
2532 | 357 if not flags.node: |
3028 | 358 default = defaults.pop('node', _('standard node')) |
2547
2d69a0afe039
jp: new argument pubsub_default can be used in Commands to replace default value in help string
Goffi <goffi@goffi.org>
parents:
2539
diff
changeset
|
359 if default is not None: |
3028 | 360 node_help += _(" (DEFAULT: {default})".format(default=default)) |
361 pubsub_group.add_argument("-n", "--node", default='', help=node_help) | |
2532 | 362 |
363 if flags.single_item: | |
3028 | 364 item_help = ("item to retrieve") |
2552
38e1e29c48e9
jp (base): added C.ITEM pubsub flag when --item is required
Goffi <goffi@goffi.org>
parents:
2550
diff
changeset
|
365 if not flags.item: |
3028 | 366 default = defaults.pop('item', _('last item')) |
2552
38e1e29c48e9
jp (base): added C.ITEM pubsub flag when --item is required
Goffi <goffi@goffi.org>
parents:
2550
diff
changeset
|
367 if default is not None: |
3028 | 368 item_help += _(" (DEFAULT: {default})".format(default=default)) |
369 pubsub_group.add_argument("-i", "--item", default='', | |
2910
b2f323237fce
jp, plugin merge-requests: used u'' as default for item id in pubsub arguments + fixed some required arguments:
Goffi <goffi@goffi.org>
parents:
2775
diff
changeset
|
370 help=item_help) |
3040 | 371 pubsub_group.add_argument( |
372 "-L", "--last-item", action='store_true', help=_('retrieve last item')) | |
2532 | 373 elif flags.multi_items: |
2764
92af49cde255
jp (base): MAM and RSM arguments can now be used for pubsub commands:
Goffi <goffi@goffi.org>
parents:
2761
diff
changeset
|
374 # mutiple items, this activate several features: max-items, RSM, MAM |
92af49cde255
jp (base): MAM and RSM arguments can now be used for pubsub commands:
Goffi <goffi@goffi.org>
parents:
2761
diff
changeset
|
375 # and Orbder-by |
3040 | 376 pubsub_group.add_argument( |
377 "-i", "--item", action='append', dest='items', default=[], | |
378 help=_("items to retrieve (DEFAULT: all)")) | |
2539 | 379 if not flags.no_max: |
2775
2dfd5b1d39df
jp (base): fixed default values for --max-items and --max when using pubsub
Goffi <goffi@goffi.org>
parents:
2771
diff
changeset
|
380 max_group = pubsub_group.add_mutually_exclusive_group() |
2dfd5b1d39df
jp (base): fixed default values for --max-items and --max when using pubsub
Goffi <goffi@goffi.org>
parents:
2771
diff
changeset
|
381 # XXX: defaut value for --max-items or --max is set in parse_pubsub_args |
2dfd5b1d39df
jp (base): fixed default values for --max-items and --max when using pubsub
Goffi <goffi@goffi.org>
parents:
2771
diff
changeset
|
382 max_group.add_argument( |
2dfd5b1d39df
jp (base): fixed default values for --max-items and --max when using pubsub
Goffi <goffi@goffi.org>
parents:
2771
diff
changeset
|
383 "-M", "--max-items", dest="max", type=int, |
3028 | 384 help=_("maximum number of items to get ({no_limit} to get all items)" |
2764
92af49cde255
jp (base): MAM and RSM arguments can now be used for pubsub commands:
Goffi <goffi@goffi.org>
parents:
2761
diff
changeset
|
385 .format(no_limit=C.NO_LIMIT))) |
2775
2dfd5b1d39df
jp (base): fixed default values for --max-items and --max when using pubsub
Goffi <goffi@goffi.org>
parents:
2771
diff
changeset
|
386 # FIXME: it could be possible to no duplicate max (between pubsub |
2dfd5b1d39df
jp (base): fixed default values for --max-items and --max when using pubsub
Goffi <goffi@goffi.org>
parents:
2771
diff
changeset
|
387 # max-items and RSM max)should not be duplicated, RSM could be |
2dfd5b1d39df
jp (base): fixed default values for --max-items and --max when using pubsub
Goffi <goffi@goffi.org>
parents:
2771
diff
changeset
|
388 # used when available and pubsub max otherwise |
2dfd5b1d39df
jp (base): fixed default values for --max-items and --max when using pubsub
Goffi <goffi@goffi.org>
parents:
2771
diff
changeset
|
389 max_group.add_argument( |
2dfd5b1d39df
jp (base): fixed default values for --max-items and --max when using pubsub
Goffi <goffi@goffi.org>
parents:
2771
diff
changeset
|
390 "-m", "--max", dest="rsm_max", type=int, |
3028 | 391 help=_("maximum number of items to get per page (DEFAULT: 10)")) |
2764
92af49cde255
jp (base): MAM and RSM arguments can now be used for pubsub commands:
Goffi <goffi@goffi.org>
parents:
2761
diff
changeset
|
392 |
92af49cde255
jp (base): MAM and RSM arguments can now be used for pubsub commands:
Goffi <goffi@goffi.org>
parents:
2761
diff
changeset
|
393 # RSM |
92af49cde255
jp (base): MAM and RSM arguments can now be used for pubsub commands:
Goffi <goffi@goffi.org>
parents:
2761
diff
changeset
|
394 |
92af49cde255
jp (base): MAM and RSM arguments can now be used for pubsub commands:
Goffi <goffi@goffi.org>
parents:
2761
diff
changeset
|
395 rsm_page_group = pubsub_group.add_mutually_exclusive_group() |
92af49cde255
jp (base): MAM and RSM arguments can now be used for pubsub commands:
Goffi <goffi@goffi.org>
parents:
2761
diff
changeset
|
396 rsm_page_group.add_argument( |
3028 | 397 "-a", "--after", dest="rsm_after", |
398 help=_("find page after this item"), metavar='ITEM_ID') | |
2764
92af49cde255
jp (base): MAM and RSM arguments can now be used for pubsub commands:
Goffi <goffi@goffi.org>
parents:
2761
diff
changeset
|
399 rsm_page_group.add_argument( |
3028 | 400 "-b", "--before", dest="rsm_before", |
401 help=_("find page before this item"), metavar='ITEM_ID') | |
2764
92af49cde255
jp (base): MAM and RSM arguments can now be used for pubsub commands:
Goffi <goffi@goffi.org>
parents:
2761
diff
changeset
|
402 rsm_page_group.add_argument( |
92af49cde255
jp (base): MAM and RSM arguments can now be used for pubsub commands:
Goffi <goffi@goffi.org>
parents:
2761
diff
changeset
|
403 "--index", dest="rsm_index", type=int, |
3028 | 404 help=_("index of the page to retrieve")) |
2764
92af49cde255
jp (base): MAM and RSM arguments can now be used for pubsub commands:
Goffi <goffi@goffi.org>
parents:
2761
diff
changeset
|
405 |
92af49cde255
jp (base): MAM and RSM arguments can now be used for pubsub commands:
Goffi <goffi@goffi.org>
parents:
2761
diff
changeset
|
406 |
92af49cde255
jp (base): MAM and RSM arguments can now be used for pubsub commands:
Goffi <goffi@goffi.org>
parents:
2761
diff
changeset
|
407 # MAM |
92af49cde255
jp (base): MAM and RSM arguments can now be used for pubsub commands:
Goffi <goffi@goffi.org>
parents:
2761
diff
changeset
|
408 |
92af49cde255
jp (base): MAM and RSM arguments can now be used for pubsub commands:
Goffi <goffi@goffi.org>
parents:
2761
diff
changeset
|
409 pubsub_group.add_argument( |
3028 | 410 "-f", "--filter", dest='mam_filters', nargs=2, |
411 action='append', default=[], help=_("MAM filters to use"), | |
412 metavar=("FILTER_NAME", "VALUE") | |
2764
92af49cde255
jp (base): MAM and RSM arguments can now be used for pubsub commands:
Goffi <goffi@goffi.org>
parents:
2761
diff
changeset
|
413 ) |
92af49cde255
jp (base): MAM and RSM arguments can now be used for pubsub commands:
Goffi <goffi@goffi.org>
parents:
2761
diff
changeset
|
414 |
92af49cde255
jp (base): MAM and RSM arguments can now be used for pubsub commands:
Goffi <goffi@goffi.org>
parents:
2761
diff
changeset
|
415 # Order-By |
92af49cde255
jp (base): MAM and RSM arguments can now be used for pubsub commands:
Goffi <goffi@goffi.org>
parents:
2761
diff
changeset
|
416 |
92af49cde255
jp (base): MAM and RSM arguments can now be used for pubsub commands:
Goffi <goffi@goffi.org>
parents:
2761
diff
changeset
|
417 # TODO: order-by should be a list to handle several levels of ordering |
92af49cde255
jp (base): MAM and RSM arguments can now be used for pubsub commands:
Goffi <goffi@goffi.org>
parents:
2761
diff
changeset
|
418 # but this is not yet done in SàT (and not really useful with |
92af49cde255
jp (base): MAM and RSM arguments can now be used for pubsub commands:
Goffi <goffi@goffi.org>
parents:
2761
diff
changeset
|
419 # current specifications, as only "creation" and "modification" are |
92af49cde255
jp (base): MAM and RSM arguments can now be used for pubsub commands:
Goffi <goffi@goffi.org>
parents:
2761
diff
changeset
|
420 # available) |
92af49cde255
jp (base): MAM and RSM arguments can now be used for pubsub commands:
Goffi <goffi@goffi.org>
parents:
2761
diff
changeset
|
421 pubsub_group.add_argument( |
92af49cde255
jp (base): MAM and RSM arguments can now be used for pubsub commands:
Goffi <goffi@goffi.org>
parents:
2761
diff
changeset
|
422 "-o", "--order-by", choices=[C.ORDER_BY_CREATION, |
92af49cde255
jp (base): MAM and RSM arguments can now be used for pubsub commands:
Goffi <goffi@goffi.org>
parents:
2761
diff
changeset
|
423 C.ORDER_BY_MODIFICATION], |
3028 | 424 help=_("how items should be ordered")) |
2532 | 425 |
2615
b4ecbcc2fd08
tools (misc): do not remove flags while using them anymore, instead added "all_used" and "unused" properties in FlagsHandler
Goffi <goffi@goffi.org>
parents:
2614
diff
changeset
|
426 if not flags.all_used: |
3040 | 427 raise exceptions.InternalError('unknown flags: {flags}'.format( |
428 flags=', '.join(flags.unused))) | |
2547
2d69a0afe039
jp: new argument pubsub_default can be used in Commands to replace default value in help string
Goffi <goffi@goffi.org>
parents:
2539
diff
changeset
|
429 if defaults: |
3040 | 430 raise exceptions.InternalError(f'unused defaults: {defaults}') |
2532 | 431 |
432 return parent | |
2235
4db836386641
jp: added use_pubsub and use_pubsub_node_req arguments to CommandBase
Goffi <goffi@goffi.org>
parents:
2213
diff
changeset
|
433 |
817 | 434 def add_parser_options(self): |
3040 | 435 self.parser.add_argument( |
436 '--version', | |
437 action='version', | |
438 version=("{name} {version} {copyleft}".format( | |
3555
53fec6309fa3
cli: update constants to use new name
Goffi <goffi@goffi.org>
parents:
3547
diff
changeset
|
439 name = C.APP_NAME, |
3040 | 440 version = self.version, |
441 copyleft = COPYLEFT)) | |
442 ) | |
817 | 443 |
2189
a25a256688e2
jp (base): output can now specify a default when registering
Goffi <goffi@goffi.org>
parents:
2188
diff
changeset
|
444 def register_output(self, type_, name, callback, description="", default=False): |
1950 | 445 if type_ not in C.OUTPUT_TYPES: |
3028 | 446 log.error("Invalid output type {}".format(type_)) |
1950 | 447 return |
448 self._outputs[type_][name] = {'callback': callback, | |
449 'description': description | |
450 } | |
2189
a25a256688e2
jp (base): output can now specify a default when registering
Goffi <goffi@goffi.org>
parents:
2188
diff
changeset
|
451 if default: |
a25a256688e2
jp (base): output can now specify a default when registering
Goffi <goffi@goffi.org>
parents:
2188
diff
changeset
|
452 if type_ in self.default_output: |
3040 | 453 self.disp( |
3568
04283582966f
core, frontends: fix invalid translatable strings.
Goffi <goffi@goffi.org>
parents:
3555
diff
changeset
|
454 _('there is already a default output for {type}, ignoring new one') |
04283582966f
core, frontends: fix invalid translatable strings.
Goffi <goffi@goffi.org>
parents:
3555
diff
changeset
|
455 .format(type=type_) |
3040 | 456 ) |
2189
a25a256688e2
jp (base): output can now specify a default when registering
Goffi <goffi@goffi.org>
parents:
2188
diff
changeset
|
457 else: |
a25a256688e2
jp (base): output can now specify a default when registering
Goffi <goffi@goffi.org>
parents:
2188
diff
changeset
|
458 self.default_output[type_] = name |
a25a256688e2
jp (base): output can now specify a default when registering
Goffi <goffi@goffi.org>
parents:
2188
diff
changeset
|
459 |
1950 | 460 |
2187
4ec72927a222
jp (outputs): moved output options parsing and checking to base methods
Goffi <goffi@goffi.org>
parents:
2178
diff
changeset
|
461 def parse_output_options(self): |
4ec72927a222
jp (outputs): moved output options parsing and checking to base methods
Goffi <goffi@goffi.org>
parents:
2178
diff
changeset
|
462 options = self.command.args.output_opts |
4ec72927a222
jp (outputs): moved output options parsing and checking to base methods
Goffi <goffi@goffi.org>
parents:
2178
diff
changeset
|
463 options_dict = {} |
4ec72927a222
jp (outputs): moved output options parsing and checking to base methods
Goffi <goffi@goffi.org>
parents:
2178
diff
changeset
|
464 for option in options: |
4ec72927a222
jp (outputs): moved output options parsing and checking to base methods
Goffi <goffi@goffi.org>
parents:
2178
diff
changeset
|
465 try: |
3028 | 466 key, value = option.split('=', 1) |
2187
4ec72927a222
jp (outputs): moved output options parsing and checking to base methods
Goffi <goffi@goffi.org>
parents:
2178
diff
changeset
|
467 except ValueError: |
4ec72927a222
jp (outputs): moved output options parsing and checking to base methods
Goffi <goffi@goffi.org>
parents:
2178
diff
changeset
|
468 key, value = option, None |
4ec72927a222
jp (outputs): moved output options parsing and checking to base methods
Goffi <goffi@goffi.org>
parents:
2178
diff
changeset
|
469 options_dict[key.strip()] = value.strip() if value is not None else None |
4ec72927a222
jp (outputs): moved output options parsing and checking to base methods
Goffi <goffi@goffi.org>
parents:
2178
diff
changeset
|
470 return options_dict |
4ec72927a222
jp (outputs): moved output options parsing and checking to base methods
Goffi <goffi@goffi.org>
parents:
2178
diff
changeset
|
471 |
4ec72927a222
jp (outputs): moved output options parsing and checking to base methods
Goffi <goffi@goffi.org>
parents:
2178
diff
changeset
|
472 def check_output_options(self, accepted_set, options): |
4ec72927a222
jp (outputs): moved output options parsing and checking to base methods
Goffi <goffi@goffi.org>
parents:
2178
diff
changeset
|
473 if not accepted_set.issuperset(options): |
3040 | 474 self.disp( |
475 _("The following output options are invalid: {invalid_options}").format( | |
3028 | 476 invalid_options = ', '.join(set(options).difference(accepted_set))), |
2187
4ec72927a222
jp (outputs): moved output options parsing and checking to base methods
Goffi <goffi@goffi.org>
parents:
2178
diff
changeset
|
477 error=True) |
4ec72927a222
jp (outputs): moved output options parsing and checking to base methods
Goffi <goffi@goffi.org>
parents:
2178
diff
changeset
|
478 self.quit(C.EXIT_BAD_ARG) |
4ec72927a222
jp (outputs): moved output options parsing and checking to base methods
Goffi <goffi@goffi.org>
parents:
2178
diff
changeset
|
479 |
1950 | 480 def import_plugins(self): |
481 """Automaticaly import commands and outputs in jp | |
482 | |
817 | 483 looks from modules names cmd_*.py in jp path and import them |
484 """ | |
485 path = os.path.dirname(sat_frontends.jp.__file__) | |
1950 | 486 # XXX: outputs must be imported before commands as they are used for arguments |
3040 | 487 for type_, pattern in ((C.PLUGIN_OUTPUT, 'output_*.py'), |
488 (C.PLUGIN_CMD, 'cmd_*.py')): | |
489 modules = ( | |
490 os.path.splitext(module)[0] | |
491 for module in map(os.path.basename, iglob(os.path.join(path, pattern)))) | |
1950 | 492 for module_name in modules: |
2162
c9a67eb5bf72
jp (base): improved module import:
Goffi <goffi@goffi.org>
parents:
2161
diff
changeset
|
493 module_path = "sat_frontends.jp." + module_name |
1950 | 494 try: |
2162
c9a67eb5bf72
jp (base): improved module import:
Goffi <goffi@goffi.org>
parents:
2161
diff
changeset
|
495 module = import_module(module_path) |
1950 | 496 self.import_plugin_module(module, type_) |
2178
b9bfc45cea22
jp (base): added generic errback to CommandBase + show error message on plugin ImportError
Goffi <goffi@goffi.org>
parents:
2168
diff
changeset
|
497 except ImportError as e: |
3040 | 498 self.disp( |
3568
04283582966f
core, frontends: fix invalid translatable strings.
Goffi <goffi@goffi.org>
parents:
3555
diff
changeset
|
499 _("Can't import {module_path} plugin, ignoring it: {e}") |
04283582966f
core, frontends: fix invalid translatable strings.
Goffi <goffi@goffi.org>
parents:
3555
diff
changeset
|
500 .format(module_path=module_path, e=e), |
3040 | 501 error=True) |
2162
c9a67eb5bf72
jp (base): improved module import:
Goffi <goffi@goffi.org>
parents:
2161
diff
changeset
|
502 except exceptions.CancelError: |
1950 | 503 continue |
2162
c9a67eb5bf72
jp (base): improved module import:
Goffi <goffi@goffi.org>
parents:
2161
diff
changeset
|
504 except exceptions.MissingModule as e: |
3028 | 505 self.disp(_("Missing module for plugin {name}: {missing}".format( |
2162
c9a67eb5bf72
jp (base): improved module import:
Goffi <goffi@goffi.org>
parents:
2161
diff
changeset
|
506 name = module_path, |
2188
052d560d0dce
jp (base): replaced log.warning by stderr prints
Goffi <goffi@goffi.org>
parents:
2187
diff
changeset
|
507 missing = e)), error=True) |
2162
c9a67eb5bf72
jp (base): improved module import:
Goffi <goffi@goffi.org>
parents:
2161
diff
changeset
|
508 |
0 | 509 |
1950 | 510 def import_plugin_module(self, module, type_): |
511 """add commands or outpus from a module to jp | |
817 | 512 |
1950 | 513 @param module: module containing commands or outputs |
514 @param type_(str): one of C_PLUGIN_* | |
817 | 515 """ |
516 try: | |
1950 | 517 class_names = getattr(module, '__{}__'.format(type_)) |
817 | 518 except AttributeError: |
3568
04283582966f
core, frontends: fix invalid translatable strings.
Goffi <goffi@goffi.org>
parents:
3555
diff
changeset
|
519 log.disp( |
04283582966f
core, frontends: fix invalid translatable strings.
Goffi <goffi@goffi.org>
parents:
3555
diff
changeset
|
520 _("Invalid plugin module [{type}] {module}") |
04283582966f
core, frontends: fix invalid translatable strings.
Goffi <goffi@goffi.org>
parents:
3555
diff
changeset
|
521 .format(type=type_, module=module), |
04283582966f
core, frontends: fix invalid translatable strings.
Goffi <goffi@goffi.org>
parents:
3555
diff
changeset
|
522 error=True) |
817 | 523 raise ImportError |
1950 | 524 else: |
525 for class_name in class_names: | |
526 cls = getattr(module, class_name) | |
527 cls(self) | |
817 | 528 |
2532 | 529 def get_xmpp_uri_from_http(self, http_url): |
530 """parse HTML page at http(s) URL, and looks for xmpp: uri""" | |
531 if http_url.startswith('https'): | |
3028 | 532 scheme = 'https' |
2532 | 533 elif http_url.startswith('http'): |
3028 | 534 scheme = 'http' |
2532 | 535 else: |
3028 | 536 raise exceptions.InternalError('An HTTP scheme is expected in this method') |
3040 | 537 self.disp(f"{scheme.upper()} URL found, trying to find associated xmpp: URI", 1) |
2532 | 538 # HTTP URL, we try to find xmpp: links |
539 try: | |
540 from lxml import etree | |
541 except ImportError: | |
3040 | 542 self.disp( |
543 "lxml module must be installed to use http(s) scheme, please install it " | |
544 "with \"pip install lxml\"", | |
545 error=True) | |
2672 | 546 self.quit(1) |
3028 | 547 import urllib.request, urllib.error, urllib.parse |
2532 | 548 parser = etree.HTMLParser() |
549 try: | |
3028 | 550 root = etree.parse(urllib.request.urlopen(http_url), parser) |
2532 | 551 except etree.XMLSyntaxError as e: |
3028 | 552 self.disp(_("Can't parse HTML page : {msg}").format(msg=e)) |
2532 | 553 links = [] |
554 else: | |
555 links = root.xpath("//link[@rel='alternate' and starts-with(@href, 'xmpp:')]") | |
556 if not links: | |
3040 | 557 self.disp( |
558 _('Could not find alternate "xmpp:" URI, can\'t find associated XMPP ' | |
559 'PubSub node/item'), | |
560 error=True) | |
2672 | 561 self.quit(1) |
2532 | 562 xmpp_uri = links[0].get('href') |
563 return xmpp_uri | |
564 | |
565 def parse_pubsub_args(self): | |
566 if self.args.pubsub_url is not None: | |
567 url = self.args.pubsub_url | |
568 | |
569 if url.startswith('http'): | |
570 # http(s) URL, we try to retrieve xmpp one from there | |
571 url = self.get_xmpp_uri_from_http(url) | |
572 | |
573 try: | |
574 uri_data = uri.parseXMPPUri(url) | |
575 except ValueError: | |
3028 | 576 self.parser.error(_('invalid XMPP URL: {url}').format(url=url)) |
2532 | 577 else: |
3028 | 578 if uri_data['type'] == 'pubsub': |
2532 | 579 # URL is alright, we only set data not already set by other options |
580 if not self.args.service: | |
3028 | 581 self.args.service = uri_data['path'] |
2532 | 582 if not self.args.node: |
3028 | 583 self.args.node = uri_data['node'] |
584 uri_item = uri_data.get('item') | |
2532 | 585 if uri_item: |
2556
340128e0b354
jp (base): fixed URI's item with use_pubsub
Goffi <goffi@goffi.org>
parents:
2552
diff
changeset
|
586 # there is an item in URI |
340128e0b354
jp (base): fixed URI's item with use_pubsub
Goffi <goffi@goffi.org>
parents:
2552
diff
changeset
|
587 # we use it only if item is not already set |
340128e0b354
jp (base): fixed URI's item with use_pubsub
Goffi <goffi@goffi.org>
parents:
2552
diff
changeset
|
588 # and item_last is not used either |
2532 | 589 try: |
2556
340128e0b354
jp (base): fixed URI's item with use_pubsub
Goffi <goffi@goffi.org>
parents:
2552
diff
changeset
|
590 item = self.args.item |
2532 | 591 except AttributeError: |
2609
75d2ac872965
jp (base): do not crash when item is specified (e.g. in URL) but not needed in command, but display a message on stderr.
Goffi <goffi@goffi.org>
parents:
2588
diff
changeset
|
592 try: |
75d2ac872965
jp (base): do not crash when item is specified (e.g. in URL) but not needed in command, but display a message on stderr.
Goffi <goffi@goffi.org>
parents:
2588
diff
changeset
|
593 items = self.args.items |
75d2ac872965
jp (base): do not crash when item is specified (e.g. in URL) but not needed in command, but display a message on stderr.
Goffi <goffi@goffi.org>
parents:
2588
diff
changeset
|
594 except AttributeError: |
3040 | 595 self.disp( |
596 _("item specified in URL but not needed in command, " | |
597 "ignoring it"), | |
598 error=True) | |
2609
75d2ac872965
jp (base): do not crash when item is specified (e.g. in URL) but not needed in command, but display a message on stderr.
Goffi <goffi@goffi.org>
parents:
2588
diff
changeset
|
599 else: |
75d2ac872965
jp (base): do not crash when item is specified (e.g. in URL) but not needed in command, but display a message on stderr.
Goffi <goffi@goffi.org>
parents:
2588
diff
changeset
|
600 if not items: |
75d2ac872965
jp (base): do not crash when item is specified (e.g. in URL) but not needed in command, but display a message on stderr.
Goffi <goffi@goffi.org>
parents:
2588
diff
changeset
|
601 self.args.items = [uri_item] |
2532 | 602 else: |
2556
340128e0b354
jp (base): fixed URI's item with use_pubsub
Goffi <goffi@goffi.org>
parents:
2552
diff
changeset
|
603 if not item: |
340128e0b354
jp (base): fixed URI's item with use_pubsub
Goffi <goffi@goffi.org>
parents:
2552
diff
changeset
|
604 try: |
340128e0b354
jp (base): fixed URI's item with use_pubsub
Goffi <goffi@goffi.org>
parents:
2552
diff
changeset
|
605 item_last = self.args.item_last |
340128e0b354
jp (base): fixed URI's item with use_pubsub
Goffi <goffi@goffi.org>
parents:
2552
diff
changeset
|
606 except AttributeError: |
340128e0b354
jp (base): fixed URI's item with use_pubsub
Goffi <goffi@goffi.org>
parents:
2552
diff
changeset
|
607 item_last = False |
340128e0b354
jp (base): fixed URI's item with use_pubsub
Goffi <goffi@goffi.org>
parents:
2552
diff
changeset
|
608 if not item_last: |
340128e0b354
jp (base): fixed URI's item with use_pubsub
Goffi <goffi@goffi.org>
parents:
2552
diff
changeset
|
609 self.args.item = uri_item |
2532 | 610 else: |
3568
04283582966f
core, frontends: fix invalid translatable strings.
Goffi <goffi@goffi.org>
parents:
3555
diff
changeset
|
611 self.parser.error( |
04283582966f
core, frontends: fix invalid translatable strings.
Goffi <goffi@goffi.org>
parents:
3555
diff
changeset
|
612 _('XMPP URL is not a pubsub one: {url}').format(url=url) |
04283582966f
core, frontends: fix invalid translatable strings.
Goffi <goffi@goffi.org>
parents:
3555
diff
changeset
|
613 ) |
2532 | 614 flags = self.args._cmd._pubsub_flags |
615 # we check required arguments here instead of using add_arguments' required option | |
616 # because the required argument can be set in URL | |
617 if C.SERVICE in flags and not self.args.service: | |
3028 | 618 self.parser.error(_("argument -s/--service is required")) |
2532 | 619 if C.NODE in flags and not self.args.node: |
3028 | 620 self.parser.error(_("argument -n/--node is required")) |
2552
38e1e29c48e9
jp (base): added C.ITEM pubsub flag when --item is required
Goffi <goffi@goffi.org>
parents:
2550
diff
changeset
|
621 if C.ITEM in flags and not self.args.item: |
3028 | 622 self.parser.error(_("argument -i/--item is required")) |
2532 | 623 |
624 # FIXME: mutually groups can't be nested in a group and don't support title | |
625 # so we check conflict here. This may be fixed in Python 3, to be checked | |
626 try: | |
627 if self.args.item and self.args.item_last: | |
3040 | 628 self.parser.error( |
629 _("--item and --item-last can't be used at the same time")) | |
2532 | 630 except AttributeError: |
631 pass | |
632 | |
2775
2dfd5b1d39df
jp (base): fixed default values for --max-items and --max when using pubsub
Goffi <goffi@goffi.org>
parents:
2771
diff
changeset
|
633 try: |
2dfd5b1d39df
jp (base): fixed default values for --max-items and --max when using pubsub
Goffi <goffi@goffi.org>
parents:
2771
diff
changeset
|
634 max_items = self.args.max |
2dfd5b1d39df
jp (base): fixed default values for --max-items and --max when using pubsub
Goffi <goffi@goffi.org>
parents:
2771
diff
changeset
|
635 rsm_max = self.args.rsm_max |
2dfd5b1d39df
jp (base): fixed default values for --max-items and --max when using pubsub
Goffi <goffi@goffi.org>
parents:
2771
diff
changeset
|
636 except AttributeError: |
2dfd5b1d39df
jp (base): fixed default values for --max-items and --max when using pubsub
Goffi <goffi@goffi.org>
parents:
2771
diff
changeset
|
637 pass |
2dfd5b1d39df
jp (base): fixed default values for --max-items and --max when using pubsub
Goffi <goffi@goffi.org>
parents:
2771
diff
changeset
|
638 else: |
2dfd5b1d39df
jp (base): fixed default values for --max-items and --max when using pubsub
Goffi <goffi@goffi.org>
parents:
2771
diff
changeset
|
639 # we need to set a default value for max, but we need to know if we want |
2dfd5b1d39df
jp (base): fixed default values for --max-items and --max when using pubsub
Goffi <goffi@goffi.org>
parents:
2771
diff
changeset
|
640 # to use pubsub's max or RSM's max. The later is used if any RSM or MAM |
2dfd5b1d39df
jp (base): fixed default values for --max-items and --max when using pubsub
Goffi <goffi@goffi.org>
parents:
2771
diff
changeset
|
641 # argument is set |
2dfd5b1d39df
jp (base): fixed default values for --max-items and --max when using pubsub
Goffi <goffi@goffi.org>
parents:
2771
diff
changeset
|
642 if max_items is None and rsm_max is None: |
2dfd5b1d39df
jp (base): fixed default values for --max-items and --max when using pubsub
Goffi <goffi@goffi.org>
parents:
2771
diff
changeset
|
643 to_check = ('mam_filters', 'rsm_max', 'rsm_after', 'rsm_before', |
2dfd5b1d39df
jp (base): fixed default values for --max-items and --max when using pubsub
Goffi <goffi@goffi.org>
parents:
2771
diff
changeset
|
644 'rsm_index') |
2dfd5b1d39df
jp (base): fixed default values for --max-items and --max when using pubsub
Goffi <goffi@goffi.org>
parents:
2771
diff
changeset
|
645 if any((getattr(self.args, name) for name in to_check)): |
2dfd5b1d39df
jp (base): fixed default values for --max-items and --max when using pubsub
Goffi <goffi@goffi.org>
parents:
2771
diff
changeset
|
646 # we use RSM |
2dfd5b1d39df
jp (base): fixed default values for --max-items and --max when using pubsub
Goffi <goffi@goffi.org>
parents:
2771
diff
changeset
|
647 self.args.rsm_max = 10 |
2dfd5b1d39df
jp (base): fixed default values for --max-items and --max when using pubsub
Goffi <goffi@goffi.org>
parents:
2771
diff
changeset
|
648 else: |
2dfd5b1d39df
jp (base): fixed default values for --max-items and --max when using pubsub
Goffi <goffi@goffi.org>
parents:
2771
diff
changeset
|
649 # we use pubsub without RSM |
2dfd5b1d39df
jp (base): fixed default values for --max-items and --max when using pubsub
Goffi <goffi@goffi.org>
parents:
2771
diff
changeset
|
650 self.args.max = 10 |
2dfd5b1d39df
jp (base): fixed default values for --max-items and --max when using pubsub
Goffi <goffi@goffi.org>
parents:
2771
diff
changeset
|
651 if self.args.max is None: |
2dfd5b1d39df
jp (base): fixed default values for --max-items and --max when using pubsub
Goffi <goffi@goffi.org>
parents:
2771
diff
changeset
|
652 self.args.max = C.NO_LIMIT |
2dfd5b1d39df
jp (base): fixed default values for --max-items and --max when using pubsub
Goffi <goffi@goffi.org>
parents:
2771
diff
changeset
|
653 |
3040 | 654 async def main(self, args, namespace): |
1884
0fe69871b71f
jp: moved KeyboardInterrupt catch one level higher, so it is also catched if the loop is not started
Goffi <goffi@goffi.org>
parents:
1872
diff
changeset
|
655 try: |
3040 | 656 await self.bridge.bridgeConnect() |
657 except Exception as e: | |
658 if isinstance(e, exceptions.BridgeExceptionNoService): | |
3568
04283582966f
core, frontends: fix invalid translatable strings.
Goffi <goffi@goffi.org>
parents:
3555
diff
changeset
|
659 print(_("Can't connect to SàT backend, are you sure it's launched ?")) |
3490
509f7a1c67dc
frontends: use new EXIT_BACKEND_NOT_FOUND exit code:
Goffi <goffi@goffi.org>
parents:
3486
diff
changeset
|
660 self.quit(C.EXIT_BACKEND_NOT_FOUND, raise_exc=False) |
3040 | 661 elif isinstance(e, exceptions.BridgeInitError): |
3568
04283582966f
core, frontends: fix invalid translatable strings.
Goffi <goffi@goffi.org>
parents:
3555
diff
changeset
|
662 print(_("Can't init bridge")) |
3490
509f7a1c67dc
frontends: use new EXIT_BACKEND_NOT_FOUND exit code:
Goffi <goffi@goffi.org>
parents:
3486
diff
changeset
|
663 self.quit(C.EXIT_BRIDGE_ERROR, raise_exc=False) |
3040 | 664 else: |
3568
04283582966f
core, frontends: fix invalid translatable strings.
Goffi <goffi@goffi.org>
parents:
3555
diff
changeset
|
665 print( |
04283582966f
core, frontends: fix invalid translatable strings.
Goffi <goffi@goffi.org>
parents:
3555
diff
changeset
|
666 _("Error while initialising bridge: {e}").format(e=e) |
04283582966f
core, frontends: fix invalid translatable strings.
Goffi <goffi@goffi.org>
parents:
3555
diff
changeset
|
667 ) |
3490
509f7a1c67dc
frontends: use new EXIT_BACKEND_NOT_FOUND exit code:
Goffi <goffi@goffi.org>
parents:
3486
diff
changeset
|
668 self.quit(C.EXIT_BRIDGE_ERROR, raise_exc=False) |
3040 | 669 return |
3636
43542cf32e5a
cli: call `bridge.getReady()` after bridge connection
Goffi <goffi@goffi.org>
parents:
3568
diff
changeset
|
670 await self.bridge.getReady() |
3040 | 671 self.version = await self.bridge.getVersion() |
672 self._bridgeConnected() | |
673 self.import_plugins() | |
674 try: | |
675 self.args = self.parser.parse_args(args, namespace=None) | |
676 if self.args._cmd._use_pubsub: | |
677 self.parse_pubsub_args() | |
678 await self.args._cmd.run() | |
679 except SystemExit as e: | |
680 self.quit(e.code, raise_exc=False) | |
681 return | |
682 except QuitException: | |
683 return | |
817 | 684 |
3481
7892585b7e17
core (setup), jp, primitivus: update console scripts + classifiers:
Goffi <goffi@goffi.org>
parents:
3479
diff
changeset
|
685 def _run(self, args=None, namespace=None): |
2098
e0066920a661
primitivus, jp: dynamic bridge + fixed D-Bus bridge:
Goffi <goffi@goffi.org>
parents:
2086
diff
changeset
|
686 self.loop = JPLoop() |
3040 | 687 self.loop.run(self, args, namespace) |
0 | 688 |
3481
7892585b7e17
core (setup), jp, primitivus: update console scripts + classifiers:
Goffi <goffi@goffi.org>
parents:
3479
diff
changeset
|
689 @classmethod |
7892585b7e17
core (setup), jp, primitivus: update console scripts + classifiers:
Goffi <goffi@goffi.org>
parents:
3479
diff
changeset
|
690 def run(cls): |
7892585b7e17
core (setup), jp, primitivus: update console scripts + classifiers:
Goffi <goffi@goffi.org>
parents:
3479
diff
changeset
|
691 cls()._run() |
7892585b7e17
core (setup), jp, primitivus: update console scripts + classifiers:
Goffi <goffi@goffi.org>
parents:
3479
diff
changeset
|
692 |
3040 | 693 def _read_stdin(self, stdin_fut): |
694 """Callback called by ainput to read stdin""" | |
695 line = sys.stdin.readline() | |
696 if line: | |
697 stdin_fut.set_result(line.rstrip(os.linesep)) | |
698 else: | |
699 stdin_fut.set_exception(EOFError()) | |
587
952322b1d490
Remove trailing whitespaces.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
572
diff
changeset
|
700 |
3040 | 701 async def ainput(self, msg=''): |
702 """Asynchronous version of buildin "input" function""" | |
3407
2f0be2b7de68
jp: replace `no_lf` argument by `end` in `disp` (same as in `print`)
Goffi <goffi@goffi.org>
parents:
3378
diff
changeset
|
703 self.disp(msg, end=' ') |
3040 | 704 sys.stdout.flush() |
705 loop = asyncio.get_running_loop() | |
706 stdin_fut = loop.create_future() | |
707 loop.add_reader(sys.stdin, self._read_stdin, stdin_fut) | |
708 return await stdin_fut | |
709 | |
3409 | 710 async def confirm(self, message): |
711 """Request user to confirm action, return answer as boolean""" | |
712 res = await self.ainput(f"{message} (y/N)? ") | |
713 return res in ("y", "Y") | |
714 | |
3040 | 715 async def confirmOrQuit(self, message, cancel_message=_("action cancelled by user")): |
2550
1d754bc14381
jp (base): new confirmOrQuit helper method to ask confirmation to user, and quit if he cancel
Goffi <goffi@goffi.org>
parents:
2547
diff
changeset
|
716 """Request user to confirm action, and quit if he doesn't""" |
3409 | 717 confirmed = await self.confirm(message) |
718 if not confirmed: | |
2550
1d754bc14381
jp (base): new confirmOrQuit helper method to ask confirmation to user, and quit if he cancel
Goffi <goffi@goffi.org>
parents:
2547
diff
changeset
|
719 self.disp(cancel_message) |
1d754bc14381
jp (base): new confirmOrQuit helper method to ask confirmation to user, and quit if he cancel
Goffi <goffi@goffi.org>
parents:
2547
diff
changeset
|
720 self.quit(C.EXIT_USER_CANCELLED) |
1d754bc14381
jp (base): new confirmOrQuit helper method to ask confirmation to user, and quit if he cancel
Goffi <goffi@goffi.org>
parents:
2547
diff
changeset
|
721 |
3040 | 722 def quitFromSignal(self, exit_code=0): |
723 r"""Same as self.quit, but from a signal handler | |
1604
9ac78437000d
jp (base): added quitFromSignal method to quit from signal handler with errcode without traceback, and addOnQuitCallback to manage cleaning callbacks
Goffi <goffi@goffi.org>
parents:
1600
diff
changeset
|
724 |
9ac78437000d
jp (base): added quitFromSignal method to quit from signal handler with errcode without traceback, and addOnQuitCallback to manage cleaning callbacks
Goffi <goffi@goffi.org>
parents:
1600
diff
changeset
|
725 /!\: return must be used after calling this method ! |
9ac78437000d
jp (base): added quitFromSignal method to quit from signal handler with errcode without traceback, and addOnQuitCallback to manage cleaning callbacks
Goffi <goffi@goffi.org>
parents:
1600
diff
changeset
|
726 """ |
1918
01d56efd488b
jp: fixed traceback shown on a normal quit when a progression is finished
Goffi <goffi@goffi.org>
parents:
1884
diff
changeset
|
727 # XXX: python-dbus will show a traceback if we exit in a signal handler |
1604
9ac78437000d
jp (base): added quitFromSignal method to quit from signal handler with errcode without traceback, and addOnQuitCallback to manage cleaning callbacks
Goffi <goffi@goffi.org>
parents:
1600
diff
changeset
|
728 # so we use this little timeout trick to avoid it |
3040 | 729 self.loop.call_later(0, self.quit, exit_code) |
730 | |
731 def quit(self, exit_code=0, raise_exc=True): | |
732 """Terminate the execution with specified exit_code | |
1604
9ac78437000d
jp (base): added quitFromSignal method to quit from signal handler with errcode without traceback, and addOnQuitCallback to manage cleaning callbacks
Goffi <goffi@goffi.org>
parents:
1600
diff
changeset
|
733 |
3040 | 734 This will stop the loop. |
735 @param exit_code(int): code to return when quitting the program | |
736 @param raise_exp(boolean): if True raise a QuitException to stop code execution | |
737 The default value should be used most of time. | |
738 """ | |
1604
9ac78437000d
jp (base): added quitFromSignal method to quit from signal handler with errcode without traceback, and addOnQuitCallback to manage cleaning callbacks
Goffi <goffi@goffi.org>
parents:
1600
diff
changeset
|
739 # first the onQuitCallbacks |
9ac78437000d
jp (base): added quitFromSignal method to quit from signal handler with errcode without traceback, and addOnQuitCallback to manage cleaning callbacks
Goffi <goffi@goffi.org>
parents:
1600
diff
changeset
|
740 try: |
9ac78437000d
jp (base): added quitFromSignal method to quit from signal handler with errcode without traceback, and addOnQuitCallback to manage cleaning callbacks
Goffi <goffi@goffi.org>
parents:
1600
diff
changeset
|
741 callbacks_list = self._onQuitCallbacks |
9ac78437000d
jp (base): added quitFromSignal method to quit from signal handler with errcode without traceback, and addOnQuitCallback to manage cleaning callbacks
Goffi <goffi@goffi.org>
parents:
1600
diff
changeset
|
742 except AttributeError: |
9ac78437000d
jp (base): added quitFromSignal method to quit from signal handler with errcode without traceback, and addOnQuitCallback to manage cleaning callbacks
Goffi <goffi@goffi.org>
parents:
1600
diff
changeset
|
743 pass |
9ac78437000d
jp (base): added quitFromSignal method to quit from signal handler with errcode without traceback, and addOnQuitCallback to manage cleaning callbacks
Goffi <goffi@goffi.org>
parents:
1600
diff
changeset
|
744 else: |
9ac78437000d
jp (base): added quitFromSignal method to quit from signal handler with errcode without traceback, and addOnQuitCallback to manage cleaning callbacks
Goffi <goffi@goffi.org>
parents:
1600
diff
changeset
|
745 for callback, args, kwargs in callbacks_list: |
9ac78437000d
jp (base): added quitFromSignal method to quit from signal handler with errcode without traceback, and addOnQuitCallback to manage cleaning callbacks
Goffi <goffi@goffi.org>
parents:
1600
diff
changeset
|
746 callback(*args, **kwargs) |
9ac78437000d
jp (base): added quitFromSignal method to quit from signal handler with errcode without traceback, and addOnQuitCallback to manage cleaning callbacks
Goffi <goffi@goffi.org>
parents:
1600
diff
changeset
|
747 |
3040 | 748 self.loop.quit(exit_code) |
749 if raise_exc: | |
750 raise QuitException | |
587
952322b1d490
Remove trailing whitespaces.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
572
diff
changeset
|
751 |
3040 | 752 async def check_jids(self, jids): |
814 | 753 """Check jids validity, transform roster name to corresponding jids |
110
cb904fa7de3c
jp: profile management (new option: --profile)
Goffi <goffi@goffi.org>
parents:
70
diff
changeset
|
754 |
817 | 755 @param profile: profile name |
756 @param jids: list of jids | |
757 @return: List of jids | |
758 | |
814 | 759 """ |
401
b2caa2615c4c
jp roster name manegement + Pipe transfer
Goffi <goffi@goffi.org>
parents:
393
diff
changeset
|
760 names2jid = {} |
493
b7c4bb2c0668
jp: - better expandJid: roster's jids' nodes are used after names to expand jid
Goffi <goffi@goffi.org>
parents:
480
diff
changeset
|
761 nodes2jid = {} |
393 | 762 |
3040 | 763 for contact in await self.bridge.getContacts(self.profile): |
1395
1ae9aa94c351
jp: fixed bad try/except hidding errors + fixed bad management of jids without node
Goffi <goffi@goffi.org>
parents:
1290
diff
changeset
|
764 jid_s, attr, groups = contact |
1ae9aa94c351
jp: fixed bad try/except hidding errors + fixed bad management of jids without node
Goffi <goffi@goffi.org>
parents:
1290
diff
changeset
|
765 _jid = JID(jid_s) |
1ae9aa94c351
jp: fixed bad try/except hidding errors + fixed bad management of jids without node
Goffi <goffi@goffi.org>
parents:
1290
diff
changeset
|
766 try: |
1ae9aa94c351
jp: fixed bad try/except hidding errors + fixed bad management of jids without node
Goffi <goffi@goffi.org>
parents:
1290
diff
changeset
|
767 names2jid[attr["name"].lower()] = jid_s |
1ae9aa94c351
jp: fixed bad try/except hidding errors + fixed bad management of jids without node
Goffi <goffi@goffi.org>
parents:
1290
diff
changeset
|
768 except KeyError: |
1ae9aa94c351
jp: fixed bad try/except hidding errors + fixed bad management of jids without node
Goffi <goffi@goffi.org>
parents:
1290
diff
changeset
|
769 pass |
1ae9aa94c351
jp: fixed bad try/except hidding errors + fixed bad management of jids without node
Goffi <goffi@goffi.org>
parents:
1290
diff
changeset
|
770 |
1ae9aa94c351
jp: fixed bad try/except hidding errors + fixed bad management of jids without node
Goffi <goffi@goffi.org>
parents:
1290
diff
changeset
|
771 if _jid.node: |
1ae9aa94c351
jp: fixed bad try/except hidding errors + fixed bad management of jids without node
Goffi <goffi@goffi.org>
parents:
1290
diff
changeset
|
772 nodes2jid[_jid.node.lower()] = jid_s |
401
b2caa2615c4c
jp roster name manegement + Pipe transfer
Goffi <goffi@goffi.org>
parents:
393
diff
changeset
|
773 |
817 | 774 def expand_jid(jid): |
401
b2caa2615c4c
jp roster name manegement + Pipe transfer
Goffi <goffi@goffi.org>
parents:
393
diff
changeset
|
775 _jid = jid.lower() |
493
b7c4bb2c0668
jp: - better expandJid: roster's jids' nodes are used after names to expand jid
Goffi <goffi@goffi.org>
parents:
480
diff
changeset
|
776 if _jid in names2jid: |
b7c4bb2c0668
jp: - better expandJid: roster's jids' nodes are used after names to expand jid
Goffi <goffi@goffi.org>
parents:
480
diff
changeset
|
777 expanded = names2jid[_jid] |
b7c4bb2c0668
jp: - better expandJid: roster's jids' nodes are used after names to expand jid
Goffi <goffi@goffi.org>
parents:
480
diff
changeset
|
778 elif _jid in nodes2jid: |
b7c4bb2c0668
jp: - better expandJid: roster's jids' nodes are used after names to expand jid
Goffi <goffi@goffi.org>
parents:
480
diff
changeset
|
779 expanded = nodes2jid[_jid] |
b7c4bb2c0668
jp: - better expandJid: roster's jids' nodes are used after names to expand jid
Goffi <goffi@goffi.org>
parents:
480
diff
changeset
|
780 else: |
b7c4bb2c0668
jp: - better expandJid: roster's jids' nodes are used after names to expand jid
Goffi <goffi@goffi.org>
parents:
480
diff
changeset
|
781 expanded = jid |
2588 | 782 return expanded |
401
b2caa2615c4c
jp roster name manegement + Pipe transfer
Goffi <goffi@goffi.org>
parents:
393
diff
changeset
|
783 |
b2caa2615c4c
jp roster name manegement + Pipe transfer
Goffi <goffi@goffi.org>
parents:
393
diff
changeset
|
784 def check(jid): |
b2caa2615c4c
jp roster name manegement + Pipe transfer
Goffi <goffi@goffi.org>
parents:
393
diff
changeset
|
785 if not jid.is_valid: |
1605
0aded9648c5c
jp (base): added a self.disp method which manage verbosity and stderr + verbosity property
Goffi <goffi@goffi.org>
parents:
1604
diff
changeset
|
786 log.error (_("%s is not a valid JID !"), jid) |
817 | 787 self.quit(1) |
401
b2caa2615c4c
jp roster name manegement + Pipe transfer
Goffi <goffi@goffi.org>
parents:
393
diff
changeset
|
788 |
814 | 789 dest_jids=[] |
401
b2caa2615c4c
jp roster name manegement + Pipe transfer
Goffi <goffi@goffi.org>
parents:
393
diff
changeset
|
790 try: |
814 | 791 for i in range(len(jids)): |
817 | 792 dest_jids.append(expand_jid(jids[i])) |
814 | 793 check(dest_jids[i]) |
401
b2caa2615c4c
jp roster name manegement + Pipe transfer
Goffi <goffi@goffi.org>
parents:
393
diff
changeset
|
794 except AttributeError: |
b2caa2615c4c
jp roster name manegement + Pipe transfer
Goffi <goffi@goffi.org>
parents:
393
diff
changeset
|
795 pass |
0 | 796 |
814 | 797 return dest_jids |
0 | 798 |
3049
9839ce068140
jp: password is now prompted if needed:
Goffi <goffi@goffi.org>
parents:
3046
diff
changeset
|
799 async def a_pwd_input(self, msg=''): |
9839ce068140
jp: password is now prompted if needed:
Goffi <goffi@goffi.org>
parents:
3046
diff
changeset
|
800 """Like ainput but with echo disabled (useful for passwords)""" |
9839ce068140
jp: password is now prompted if needed:
Goffi <goffi@goffi.org>
parents:
3046
diff
changeset
|
801 # we disable echo, code adapted from getpass standard module which has been |
9839ce068140
jp: password is now prompted if needed:
Goffi <goffi@goffi.org>
parents:
3046
diff
changeset
|
802 # written by Piers Lauder (original), Guido van Rossum (Windows support and |
9839ce068140
jp: password is now prompted if needed:
Goffi <goffi@goffi.org>
parents:
3046
diff
changeset
|
803 # cleanup) and Gregory P. Smith (tty support & GetPassWarning), a big thanks |
9839ce068140
jp: password is now prompted if needed:
Goffi <goffi@goffi.org>
parents:
3046
diff
changeset
|
804 # to them (and for all the amazing work on Python). |
9839ce068140
jp: password is now prompted if needed:
Goffi <goffi@goffi.org>
parents:
3046
diff
changeset
|
805 stdin_fd = sys.stdin.fileno() |
9839ce068140
jp: password is now prompted if needed:
Goffi <goffi@goffi.org>
parents:
3046
diff
changeset
|
806 old = termios.tcgetattr(sys.stdin) |
9839ce068140
jp: password is now prompted if needed:
Goffi <goffi@goffi.org>
parents:
3046
diff
changeset
|
807 new = old[:] |
9839ce068140
jp: password is now prompted if needed:
Goffi <goffi@goffi.org>
parents:
3046
diff
changeset
|
808 new[3] &= ~termios.ECHO |
9839ce068140
jp: password is now prompted if needed:
Goffi <goffi@goffi.org>
parents:
3046
diff
changeset
|
809 tcsetattr_flags = termios.TCSAFLUSH |
9839ce068140
jp: password is now prompted if needed:
Goffi <goffi@goffi.org>
parents:
3046
diff
changeset
|
810 if hasattr(termios, 'TCSASOFT'): |
9839ce068140
jp: password is now prompted if needed:
Goffi <goffi@goffi.org>
parents:
3046
diff
changeset
|
811 tcsetattr_flags |= termios.TCSASOFT |
9839ce068140
jp: password is now prompted if needed:
Goffi <goffi@goffi.org>
parents:
3046
diff
changeset
|
812 try: |
9839ce068140
jp: password is now prompted if needed:
Goffi <goffi@goffi.org>
parents:
3046
diff
changeset
|
813 termios.tcsetattr(stdin_fd, tcsetattr_flags, new) |
9839ce068140
jp: password is now prompted if needed:
Goffi <goffi@goffi.org>
parents:
3046
diff
changeset
|
814 pwd = await self.ainput(msg=msg) |
9839ce068140
jp: password is now prompted if needed:
Goffi <goffi@goffi.org>
parents:
3046
diff
changeset
|
815 finally: |
9839ce068140
jp: password is now prompted if needed:
Goffi <goffi@goffi.org>
parents:
3046
diff
changeset
|
816 termios.tcsetattr(stdin_fd, tcsetattr_flags, old) |
9839ce068140
jp: password is now prompted if needed:
Goffi <goffi@goffi.org>
parents:
3046
diff
changeset
|
817 sys.stderr.flush() |
9839ce068140
jp: password is now prompted if needed:
Goffi <goffi@goffi.org>
parents:
3046
diff
changeset
|
818 self.disp('') |
9839ce068140
jp: password is now prompted if needed:
Goffi <goffi@goffi.org>
parents:
3046
diff
changeset
|
819 return pwd |
9839ce068140
jp: password is now prompted if needed:
Goffi <goffi@goffi.org>
parents:
3046
diff
changeset
|
820 |
9839ce068140
jp: password is now prompted if needed:
Goffi <goffi@goffi.org>
parents:
3046
diff
changeset
|
821 async def connectOrPrompt(self, method, err_msg=None): |
9839ce068140
jp: password is now prompted if needed:
Goffi <goffi@goffi.org>
parents:
3046
diff
changeset
|
822 """Try to connect/start profile session and prompt for password if needed |
9839ce068140
jp: password is now prompted if needed:
Goffi <goffi@goffi.org>
parents:
3046
diff
changeset
|
823 |
9839ce068140
jp: password is now prompted if needed:
Goffi <goffi@goffi.org>
parents:
3046
diff
changeset
|
824 @param method(callable): bridge method to either connect or start profile session |
9839ce068140
jp: password is now prompted if needed:
Goffi <goffi@goffi.org>
parents:
3046
diff
changeset
|
825 It will be called with password as sole argument, use lambda to do the call |
9839ce068140
jp: password is now prompted if needed:
Goffi <goffi@goffi.org>
parents:
3046
diff
changeset
|
826 properly |
9839ce068140
jp: password is now prompted if needed:
Goffi <goffi@goffi.org>
parents:
3046
diff
changeset
|
827 @param err_msg(str): message to show if connection fail |
9839ce068140
jp: password is now prompted if needed:
Goffi <goffi@goffi.org>
parents:
3046
diff
changeset
|
828 """ |
9839ce068140
jp: password is now prompted if needed:
Goffi <goffi@goffi.org>
parents:
3046
diff
changeset
|
829 password = self.args.pwd |
9839ce068140
jp: password is now prompted if needed:
Goffi <goffi@goffi.org>
parents:
3046
diff
changeset
|
830 while True: |
9839ce068140
jp: password is now prompted if needed:
Goffi <goffi@goffi.org>
parents:
3046
diff
changeset
|
831 try: |
9839ce068140
jp: password is now prompted if needed:
Goffi <goffi@goffi.org>
parents:
3046
diff
changeset
|
832 await method(password or '') |
9839ce068140
jp: password is now prompted if needed:
Goffi <goffi@goffi.org>
parents:
3046
diff
changeset
|
833 except Exception as e: |
9839ce068140
jp: password is now prompted if needed:
Goffi <goffi@goffi.org>
parents:
3046
diff
changeset
|
834 if ((isinstance(e, BridgeException) |
9839ce068140
jp: password is now prompted if needed:
Goffi <goffi@goffi.org>
parents:
3046
diff
changeset
|
835 and e.classname == 'PasswordError' |
9839ce068140
jp: password is now prompted if needed:
Goffi <goffi@goffi.org>
parents:
3046
diff
changeset
|
836 and self.args.pwd is None)): |
9839ce068140
jp: password is now prompted if needed:
Goffi <goffi@goffi.org>
parents:
3046
diff
changeset
|
837 if password is not None: |
9839ce068140
jp: password is now prompted if needed:
Goffi <goffi@goffi.org>
parents:
3046
diff
changeset
|
838 self.disp(A.color(C.A_WARNING, _("invalid password"))) |
9839ce068140
jp: password is now prompted if needed:
Goffi <goffi@goffi.org>
parents:
3046
diff
changeset
|
839 password = await self.a_pwd_input( |
9839ce068140
jp: password is now prompted if needed:
Goffi <goffi@goffi.org>
parents:
3046
diff
changeset
|
840 _("please enter profile password:")) |
9839ce068140
jp: password is now prompted if needed:
Goffi <goffi@goffi.org>
parents:
3046
diff
changeset
|
841 else: |
9839ce068140
jp: password is now prompted if needed:
Goffi <goffi@goffi.org>
parents:
3046
diff
changeset
|
842 self.disp(err_msg.format(profile=self.profile, e=e), error=True) |
9839ce068140
jp: password is now prompted if needed:
Goffi <goffi@goffi.org>
parents:
3046
diff
changeset
|
843 self.quit(C.EXIT_ERROR) |
9839ce068140
jp: password is now prompted if needed:
Goffi <goffi@goffi.org>
parents:
3046
diff
changeset
|
844 else: |
9839ce068140
jp: password is now prompted if needed:
Goffi <goffi@goffi.org>
parents:
3046
diff
changeset
|
845 break |
9839ce068140
jp: password is now prompted if needed:
Goffi <goffi@goffi.org>
parents:
3046
diff
changeset
|
846 |
3040 | 847 async def connect_profile(self): |
848 """Check if the profile is connected and do it if requested | |
1401
265ff2bd8d67
jp: fixed crash on commands using profile without "connect" option
Goffi <goffi@goffi.org>
parents:
1396
diff
changeset
|
849 |
817 | 850 @exit: - 1 when profile is not connected and --connect is not set |
851 - 1 when the profile doesn't exists | |
852 - 1 when there is a connection error | |
853 """ | |
854 # FIXME: need better exit codes | |
855 | |
3040 | 856 self.profile = await self.bridge.profileNameGet(self.args.profile) |
0 | 857 |
817 | 858 if not self.profile: |
3568
04283582966f
core, frontends: fix invalid translatable strings.
Goffi <goffi@goffi.org>
parents:
3555
diff
changeset
|
859 log.error( |
04283582966f
core, frontends: fix invalid translatable strings.
Goffi <goffi@goffi.org>
parents:
3555
diff
changeset
|
860 _("The profile [{profile}] doesn't exist") |
04283582966f
core, frontends: fix invalid translatable strings.
Goffi <goffi@goffi.org>
parents:
3555
diff
changeset
|
861 .format(profile=self.args.profile) |
04283582966f
core, frontends: fix invalid translatable strings.
Goffi <goffi@goffi.org>
parents:
3555
diff
changeset
|
862 ) |
3040 | 863 self.quit(C.EXIT_ERROR) |
817 | 864 |
1594
313f2bb7841b
jp: profile session can now be started without connection:
Goffi <goffi@goffi.org>
parents:
1588
diff
changeset
|
865 try: |
313f2bb7841b
jp: profile session can now be started without connection:
Goffi <goffi@goffi.org>
parents:
1588
diff
changeset
|
866 start_session = self.args.start_session |
313f2bb7841b
jp: profile session can now be started without connection:
Goffi <goffi@goffi.org>
parents:
1588
diff
changeset
|
867 except AttributeError: |
313f2bb7841b
jp: profile session can now be started without connection:
Goffi <goffi@goffi.org>
parents:
1588
diff
changeset
|
868 pass |
313f2bb7841b
jp: profile session can now be started without connection:
Goffi <goffi@goffi.org>
parents:
1588
diff
changeset
|
869 else: |
313f2bb7841b
jp: profile session can now be started without connection:
Goffi <goffi@goffi.org>
parents:
1588
diff
changeset
|
870 if start_session: |
3049
9839ce068140
jp: password is now prompted if needed:
Goffi <goffi@goffi.org>
parents:
3046
diff
changeset
|
871 await self.connectOrPrompt( |
9839ce068140
jp: password is now prompted if needed:
Goffi <goffi@goffi.org>
parents:
3046
diff
changeset
|
872 lambda pwd: self.bridge.profileStartSession(pwd, self.profile), |
9839ce068140
jp: password is now prompted if needed:
Goffi <goffi@goffi.org>
parents:
3046
diff
changeset
|
873 err_msg="Can't start {profile}'s session: {e}" |
9839ce068140
jp: password is now prompted if needed:
Goffi <goffi@goffi.org>
parents:
3046
diff
changeset
|
874 ) |
1594
313f2bb7841b
jp: profile session can now be started without connection:
Goffi <goffi@goffi.org>
parents:
1588
diff
changeset
|
875 return |
3040 | 876 elif not await self.bridge.profileIsSessionStarted(self.profile): |
1594
313f2bb7841b
jp: profile session can now be started without connection:
Goffi <goffi@goffi.org>
parents:
1588
diff
changeset
|
877 if not self.args.connect: |
3040 | 878 self.disp(_( |
3568
04283582966f
core, frontends: fix invalid translatable strings.
Goffi <goffi@goffi.org>
parents:
3555
diff
changeset
|
879 "Session for [{profile}] is not started, please start it " |
04283582966f
core, frontends: fix invalid translatable strings.
Goffi <goffi@goffi.org>
parents:
3555
diff
changeset
|
880 "before using jp, or use either --start-session or --connect " |
04283582966f
core, frontends: fix invalid translatable strings.
Goffi <goffi@goffi.org>
parents:
3555
diff
changeset
|
881 "option" |
04283582966f
core, frontends: fix invalid translatable strings.
Goffi <goffi@goffi.org>
parents:
3555
diff
changeset
|
882 .format(profile=self.profile) |
04283582966f
core, frontends: fix invalid translatable strings.
Goffi <goffi@goffi.org>
parents:
3555
diff
changeset
|
883 ), error=True) |
1594
313f2bb7841b
jp: profile session can now be started without connection:
Goffi <goffi@goffi.org>
parents:
1588
diff
changeset
|
884 self.quit(1) |
2692
7d4679ee7ded
jp (base): fixed connection when start_session arg exists but is False
Goffi <goffi@goffi.org>
parents:
2672
diff
changeset
|
885 elif not getattr(self.args, "connect", False): |
1594
313f2bb7841b
jp: profile session can now be started without connection:
Goffi <goffi@goffi.org>
parents:
1588
diff
changeset
|
886 return |
313f2bb7841b
jp: profile session can now be started without connection:
Goffi <goffi@goffi.org>
parents:
1588
diff
changeset
|
887 |
313f2bb7841b
jp: profile session can now be started without connection:
Goffi <goffi@goffi.org>
parents:
1588
diff
changeset
|
888 |
1401
265ff2bd8d67
jp: fixed crash on commands using profile without "connect" option
Goffi <goffi@goffi.org>
parents:
1396
diff
changeset
|
889 if not hasattr(self.args, 'connect'): |
3040 | 890 # a profile can be present without connect option (e.g. on profile |
891 # creation/deletion) | |
1401
265ff2bd8d67
jp: fixed crash on commands using profile without "connect" option
Goffi <goffi@goffi.org>
parents:
1396
diff
changeset
|
892 return |
1588
823a385235ef
jp: fixed bad --connect option check
Goffi <goffi@goffi.org>
parents:
1544
diff
changeset
|
893 elif self.args.connect is True: # if connection is asked, we connect the profile |
3049
9839ce068140
jp: password is now prompted if needed:
Goffi <goffi@goffi.org>
parents:
3046
diff
changeset
|
894 await self.connectOrPrompt( |
9839ce068140
jp: password is now prompted if needed:
Goffi <goffi@goffi.org>
parents:
3046
diff
changeset
|
895 lambda pwd: self.bridge.connect(self.profile, pwd, {}), |
9839ce068140
jp: password is now prompted if needed:
Goffi <goffi@goffi.org>
parents:
3046
diff
changeset
|
896 err_msg = 'Can\'t connect profile "{profile!s}": {e}' |
9839ce068140
jp: password is now prompted if needed:
Goffi <goffi@goffi.org>
parents:
3046
diff
changeset
|
897 ) |
814 | 898 return |
1594
313f2bb7841b
jp: profile session can now be started without connection:
Goffi <goffi@goffi.org>
parents:
1588
diff
changeset
|
899 else: |
3040 | 900 if not await self.bridge.isConnected(self.profile): |
901 log.error( | |
3568
04283582966f
core, frontends: fix invalid translatable strings.
Goffi <goffi@goffi.org>
parents:
3555
diff
changeset
|
902 _("Profile [{profile}] is not connected, please connect it " |
04283582966f
core, frontends: fix invalid translatable strings.
Goffi <goffi@goffi.org>
parents:
3555
diff
changeset
|
903 "before using jp, or use --connect option") |
04283582966f
core, frontends: fix invalid translatable strings.
Goffi <goffi@goffi.org>
parents:
3555
diff
changeset
|
904 .format(profile=self.profile) |
04283582966f
core, frontends: fix invalid translatable strings.
Goffi <goffi@goffi.org>
parents:
3555
diff
changeset
|
905 ) |
1594
313f2bb7841b
jp: profile session can now be started without connection:
Goffi <goffi@goffi.org>
parents:
1588
diff
changeset
|
906 self.quit(1) |
0 | 907 |
3040 | 908 async def get_full_jid(self, param_jid): |
1290
faa1129559b8
core, frontends: refactoring to base Libervia on QuickFrontend (big mixed commit):
Goffi <goffi@goffi.org>
parents:
1139
diff
changeset
|
909 """Return the full jid if possible (add main resource when find a bare jid)""" |
3408
19bc03743aeb
jp (file/send): don't add main resource to bare jid anymore:
Goffi <goffi@goffi.org>
parents:
3407
diff
changeset
|
910 # TODO: to be removed, bare jid should work with all commands, notably for file |
19bc03743aeb
jp (file/send): don't add main resource to bare jid anymore:
Goffi <goffi@goffi.org>
parents:
3407
diff
changeset
|
911 # as backend now handle jingles message initiation |
401
b2caa2615c4c
jp roster name manegement + Pipe transfer
Goffi <goffi@goffi.org>
parents:
393
diff
changeset
|
912 _jid = JID(param_jid) |
b2caa2615c4c
jp roster name manegement + Pipe transfer
Goffi <goffi@goffi.org>
parents:
393
diff
changeset
|
913 if not _jid.resource: |
1606
de785fcf9a7b
jp (base, file): file command and progress fixes and adaptation to new API:
Goffi <goffi@goffi.org>
parents:
1605
diff
changeset
|
914 #if the resource is not given, we try to add the main resource |
3040 | 915 main_resource = await self.bridge.getMainResource(param_jid, self.profile) |
1606
de785fcf9a7b
jp (base, file): file command and progress fixes and adaptation to new API:
Goffi <goffi@goffi.org>
parents:
1605
diff
changeset
|
916 if main_resource: |
3040 | 917 return f"{_jid.bare}/{main_resource}" |
401
b2caa2615c4c
jp roster name manegement + Pipe transfer
Goffi <goffi@goffi.org>
parents:
393
diff
changeset
|
918 return param_jid |
b2caa2615c4c
jp roster name manegement + Pipe transfer
Goffi <goffi@goffi.org>
parents:
393
diff
changeset
|
919 |
814 | 920 |
817 | 921 class CommandBase(object): |
814 | 922 |
2155 | 923 def __init__(self, host, name, use_profile=True, use_output=False, extra_outputs=None, |
1950 | 924 need_connect=None, help=None, **kwargs): |
2098
e0066920a661
primitivus, jp: dynamic bridge + fixed D-Bus bridge:
Goffi <goffi@goffi.org>
parents:
2086
diff
changeset
|
925 """Initialise CommandBase |
e0066920a661
primitivus, jp: dynamic bridge + fixed D-Bus bridge:
Goffi <goffi@goffi.org>
parents:
2086
diff
changeset
|
926 |
817 | 927 @param host: Jp instance |
1594
313f2bb7841b
jp: profile session can now be started without connection:
Goffi <goffi@goffi.org>
parents:
1588
diff
changeset
|
928 @param name(unicode): name of the new command |
313f2bb7841b
jp: profile session can now be started without connection:
Goffi <goffi@goffi.org>
parents:
1588
diff
changeset
|
929 @param use_profile(bool): if True, add profile selection/connection commands |
2114
dc5d214f0a3b
jp (info/session): added a command to get data on current session
Goffi <goffi@goffi.org>
parents:
2098
diff
changeset
|
930 @param use_output(bool, unicode): if not False, add --output option |
2155 | 931 @param extra_outputs(dict): list of command specific outputs: |
932 key is output name ("default" to use as main output) | |
3040 | 933 value is a callable which will format the output (data will be used as only |
934 argument) | |
2155 | 935 if a key already exists with normal outputs, the extra one will be used |
1594
313f2bb7841b
jp: profile session can now be started without connection:
Goffi <goffi@goffi.org>
parents:
1588
diff
changeset
|
936 @param need_connect(bool, None): True if profile connection is needed |
313f2bb7841b
jp: profile session can now be started without connection:
Goffi <goffi@goffi.org>
parents:
1588
diff
changeset
|
937 False else (profile session must still be started) |
313f2bb7841b
jp: profile session can now be started without connection:
Goffi <goffi@goffi.org>
parents:
1588
diff
changeset
|
938 None to set auto value (i.e. True if use_profile is set) |
313f2bb7841b
jp: profile session can now be started without connection:
Goffi <goffi@goffi.org>
parents:
1588
diff
changeset
|
939 Can't be set if use_profile is False |
313f2bb7841b
jp: profile session can now be started without connection:
Goffi <goffi@goffi.org>
parents:
1588
diff
changeset
|
940 @param help(unicode): help message to display |
817 | 941 @param **kwargs: args passed to ArgumentParser |
1950 | 942 use_* are handled directly, they can be: |
943 - use_progress(bool): if True, add progress bar activation option | |
944 progress* signals will be handled | |
945 - use_verbose(bool): if True, add verbosity option | |
2532 | 946 - use_pubsub(bool): if True, add pubsub options |
947 mandatory arguments are controlled by pubsub_req | |
948 - use_draft(bool): if True, add draft handling options | |
949 ** other arguments ** | |
3040 | 950 - pubsub_flags(iterable[unicode]): tuple of flags to set pubsub options, |
951 can be: | |
2532 | 952 C.SERVICE: service is required |
953 C.NODE: node is required | |
2614
a5b96950b81a
jp (event): fixed crash on missing item in get and inviteeGet by making it mandatory.
Goffi <goffi@goffi.org>
parents:
2609
diff
changeset
|
954 C.ITEM: item is required |
2532 | 955 C.SINGLE_ITEM: only one item is allowed |
814 | 956 """ |
817 | 957 try: # If we have subcommands, host is a CommandBase and we need to use host.host |
958 self.host = host.host | |
959 except AttributeError: | |
960 self.host = host | |
961 | |
1950 | 962 # --profile option |
817 | 963 parents = kwargs.setdefault('parents', set()) |
964 if use_profile: | |
3040 | 965 # self.host.parents['profile'] is an ArgumentParser with profile connection |
966 # arguments | |
1594
313f2bb7841b
jp: profile session can now be started without connection:
Goffi <goffi@goffi.org>
parents:
1588
diff
changeset
|
967 if need_connect is None: |
313f2bb7841b
jp: profile session can now be started without connection:
Goffi <goffi@goffi.org>
parents:
1588
diff
changeset
|
968 need_connect = True |
3040 | 969 parents.add( |
970 self.host.parents['profile' if need_connect else 'profile_session']) | |
1594
313f2bb7841b
jp: profile session can now be started without connection:
Goffi <goffi@goffi.org>
parents:
1588
diff
changeset
|
971 else: |
313f2bb7841b
jp: profile session can now be started without connection:
Goffi <goffi@goffi.org>
parents:
1588
diff
changeset
|
972 assert need_connect is None |
1860
afc7f6328394
jp (base): use need_connect attribue to detect if connection is needed instead of self.args.profile, as profile argument can be used by any command even if use_profile is False
Goffi <goffi@goffi.org>
parents:
1840
diff
changeset
|
973 self.need_connect = need_connect |
afc7f6328394
jp (base): use need_connect attribue to detect if connection is needed instead of self.args.profile, as profile argument can be used by any command even if use_profile is False
Goffi <goffi@goffi.org>
parents:
1840
diff
changeset
|
974 # from this point, self.need_connect is None if connection is not needed at all |
afc7f6328394
jp (base): use need_connect attribue to detect if connection is needed instead of self.args.profile, as profile argument can be used by any command even if use_profile is False
Goffi <goffi@goffi.org>
parents:
1840
diff
changeset
|
975 # False if session starting is needed, and True if full connection is needed |
1594
313f2bb7841b
jp: profile session can now be started without connection:
Goffi <goffi@goffi.org>
parents:
1588
diff
changeset
|
976 |
1950 | 977 # --output option |
978 if use_output: | |
2155 | 979 if extra_outputs is None: |
980 extra_outputs = {} | |
981 self.extra_outputs = extra_outputs | |
1950 | 982 if use_output == True: |
983 use_output = C.OUTPUT_TEXT | |
984 assert use_output in C.OUTPUT_TYPES | |
985 self._output_type = use_output | |
986 output_parent = argparse.ArgumentParser(add_help=False) | |
2155 | 987 choices = set(self.host.getOutputChoices(use_output)) |
988 choices.update(extra_outputs) | |
1950 | 989 if not choices: |
3040 | 990 raise exceptions.InternalError( |
991 "No choice found for {} output type".format(use_output)) | |
2189
a25a256688e2
jp (base): output can now specify a default when registering
Goffi <goffi@goffi.org>
parents:
2188
diff
changeset
|
992 try: |
a25a256688e2
jp (base): output can now specify a default when registering
Goffi <goffi@goffi.org>
parents:
2188
diff
changeset
|
993 default = self.host.default_output[use_output] |
a25a256688e2
jp (base): output can now specify a default when registering
Goffi <goffi@goffi.org>
parents:
2188
diff
changeset
|
994 except KeyError: |
3028 | 995 if 'default' in choices: |
996 default = 'default' | |
997 elif 'simple' in choices: | |
998 default = 'simple' | |
2189
a25a256688e2
jp (base): output can now specify a default when registering
Goffi <goffi@goffi.org>
parents:
2188
diff
changeset
|
999 else: |
a25a256688e2
jp (base): output can now specify a default when registering
Goffi <goffi@goffi.org>
parents:
2188
diff
changeset
|
1000 default = list(choices)[0] |
3040 | 1001 output_parent.add_argument( |
1002 '--output', '-O', choices=sorted(choices), default=default, | |
1003 help=_("select output format (default: {})".format(default))) | |
1004 output_parent.add_argument( | |
1005 '--output-option', '--oo', action="append", dest='output_opts', | |
1006 default=[], help=_("output specific option")) | |
1950 | 1007 parents.add(output_parent) |
2155 | 1008 else: |
1009 assert extra_outputs is None | |
817 | 1010 |
2532 | 1011 self._use_pubsub = kwargs.pop('use_pubsub', False) |
1012 if self._use_pubsub: | |
2538
0a22dc80d671
jp (base): fixed use_pubsub when pubsub_flags is not needed
Goffi <goffi@goffi.org>
parents:
2532
diff
changeset
|
1013 flags = kwargs.pop('pubsub_flags', []) |
2547
2d69a0afe039
jp: new argument pubsub_default can be used in Commands to replace default value in help string
Goffi <goffi@goffi.org>
parents:
2539
diff
changeset
|
1014 defaults = kwargs.pop('pubsub_defaults', {}) |
2d69a0afe039
jp: new argument pubsub_default can be used in Commands to replace default value in help string
Goffi <goffi@goffi.org>
parents:
2539
diff
changeset
|
1015 parents.add(self.host.make_pubsub_group(flags, defaults)) |
2532 | 1016 self._pubsub_flags = flags |
2235
4db836386641
jp: added use_pubsub and use_pubsub_node_req arguments to CommandBase
Goffi <goffi@goffi.org>
parents:
2213
diff
changeset
|
1017 |
1950 | 1018 # other common options |
3028 | 1019 use_opts = {k:v for k,v in kwargs.items() if k.startswith('use_')} |
1020 for param, do_use in use_opts.items(): | |
1950 | 1021 opt=param[4:] # if param is use_verbose, opt is verbose |
1022 if opt not in self.host.parents: | |
3028 | 1023 raise exceptions.InternalError("Unknown parent option {}".format(opt)) |
1950 | 1024 del kwargs[param] |
1025 if do_use: | |
1026 parents.add(self.host.parents[opt]) | |
1600 | 1027 |
817 | 1028 self.parser = host.subparsers.add_parser(name, help=help, **kwargs) |
1029 if hasattr(self, "subcommands"): | |
3040 | 1030 self.subparsers = self.parser.add_subparsers(dest='subcommand', required=True) |
817 | 1031 else: |
2532 | 1032 self.parser.set_defaults(_cmd=self) |
817 | 1033 self.add_parser_options() |
1034 | |
1035 @property | |
3046 | 1036 def sat_conf(self): |
1037 return self.host.sat_conf | |
1038 | |
1039 @property | |
817 | 1040 def args(self): |
1041 return self.host.args | |
1042 | |
1043 @property | |
1044 def profile(self): | |
1045 return self.host.profile | |
1046 | |
1047 @property | |
2490
b4bf282d6354
jp (base): added verbosity property to CommandBase
Goffi <goffi@goffi.org>
parents:
2486
diff
changeset
|
1048 def verbosity(self): |
b4bf282d6354
jp (base): added verbosity property to CommandBase
Goffi <goffi@goffi.org>
parents:
2486
diff
changeset
|
1049 return self.host.verbosity |
b4bf282d6354
jp (base): added verbosity property to CommandBase
Goffi <goffi@goffi.org>
parents:
2486
diff
changeset
|
1050 |
b4bf282d6354
jp (base): added verbosity property to CommandBase
Goffi <goffi@goffi.org>
parents:
2486
diff
changeset
|
1051 @property |
817 | 1052 def progress_id(self): |
1053 return self.host.progress_id | |
814 | 1054 |
3040 | 1055 async def set_progress_id(self, progress_id): |
1056 return await self.host.set_progress_id(progress_id) | |
817 | 1057 |
3040 | 1058 async def progressStartedHandler(self, uid, metadata, profile): |
1627
5a641e7b858a
jp (base, file): use of new progress API. Progress callbacks are managed through CommandBase.onProgress* method instead of host attributes.
Goffi <goffi@goffi.org>
parents:
1623
diff
changeset
|
1059 if profile != self.profile: |
5a641e7b858a
jp (base, file): use of new progress API. Progress callbacks are managed through CommandBase.onProgress* method instead of host attributes.
Goffi <goffi@goffi.org>
parents:
1623
diff
changeset
|
1060 return |
1642
7ec7ce9cdc4c
jp (base): progressStarted signals are cached until progress_id is known, this avoid missing the progression if we have the signal before the id.
Goffi <goffi@goffi.org>
parents:
1641
diff
changeset
|
1061 if self.progress_id is None: |
7ec7ce9cdc4c
jp (base): progressStarted signals are cached until progress_id is known, this avoid missing the progression if we have the signal before the id.
Goffi <goffi@goffi.org>
parents:
1641
diff
changeset
|
1062 # the progress started message can be received before the id |
7ec7ce9cdc4c
jp (base): progressStarted signals are cached until progress_id is known, this avoid missing the progression if we have the signal before the id.
Goffi <goffi@goffi.org>
parents:
1641
diff
changeset
|
1063 # so we keep progressStarted signals in cache to replay they |
7ec7ce9cdc4c
jp (base): progressStarted signals are cached until progress_id is known, this avoid missing the progression if we have the signal before the id.
Goffi <goffi@goffi.org>
parents:
1641
diff
changeset
|
1064 # when the progress_id is received |
7ec7ce9cdc4c
jp (base): progressStarted signals are cached until progress_id is known, this avoid missing the progression if we have the signal before the id.
Goffi <goffi@goffi.org>
parents:
1641
diff
changeset
|
1065 cache_data = (self.progressStartedHandler, uid, metadata, profile) |
7ec7ce9cdc4c
jp (base): progressStarted signals are cached until progress_id is known, this avoid missing the progression if we have the signal before the id.
Goffi <goffi@goffi.org>
parents:
1641
diff
changeset
|
1066 try: |
3040 | 1067 cache = self.host.progress_ids_cache |
1642
7ec7ce9cdc4c
jp (base): progressStarted signals are cached until progress_id is known, this avoid missing the progression if we have the signal before the id.
Goffi <goffi@goffi.org>
parents:
1641
diff
changeset
|
1068 except AttributeError: |
3040 | 1069 cache = self.host.progress_ids_cache = [] |
1070 cache.append(cache_data) | |
1642
7ec7ce9cdc4c
jp (base): progressStarted signals are cached until progress_id is known, this avoid missing the progression if we have the signal before the id.
Goffi <goffi@goffi.org>
parents:
1641
diff
changeset
|
1071 else: |
7ec7ce9cdc4c
jp (base): progressStarted signals are cached until progress_id is known, this avoid missing the progression if we have the signal before the id.
Goffi <goffi@goffi.org>
parents:
1641
diff
changeset
|
1072 if self.host.watch_progress and uid == self.progress_id: |
3040 | 1073 await self.onProgressStarted(metadata) |
1074 while True: | |
1075 await asyncio.sleep(PROGRESS_DELAY) | |
1076 cont = await self.progressUpdate() | |
1077 if not cont: | |
1078 break | |
1627
5a641e7b858a
jp (base, file): use of new progress API. Progress callbacks are managed through CommandBase.onProgress* method instead of host attributes.
Goffi <goffi@goffi.org>
parents:
1623
diff
changeset
|
1079 |
3040 | 1080 async def progressFinishedHandler(self, uid, metadata, profile): |
1627
5a641e7b858a
jp (base, file): use of new progress API. Progress callbacks are managed through CommandBase.onProgress* method instead of host attributes.
Goffi <goffi@goffi.org>
parents:
1623
diff
changeset
|
1081 if profile != self.profile: |
5a641e7b858a
jp (base, file): use of new progress API. Progress callbacks are managed through CommandBase.onProgress* method instead of host attributes.
Goffi <goffi@goffi.org>
parents:
1623
diff
changeset
|
1082 return |
5a641e7b858a
jp (base, file): use of new progress API. Progress callbacks are managed through CommandBase.onProgress* method instead of host attributes.
Goffi <goffi@goffi.org>
parents:
1623
diff
changeset
|
1083 if uid == self.progress_id: |
5a641e7b858a
jp (base, file): use of new progress API. Progress callbacks are managed through CommandBase.onProgress* method instead of host attributes.
Goffi <goffi@goffi.org>
parents:
1623
diff
changeset
|
1084 try: |
5a641e7b858a
jp (base, file): use of new progress API. Progress callbacks are managed through CommandBase.onProgress* method instead of host attributes.
Goffi <goffi@goffi.org>
parents:
1623
diff
changeset
|
1085 self.host.pbar.finish() |
5a641e7b858a
jp (base, file): use of new progress API. Progress callbacks are managed through CommandBase.onProgress* method instead of host attributes.
Goffi <goffi@goffi.org>
parents:
1623
diff
changeset
|
1086 except AttributeError: |
5a641e7b858a
jp (base, file): use of new progress API. Progress callbacks are managed through CommandBase.onProgress* method instead of host attributes.
Goffi <goffi@goffi.org>
parents:
1623
diff
changeset
|
1087 pass |
3040 | 1088 await self.onProgressFinished(metadata) |
1627
5a641e7b858a
jp (base, file): use of new progress API. Progress callbacks are managed through CommandBase.onProgress* method instead of host attributes.
Goffi <goffi@goffi.org>
parents:
1623
diff
changeset
|
1089 if self.host.quit_on_progress_end: |
1918
01d56efd488b
jp: fixed traceback shown on a normal quit when a progression is finished
Goffi <goffi@goffi.org>
parents:
1884
diff
changeset
|
1090 self.host.quitFromSignal() |
1627
5a641e7b858a
jp (base, file): use of new progress API. Progress callbacks are managed through CommandBase.onProgress* method instead of host attributes.
Goffi <goffi@goffi.org>
parents:
1623
diff
changeset
|
1091 |
3040 | 1092 async def progressErrorHandler(self, uid, message, profile): |
1627
5a641e7b858a
jp (base, file): use of new progress API. Progress callbacks are managed through CommandBase.onProgress* method instead of host attributes.
Goffi <goffi@goffi.org>
parents:
1623
diff
changeset
|
1093 if profile != self.profile: |
5a641e7b858a
jp (base, file): use of new progress API. Progress callbacks are managed through CommandBase.onProgress* method instead of host attributes.
Goffi <goffi@goffi.org>
parents:
1623
diff
changeset
|
1094 return |
5a641e7b858a
jp (base, file): use of new progress API. Progress callbacks are managed through CommandBase.onProgress* method instead of host attributes.
Goffi <goffi@goffi.org>
parents:
1623
diff
changeset
|
1095 if uid == self.progress_id: |
1641
44a14f83e64b
jp (base): fixed verbose option + there is a new line on ProgressErrorHandler only if the progress bar is actually displayed
Goffi <goffi@goffi.org>
parents:
1627
diff
changeset
|
1096 if self.args.progress: |
44a14f83e64b
jp (base): fixed verbose option + there is a new line on ProgressErrorHandler only if the progress bar is actually displayed
Goffi <goffi@goffi.org>
parents:
1627
diff
changeset
|
1097 self.disp('') # progress is not finished, so we skip a line |
1627
5a641e7b858a
jp (base, file): use of new progress API. Progress callbacks are managed through CommandBase.onProgress* method instead of host attributes.
Goffi <goffi@goffi.org>
parents:
1623
diff
changeset
|
1098 if self.host.quit_on_progress_end: |
3040 | 1099 await self.onProgressError(message) |
1100 self.host.quitFromSignal(C.EXIT_ERROR) | |
1627
5a641e7b858a
jp (base, file): use of new progress API. Progress callbacks are managed through CommandBase.onProgress* method instead of host attributes.
Goffi <goffi@goffi.org>
parents:
1623
diff
changeset
|
1101 |
3040 | 1102 async def progressUpdate(self): |
1103 """This method is continualy called to update the progress bar | |
1104 | |
1105 @return (bool): False to stop being called | |
1106 """ | |
1107 data = await self.host.bridge.progressGet(self.progress_id, self.profile) | |
1832
39545dc527a1
jp: an onProgressUpdate method is now called on each progress update, allowing to handle metadata
Goffi <goffi@goffi.org>
parents:
1766
diff
changeset
|
1108 if data: |
39545dc527a1
jp: an onProgressUpdate method is now called on each progress update, allowing to handle metadata
Goffi <goffi@goffi.org>
parents:
1766
diff
changeset
|
1109 try: |
39545dc527a1
jp: an onProgressUpdate method is now called on each progress update, allowing to handle metadata
Goffi <goffi@goffi.org>
parents:
1766
diff
changeset
|
1110 size = data['size'] |
39545dc527a1
jp: an onProgressUpdate method is now called on each progress update, allowing to handle metadata
Goffi <goffi@goffi.org>
parents:
1766
diff
changeset
|
1111 except KeyError: |
3040 | 1112 self.disp(_("file size is not known, we can't show a progress bar"), 1, |
1113 error=True) | |
1832
39545dc527a1
jp: an onProgressUpdate method is now called on each progress update, allowing to handle metadata
Goffi <goffi@goffi.org>
parents:
1766
diff
changeset
|
1114 return False |
39545dc527a1
jp: an onProgressUpdate method is now called on each progress update, allowing to handle metadata
Goffi <goffi@goffi.org>
parents:
1766
diff
changeset
|
1115 if self.host.pbar is None: |
39545dc527a1
jp: an onProgressUpdate method is now called on each progress update, allowing to handle metadata
Goffi <goffi@goffi.org>
parents:
1766
diff
changeset
|
1116 #first answer, we must construct the bar |
3040 | 1117 |
1118 # if the instance has a pbar_template attribute, it is used has model, | |
1119 # else default one is used | |
1120 # template is a list of part, where part can be either a str to show directly | |
1121 # or a list where first argument is a name of a progressbar widget, and others | |
1122 # are used as widget arguments | |
1123 try: | |
1124 template = self.pbar_template | |
1125 except AttributeError: | |
1126 template = [ | |
1127 _("Progress: "), ["Percentage"], " ", ["Bar"], " ", | |
1128 ["FileTransferSpeed"], " ", ["ETA"] | |
1129 ] | |
1130 | |
1131 widgets = [] | |
1132 for part in template: | |
1133 if isinstance(part, str): | |
1134 widgets.append(part) | |
1135 else: | |
1136 widget = getattr(progressbar, part.pop(0)) | |
1137 widgets.append(widget(*part)) | |
1138 | |
1139 self.host.pbar = progressbar.ProgressBar(max_value=int(size), widgets=widgets) | |
1832
39545dc527a1
jp: an onProgressUpdate method is now called on each progress update, allowing to handle metadata
Goffi <goffi@goffi.org>
parents:
1766
diff
changeset
|
1140 self.host.pbar.start() |
39545dc527a1
jp: an onProgressUpdate method is now called on each progress update, allowing to handle metadata
Goffi <goffi@goffi.org>
parents:
1766
diff
changeset
|
1141 |
39545dc527a1
jp: an onProgressUpdate method is now called on each progress update, allowing to handle metadata
Goffi <goffi@goffi.org>
parents:
1766
diff
changeset
|
1142 self.host.pbar.update(int(data['position'])) |
39545dc527a1
jp: an onProgressUpdate method is now called on each progress update, allowing to handle metadata
Goffi <goffi@goffi.org>
parents:
1766
diff
changeset
|
1143 |
39545dc527a1
jp: an onProgressUpdate method is now called on each progress update, allowing to handle metadata
Goffi <goffi@goffi.org>
parents:
1766
diff
changeset
|
1144 elif self.host.pbar is not None: |
39545dc527a1
jp: an onProgressUpdate method is now called on each progress update, allowing to handle metadata
Goffi <goffi@goffi.org>
parents:
1766
diff
changeset
|
1145 return False |
39545dc527a1
jp: an onProgressUpdate method is now called on each progress update, allowing to handle metadata
Goffi <goffi@goffi.org>
parents:
1766
diff
changeset
|
1146 |
3040 | 1147 await self.onProgressUpdate(data) |
1832
39545dc527a1
jp: an onProgressUpdate method is now called on each progress update, allowing to handle metadata
Goffi <goffi@goffi.org>
parents:
1766
diff
changeset
|
1148 |
39545dc527a1
jp: an onProgressUpdate method is now called on each progress update, allowing to handle metadata
Goffi <goffi@goffi.org>
parents:
1766
diff
changeset
|
1149 return True |
39545dc527a1
jp: an onProgressUpdate method is now called on each progress update, allowing to handle metadata
Goffi <goffi@goffi.org>
parents:
1766
diff
changeset
|
1150 |
3040 | 1151 async def onProgressStarted(self, metadata): |
1832
39545dc527a1
jp: an onProgressUpdate method is now called on each progress update, allowing to handle metadata
Goffi <goffi@goffi.org>
parents:
1766
diff
changeset
|
1152 """Called when progress has just started |
39545dc527a1
jp: an onProgressUpdate method is now called on each progress update, allowing to handle metadata
Goffi <goffi@goffi.org>
parents:
1766
diff
changeset
|
1153 |
39545dc527a1
jp: an onProgressUpdate method is now called on each progress update, allowing to handle metadata
Goffi <goffi@goffi.org>
parents:
1766
diff
changeset
|
1154 can be overidden by a command |
39545dc527a1
jp: an onProgressUpdate method is now called on each progress update, allowing to handle metadata
Goffi <goffi@goffi.org>
parents:
1766
diff
changeset
|
1155 @param metadata(dict): metadata as sent by bridge.progressStarted |
39545dc527a1
jp: an onProgressUpdate method is now called on each progress update, allowing to handle metadata
Goffi <goffi@goffi.org>
parents:
1766
diff
changeset
|
1156 """ |
3028 | 1157 self.disp(_("Operation started"), 2) |
1627
5a641e7b858a
jp (base, file): use of new progress API. Progress callbacks are managed through CommandBase.onProgress* method instead of host attributes.
Goffi <goffi@goffi.org>
parents:
1623
diff
changeset
|
1158 |
3040 | 1159 async def onProgressUpdate(self, metadata): |
1832
39545dc527a1
jp: an onProgressUpdate method is now called on each progress update, allowing to handle metadata
Goffi <goffi@goffi.org>
parents:
1766
diff
changeset
|
1160 """Method called on each progress updata |
39545dc527a1
jp: an onProgressUpdate method is now called on each progress update, allowing to handle metadata
Goffi <goffi@goffi.org>
parents:
1766
diff
changeset
|
1161 |
39545dc527a1
jp: an onProgressUpdate method is now called on each progress update, allowing to handle metadata
Goffi <goffi@goffi.org>
parents:
1766
diff
changeset
|
1162 can be overidden by a command to handle progress metadata |
39545dc527a1
jp: an onProgressUpdate method is now called on each progress update, allowing to handle metadata
Goffi <goffi@goffi.org>
parents:
1766
diff
changeset
|
1163 @para metadata(dict): metadata as returned by bridge.progressGet |
39545dc527a1
jp: an onProgressUpdate method is now called on each progress update, allowing to handle metadata
Goffi <goffi@goffi.org>
parents:
1766
diff
changeset
|
1164 """ |
39545dc527a1
jp: an onProgressUpdate method is now called on each progress update, allowing to handle metadata
Goffi <goffi@goffi.org>
parents:
1766
diff
changeset
|
1165 pass |
39545dc527a1
jp: an onProgressUpdate method is now called on each progress update, allowing to handle metadata
Goffi <goffi@goffi.org>
parents:
1766
diff
changeset
|
1166 |
3040 | 1167 async def onProgressFinished(self, metadata): |
1832
39545dc527a1
jp: an onProgressUpdate method is now called on each progress update, allowing to handle metadata
Goffi <goffi@goffi.org>
parents:
1766
diff
changeset
|
1168 """Called when progress has just finished |
39545dc527a1
jp: an onProgressUpdate method is now called on each progress update, allowing to handle metadata
Goffi <goffi@goffi.org>
parents:
1766
diff
changeset
|
1169 |
39545dc527a1
jp: an onProgressUpdate method is now called on each progress update, allowing to handle metadata
Goffi <goffi@goffi.org>
parents:
1766
diff
changeset
|
1170 can be overidden by a command |
39545dc527a1
jp: an onProgressUpdate method is now called on each progress update, allowing to handle metadata
Goffi <goffi@goffi.org>
parents:
1766
diff
changeset
|
1171 @param metadata(dict): metadata as sent by bridge.progressFinished |
39545dc527a1
jp: an onProgressUpdate method is now called on each progress update, allowing to handle metadata
Goffi <goffi@goffi.org>
parents:
1766
diff
changeset
|
1172 """ |
3028 | 1173 self.disp(_("Operation successfully finished"), 2) |
1627
5a641e7b858a
jp (base, file): use of new progress API. Progress callbacks are managed through CommandBase.onProgress* method instead of host attributes.
Goffi <goffi@goffi.org>
parents:
1623
diff
changeset
|
1174 |
3040 | 1175 async def onProgressError(self, e): |
1832
39545dc527a1
jp: an onProgressUpdate method is now called on each progress update, allowing to handle metadata
Goffi <goffi@goffi.org>
parents:
1766
diff
changeset
|
1176 """Called when a progress failed |
39545dc527a1
jp: an onProgressUpdate method is now called on each progress update, allowing to handle metadata
Goffi <goffi@goffi.org>
parents:
1766
diff
changeset
|
1177 |
39545dc527a1
jp: an onProgressUpdate method is now called on each progress update, allowing to handle metadata
Goffi <goffi@goffi.org>
parents:
1766
diff
changeset
|
1178 @param error_msg(unicode): error message as sent by bridge.progressError |
39545dc527a1
jp: an onProgressUpdate method is now called on each progress update, allowing to handle metadata
Goffi <goffi@goffi.org>
parents:
1766
diff
changeset
|
1179 """ |
3568
04283582966f
core, frontends: fix invalid translatable strings.
Goffi <goffi@goffi.org>
parents:
3555
diff
changeset
|
1180 self.disp(_("Error while doing operation: {e}").format(e=e), error=True) |
1627
5a641e7b858a
jp (base, file): use of new progress API. Progress callbacks are managed through CommandBase.onProgress* method instead of host attributes.
Goffi <goffi@goffi.org>
parents:
1623
diff
changeset
|
1181 |
3407
2f0be2b7de68
jp: replace `no_lf` argument by `end` in `disp` (same as in `print`)
Goffi <goffi@goffi.org>
parents:
3378
diff
changeset
|
1182 def disp(self, msg, verbosity=0, error=False, end='\n'): |
2f0be2b7de68
jp: replace `no_lf` argument by `end` in `disp` (same as in `print`)
Goffi <goffi@goffi.org>
parents:
3378
diff
changeset
|
1183 return self.host.disp(msg, verbosity, error, end) |
1605
0aded9648c5c
jp (base): added a self.disp method which manage verbosity and stderr + verbosity property
Goffi <goffi@goffi.org>
parents:
1604
diff
changeset
|
1184 |
1950 | 1185 def output(self, data): |
2193
33b82250eadd
jp (base): raise InternalError if output is used when use_output is not declared
Goffi <goffi@goffi.org>
parents:
2189
diff
changeset
|
1186 try: |
33b82250eadd
jp (base): raise InternalError if output is used when use_output is not declared
Goffi <goffi@goffi.org>
parents:
2189
diff
changeset
|
1187 output_type = self._output_type |
33b82250eadd
jp (base): raise InternalError if output is used when use_output is not declared
Goffi <goffi@goffi.org>
parents:
2189
diff
changeset
|
1188 except AttributeError: |
3040 | 1189 raise exceptions.InternalError( |
1190 _('trying to use output when use_output has not been set')) | |
2193
33b82250eadd
jp (base): raise InternalError if output is used when use_output is not declared
Goffi <goffi@goffi.org>
parents:
2189
diff
changeset
|
1191 return self.host.output(output_type, self.args.output, self.extra_outputs, data) |
1950 | 1192 |
2761
4b693ea24d5f
jp (base, pubsub, ticket): handle order-by:
Goffi <goffi@goffi.org>
parents:
2706
diff
changeset
|
1193 def getPubsubExtra(self, extra=None): |
4b693ea24d5f
jp (base, pubsub, ticket): handle order-by:
Goffi <goffi@goffi.org>
parents:
2706
diff
changeset
|
1194 """Helper method to compute extra data from pubsub arguments |
4b693ea24d5f
jp (base, pubsub, ticket): handle order-by:
Goffi <goffi@goffi.org>
parents:
2706
diff
changeset
|
1195 |
4b693ea24d5f
jp (base, pubsub, ticket): handle order-by:
Goffi <goffi@goffi.org>
parents:
2706
diff
changeset
|
1196 @param extra(None, dict): base extra dict, or None to generate a new one |
4b693ea24d5f
jp (base, pubsub, ticket): handle order-by:
Goffi <goffi@goffi.org>
parents:
2706
diff
changeset
|
1197 @return (dict): dict which can be used directly in the bridge for pubsub |
4b693ea24d5f
jp (base, pubsub, ticket): handle order-by:
Goffi <goffi@goffi.org>
parents:
2706
diff
changeset
|
1198 """ |
4b693ea24d5f
jp (base, pubsub, ticket): handle order-by:
Goffi <goffi@goffi.org>
parents:
2706
diff
changeset
|
1199 if extra is None: |
4b693ea24d5f
jp (base, pubsub, ticket): handle order-by:
Goffi <goffi@goffi.org>
parents:
2706
diff
changeset
|
1200 extra = {} |
4b693ea24d5f
jp (base, pubsub, ticket): handle order-by:
Goffi <goffi@goffi.org>
parents:
2706
diff
changeset
|
1201 else: |
3028 | 1202 intersection = {C.KEY_ORDER_BY}.intersection(list(extra.keys())) |
2764
92af49cde255
jp (base): MAM and RSM arguments can now be used for pubsub commands:
Goffi <goffi@goffi.org>
parents:
2761
diff
changeset
|
1203 if intersection: |
92af49cde255
jp (base): MAM and RSM arguments can now be used for pubsub commands:
Goffi <goffi@goffi.org>
parents:
2761
diff
changeset
|
1204 raise exceptions.ConflictError( |
3028 | 1205 "given extra dict has conflicting keys with pubsub keys " |
1206 "{intersection}".format(intersection=intersection)) | |
2764
92af49cde255
jp (base): MAM and RSM arguments can now be used for pubsub commands:
Goffi <goffi@goffi.org>
parents:
2761
diff
changeset
|
1207 |
92af49cde255
jp (base): MAM and RSM arguments can now be used for pubsub commands:
Goffi <goffi@goffi.org>
parents:
2761
diff
changeset
|
1208 # RSM |
92af49cde255
jp (base): MAM and RSM arguments can now be used for pubsub commands:
Goffi <goffi@goffi.org>
parents:
2761
diff
changeset
|
1209 |
3028 | 1210 for attribute in ('max', 'after', 'before', 'index'): |
1211 key = 'rsm_' + attribute | |
2764
92af49cde255
jp (base): MAM and RSM arguments can now be used for pubsub commands:
Goffi <goffi@goffi.org>
parents:
2761
diff
changeset
|
1212 if key in extra: |
92af49cde255
jp (base): MAM and RSM arguments can now be used for pubsub commands:
Goffi <goffi@goffi.org>
parents:
2761
diff
changeset
|
1213 raise exceptions.ConflictError( |
3028 | 1214 "This key already exists in extra: u{key}".format(key=key)) |
2764
92af49cde255
jp (base): MAM and RSM arguments can now be used for pubsub commands:
Goffi <goffi@goffi.org>
parents:
2761
diff
changeset
|
1215 value = getattr(self.args, key, None) |
92af49cde255
jp (base): MAM and RSM arguments can now be used for pubsub commands:
Goffi <goffi@goffi.org>
parents:
2761
diff
changeset
|
1216 if value is not None: |
3028 | 1217 extra[key] = str(value) |
2764
92af49cde255
jp (base): MAM and RSM arguments can now be used for pubsub commands:
Goffi <goffi@goffi.org>
parents:
2761
diff
changeset
|
1218 |
92af49cde255
jp (base): MAM and RSM arguments can now be used for pubsub commands:
Goffi <goffi@goffi.org>
parents:
2761
diff
changeset
|
1219 # MAM |
92af49cde255
jp (base): MAM and RSM arguments can now be used for pubsub commands:
Goffi <goffi@goffi.org>
parents:
2761
diff
changeset
|
1220 |
3028 | 1221 if hasattr(self.args, 'mam_filters'): |
2764
92af49cde255
jp (base): MAM and RSM arguments can now be used for pubsub commands:
Goffi <goffi@goffi.org>
parents:
2761
diff
changeset
|
1222 for key, value in self.args.mam_filters: |
3028 | 1223 key = 'filter_' + key |
2764
92af49cde255
jp (base): MAM and RSM arguments can now be used for pubsub commands:
Goffi <goffi@goffi.org>
parents:
2761
diff
changeset
|
1224 if key in extra: |
92af49cde255
jp (base): MAM and RSM arguments can now be used for pubsub commands:
Goffi <goffi@goffi.org>
parents:
2761
diff
changeset
|
1225 raise exceptions.ConflictError( |
3028 | 1226 "This key already exists in extra: u{key}".format(key=key)) |
2764
92af49cde255
jp (base): MAM and RSM arguments can now be used for pubsub commands:
Goffi <goffi@goffi.org>
parents:
2761
diff
changeset
|
1227 extra[key] = value |
92af49cde255
jp (base): MAM and RSM arguments can now be used for pubsub commands:
Goffi <goffi@goffi.org>
parents:
2761
diff
changeset
|
1228 |
92af49cde255
jp (base): MAM and RSM arguments can now be used for pubsub commands:
Goffi <goffi@goffi.org>
parents:
2761
diff
changeset
|
1229 # Order-By |
92af49cde255
jp (base): MAM and RSM arguments can now be used for pubsub commands:
Goffi <goffi@goffi.org>
parents:
2761
diff
changeset
|
1230 |
2761
4b693ea24d5f
jp (base, pubsub, ticket): handle order-by:
Goffi <goffi@goffi.org>
parents:
2706
diff
changeset
|
1231 try: |
4b693ea24d5f
jp (base, pubsub, ticket): handle order-by:
Goffi <goffi@goffi.org>
parents:
2706
diff
changeset
|
1232 order_by = self.args.order_by |
4b693ea24d5f
jp (base, pubsub, ticket): handle order-by:
Goffi <goffi@goffi.org>
parents:
2706
diff
changeset
|
1233 except AttributeError: |
4b693ea24d5f
jp (base, pubsub, ticket): handle order-by:
Goffi <goffi@goffi.org>
parents:
2706
diff
changeset
|
1234 pass |
4b693ea24d5f
jp (base, pubsub, ticket): handle order-by:
Goffi <goffi@goffi.org>
parents:
2706
diff
changeset
|
1235 else: |
4b693ea24d5f
jp (base, pubsub, ticket): handle order-by:
Goffi <goffi@goffi.org>
parents:
2706
diff
changeset
|
1236 if order_by is not None: |
4b693ea24d5f
jp (base, pubsub, ticket): handle order-by:
Goffi <goffi@goffi.org>
parents:
2706
diff
changeset
|
1237 extra[C.KEY_ORDER_BY] = self.args.order_by |
4b693ea24d5f
jp (base, pubsub, ticket): handle order-by:
Goffi <goffi@goffi.org>
parents:
2706
diff
changeset
|
1238 return extra |
4b693ea24d5f
jp (base, pubsub, ticket): handle order-by:
Goffi <goffi@goffi.org>
parents:
2706
diff
changeset
|
1239 |
817 | 1240 def add_parser_options(self): |
1241 try: | |
1242 subcommands = self.subcommands | |
1243 except AttributeError: | |
1244 # We don't have subcommands, the class need to implements add_parser_options | |
1245 raise NotImplementedError | |
1246 | |
1247 # now we add subcommands to ourself | |
1248 for cls in subcommands: | |
1249 cls(self) | |
814 | 1250 |
3040 | 1251 async def run(self): |
1862
6d9c87bdc452
jp (base): added a CommandBase.start method which is called by run or connected, so subclasses can implement it (this is for simplicity sake, as it's not always clear if run or connected must be used)
Goffi <goffi@goffi.org>
parents:
1860
diff
changeset
|
1252 """this method is called when a command is actually run |
1395
1ae9aa94c351
jp: fixed bad try/except hidding errors + fixed bad management of jids without node
Goffi <goffi@goffi.org>
parents:
1290
diff
changeset
|
1253 |
1862
6d9c87bdc452
jp (base): added a CommandBase.start method which is called by run or connected, so subclasses can implement it (this is for simplicity sake, as it's not always clear if run or connected must be used)
Goffi <goffi@goffi.org>
parents:
1860
diff
changeset
|
1254 It set stuff like progression callbacks and profile connection |
6d9c87bdc452
jp (base): added a CommandBase.start method which is called by run or connected, so subclasses can implement it (this is for simplicity sake, as it's not always clear if run or connected must be used)
Goffi <goffi@goffi.org>
parents:
1860
diff
changeset
|
1255 You should not overide this method: you should call self.start instead |
6d9c87bdc452
jp (base): added a CommandBase.start method which is called by run or connected, so subclasses can implement it (this is for simplicity sake, as it's not always clear if run or connected must be used)
Goffi <goffi@goffi.org>
parents:
1860
diff
changeset
|
1256 """ |
2155 | 1257 # we keep a reference to run command, it may be useful e.g. for outputs |
1258 self.host.command = self | |
1863
b2ddd7f5dcdf
jp (base): refactored need_loop so it is set only when the command is run. It can now be set in __init__ methods of commands classes
Goffi <goffi@goffi.org>
parents:
1862
diff
changeset
|
1259 |
817 | 1260 try: |
1606
de785fcf9a7b
jp (base, file): file command and progress fixes and adaptation to new API:
Goffi <goffi@goffi.org>
parents:
1605
diff
changeset
|
1261 show_progress = self.args.progress |
817 | 1262 except AttributeError: |
1263 # the command doesn't use progress bar | |
1264 pass | |
1395
1ae9aa94c351
jp: fixed bad try/except hidding errors + fixed bad management of jids without node
Goffi <goffi@goffi.org>
parents:
1290
diff
changeset
|
1265 else: |
1606
de785fcf9a7b
jp (base, file): file command and progress fixes and adaptation to new API:
Goffi <goffi@goffi.org>
parents:
1605
diff
changeset
|
1266 if show_progress: |
de785fcf9a7b
jp (base, file): file command and progress fixes and adaptation to new API:
Goffi <goffi@goffi.org>
parents:
1605
diff
changeset
|
1267 self.host.watch_progress = True |
3040 | 1268 # we need to register the following signal even if we don't display the |
1269 # progress bar | |
1270 self.host.bridge.register_signal( | |
1271 "progressStarted", self.progressStartedHandler) | |
1272 self.host.bridge.register_signal( | |
1273 "progressFinished", self.progressFinishedHandler) | |
1274 self.host.bridge.register_signal( | |
1275 "progressError", self.progressErrorHandler) | |
817 | 1276 |
1862
6d9c87bdc452
jp (base): added a CommandBase.start method which is called by run or connected, so subclasses can implement it (this is for simplicity sake, as it's not always clear if run or connected must be used)
Goffi <goffi@goffi.org>
parents:
1860
diff
changeset
|
1277 if self.need_connect is not None: |
3040 | 1278 await self.host.connect_profile() |
1279 await self.start() | |
1862
6d9c87bdc452
jp (base): added a CommandBase.start method which is called by run or connected, so subclasses can implement it (this is for simplicity sake, as it's not always clear if run or connected must be used)
Goffi <goffi@goffi.org>
parents:
1860
diff
changeset
|
1280 |
3040 | 1281 async def start(self): |
1282 """This is the starting point of the command, this method must be overriden | |
1862
6d9c87bdc452
jp (base): added a CommandBase.start method which is called by run or connected, so subclasses can implement it (this is for simplicity sake, as it's not always clear if run or connected must be used)
Goffi <goffi@goffi.org>
parents:
1860
diff
changeset
|
1283 |
6d9c87bdc452
jp (base): added a CommandBase.start method which is called by run or connected, so subclasses can implement it (this is for simplicity sake, as it's not always clear if run or connected must be used)
Goffi <goffi@goffi.org>
parents:
1860
diff
changeset
|
1284 at this point, profile are connected if needed |
6d9c87bdc452
jp (base): added a CommandBase.start method which is called by run or connected, so subclasses can implement it (this is for simplicity sake, as it's not always clear if run or connected must be used)
Goffi <goffi@goffi.org>
parents:
1860
diff
changeset
|
1285 """ |
3040 | 1286 raise NotImplementedError |
817 | 1287 |
1288 | |
1289 class CommandAnswering(CommandBase): | |
1606
de785fcf9a7b
jp (base, file): file command and progress fixes and adaptation to new API:
Goffi <goffi@goffi.org>
parents:
1605
diff
changeset
|
1290 """Specialised commands which answer to specific actions |
817 | 1291 |
1606
de785fcf9a7b
jp (base, file): file command and progress fixes and adaptation to new API:
Goffi <goffi@goffi.org>
parents:
1605
diff
changeset
|
1292 to manage action_types answer, |
de785fcf9a7b
jp (base, file): file command and progress fixes and adaptation to new API:
Goffi <goffi@goffi.org>
parents:
1605
diff
changeset
|
1293 """ |
2409
d2ff5ff3de77
jp (ad-hoc): new "list" and "run" commands:
Goffi <goffi@goffi.org>
parents:
2368
diff
changeset
|
1294 action_callbacks = {} # XXX: set managed action types in a dict here: |
1606
de785fcf9a7b
jp (base, file): file command and progress fixes and adaptation to new API:
Goffi <goffi@goffi.org>
parents:
1605
diff
changeset
|
1295 # key is the action_type, value is the callable |
de785fcf9a7b
jp (base, file): file command and progress fixes and adaptation to new API:
Goffi <goffi@goffi.org>
parents:
1605
diff
changeset
|
1296 # which will manage the answer. profile filtering is |
de785fcf9a7b
jp (base, file): file command and progress fixes and adaptation to new API:
Goffi <goffi@goffi.org>
parents:
1605
diff
changeset
|
1297 # already managed when callback is called |
de785fcf9a7b
jp (base, file): file command and progress fixes and adaptation to new API:
Goffi <goffi@goffi.org>
parents:
1605
diff
changeset
|
1298 |
2486
031aa3cc67ac
jp (base): fixed assertion error when using CommandAnswering
Goffi <goffi@goffi.org>
parents:
2483
diff
changeset
|
1299 def __init__(self, *args, **kwargs): |
031aa3cc67ac
jp (base): fixed assertion error when using CommandAnswering
Goffi <goffi@goffi.org>
parents:
2483
diff
changeset
|
1300 super(CommandAnswering, self).__init__(*args, **kwargs) |
031aa3cc67ac
jp (base): fixed assertion error when using CommandAnswering
Goffi <goffi@goffi.org>
parents:
2483
diff
changeset
|
1301 |
3040 | 1302 async def onActionNew(self, action_data, action_id, security_limit, profile): |
538
2c4016921403
core, frontends, bridgen plugins: fixed methods which were unproperly managing multi-profiles
Goffi <goffi@goffi.org>
parents:
493
diff
changeset
|
1303 if profile != self.profile: |
2c4016921403
core, frontends, bridgen plugins: fixed methods which were unproperly managing multi-profiles
Goffi <goffi@goffi.org>
parents:
493
diff
changeset
|
1304 return |
1606
de785fcf9a7b
jp (base, file): file command and progress fixes and adaptation to new API:
Goffi <goffi@goffi.org>
parents:
1605
diff
changeset
|
1305 try: |
de785fcf9a7b
jp (base, file): file command and progress fixes and adaptation to new API:
Goffi <goffi@goffi.org>
parents:
1605
diff
changeset
|
1306 action_type = action_data['meta_type'] |
de785fcf9a7b
jp (base, file): file command and progress fixes and adaptation to new API:
Goffi <goffi@goffi.org>
parents:
1605
diff
changeset
|
1307 except KeyError: |
1840
9eabf7fadfdd
frontends (jp): onActionNew displays xmlui message if no meta_type is defined and xmlui is defined
souliane <souliane@mailoo.org>
parents:
1832
diff
changeset
|
1308 try: |
9eabf7fadfdd
frontends (jp): onActionNew displays xmlui message if no meta_type is defined and xmlui is defined
souliane <souliane@mailoo.org>
parents:
1832
diff
changeset
|
1309 xml_ui = action_data["xmlui"] |
9eabf7fadfdd
frontends (jp): onActionNew displays xmlui message if no meta_type is defined and xmlui is defined
souliane <souliane@mailoo.org>
parents:
1832
diff
changeset
|
1310 except KeyError: |
9eabf7fadfdd
frontends (jp): onActionNew displays xmlui message if no meta_type is defined and xmlui is defined
souliane <souliane@mailoo.org>
parents:
1832
diff
changeset
|
1311 pass |
9eabf7fadfdd
frontends (jp): onActionNew displays xmlui message if no meta_type is defined and xmlui is defined
souliane <souliane@mailoo.org>
parents:
1832
diff
changeset
|
1312 else: |
9eabf7fadfdd
frontends (jp): onActionNew displays xmlui message if no meta_type is defined and xmlui is defined
souliane <souliane@mailoo.org>
parents:
1832
diff
changeset
|
1313 self.onXMLUI(xml_ui) |
1606
de785fcf9a7b
jp (base, file): file command and progress fixes and adaptation to new API:
Goffi <goffi@goffi.org>
parents:
1605
diff
changeset
|
1314 else: |
de785fcf9a7b
jp (base, file): file command and progress fixes and adaptation to new API:
Goffi <goffi@goffi.org>
parents:
1605
diff
changeset
|
1315 try: |
de785fcf9a7b
jp (base, file): file command and progress fixes and adaptation to new API:
Goffi <goffi@goffi.org>
parents:
1605
diff
changeset
|
1316 callback = self.action_callbacks[action_type] |
de785fcf9a7b
jp (base, file): file command and progress fixes and adaptation to new API:
Goffi <goffi@goffi.org>
parents:
1605
diff
changeset
|
1317 except KeyError: |
de785fcf9a7b
jp (base, file): file command and progress fixes and adaptation to new API:
Goffi <goffi@goffi.org>
parents:
1605
diff
changeset
|
1318 pass |
0 | 1319 else: |
3040 | 1320 await callback(action_data, action_id, security_limit, profile) |
587
952322b1d490
Remove trailing whitespaces.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
572
diff
changeset
|
1321 |
1840
9eabf7fadfdd
frontends (jp): onActionNew displays xmlui message if no meta_type is defined and xmlui is defined
souliane <souliane@mailoo.org>
parents:
1832
diff
changeset
|
1322 def onXMLUI(self, xml_ui): |
9eabf7fadfdd
frontends (jp): onActionNew displays xmlui message if no meta_type is defined and xmlui is defined
souliane <souliane@mailoo.org>
parents:
1832
diff
changeset
|
1323 """Display a dialog received from the backend. |
9eabf7fadfdd
frontends (jp): onActionNew displays xmlui message if no meta_type is defined and xmlui is defined
souliane <souliane@mailoo.org>
parents:
1832
diff
changeset
|
1324 |
9eabf7fadfdd
frontends (jp): onActionNew displays xmlui message if no meta_type is defined and xmlui is defined
souliane <souliane@mailoo.org>
parents:
1832
diff
changeset
|
1325 @param xml_ui (unicode): dialog XML representation |
9eabf7fadfdd
frontends (jp): onActionNew displays xmlui message if no meta_type is defined and xmlui is defined
souliane <souliane@mailoo.org>
parents:
1832
diff
changeset
|
1326 """ |
9eabf7fadfdd
frontends (jp): onActionNew displays xmlui message if no meta_type is defined and xmlui is defined
souliane <souliane@mailoo.org>
parents:
1832
diff
changeset
|
1327 # FIXME: we temporarily use ElementTree, but a real XMLUI managing module |
9eabf7fadfdd
frontends (jp): onActionNew displays xmlui message if no meta_type is defined and xmlui is defined
souliane <souliane@mailoo.org>
parents:
1832
diff
changeset
|
1328 # should be available in the future |
9eabf7fadfdd
frontends (jp): onActionNew displays xmlui message if no meta_type is defined and xmlui is defined
souliane <souliane@mailoo.org>
parents:
1832
diff
changeset
|
1329 # TODO: XMLUI module |
9eabf7fadfdd
frontends (jp): onActionNew displays xmlui message if no meta_type is defined and xmlui is defined
souliane <souliane@mailoo.org>
parents:
1832
diff
changeset
|
1330 ui = ET.fromstring(xml_ui.encode('utf-8')) |
9eabf7fadfdd
frontends (jp): onActionNew displays xmlui message if no meta_type is defined and xmlui is defined
souliane <souliane@mailoo.org>
parents:
1832
diff
changeset
|
1331 dialog = ui.find("dialog") |
9eabf7fadfdd
frontends (jp): onActionNew displays xmlui message if no meta_type is defined and xmlui is defined
souliane <souliane@mailoo.org>
parents:
1832
diff
changeset
|
1332 if dialog is not None: |
9eabf7fadfdd
frontends (jp): onActionNew displays xmlui message if no meta_type is defined and xmlui is defined
souliane <souliane@mailoo.org>
parents:
1832
diff
changeset
|
1333 self.disp(dialog.findtext("message"), error=dialog.get("level") == "error") |
9eabf7fadfdd
frontends (jp): onActionNew displays xmlui message if no meta_type is defined and xmlui is defined
souliane <souliane@mailoo.org>
parents:
1832
diff
changeset
|
1334 |
3040 | 1335 async def start_answering(self): |
1336 """Auto reply to confirmation requests""" | |
2368
3865a772c360
jp (base): fixed CommandAnswering and progress bar
Goffi <goffi@goffi.org>
parents:
2313
diff
changeset
|
1337 self.host.bridge.register_signal("actionNew", self.onActionNew) |
3040 | 1338 actions = await self.host.bridge.actionsGet(self.profile) |
1623 | 1339 for action_data, action_id, security_limit in actions: |
3040 | 1340 await self.onActionNew(action_data, action_id, security_limit, self.profile) |