Mercurial > libervia-backend
annotate sat_frontends/jp/base.py @ 3576:8876803db81b
/!\ package is being renamed to libervia-backend following global name change /!\
author | Goffi <goffi@goffi.org> |
---|---|
date | Fri, 18 Jun 2021 14:44:01 +0200 |
parents | 04283582966f |
children | 5f65f4e9f8cb 43542cf32e5a |
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 |
670 self.version = await self.bridge.getVersion() | |
671 self._bridgeConnected() | |
672 self.import_plugins() | |
673 try: | |
674 self.args = self.parser.parse_args(args, namespace=None) | |
675 if self.args._cmd._use_pubsub: | |
676 self.parse_pubsub_args() | |
677 await self.args._cmd.run() | |
678 except SystemExit as e: | |
679 self.quit(e.code, raise_exc=False) | |
680 return | |
681 except QuitException: | |
682 return | |
817 | 683 |
3481
7892585b7e17
core (setup), jp, primitivus: update console scripts + classifiers:
Goffi <goffi@goffi.org>
parents:
3479
diff
changeset
|
684 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
|
685 self.loop = JPLoop() |
3040 | 686 self.loop.run(self, args, namespace) |
0 | 687 |
3481
7892585b7e17
core (setup), jp, primitivus: update console scripts + classifiers:
Goffi <goffi@goffi.org>
parents:
3479
diff
changeset
|
688 @classmethod |
7892585b7e17
core (setup), jp, primitivus: update console scripts + classifiers:
Goffi <goffi@goffi.org>
parents:
3479
diff
changeset
|
689 def run(cls): |
7892585b7e17
core (setup), jp, primitivus: update console scripts + classifiers:
Goffi <goffi@goffi.org>
parents:
3479
diff
changeset
|
690 cls()._run() |
7892585b7e17
core (setup), jp, primitivus: update console scripts + classifiers:
Goffi <goffi@goffi.org>
parents:
3479
diff
changeset
|
691 |
3040 | 692 def _read_stdin(self, stdin_fut): |
693 """Callback called by ainput to read stdin""" | |
694 line = sys.stdin.readline() | |
695 if line: | |
696 stdin_fut.set_result(line.rstrip(os.linesep)) | |
697 else: | |
698 stdin_fut.set_exception(EOFError()) | |
587
952322b1d490
Remove trailing whitespaces.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
572
diff
changeset
|
699 |
3040 | 700 async def ainput(self, msg=''): |
701 """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
|
702 self.disp(msg, end=' ') |
3040 | 703 sys.stdout.flush() |
704 loop = asyncio.get_running_loop() | |
705 stdin_fut = loop.create_future() | |
706 loop.add_reader(sys.stdin, self._read_stdin, stdin_fut) | |
707 return await stdin_fut | |
708 | |
3409 | 709 async def confirm(self, message): |
710 """Request user to confirm action, return answer as boolean""" | |
711 res = await self.ainput(f"{message} (y/N)? ") | |
712 return res in ("y", "Y") | |
713 | |
3040 | 714 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
|
715 """Request user to confirm action, and quit if he doesn't""" |
3409 | 716 confirmed = await self.confirm(message) |
717 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
|
718 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
|
719 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
|
720 |
3040 | 721 def quitFromSignal(self, exit_code=0): |
722 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
|
723 |
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 /!\: 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
|
725 """ |
1918
01d56efd488b
jp: fixed traceback shown on a normal quit when a progression is finished
Goffi <goffi@goffi.org>
parents:
1884
diff
changeset
|
726 # 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
|
727 # so we use this little timeout trick to avoid it |
3040 | 728 self.loop.call_later(0, self.quit, exit_code) |
729 | |
730 def quit(self, exit_code=0, raise_exc=True): | |
731 """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
|
732 |
3040 | 733 This will stop the loop. |
734 @param exit_code(int): code to return when quitting the program | |
735 @param raise_exp(boolean): if True raise a QuitException to stop code execution | |
736 The default value should be used most of time. | |
737 """ | |
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
|
738 # 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
|
739 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
|
740 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
|
741 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
|
742 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
|
743 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
|
744 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
|
745 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
|
746 |
3040 | 747 self.loop.quit(exit_code) |
748 if raise_exc: | |
749 raise QuitException | |
587
952322b1d490
Remove trailing whitespaces.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
572
diff
changeset
|
750 |
3040 | 751 async def check_jids(self, jids): |
814 | 752 """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
|
753 |
817 | 754 @param profile: profile name |
755 @param jids: list of jids | |
756 @return: List of jids | |
757 | |
814 | 758 """ |
401
b2caa2615c4c
jp roster name manegement + Pipe transfer
Goffi <goffi@goffi.org>
parents:
393
diff
changeset
|
759 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
|
760 nodes2jid = {} |
393 | 761 |
3040 | 762 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
|
763 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
|
764 _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
|
765 try: |
1ae9aa94c351
jp: fixed bad try/except hidding errors + fixed bad management of jids without node
Goffi <goffi@goffi.org>
parents:
1290
diff
changeset
|
766 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
|
767 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
|
768 pass |
1ae9aa94c351
jp: fixed bad try/except hidding errors + fixed bad management of jids without node
Goffi <goffi@goffi.org>
parents:
1290
diff
changeset
|
769 |
1ae9aa94c351
jp: fixed bad try/except hidding errors + fixed bad management of jids without node
Goffi <goffi@goffi.org>
parents:
1290
diff
changeset
|
770 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
|
771 nodes2jid[_jid.node.lower()] = jid_s |
401
b2caa2615c4c
jp roster name manegement + Pipe transfer
Goffi <goffi@goffi.org>
parents:
393
diff
changeset
|
772 |
817 | 773 def expand_jid(jid): |
401
b2caa2615c4c
jp roster name manegement + Pipe transfer
Goffi <goffi@goffi.org>
parents:
393
diff
changeset
|
774 _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
|
775 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
|
776 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
|
777 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
|
778 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
|
779 else: |
b7c4bb2c0668
jp: - better expandJid: roster's jids' nodes are used after names to expand jid
Goffi <goffi@goffi.org>
parents:
480
diff
changeset
|
780 expanded = jid |
2588 | 781 return expanded |
401
b2caa2615c4c
jp roster name manegement + Pipe transfer
Goffi <goffi@goffi.org>
parents:
393
diff
changeset
|
782 |
b2caa2615c4c
jp roster name manegement + Pipe transfer
Goffi <goffi@goffi.org>
parents:
393
diff
changeset
|
783 def check(jid): |
b2caa2615c4c
jp roster name manegement + Pipe transfer
Goffi <goffi@goffi.org>
parents:
393
diff
changeset
|
784 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
|
785 log.error (_("%s is not a valid JID !"), jid) |
817 | 786 self.quit(1) |
401
b2caa2615c4c
jp roster name manegement + Pipe transfer
Goffi <goffi@goffi.org>
parents:
393
diff
changeset
|
787 |
814 | 788 dest_jids=[] |
401
b2caa2615c4c
jp roster name manegement + Pipe transfer
Goffi <goffi@goffi.org>
parents:
393
diff
changeset
|
789 try: |
814 | 790 for i in range(len(jids)): |
817 | 791 dest_jids.append(expand_jid(jids[i])) |
814 | 792 check(dest_jids[i]) |
401
b2caa2615c4c
jp roster name manegement + Pipe transfer
Goffi <goffi@goffi.org>
parents:
393
diff
changeset
|
793 except AttributeError: |
b2caa2615c4c
jp roster name manegement + Pipe transfer
Goffi <goffi@goffi.org>
parents:
393
diff
changeset
|
794 pass |
0 | 795 |
814 | 796 return dest_jids |
0 | 797 |
3049
9839ce068140
jp: password is now prompted if needed:
Goffi <goffi@goffi.org>
parents:
3046
diff
changeset
|
798 async def a_pwd_input(self, msg=''): |
9839ce068140
jp: password is now prompted if needed:
Goffi <goffi@goffi.org>
parents:
3046
diff
changeset
|
799 """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
|
800 # 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
|
801 # 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
|
802 # 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
|
803 # 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
|
804 stdin_fd = sys.stdin.fileno() |
9839ce068140
jp: password is now prompted if needed:
Goffi <goffi@goffi.org>
parents:
3046
diff
changeset
|
805 old = termios.tcgetattr(sys.stdin) |
9839ce068140
jp: password is now prompted if needed:
Goffi <goffi@goffi.org>
parents:
3046
diff
changeset
|
806 new = old[:] |
9839ce068140
jp: password is now prompted if needed:
Goffi <goffi@goffi.org>
parents:
3046
diff
changeset
|
807 new[3] &= ~termios.ECHO |
9839ce068140
jp: password is now prompted if needed:
Goffi <goffi@goffi.org>
parents:
3046
diff
changeset
|
808 tcsetattr_flags = termios.TCSAFLUSH |
9839ce068140
jp: password is now prompted if needed:
Goffi <goffi@goffi.org>
parents:
3046
diff
changeset
|
809 if hasattr(termios, 'TCSASOFT'): |
9839ce068140
jp: password is now prompted if needed:
Goffi <goffi@goffi.org>
parents:
3046
diff
changeset
|
810 tcsetattr_flags |= termios.TCSASOFT |
9839ce068140
jp: password is now prompted if needed:
Goffi <goffi@goffi.org>
parents:
3046
diff
changeset
|
811 try: |
9839ce068140
jp: password is now prompted if needed:
Goffi <goffi@goffi.org>
parents:
3046
diff
changeset
|
812 termios.tcsetattr(stdin_fd, tcsetattr_flags, new) |
9839ce068140
jp: password is now prompted if needed:
Goffi <goffi@goffi.org>
parents:
3046
diff
changeset
|
813 pwd = await self.ainput(msg=msg) |
9839ce068140
jp: password is now prompted if needed:
Goffi <goffi@goffi.org>
parents:
3046
diff
changeset
|
814 finally: |
9839ce068140
jp: password is now prompted if needed:
Goffi <goffi@goffi.org>
parents:
3046
diff
changeset
|
815 termios.tcsetattr(stdin_fd, tcsetattr_flags, old) |
9839ce068140
jp: password is now prompted if needed:
Goffi <goffi@goffi.org>
parents:
3046
diff
changeset
|
816 sys.stderr.flush() |
9839ce068140
jp: password is now prompted if needed:
Goffi <goffi@goffi.org>
parents:
3046
diff
changeset
|
817 self.disp('') |
9839ce068140
jp: password is now prompted if needed:
Goffi <goffi@goffi.org>
parents:
3046
diff
changeset
|
818 return pwd |
9839ce068140
jp: password is now prompted if needed:
Goffi <goffi@goffi.org>
parents:
3046
diff
changeset
|
819 |
9839ce068140
jp: password is now prompted if needed:
Goffi <goffi@goffi.org>
parents:
3046
diff
changeset
|
820 async def connectOrPrompt(self, method, err_msg=None): |
9839ce068140
jp: password is now prompted if needed:
Goffi <goffi@goffi.org>
parents:
3046
diff
changeset
|
821 """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
|
822 |
9839ce068140
jp: password is now prompted if needed:
Goffi <goffi@goffi.org>
parents:
3046
diff
changeset
|
823 @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
|
824 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
|
825 properly |
9839ce068140
jp: password is now prompted if needed:
Goffi <goffi@goffi.org>
parents:
3046
diff
changeset
|
826 @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
|
827 """ |
9839ce068140
jp: password is now prompted if needed:
Goffi <goffi@goffi.org>
parents:
3046
diff
changeset
|
828 password = self.args.pwd |
9839ce068140
jp: password is now prompted if needed:
Goffi <goffi@goffi.org>
parents:
3046
diff
changeset
|
829 while True: |
9839ce068140
jp: password is now prompted if needed:
Goffi <goffi@goffi.org>
parents:
3046
diff
changeset
|
830 try: |
9839ce068140
jp: password is now prompted if needed:
Goffi <goffi@goffi.org>
parents:
3046
diff
changeset
|
831 await method(password or '') |
9839ce068140
jp: password is now prompted if needed:
Goffi <goffi@goffi.org>
parents:
3046
diff
changeset
|
832 except Exception as e: |
9839ce068140
jp: password is now prompted if needed:
Goffi <goffi@goffi.org>
parents:
3046
diff
changeset
|
833 if ((isinstance(e, BridgeException) |
9839ce068140
jp: password is now prompted if needed:
Goffi <goffi@goffi.org>
parents:
3046
diff
changeset
|
834 and e.classname == 'PasswordError' |
9839ce068140
jp: password is now prompted if needed:
Goffi <goffi@goffi.org>
parents:
3046
diff
changeset
|
835 and self.args.pwd is None)): |
9839ce068140
jp: password is now prompted if needed:
Goffi <goffi@goffi.org>
parents:
3046
diff
changeset
|
836 if password is not None: |
9839ce068140
jp: password is now prompted if needed:
Goffi <goffi@goffi.org>
parents:
3046
diff
changeset
|
837 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
|
838 password = await self.a_pwd_input( |
9839ce068140
jp: password is now prompted if needed:
Goffi <goffi@goffi.org>
parents:
3046
diff
changeset
|
839 _("please enter profile password:")) |
9839ce068140
jp: password is now prompted if needed:
Goffi <goffi@goffi.org>
parents:
3046
diff
changeset
|
840 else: |
9839ce068140
jp: password is now prompted if needed:
Goffi <goffi@goffi.org>
parents:
3046
diff
changeset
|
841 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
|
842 self.quit(C.EXIT_ERROR) |
9839ce068140
jp: password is now prompted if needed:
Goffi <goffi@goffi.org>
parents:
3046
diff
changeset
|
843 else: |
9839ce068140
jp: password is now prompted if needed:
Goffi <goffi@goffi.org>
parents:
3046
diff
changeset
|
844 break |
9839ce068140
jp: password is now prompted if needed:
Goffi <goffi@goffi.org>
parents:
3046
diff
changeset
|
845 |
3040 | 846 async def connect_profile(self): |
847 """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
|
848 |
817 | 849 @exit: - 1 when profile is not connected and --connect is not set |
850 - 1 when the profile doesn't exists | |
851 - 1 when there is a connection error | |
852 """ | |
853 # FIXME: need better exit codes | |
854 | |
3040 | 855 self.profile = await self.bridge.profileNameGet(self.args.profile) |
0 | 856 |
817 | 857 if not self.profile: |
3568
04283582966f
core, frontends: fix invalid translatable strings.
Goffi <goffi@goffi.org>
parents:
3555
diff
changeset
|
858 log.error( |
04283582966f
core, frontends: fix invalid translatable strings.
Goffi <goffi@goffi.org>
parents:
3555
diff
changeset
|
859 _("The profile [{profile}] doesn't exist") |
04283582966f
core, frontends: fix invalid translatable strings.
Goffi <goffi@goffi.org>
parents:
3555
diff
changeset
|
860 .format(profile=self.args.profile) |
04283582966f
core, frontends: fix invalid translatable strings.
Goffi <goffi@goffi.org>
parents:
3555
diff
changeset
|
861 ) |
3040 | 862 self.quit(C.EXIT_ERROR) |
817 | 863 |
1594
313f2bb7841b
jp: profile session can now be started without connection:
Goffi <goffi@goffi.org>
parents:
1588
diff
changeset
|
864 try: |
313f2bb7841b
jp: profile session can now be started without connection:
Goffi <goffi@goffi.org>
parents:
1588
diff
changeset
|
865 start_session = self.args.start_session |
313f2bb7841b
jp: profile session can now be started without connection:
Goffi <goffi@goffi.org>
parents:
1588
diff
changeset
|
866 except AttributeError: |
313f2bb7841b
jp: profile session can now be started without connection:
Goffi <goffi@goffi.org>
parents:
1588
diff
changeset
|
867 pass |
313f2bb7841b
jp: profile session can now be started without connection:
Goffi <goffi@goffi.org>
parents:
1588
diff
changeset
|
868 else: |
313f2bb7841b
jp: profile session can now be started without connection:
Goffi <goffi@goffi.org>
parents:
1588
diff
changeset
|
869 if start_session: |
3049
9839ce068140
jp: password is now prompted if needed:
Goffi <goffi@goffi.org>
parents:
3046
diff
changeset
|
870 await self.connectOrPrompt( |
9839ce068140
jp: password is now prompted if needed:
Goffi <goffi@goffi.org>
parents:
3046
diff
changeset
|
871 lambda pwd: self.bridge.profileStartSession(pwd, self.profile), |
9839ce068140
jp: password is now prompted if needed:
Goffi <goffi@goffi.org>
parents:
3046
diff
changeset
|
872 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
|
873 ) |
1594
313f2bb7841b
jp: profile session can now be started without connection:
Goffi <goffi@goffi.org>
parents:
1588
diff
changeset
|
874 return |
3040 | 875 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
|
876 if not self.args.connect: |
3040 | 877 self.disp(_( |
3568
04283582966f
core, frontends: fix invalid translatable strings.
Goffi <goffi@goffi.org>
parents:
3555
diff
changeset
|
878 "Session for [{profile}] is not started, please start it " |
04283582966f
core, frontends: fix invalid translatable strings.
Goffi <goffi@goffi.org>
parents:
3555
diff
changeset
|
879 "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
|
880 "option" |
04283582966f
core, frontends: fix invalid translatable strings.
Goffi <goffi@goffi.org>
parents:
3555
diff
changeset
|
881 .format(profile=self.profile) |
04283582966f
core, frontends: fix invalid translatable strings.
Goffi <goffi@goffi.org>
parents:
3555
diff
changeset
|
882 ), error=True) |
1594
313f2bb7841b
jp: profile session can now be started without connection:
Goffi <goffi@goffi.org>
parents:
1588
diff
changeset
|
883 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
|
884 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
|
885 return |
313f2bb7841b
jp: profile session can now be started without connection:
Goffi <goffi@goffi.org>
parents:
1588
diff
changeset
|
886 |
313f2bb7841b
jp: profile session can now be started without connection:
Goffi <goffi@goffi.org>
parents:
1588
diff
changeset
|
887 |
1401
265ff2bd8d67
jp: fixed crash on commands using profile without "connect" option
Goffi <goffi@goffi.org>
parents:
1396
diff
changeset
|
888 if not hasattr(self.args, 'connect'): |
3040 | 889 # a profile can be present without connect option (e.g. on profile |
890 # creation/deletion) | |
1401
265ff2bd8d67
jp: fixed crash on commands using profile without "connect" option
Goffi <goffi@goffi.org>
parents:
1396
diff
changeset
|
891 return |
1588
823a385235ef
jp: fixed bad --connect option check
Goffi <goffi@goffi.org>
parents:
1544
diff
changeset
|
892 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
|
893 await self.connectOrPrompt( |
9839ce068140
jp: password is now prompted if needed:
Goffi <goffi@goffi.org>
parents:
3046
diff
changeset
|
894 lambda pwd: self.bridge.connect(self.profile, pwd, {}), |
9839ce068140
jp: password is now prompted if needed:
Goffi <goffi@goffi.org>
parents:
3046
diff
changeset
|
895 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
|
896 ) |
814 | 897 return |
1594
313f2bb7841b
jp: profile session can now be started without connection:
Goffi <goffi@goffi.org>
parents:
1588
diff
changeset
|
898 else: |
3040 | 899 if not await self.bridge.isConnected(self.profile): |
900 log.error( | |
3568
04283582966f
core, frontends: fix invalid translatable strings.
Goffi <goffi@goffi.org>
parents:
3555
diff
changeset
|
901 _("Profile [{profile}] is not connected, please connect it " |
04283582966f
core, frontends: fix invalid translatable strings.
Goffi <goffi@goffi.org>
parents:
3555
diff
changeset
|
902 "before using jp, or use --connect option") |
04283582966f
core, frontends: fix invalid translatable strings.
Goffi <goffi@goffi.org>
parents:
3555
diff
changeset
|
903 .format(profile=self.profile) |
04283582966f
core, frontends: fix invalid translatable strings.
Goffi <goffi@goffi.org>
parents:
3555
diff
changeset
|
904 ) |
1594
313f2bb7841b
jp: profile session can now be started without connection:
Goffi <goffi@goffi.org>
parents:
1588
diff
changeset
|
905 self.quit(1) |
0 | 906 |
3040 | 907 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
|
908 """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
|
909 # 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
|
910 # as backend now handle jingles message initiation |
401
b2caa2615c4c
jp roster name manegement + Pipe transfer
Goffi <goffi@goffi.org>
parents:
393
diff
changeset
|
911 _jid = JID(param_jid) |
b2caa2615c4c
jp roster name manegement + Pipe transfer
Goffi <goffi@goffi.org>
parents:
393
diff
changeset
|
912 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
|
913 #if the resource is not given, we try to add the main resource |
3040 | 914 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
|
915 if main_resource: |
3040 | 916 return f"{_jid.bare}/{main_resource}" |
401
b2caa2615c4c
jp roster name manegement + Pipe transfer
Goffi <goffi@goffi.org>
parents:
393
diff
changeset
|
917 return param_jid |
b2caa2615c4c
jp roster name manegement + Pipe transfer
Goffi <goffi@goffi.org>
parents:
393
diff
changeset
|
918 |
814 | 919 |
817 | 920 class CommandBase(object): |
814 | 921 |
2155 | 922 def __init__(self, host, name, use_profile=True, use_output=False, extra_outputs=None, |
1950 | 923 need_connect=None, help=None, **kwargs): |
2098
e0066920a661
primitivus, jp: dynamic bridge + fixed D-Bus bridge:
Goffi <goffi@goffi.org>
parents:
2086
diff
changeset
|
924 """Initialise CommandBase |
e0066920a661
primitivus, jp: dynamic bridge + fixed D-Bus bridge:
Goffi <goffi@goffi.org>
parents:
2086
diff
changeset
|
925 |
817 | 926 @param host: Jp instance |
1594
313f2bb7841b
jp: profile session can now be started without connection:
Goffi <goffi@goffi.org>
parents:
1588
diff
changeset
|
927 @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
|
928 @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
|
929 @param use_output(bool, unicode): if not False, add --output option |
2155 | 930 @param extra_outputs(dict): list of command specific outputs: |
931 key is output name ("default" to use as main output) | |
3040 | 932 value is a callable which will format the output (data will be used as only |
933 argument) | |
2155 | 934 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
|
935 @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
|
936 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
|
937 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
|
938 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
|
939 @param help(unicode): help message to display |
817 | 940 @param **kwargs: args passed to ArgumentParser |
1950 | 941 use_* are handled directly, they can be: |
942 - use_progress(bool): if True, add progress bar activation option | |
943 progress* signals will be handled | |
944 - use_verbose(bool): if True, add verbosity option | |
2532 | 945 - use_pubsub(bool): if True, add pubsub options |
946 mandatory arguments are controlled by pubsub_req | |
947 - use_draft(bool): if True, add draft handling options | |
948 ** other arguments ** | |
3040 | 949 - pubsub_flags(iterable[unicode]): tuple of flags to set pubsub options, |
950 can be: | |
2532 | 951 C.SERVICE: service is required |
952 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
|
953 C.ITEM: item is required |
2532 | 954 C.SINGLE_ITEM: only one item is allowed |
814 | 955 """ |
817 | 956 try: # If we have subcommands, host is a CommandBase and we need to use host.host |
957 self.host = host.host | |
958 except AttributeError: | |
959 self.host = host | |
960 | |
1950 | 961 # --profile option |
817 | 962 parents = kwargs.setdefault('parents', set()) |
963 if use_profile: | |
3040 | 964 # self.host.parents['profile'] is an ArgumentParser with profile connection |
965 # arguments | |
1594
313f2bb7841b
jp: profile session can now be started without connection:
Goffi <goffi@goffi.org>
parents:
1588
diff
changeset
|
966 if need_connect is None: |
313f2bb7841b
jp: profile session can now be started without connection:
Goffi <goffi@goffi.org>
parents:
1588
diff
changeset
|
967 need_connect = True |
3040 | 968 parents.add( |
969 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
|
970 else: |
313f2bb7841b
jp: profile session can now be started without connection:
Goffi <goffi@goffi.org>
parents:
1588
diff
changeset
|
971 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
|
972 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
|
973 # 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
|
974 # 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
|
975 |
1950 | 976 # --output option |
977 if use_output: | |
2155 | 978 if extra_outputs is None: |
979 extra_outputs = {} | |
980 self.extra_outputs = extra_outputs | |
1950 | 981 if use_output == True: |
982 use_output = C.OUTPUT_TEXT | |
983 assert use_output in C.OUTPUT_TYPES | |
984 self._output_type = use_output | |
985 output_parent = argparse.ArgumentParser(add_help=False) | |
2155 | 986 choices = set(self.host.getOutputChoices(use_output)) |
987 choices.update(extra_outputs) | |
1950 | 988 if not choices: |
3040 | 989 raise exceptions.InternalError( |
990 "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
|
991 try: |
a25a256688e2
jp (base): output can now specify a default when registering
Goffi <goffi@goffi.org>
parents:
2188
diff
changeset
|
992 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
|
993 except KeyError: |
3028 | 994 if 'default' in choices: |
995 default = 'default' | |
996 elif 'simple' in choices: | |
997 default = 'simple' | |
2189
a25a256688e2
jp (base): output can now specify a default when registering
Goffi <goffi@goffi.org>
parents:
2188
diff
changeset
|
998 else: |
a25a256688e2
jp (base): output can now specify a default when registering
Goffi <goffi@goffi.org>
parents:
2188
diff
changeset
|
999 default = list(choices)[0] |
3040 | 1000 output_parent.add_argument( |
1001 '--output', '-O', choices=sorted(choices), default=default, | |
1002 help=_("select output format (default: {})".format(default))) | |
1003 output_parent.add_argument( | |
1004 '--output-option', '--oo', action="append", dest='output_opts', | |
1005 default=[], help=_("output specific option")) | |
1950 | 1006 parents.add(output_parent) |
2155 | 1007 else: |
1008 assert extra_outputs is None | |
817 | 1009 |
2532 | 1010 self._use_pubsub = kwargs.pop('use_pubsub', False) |
1011 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
|
1012 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
|
1013 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
|
1014 parents.add(self.host.make_pubsub_group(flags, defaults)) |
2532 | 1015 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
|
1016 |
1950 | 1017 # other common options |
3028 | 1018 use_opts = {k:v for k,v in kwargs.items() if k.startswith('use_')} |
1019 for param, do_use in use_opts.items(): | |
1950 | 1020 opt=param[4:] # if param is use_verbose, opt is verbose |
1021 if opt not in self.host.parents: | |
3028 | 1022 raise exceptions.InternalError("Unknown parent option {}".format(opt)) |
1950 | 1023 del kwargs[param] |
1024 if do_use: | |
1025 parents.add(self.host.parents[opt]) | |
1600 | 1026 |
817 | 1027 self.parser = host.subparsers.add_parser(name, help=help, **kwargs) |
1028 if hasattr(self, "subcommands"): | |
3040 | 1029 self.subparsers = self.parser.add_subparsers(dest='subcommand', required=True) |
817 | 1030 else: |
2532 | 1031 self.parser.set_defaults(_cmd=self) |
817 | 1032 self.add_parser_options() |
1033 | |
1034 @property | |
3046 | 1035 def sat_conf(self): |
1036 return self.host.sat_conf | |
1037 | |
1038 @property | |
817 | 1039 def args(self): |
1040 return self.host.args | |
1041 | |
1042 @property | |
1043 def profile(self): | |
1044 return self.host.profile | |
1045 | |
1046 @property | |
2490
b4bf282d6354
jp (base): added verbosity property to CommandBase
Goffi <goffi@goffi.org>
parents:
2486
diff
changeset
|
1047 def verbosity(self): |
b4bf282d6354
jp (base): added verbosity property to CommandBase
Goffi <goffi@goffi.org>
parents:
2486
diff
changeset
|
1048 return self.host.verbosity |
b4bf282d6354
jp (base): added verbosity property to CommandBase
Goffi <goffi@goffi.org>
parents:
2486
diff
changeset
|
1049 |
b4bf282d6354
jp (base): added verbosity property to CommandBase
Goffi <goffi@goffi.org>
parents:
2486
diff
changeset
|
1050 @property |
817 | 1051 def progress_id(self): |
1052 return self.host.progress_id | |
814 | 1053 |
3040 | 1054 async def set_progress_id(self, progress_id): |
1055 return await self.host.set_progress_id(progress_id) | |
817 | 1056 |
3040 | 1057 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
|
1058 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
|
1059 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
|
1060 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
|
1061 # 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
|
1062 # 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
|
1063 # 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
|
1064 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
|
1065 try: |
3040 | 1066 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
|
1067 except AttributeError: |
3040 | 1068 cache = self.host.progress_ids_cache = [] |
1069 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
|
1070 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
|
1071 if self.host.watch_progress and uid == self.progress_id: |
3040 | 1072 await self.onProgressStarted(metadata) |
1073 while True: | |
1074 await asyncio.sleep(PROGRESS_DELAY) | |
1075 cont = await self.progressUpdate() | |
1076 if not cont: | |
1077 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
|
1078 |
3040 | 1079 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
|
1080 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
|
1081 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
|
1082 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
|
1083 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
|
1084 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
|
1085 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
|
1086 pass |
3040 | 1087 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
|
1088 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
|
1089 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
|
1090 |
3040 | 1091 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
|
1092 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
|
1093 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
|
1094 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
|
1095 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
|
1096 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
|
1097 if self.host.quit_on_progress_end: |
3040 | 1098 await self.onProgressError(message) |
1099 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
|
1100 |
3040 | 1101 async def progressUpdate(self): |
1102 """This method is continualy called to update the progress bar | |
1103 | |
1104 @return (bool): False to stop being called | |
1105 """ | |
1106 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
|
1107 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
|
1108 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
|
1109 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
|
1110 except KeyError: |
3040 | 1111 self.disp(_("file size is not known, we can't show a progress bar"), 1, |
1112 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
|
1113 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
|
1114 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
|
1115 #first answer, we must construct the bar |
3040 | 1116 |
1117 # if the instance has a pbar_template attribute, it is used has model, | |
1118 # else default one is used | |
1119 # template is a list of part, where part can be either a str to show directly | |
1120 # or a list where first argument is a name of a progressbar widget, and others | |
1121 # are used as widget arguments | |
1122 try: | |
1123 template = self.pbar_template | |
1124 except AttributeError: | |
1125 template = [ | |
1126 _("Progress: "), ["Percentage"], " ", ["Bar"], " ", | |
1127 ["FileTransferSpeed"], " ", ["ETA"] | |
1128 ] | |
1129 | |
1130 widgets = [] | |
1131 for part in template: | |
1132 if isinstance(part, str): | |
1133 widgets.append(part) | |
1134 else: | |
1135 widget = getattr(progressbar, part.pop(0)) | |
1136 widgets.append(widget(*part)) | |
1137 | |
1138 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
|
1139 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
|
1140 |
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 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
|
1142 |
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 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
|
1144 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
|
1145 |
3040 | 1146 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
|
1147 |
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 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
|
1149 |
3040 | 1150 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
|
1151 """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
|
1152 |
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 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
|
1154 @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
|
1155 """ |
3028 | 1156 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
|
1157 |
3040 | 1158 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
|
1159 """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
|
1160 |
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 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
|
1162 @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
|
1163 """ |
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 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
|
1165 |
3040 | 1166 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
|
1167 """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
|
1168 |
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 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
|
1170 @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
|
1171 """ |
3028 | 1172 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
|
1173 |
3040 | 1174 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
|
1175 """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
|
1176 |
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 @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
|
1178 """ |
3568
04283582966f
core, frontends: fix invalid translatable strings.
Goffi <goffi@goffi.org>
parents:
3555
diff
changeset
|
1179 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
|
1180 |
3407
2f0be2b7de68
jp: replace `no_lf` argument by `end` in `disp` (same as in `print`)
Goffi <goffi@goffi.org>
parents:
3378
diff
changeset
|
1181 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
|
1182 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
|
1183 |
1950 | 1184 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
|
1185 try: |
33b82250eadd
jp (base): raise InternalError if output is used when use_output is not declared
Goffi <goffi@goffi.org>
parents:
2189
diff
changeset
|
1186 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
|
1187 except AttributeError: |
3040 | 1188 raise exceptions.InternalError( |
1189 _('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
|
1190 return self.host.output(output_type, self.args.output, self.extra_outputs, data) |
1950 | 1191 |
2761
4b693ea24d5f
jp (base, pubsub, ticket): handle order-by:
Goffi <goffi@goffi.org>
parents:
2706
diff
changeset
|
1192 def getPubsubExtra(self, extra=None): |
4b693ea24d5f
jp (base, pubsub, ticket): handle order-by:
Goffi <goffi@goffi.org>
parents:
2706
diff
changeset
|
1193 """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
|
1194 |
4b693ea24d5f
jp (base, pubsub, ticket): handle order-by:
Goffi <goffi@goffi.org>
parents:
2706
diff
changeset
|
1195 @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
|
1196 @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
|
1197 """ |
4b693ea24d5f
jp (base, pubsub, ticket): handle order-by:
Goffi <goffi@goffi.org>
parents:
2706
diff
changeset
|
1198 if extra is None: |
4b693ea24d5f
jp (base, pubsub, ticket): handle order-by:
Goffi <goffi@goffi.org>
parents:
2706
diff
changeset
|
1199 extra = {} |
4b693ea24d5f
jp (base, pubsub, ticket): handle order-by:
Goffi <goffi@goffi.org>
parents:
2706
diff
changeset
|
1200 else: |
3028 | 1201 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
|
1202 if intersection: |
92af49cde255
jp (base): MAM and RSM arguments can now be used for pubsub commands:
Goffi <goffi@goffi.org>
parents:
2761
diff
changeset
|
1203 raise exceptions.ConflictError( |
3028 | 1204 "given extra dict has conflicting keys with pubsub keys " |
1205 "{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
|
1206 |
92af49cde255
jp (base): MAM and RSM arguments can now be used for pubsub commands:
Goffi <goffi@goffi.org>
parents:
2761
diff
changeset
|
1207 # RSM |
92af49cde255
jp (base): MAM and RSM arguments can now be used for pubsub commands:
Goffi <goffi@goffi.org>
parents:
2761
diff
changeset
|
1208 |
3028 | 1209 for attribute in ('max', 'after', 'before', 'index'): |
1210 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
|
1211 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
|
1212 raise exceptions.ConflictError( |
3028 | 1213 "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
|
1214 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
|
1215 if value is not None: |
3028 | 1216 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
|
1217 |
92af49cde255
jp (base): MAM and RSM arguments can now be used for pubsub commands:
Goffi <goffi@goffi.org>
parents:
2761
diff
changeset
|
1218 # MAM |
92af49cde255
jp (base): MAM and RSM arguments can now be used for pubsub commands:
Goffi <goffi@goffi.org>
parents:
2761
diff
changeset
|
1219 |
3028 | 1220 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
|
1221 for key, value in self.args.mam_filters: |
3028 | 1222 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
|
1223 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
|
1224 raise exceptions.ConflictError( |
3028 | 1225 "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
|
1226 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
|
1227 |
92af49cde255
jp (base): MAM and RSM arguments can now be used for pubsub commands:
Goffi <goffi@goffi.org>
parents:
2761
diff
changeset
|
1228 # Order-By |
92af49cde255
jp (base): MAM and RSM arguments can now be used for pubsub commands:
Goffi <goffi@goffi.org>
parents:
2761
diff
changeset
|
1229 |
2761
4b693ea24d5f
jp (base, pubsub, ticket): handle order-by:
Goffi <goffi@goffi.org>
parents:
2706
diff
changeset
|
1230 try: |
4b693ea24d5f
jp (base, pubsub, ticket): handle order-by:
Goffi <goffi@goffi.org>
parents:
2706
diff
changeset
|
1231 order_by = self.args.order_by |
4b693ea24d5f
jp (base, pubsub, ticket): handle order-by:
Goffi <goffi@goffi.org>
parents:
2706
diff
changeset
|
1232 except AttributeError: |
4b693ea24d5f
jp (base, pubsub, ticket): handle order-by:
Goffi <goffi@goffi.org>
parents:
2706
diff
changeset
|
1233 pass |
4b693ea24d5f
jp (base, pubsub, ticket): handle order-by:
Goffi <goffi@goffi.org>
parents:
2706
diff
changeset
|
1234 else: |
4b693ea24d5f
jp (base, pubsub, ticket): handle order-by:
Goffi <goffi@goffi.org>
parents:
2706
diff
changeset
|
1235 if order_by is not None: |
4b693ea24d5f
jp (base, pubsub, ticket): handle order-by:
Goffi <goffi@goffi.org>
parents:
2706
diff
changeset
|
1236 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
|
1237 return extra |
4b693ea24d5f
jp (base, pubsub, ticket): handle order-by:
Goffi <goffi@goffi.org>
parents:
2706
diff
changeset
|
1238 |
817 | 1239 def add_parser_options(self): |
1240 try: | |
1241 subcommands = self.subcommands | |
1242 except AttributeError: | |
1243 # We don't have subcommands, the class need to implements add_parser_options | |
1244 raise NotImplementedError | |
1245 | |
1246 # now we add subcommands to ourself | |
1247 for cls in subcommands: | |
1248 cls(self) | |
814 | 1249 |
3040 | 1250 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
|
1251 """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
|
1252 |
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
|
1253 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
|
1254 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
|
1255 """ |
2155 | 1256 # we keep a reference to run command, it may be useful e.g. for outputs |
1257 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
|
1258 |
817 | 1259 try: |
1606
de785fcf9a7b
jp (base, file): file command and progress fixes and adaptation to new API:
Goffi <goffi@goffi.org>
parents:
1605
diff
changeset
|
1260 show_progress = self.args.progress |
817 | 1261 except AttributeError: |
1262 # the command doesn't use progress bar | |
1263 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
|
1264 else: |
1606
de785fcf9a7b
jp (base, file): file command and progress fixes and adaptation to new API:
Goffi <goffi@goffi.org>
parents:
1605
diff
changeset
|
1265 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
|
1266 self.host.watch_progress = True |
3040 | 1267 # we need to register the following signal even if we don't display the |
1268 # progress bar | |
1269 self.host.bridge.register_signal( | |
1270 "progressStarted", self.progressStartedHandler) | |
1271 self.host.bridge.register_signal( | |
1272 "progressFinished", self.progressFinishedHandler) | |
1273 self.host.bridge.register_signal( | |
1274 "progressError", self.progressErrorHandler) | |
817 | 1275 |
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
|
1276 if self.need_connect is not None: |
3040 | 1277 await self.host.connect_profile() |
1278 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
|
1279 |
3040 | 1280 async def start(self): |
1281 """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
|
1282 |
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 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
|
1284 """ |
3040 | 1285 raise NotImplementedError |
817 | 1286 |
1287 | |
1288 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
|
1289 """Specialised commands which answer to specific actions |
817 | 1290 |
1606
de785fcf9a7b
jp (base, file): file command and progress fixes and adaptation to new API:
Goffi <goffi@goffi.org>
parents:
1605
diff
changeset
|
1291 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
|
1292 """ |
2409
d2ff5ff3de77
jp (ad-hoc): new "list" and "run" commands:
Goffi <goffi@goffi.org>
parents:
2368
diff
changeset
|
1293 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
|
1294 # 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
|
1295 # 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
|
1296 # 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
|
1297 |
2486
031aa3cc67ac
jp (base): fixed assertion error when using CommandAnswering
Goffi <goffi@goffi.org>
parents:
2483
diff
changeset
|
1298 def __init__(self, *args, **kwargs): |
031aa3cc67ac
jp (base): fixed assertion error when using CommandAnswering
Goffi <goffi@goffi.org>
parents:
2483
diff
changeset
|
1299 super(CommandAnswering, self).__init__(*args, **kwargs) |
031aa3cc67ac
jp (base): fixed assertion error when using CommandAnswering
Goffi <goffi@goffi.org>
parents:
2483
diff
changeset
|
1300 |
3040 | 1301 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
|
1302 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
|
1303 return |
1606
de785fcf9a7b
jp (base, file): file command and progress fixes and adaptation to new API:
Goffi <goffi@goffi.org>
parents:
1605
diff
changeset
|
1304 try: |
de785fcf9a7b
jp (base, file): file command and progress fixes and adaptation to new API:
Goffi <goffi@goffi.org>
parents:
1605
diff
changeset
|
1305 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
|
1306 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
|
1307 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
|
1308 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
|
1309 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
|
1310 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
|
1311 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
|
1312 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
|
1313 else: |
de785fcf9a7b
jp (base, file): file command and progress fixes and adaptation to new API:
Goffi <goffi@goffi.org>
parents:
1605
diff
changeset
|
1314 try: |
de785fcf9a7b
jp (base, file): file command and progress fixes and adaptation to new API:
Goffi <goffi@goffi.org>
parents:
1605
diff
changeset
|
1315 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
|
1316 except KeyError: |
de785fcf9a7b
jp (base, file): file command and progress fixes and adaptation to new API:
Goffi <goffi@goffi.org>
parents:
1605
diff
changeset
|
1317 pass |
0 | 1318 else: |
3040 | 1319 await callback(action_data, action_id, security_limit, profile) |
587
952322b1d490
Remove trailing whitespaces.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
572
diff
changeset
|
1320 |
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
|
1321 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
|
1322 """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
|
1323 |
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 @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
|
1325 """ |
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 # 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
|
1327 # 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
|
1328 # 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
|
1329 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
|
1330 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
|
1331 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
|
1332 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
|
1333 |
3040 | 1334 async def start_answering(self): |
1335 """Auto reply to confirmation requests""" | |
2368
3865a772c360
jp (base): fixed CommandAnswering and progress bar
Goffi <goffi@goffi.org>
parents:
2313
diff
changeset
|
1336 self.host.bridge.register_signal("actionNew", self.onActionNew) |
3040 | 1337 actions = await self.host.bridge.actionsGet(self.profile) |
1623 | 1338 for action_data, action_id, security_limit in actions: |
3040 | 1339 await self.onActionNew(action_data, action_id, security_limit, self.profile) |