Mercurial > libervia-backend
comparison sat_frontends/jp/cmd_input.py @ 2624:56f94936df1e
code style reformatting using black
author | Goffi <goffi@goffi.org> |
---|---|
date | Wed, 27 Jun 2018 20:14:46 +0200 |
parents | 26edcf3a30eb |
children | 003b8b4b56a7 |
comparison
equal
deleted
inserted
replaced
2623:49533de4540b | 2624:56f94936df1e |
---|---|
26 import subprocess | 26 import subprocess |
27 import argparse | 27 import argparse |
28 import sys | 28 import sys |
29 | 29 |
30 __commands__ = ["Input"] | 30 __commands__ = ["Input"] |
31 OPT_STDIN = 'stdin' | 31 OPT_STDIN = "stdin" |
32 OPT_SHORT = 'short' | 32 OPT_SHORT = "short" |
33 OPT_LONG = 'long' | 33 OPT_LONG = "long" |
34 OPT_POS = 'positional' | 34 OPT_POS = "positional" |
35 OPT_IGNORE = 'ignore' | 35 OPT_IGNORE = "ignore" |
36 OPT_TYPES = (OPT_STDIN, OPT_SHORT, OPT_LONG, OPT_POS, OPT_IGNORE) | 36 OPT_TYPES = (OPT_STDIN, OPT_SHORT, OPT_LONG, OPT_POS, OPT_IGNORE) |
37 OPT_EMPTY_SKIP = 'skip' | 37 OPT_EMPTY_SKIP = "skip" |
38 OPT_EMPTY_IGNORE = 'ignore' | 38 OPT_EMPTY_IGNORE = "ignore" |
39 OPT_EMPTY_CHOICES = (OPT_EMPTY_SKIP, OPT_EMPTY_IGNORE) | 39 OPT_EMPTY_CHOICES = (OPT_EMPTY_SKIP, OPT_EMPTY_IGNORE) |
40 | 40 |
41 | 41 |
42 class InputCommon(base.CommandBase): | 42 class InputCommon(base.CommandBase): |
43 | |
44 def __init__(self, host, name, help): | 43 def __init__(self, host, name, help): |
45 base.CommandBase.__init__(self, host, name, use_verbose=True, use_profile=False, help=help) | 44 base.CommandBase.__init__( |
45 self, host, name, use_verbose=True, use_profile=False, help=help | |
46 ) | |
46 self.idx = 0 | 47 self.idx = 0 |
47 self.reset() | 48 self.reset() |
48 | 49 |
49 def reset(self): | 50 def reset(self): |
50 self.args_idx = 0 | 51 self.args_idx = 0 |
52 self._opts = [] | 53 self._opts = [] |
53 self._pos = [] | 54 self._pos = [] |
54 self._values_ori = [] | 55 self._values_ori = [] |
55 | 56 |
56 def add_parser_options(self): | 57 def add_parser_options(self): |
57 self.parser.add_argument("--encoding", default='utf-8', help=_(u"encoding of the input data")) | 58 self.parser.add_argument( |
58 self.parser.add_argument("-i", "--stdin", action='append_const', const=(OPT_STDIN, None), dest='arguments', help=_(u"standard input")) | 59 "--encoding", default="utf-8", help=_(u"encoding of the input data") |
59 self.parser.add_argument("-s", "--short", type=self.opt(OPT_SHORT), action='append', dest='arguments', help=_(u"short option")) | 60 ) |
60 self.parser.add_argument("-l", "--long", type=self.opt(OPT_LONG), action='append', dest='arguments', help=_(u"long option")) | 61 self.parser.add_argument( |
61 self.parser.add_argument("-p", "--positional", type=self.opt(OPT_POS), action='append', dest='arguments', help=_(u"positional argument")) | 62 "-i", |
62 self.parser.add_argument("-x", "--ignore", action='append_const', const=(OPT_IGNORE, None), dest='arguments', help=_(u"ignore value")) | 63 "--stdin", |
63 self.parser.add_argument("-D", "--debug", action='store_true', help=_(u"don't actually run commands but echo what would be launched")) | 64 action="append_const", |
64 self.parser.add_argument("--log", type=argparse.FileType('wb'), help=_(u"log stdout to FILE")) | 65 const=(OPT_STDIN, None), |
65 self.parser.add_argument("--log-err", type=argparse.FileType('wb'), help=_(u"log stderr to FILE")) | 66 dest="arguments", |
67 help=_(u"standard input"), | |
68 ) | |
69 self.parser.add_argument( | |
70 "-s", | |
71 "--short", | |
72 type=self.opt(OPT_SHORT), | |
73 action="append", | |
74 dest="arguments", | |
75 help=_(u"short option"), | |
76 ) | |
77 self.parser.add_argument( | |
78 "-l", | |
79 "--long", | |
80 type=self.opt(OPT_LONG), | |
81 action="append", | |
82 dest="arguments", | |
83 help=_(u"long option"), | |
84 ) | |
85 self.parser.add_argument( | |
86 "-p", | |
87 "--positional", | |
88 type=self.opt(OPT_POS), | |
89 action="append", | |
90 dest="arguments", | |
91 help=_(u"positional argument"), | |
92 ) | |
93 self.parser.add_argument( | |
94 "-x", | |
95 "--ignore", | |
96 action="append_const", | |
97 const=(OPT_IGNORE, None), | |
98 dest="arguments", | |
99 help=_(u"ignore value"), | |
100 ) | |
101 self.parser.add_argument( | |
102 "-D", | |
103 "--debug", | |
104 action="store_true", | |
105 help=_(u"don't actually run commands but echo what would be launched"), | |
106 ) | |
107 self.parser.add_argument( | |
108 "--log", type=argparse.FileType("wb"), help=_(u"log stdout to FILE") | |
109 ) | |
110 self.parser.add_argument( | |
111 "--log-err", type=argparse.FileType("wb"), help=_(u"log stderr to FILE") | |
112 ) | |
66 self.parser.add_argument("command", nargs=argparse.REMAINDER) | 113 self.parser.add_argument("command", nargs=argparse.REMAINDER) |
67 | 114 |
68 def opt(self, type_): | 115 def opt(self, type_): |
69 return lambda s: (type_, s) | 116 return lambda s: (type_, s) |
70 | 117 |
73 self._values_ori.append(value) | 120 self._values_ori.append(value) |
74 arguments = self.args.arguments | 121 arguments = self.args.arguments |
75 try: | 122 try: |
76 arg_type, arg_name = arguments[self.args_idx] | 123 arg_type, arg_name = arguments[self.args_idx] |
77 except IndexError: | 124 except IndexError: |
78 self.disp(_(u"arguments in input data and in arguments sequence don't match"), error=True) | 125 self.disp( |
126 _(u"arguments in input data and in arguments sequence don't match"), | |
127 error=True, | |
128 ) | |
79 self.host.quit(C.EXIT_DATA_ERROR) | 129 self.host.quit(C.EXIT_DATA_ERROR) |
80 self.args_idx += 1 | 130 self.args_idx += 1 |
81 while self.args_idx < len(arguments): | 131 while self.args_idx < len(arguments): |
82 next_arg = arguments[self.args_idx] | 132 next_arg = arguments[self.args_idx] |
83 if next_arg[0] not in OPT_TYPES: | 133 if next_arg[0] not in OPT_TYPES: |
95 return | 145 return |
96 | 146 |
97 if value is False: | 147 if value is False: |
98 # we skip the whole row | 148 # we skip the whole row |
99 if self.args.debug: | 149 if self.args.debug: |
100 self.disp(A.color(C.A_SUBHEADER, _(u'values: '), A.RESET, u', '.join(self._values_ori)), 2) | 150 self.disp( |
101 self.disp(A.color(A.BOLD, _(u'**SKIPPING**\n'))) | 151 A.color( |
152 C.A_SUBHEADER, | |
153 _(u"values: "), | |
154 A.RESET, | |
155 u", ".join(self._values_ori), | |
156 ), | |
157 2, | |
158 ) | |
159 self.disp(A.color(A.BOLD, _(u"**SKIPPING**\n"))) | |
102 self.reset() | 160 self.reset() |
103 self.idx += 1 | 161 self.idx += 1 |
104 raise exceptions.CancelError | 162 raise exceptions.CancelError |
105 | 163 |
106 if not isinstance(value, list): | 164 if not isinstance(value, list): |
107 value = [value] | 165 value = [value] |
108 | 166 |
109 for v in value: | 167 for v in value: |
110 if arg_type == OPT_STDIN: | 168 if arg_type == OPT_STDIN: |
111 self._stdin.append(v.encode('utf-8')) | 169 self._stdin.append(v.encode("utf-8")) |
112 elif arg_type == OPT_SHORT: | 170 elif arg_type == OPT_SHORT: |
113 self._opts.append('-{}'.format(arg_name)) | 171 self._opts.append("-{}".format(arg_name)) |
114 self._opts.append(v.encode('utf-8')) | 172 self._opts.append(v.encode("utf-8")) |
115 elif arg_type == OPT_LONG: | 173 elif arg_type == OPT_LONG: |
116 self._opts.append('--{}'.format(arg_name)) | 174 self._opts.append("--{}".format(arg_name)) |
117 self._opts.append(v.encode('utf-8')) | 175 self._opts.append(v.encode("utf-8")) |
118 elif arg_type == OPT_POS: | 176 elif arg_type == OPT_POS: |
119 self._pos.append(v.encode('utf-8')) | 177 self._pos.append(v.encode("utf-8")) |
120 elif arg_type == OPT_IGNORE: | 178 elif arg_type == OPT_IGNORE: |
121 pass | 179 pass |
122 else: | 180 else: |
123 self.parser.error(_(u"Invalid argument, an option type is expected, got {type_}:{name}").format( | 181 self.parser.error( |
124 type_=arg_type, name=arg_name)) | 182 _( |
183 u"Invalid argument, an option type is expected, got {type_}:{name}" | |
184 ).format(type_=arg_type, name=arg_name) | |
185 ) | |
125 | 186 |
126 def runCommand(self): | 187 def runCommand(self): |
127 """run requested command with parsed arguments""" | 188 """run requested command with parsed arguments""" |
128 if self.args_idx != len(self.args.arguments): | 189 if self.args_idx != len(self.args.arguments): |
129 self.disp(_(u"arguments in input data and in arguments sequence don't match"), error=True) | 190 self.disp( |
191 _(u"arguments in input data and in arguments sequence don't match"), | |
192 error=True, | |
193 ) | |
130 self.host.quit(C.EXIT_DATA_ERROR) | 194 self.host.quit(C.EXIT_DATA_ERROR) |
131 self.disp(A.color(C.A_HEADER, _(u'command {idx}').format(idx=self.idx)), no_lf=not self.args.debug) | 195 self.disp( |
132 stdin = ''.join(self._stdin) | 196 A.color(C.A_HEADER, _(u"command {idx}").format(idx=self.idx)), |
197 no_lf=not self.args.debug, | |
198 ) | |
199 stdin = "".join(self._stdin) | |
133 if self.args.debug: | 200 if self.args.debug: |
134 self.disp(A.color(C.A_SUBHEADER, _(u'values: '), A.RESET, u', '.join(self._values_ori)), 2) | 201 self.disp( |
202 A.color( | |
203 C.A_SUBHEADER, _(u"values: "), A.RESET, u", ".join(self._values_ori) | |
204 ), | |
205 2, | |
206 ) | |
135 | 207 |
136 if stdin: | 208 if stdin: |
137 self.disp(A.color(C.A_SUBHEADER, u'--- STDIN ---')) | 209 self.disp(A.color(C.A_SUBHEADER, u"--- STDIN ---")) |
138 self.disp(stdin.decode('utf-8')) | 210 self.disp(stdin.decode("utf-8")) |
139 self.disp(A.color(C.A_SUBHEADER, u'-------------')) | 211 self.disp(A.color(C.A_SUBHEADER, u"-------------")) |
140 self.disp(u'{indent}{prog} {static} {options} {positionals}'.format( | 212 self.disp( |
141 indent = 4*u' ', | 213 u"{indent}{prog} {static} {options} {positionals}".format( |
142 prog=sys.argv[0], | 214 indent=4 * u" ", |
143 static = ' '.join(self.args.command).decode('utf-8'), | 215 prog=sys.argv[0], |
144 options = u' '.join([o.decode('utf-8') for o in self._opts]), | 216 static=" ".join(self.args.command).decode("utf-8"), |
145 positionals = u' '.join([p.decode('utf-8') for p in self._pos]) | 217 options=u" ".join([o.decode("utf-8") for o in self._opts]), |
146 )) | 218 positionals=u" ".join([p.decode("utf-8") for p in self._pos]), |
147 self.disp(u'\n') | 219 ) |
220 ) | |
221 self.disp(u"\n") | |
148 else: | 222 else: |
149 self.disp(u' (' + u', '.join(self._values_ori) + u')', 2, no_lf=True) | 223 self.disp(u" (" + u", ".join(self._values_ori) + u")", 2, no_lf=True) |
150 args = [sys.argv[0]] + self.args.command + self._opts + self._pos | 224 args = [sys.argv[0]] + self.args.command + self._opts + self._pos |
151 p = subprocess.Popen(args, | 225 p = subprocess.Popen( |
152 stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE) | 226 args, |
227 stdin=subprocess.PIPE, | |
228 stdout=subprocess.PIPE, | |
229 stderr=subprocess.PIPE, | |
230 ) | |
153 (stdout, stderr) = p.communicate(stdin) | 231 (stdout, stderr) = p.communicate(stdin) |
154 log = self.args.log | 232 log = self.args.log |
155 log_err = self.args.log_err | 233 log_err = self.args.log_err |
156 log_tpl = '{command}\n{buff}\n\n' | 234 log_tpl = "{command}\n{buff}\n\n" |
157 if log: | 235 if log: |
158 log.write(log_tpl.format(command=' '.join(args), buff=stdout)) | 236 log.write(log_tpl.format(command=" ".join(args), buff=stdout)) |
159 if log_err: | 237 if log_err: |
160 log_err.write(log_tpl.format(command=' '.join(args), buff=stderr)) | 238 log_err.write(log_tpl.format(command=" ".join(args), buff=stderr)) |
161 ret = p.wait() | 239 ret = p.wait() |
162 if ret == 0: | 240 if ret == 0: |
163 self.disp(A.color(C.A_SUCCESS, _(u'OK'))) | 241 self.disp(A.color(C.A_SUCCESS, _(u"OK"))) |
164 else: | 242 else: |
165 self.disp(A.color(C.A_FAILURE, _(u'FAILED'))) | 243 self.disp(A.color(C.A_FAILURE, _(u"FAILED"))) |
166 | 244 |
167 self.reset() | 245 self.reset() |
168 self.idx += 1 | 246 self.idx += 1 |
169 | 247 |
170 def filter(self, filter_type, filter_arg, value): | 248 def filter(self, filter_type, filter_arg, value): |
179 """ | 257 """ |
180 raise NotImplementedError | 258 raise NotImplementedError |
181 | 259 |
182 | 260 |
183 class Csv(InputCommon): | 261 class Csv(InputCommon): |
184 | |
185 def __init__(self, host): | 262 def __init__(self, host): |
186 super(Csv, self).__init__(host, 'csv', _(u'comma-separated values')) | 263 super(Csv, self).__init__(host, "csv", _(u"comma-separated values")) |
187 | 264 |
188 def add_parser_options(self): | 265 def add_parser_options(self): |
189 InputCommon.add_parser_options(self) | 266 InputCommon.add_parser_options(self) |
190 self.parser.add_argument("-r", "--row", type=int, default=0, help=_(u"starting row (previous ones will be ignored)")) | 267 self.parser.add_argument( |
191 self.parser.add_argument("-S", "--split", action='append_const', const=('split', None), dest='arguments', help=_(u"split value in several options")) | 268 "-r", |
192 self.parser.add_argument("-E", "--empty", action='append', type=self.opt('empty'), dest='arguments', | 269 "--row", |
193 help=_(u"action to do on empty value ({choices})").format(choices=u', '.join(OPT_EMPTY_CHOICES))) | 270 type=int, |
271 default=0, | |
272 help=_(u"starting row (previous ones will be ignored)"), | |
273 ) | |
274 self.parser.add_argument( | |
275 "-S", | |
276 "--split", | |
277 action="append_const", | |
278 const=("split", None), | |
279 dest="arguments", | |
280 help=_(u"split value in several options"), | |
281 ) | |
282 self.parser.add_argument( | |
283 "-E", | |
284 "--empty", | |
285 action="append", | |
286 type=self.opt("empty"), | |
287 dest="arguments", | |
288 help=_(u"action to do on empty value ({choices})").format( | |
289 choices=u", ".join(OPT_EMPTY_CHOICES) | |
290 ), | |
291 ) | |
194 | 292 |
195 def filter(self, filter_type, filter_arg, value): | 293 def filter(self, filter_type, filter_arg, value): |
196 if filter_type == 'split': | 294 if filter_type == "split": |
197 return value.split() | 295 return value.split() |
198 elif filter_type == 'empty': | 296 elif filter_type == "empty": |
199 if filter_arg == OPT_EMPTY_IGNORE: | 297 if filter_arg == OPT_EMPTY_IGNORE: |
200 return value if value else None | 298 return value if value else None |
201 elif filter_arg == OPT_EMPTY_SKIP: | 299 elif filter_arg == OPT_EMPTY_SKIP: |
202 return value if value else False | 300 return value if value else False |
203 else: | 301 else: |
204 self.parser.error(_(u"--empty value must be one of {choices}").format(choices=u', '.join(OPT_EMPTY_CHOICES))) | 302 self.parser.error( |
303 _(u"--empty value must be one of {choices}").format( | |
304 choices=u", ".join(OPT_EMPTY_CHOICES) | |
305 ) | |
306 ) | |
205 | 307 |
206 super(Csv, self).filter(filter_type, filter_arg, value) | 308 super(Csv, self).filter(filter_type, filter_arg, value) |
207 | 309 |
208 def start(self): | 310 def start(self): |
209 import csv | 311 import csv |
312 | |
210 reader = csv.reader(sys.stdin) | 313 reader = csv.reader(sys.stdin) |
211 for idx, row in enumerate(reader): | 314 for idx, row in enumerate(reader): |
212 try: | 315 try: |
213 if idx < self.args.row: | 316 if idx < self.args.row: |
214 continue | 317 continue |
215 for value in row: | 318 for value in row: |
216 self.addValue(value.decode(self.args.encoding)) | 319 self.addValue(value.decode(self.args.encoding)) |
217 self.runCommand() | 320 self.runCommand() |
218 except exceptions.CancelError: | 321 except exceptions.CancelError: |
219 # this row has been cancelled, we skip it | 322 # this row has been cancelled, we skip it |
220 continue | 323 continue |
221 | 324 |
222 | 325 |
223 class Input(base.CommandBase): | 326 class Input(base.CommandBase): |
224 subcommands = (Csv,) | 327 subcommands = (Csv,) |
225 | 328 |
226 def __init__(self, host): | 329 def __init__(self, host): |
227 super(Input, self).__init__(host, 'input', use_profile=False, help=_(u'launch command with external input')) | 330 super(Input, self).__init__( |
331 host, | |
332 "input", | |
333 use_profile=False, | |
334 help=_(u"launch command with external input"), | |
335 ) |