annotate frontends/src/jp/cmd_input.py @ 2309:c7a72b75232b

jp (shell): shell command (REPL mode), first draft: This command launch jp in REPL mode, allowing do normal jp commands with some facilities. Command can be selected with "cmd" (e.g. "cmd blog"). An argument can be fixed with "use" (e.g. "use output fancy"). Command is launched with "do", or directly with its name if it doesn't conflict with a shell command. Arguments completion is still TODO (only shell commands are completed so far).
author Goffi <goffi@goffi.org>
date Thu, 06 Jul 2017 20:28:25 +0200
parents cbc989508474
children 8b37a62336c3
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
2278
489efbda377c jp (input): input command first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
1 #!/usr/bin/env python2
489efbda377c jp (input): input command first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
2 # -*- coding: utf-8 -*-
489efbda377c jp (input): input command first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
3
489efbda377c jp (input): input command first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
4 # jp: a SàT command line tool
489efbda377c jp (input): input command first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
5 # Copyright (C) 2009-2016 Jérôme Poisson (goffi@goffi.org)
489efbda377c jp (input): input command first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
6
489efbda377c jp (input): input command first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
7 # This program is free software: you can redistribute it and/or modify
489efbda377c jp (input): input command first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
8 # it under the terms of the GNU Affero General Public License as published by
489efbda377c jp (input): input command first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
9 # the Free Software Foundation, either version 3 of the License, or
489efbda377c jp (input): input command first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
10 # (at your option) any later version.
489efbda377c jp (input): input command first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
11
489efbda377c jp (input): input command first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
12 # This program is distributed in the hope that it will be useful,
489efbda377c jp (input): input command first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
13 # but WITHOUT ANY WARRANTY; without even the implied warranty of
489efbda377c jp (input): input command first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
489efbda377c jp (input): input command first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
15 # GNU Affero General Public License for more details.
489efbda377c jp (input): input command first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
16
489efbda377c jp (input): input command first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
17 # You should have received a copy of the GNU Affero General Public License
489efbda377c jp (input): input command first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
18 # along with this program. If not, see <http://www.gnu.org/licenses/>.
489efbda377c jp (input): input command first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
19
489efbda377c jp (input): input command first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
20
489efbda377c jp (input): input command first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
21 import base
489efbda377c jp (input): input command first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
22 from sat.core.i18n import _
2282
d8e48c850ad2 jp (input): log improvments + empty filter:
Goffi <goffi@goffi.org>
parents: 2278
diff changeset
23 from sat.core import exceptions
2278
489efbda377c jp (input): input command first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
24 from sat_frontends.jp.constants import Const as C
489efbda377c jp (input): input command first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
25 from sat.tools.common.ansi import ANSI as A
489efbda377c jp (input): input command first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
26 import subprocess
489efbda377c jp (input): input command first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
27 import argparse
489efbda377c jp (input): input command first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
28 import sys
489efbda377c jp (input): input command first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
29
489efbda377c jp (input): input command first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
30 __commands__ = ["Input"]
489efbda377c jp (input): input command first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
31 OPT_STDIN = 'stdin'
489efbda377c jp (input): input command first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
32 OPT_SHORT = 'short'
489efbda377c jp (input): input command first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
33 OPT_LONG = 'long'
489efbda377c jp (input): input command first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
34 OPT_POS = 'positional'
489efbda377c jp (input): input command first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
35 OPT_IGNORE = 'ignore'
489efbda377c jp (input): input command first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
36 OPT_TYPES = (OPT_STDIN, OPT_SHORT, OPT_LONG, OPT_POS, OPT_IGNORE)
2282
d8e48c850ad2 jp (input): log improvments + empty filter:
Goffi <goffi@goffi.org>
parents: 2278
diff changeset
37 OPT_EMPTY_SKIP = 'skip'
d8e48c850ad2 jp (input): log improvments + empty filter:
Goffi <goffi@goffi.org>
parents: 2278
diff changeset
38 OPT_EMPTY_IGNORE = 'ignore'
d8e48c850ad2 jp (input): log improvments + empty filter:
Goffi <goffi@goffi.org>
parents: 2278
diff changeset
39 OPT_EMPTY_CHOICES = (OPT_EMPTY_SKIP, OPT_EMPTY_IGNORE)
2278
489efbda377c jp (input): input command first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
40
489efbda377c jp (input): input command first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
41
489efbda377c jp (input): input command first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
42 class InputCommon(base.CommandBase):
489efbda377c jp (input): input command first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
43
489efbda377c jp (input): input command first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
44 def __init__(self, host, name, help):
489efbda377c jp (input): input command first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
45 base.CommandBase.__init__(self, host, name, use_verbose=True, use_profile=False, help=help)
489efbda377c jp (input): input command first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
46 self.idx = 0
489efbda377c jp (input): input command first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
47 self.reset()
489efbda377c jp (input): input command first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
48
489efbda377c jp (input): input command first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
49 def reset(self):
489efbda377c jp (input): input command first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
50 self.args_idx = 0
489efbda377c jp (input): input command first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
51 self._stdin = []
489efbda377c jp (input): input command first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
52 self._opts = []
489efbda377c jp (input): input command first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
53 self._pos = []
2282
d8e48c850ad2 jp (input): log improvments + empty filter:
Goffi <goffi@goffi.org>
parents: 2278
diff changeset
54 self._values_ori = []
2278
489efbda377c jp (input): input command first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
55
489efbda377c jp (input): input command first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
56 def add_parser_options(self):
489efbda377c jp (input): input command first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
57 self.parser.add_argument("--encoding", default='utf-8', help=_(u"encoding of the input data"))
489efbda377c jp (input): input command first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
58 self.parser.add_argument("-i", "--stdin", action='append_const', const=(OPT_STDIN, None), dest='arguments', help=_(u"standard input"))
489efbda377c jp (input): input command first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
59 self.parser.add_argument("-s", "--short", type=self.opt(OPT_SHORT), action='append', dest='arguments', help=_(u"short option"))
489efbda377c jp (input): input command first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
60 self.parser.add_argument("-l", "--long", type=self.opt(OPT_LONG), action='append', dest='arguments', help=_(u"long option"))
489efbda377c jp (input): input command first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
61 self.parser.add_argument("-p", "--positional", type=self.opt(OPT_POS), action='append', dest='arguments', help=_(u"positional argument"))
489efbda377c jp (input): input command first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
62 self.parser.add_argument("-x", "--ignore", action='append_const', const=(OPT_IGNORE, None), dest='arguments', help=_(u"ignore value"))
489efbda377c jp (input): input command first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
63 self.parser.add_argument("-D", "--debug", action='store_true', help=_(u"don't actually run commands but echo what would be launched"))
2282
d8e48c850ad2 jp (input): log improvments + empty filter:
Goffi <goffi@goffi.org>
parents: 2278
diff changeset
64 self.parser.add_argument("--log", type=argparse.FileType('wb'), help=_(u"log stdout to FILE"))
d8e48c850ad2 jp (input): log improvments + empty filter:
Goffi <goffi@goffi.org>
parents: 2278
diff changeset
65 self.parser.add_argument("--log-err", type=argparse.FileType('wb'), help=_(u"log stderr to FILE"))
2278
489efbda377c jp (input): input command first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
66 self.parser.add_argument("command", nargs=argparse.REMAINDER)
489efbda377c jp (input): input command first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
67
489efbda377c jp (input): input command first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
68 def opt(self, type_):
489efbda377c jp (input): input command first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
69 return lambda s: (type_, s)
489efbda377c jp (input): input command first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
70
489efbda377c jp (input): input command first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
71 def addValue(self, value):
489efbda377c jp (input): input command first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
72 """add a parsed value according to arguments sequence"""
2282
d8e48c850ad2 jp (input): log improvments + empty filter:
Goffi <goffi@goffi.org>
parents: 2278
diff changeset
73 self._values_ori.append(value)
2278
489efbda377c jp (input): input command first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
74 arguments = self.args.arguments
489efbda377c jp (input): input command first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
75 try:
489efbda377c jp (input): input command first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
76 arg_type, arg_name = arguments[self.args_idx]
489efbda377c jp (input): input command first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
77 except IndexError:
489efbda377c jp (input): input command first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
78 self.disp(_(u"arguments in input data and in arguments sequence don't match"), error=True)
489efbda377c jp (input): input command first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
79 self.host.quit(C.EXIT_DATA_ERROR)
489efbda377c jp (input): input command first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
80 self.args_idx += 1
489efbda377c jp (input): input command first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
81 while self.args_idx < len(arguments):
489efbda377c jp (input): input command first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
82 next_arg = arguments[self.args_idx]
489efbda377c jp (input): input command first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
83 if next_arg[0] not in OPT_TYPES:
2282
d8e48c850ad2 jp (input): log improvments + empty filter:
Goffi <goffi@goffi.org>
parents: 2278
diff changeset
84 # value will not be used if False or None, so we skip filter
d8e48c850ad2 jp (input): log improvments + empty filter:
Goffi <goffi@goffi.org>
parents: 2278
diff changeset
85 if value not in (False, None):
d8e48c850ad2 jp (input): log improvments + empty filter:
Goffi <goffi@goffi.org>
parents: 2278
diff changeset
86 # we have a filter
d8e48c850ad2 jp (input): log improvments + empty filter:
Goffi <goffi@goffi.org>
parents: 2278
diff changeset
87 filter_type, filter_arg = arguments[self.args_idx]
d8e48c850ad2 jp (input): log improvments + empty filter:
Goffi <goffi@goffi.org>
parents: 2278
diff changeset
88 value = self.filter(filter_type, filter_arg, value)
2278
489efbda377c jp (input): input command first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
89 else:
489efbda377c jp (input): input command first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
90 break
489efbda377c jp (input): input command first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
91 self.args_idx += 1
489efbda377c jp (input): input command first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
92
2282
d8e48c850ad2 jp (input): log improvments + empty filter:
Goffi <goffi@goffi.org>
parents: 2278
diff changeset
93 if value is None:
d8e48c850ad2 jp (input): log improvments + empty filter:
Goffi <goffi@goffi.org>
parents: 2278
diff changeset
94 # we ignore this argument
d8e48c850ad2 jp (input): log improvments + empty filter:
Goffi <goffi@goffi.org>
parents: 2278
diff changeset
95 return
d8e48c850ad2 jp (input): log improvments + empty filter:
Goffi <goffi@goffi.org>
parents: 2278
diff changeset
96
d8e48c850ad2 jp (input): log improvments + empty filter:
Goffi <goffi@goffi.org>
parents: 2278
diff changeset
97 if value is False:
d8e48c850ad2 jp (input): log improvments + empty filter:
Goffi <goffi@goffi.org>
parents: 2278
diff changeset
98 # we skip the whole row
d8e48c850ad2 jp (input): log improvments + empty filter:
Goffi <goffi@goffi.org>
parents: 2278
diff changeset
99 if self.args.debug:
d8e48c850ad2 jp (input): log improvments + empty filter:
Goffi <goffi@goffi.org>
parents: 2278
diff changeset
100 self.disp(A.color(C.A_SUBHEADER, _(u'values: '), A.RESET, u', '.join(self._values_ori)), 2)
d8e48c850ad2 jp (input): log improvments + empty filter:
Goffi <goffi@goffi.org>
parents: 2278
diff changeset
101 self.disp(A.color(A.BOLD, _(u'**SKIPPING**\n')))
d8e48c850ad2 jp (input): log improvments + empty filter:
Goffi <goffi@goffi.org>
parents: 2278
diff changeset
102 self.reset()
d8e48c850ad2 jp (input): log improvments + empty filter:
Goffi <goffi@goffi.org>
parents: 2278
diff changeset
103 self.idx += 1
d8e48c850ad2 jp (input): log improvments + empty filter:
Goffi <goffi@goffi.org>
parents: 2278
diff changeset
104 raise exceptions.CancelError
d8e48c850ad2 jp (input): log improvments + empty filter:
Goffi <goffi@goffi.org>
parents: 2278
diff changeset
105
2278
489efbda377c jp (input): input command first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
106 if not isinstance(value, list):
489efbda377c jp (input): input command first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
107 value = [value]
489efbda377c jp (input): input command first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
108
489efbda377c jp (input): input command first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
109 for v in value:
489efbda377c jp (input): input command first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
110 if arg_type == OPT_STDIN:
489efbda377c jp (input): input command first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
111 self._stdin.append(v.encode('utf-8'))
489efbda377c jp (input): input command first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
112 elif arg_type == OPT_SHORT:
489efbda377c jp (input): input command first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
113 self._opts.append('-{}'.format(arg_name))
489efbda377c jp (input): input command first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
114 self._opts.append(v.encode('utf-8'))
489efbda377c jp (input): input command first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
115 elif arg_type == OPT_LONG:
489efbda377c jp (input): input command first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
116 self._opts.append('--{}'.format(arg_name))
489efbda377c jp (input): input command first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
117 self._opts.append(v.encode('utf-8'))
489efbda377c jp (input): input command first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
118 elif arg_type == OPT_POS:
489efbda377c jp (input): input command first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
119 self._pos.append(v.encode('utf-8'))
489efbda377c jp (input): input command first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
120 elif arg_type == OPT_IGNORE:
489efbda377c jp (input): input command first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
121 pass
489efbda377c jp (input): input command first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
122 else:
489efbda377c jp (input): input command first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
123 self.parser.error(_(u"Invalid argument, an option type is expected, got {type_}:{name}").format(
489efbda377c jp (input): input command first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
124 type_=arg_type, name=arg_name))
489efbda377c jp (input): input command first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
125
489efbda377c jp (input): input command first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
126 def runCommand(self):
489efbda377c jp (input): input command first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
127 """run requested command with parsed arguments"""
489efbda377c jp (input): input command first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
128 if self.args_idx != len(self.args.arguments):
489efbda377c jp (input): input command first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
129 self.disp(_(u"arguments in input data and in arguments sequence don't match"), error=True)
489efbda377c jp (input): input command first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
130 self.host.quit(C.EXIT_DATA_ERROR)
2282
d8e48c850ad2 jp (input): log improvments + empty filter:
Goffi <goffi@goffi.org>
parents: 2278
diff changeset
131 self.disp(A.color(C.A_HEADER, _(u'command {idx}').format(idx=self.idx)), no_lf=not self.args.debug)
2278
489efbda377c jp (input): input command first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
132 stdin = ''.join(self._stdin)
489efbda377c jp (input): input command first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
133 if self.args.debug:
2282
d8e48c850ad2 jp (input): log improvments + empty filter:
Goffi <goffi@goffi.org>
parents: 2278
diff changeset
134 self.disp(A.color(C.A_SUBHEADER, _(u'values: '), A.RESET, u', '.join(self._values_ori)), 2)
d8e48c850ad2 jp (input): log improvments + empty filter:
Goffi <goffi@goffi.org>
parents: 2278
diff changeset
135
2278
489efbda377c jp (input): input command first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
136 if stdin:
2282
d8e48c850ad2 jp (input): log improvments + empty filter:
Goffi <goffi@goffi.org>
parents: 2278
diff changeset
137 self.disp(A.color(C.A_SUBHEADER, u'--- STDIN ---'))
2278
489efbda377c jp (input): input command first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
138 self.disp(stdin.decode('utf-8'))
2282
d8e48c850ad2 jp (input): log improvments + empty filter:
Goffi <goffi@goffi.org>
parents: 2278
diff changeset
139 self.disp(A.color(C.A_SUBHEADER, u'-------------'))
2278
489efbda377c jp (input): input command first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
140 self.disp(u'{indent}{prog} {static} {options} {positionals}'.format(
489efbda377c jp (input): input command first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
141 indent = 4*u' ',
489efbda377c jp (input): input command first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
142 prog=sys.argv[0],
2293
cbc989508474 jp (input/csv): fixed encoding issue in debug mode
Goffi <goffi@goffi.org>
parents: 2282
diff changeset
143 static = ' '.join(self.args.command).decode('utf-8'),
cbc989508474 jp (input/csv): fixed encoding issue in debug mode
Goffi <goffi@goffi.org>
parents: 2282
diff changeset
144 options = u' '.join([o.decode('utf-8') for o in self._opts]),
cbc989508474 jp (input/csv): fixed encoding issue in debug mode
Goffi <goffi@goffi.org>
parents: 2282
diff changeset
145 positionals = u' '.join([p.decode('utf-8') for p in self._pos])
2278
489efbda377c jp (input): input command first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
146 ))
2282
d8e48c850ad2 jp (input): log improvments + empty filter:
Goffi <goffi@goffi.org>
parents: 2278
diff changeset
147 self.disp(u'\n')
2278
489efbda377c jp (input): input command first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
148 else:
2282
d8e48c850ad2 jp (input): log improvments + empty filter:
Goffi <goffi@goffi.org>
parents: 2278
diff changeset
149 self.disp(u' (' + u', '.join(self._values_ori) + u')', 2, no_lf=True)
d8e48c850ad2 jp (input): log improvments + empty filter:
Goffi <goffi@goffi.org>
parents: 2278
diff changeset
150 args = [sys.argv[0]] + self.args.command + self._opts + self._pos
d8e48c850ad2 jp (input): log improvments + empty filter:
Goffi <goffi@goffi.org>
parents: 2278
diff changeset
151 p = subprocess.Popen(args,
d8e48c850ad2 jp (input): log improvments + empty filter:
Goffi <goffi@goffi.org>
parents: 2278
diff changeset
152 stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
d8e48c850ad2 jp (input): log improvments + empty filter:
Goffi <goffi@goffi.org>
parents: 2278
diff changeset
153 (stdout, stderr) = p.communicate(stdin)
d8e48c850ad2 jp (input): log improvments + empty filter:
Goffi <goffi@goffi.org>
parents: 2278
diff changeset
154 log = self.args.log
d8e48c850ad2 jp (input): log improvments + empty filter:
Goffi <goffi@goffi.org>
parents: 2278
diff changeset
155 log_err = self.args.log_err
d8e48c850ad2 jp (input): log improvments + empty filter:
Goffi <goffi@goffi.org>
parents: 2278
diff changeset
156 log_tpl = '{command}\n{buff}\n\n'
d8e48c850ad2 jp (input): log improvments + empty filter:
Goffi <goffi@goffi.org>
parents: 2278
diff changeset
157 if log:
d8e48c850ad2 jp (input): log improvments + empty filter:
Goffi <goffi@goffi.org>
parents: 2278
diff changeset
158 log.write(log_tpl.format(command=' '.join(args), buff=stdout))
d8e48c850ad2 jp (input): log improvments + empty filter:
Goffi <goffi@goffi.org>
parents: 2278
diff changeset
159 if log_err:
d8e48c850ad2 jp (input): log improvments + empty filter:
Goffi <goffi@goffi.org>
parents: 2278
diff changeset
160 log_err.write(log_tpl.format(command=' '.join(args), buff=stderr))
d8e48c850ad2 jp (input): log improvments + empty filter:
Goffi <goffi@goffi.org>
parents: 2278
diff changeset
161 ret = p.wait()
2278
489efbda377c jp (input): input command first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
162 if ret == 0:
489efbda377c jp (input): input command first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
163 self.disp(A.color(C.A_SUCCESS, _(u'OK')))
489efbda377c jp (input): input command first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
164 else:
489efbda377c jp (input): input command first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
165 self.disp(A.color(C.A_FAILURE, _(u'FAILED')))
489efbda377c jp (input): input command first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
166
489efbda377c jp (input): input command first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
167 self.reset()
489efbda377c jp (input): input command first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
168 self.idx += 1
489efbda377c jp (input): input command first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
169
489efbda377c jp (input): input command first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
170 def filter(self, filter_type, filter_arg, value):
2282
d8e48c850ad2 jp (input): log improvments + empty filter:
Goffi <goffi@goffi.org>
parents: 2278
diff changeset
171 """change input value
d8e48c850ad2 jp (input): log improvments + empty filter:
Goffi <goffi@goffi.org>
parents: 2278
diff changeset
172
d8e48c850ad2 jp (input): log improvments + empty filter:
Goffi <goffi@goffi.org>
parents: 2278
diff changeset
173 @param filter_type(unicode): name of the filter
d8e48c850ad2 jp (input): log improvments + empty filter:
Goffi <goffi@goffi.org>
parents: 2278
diff changeset
174 @param filter_arg(unicode, None): argument of the filter
d8e48c850ad2 jp (input): log improvments + empty filter:
Goffi <goffi@goffi.org>
parents: 2278
diff changeset
175 @param value(unicode): value to filter
d8e48c850ad2 jp (input): log improvments + empty filter:
Goffi <goffi@goffi.org>
parents: 2278
diff changeset
176 @return (unicode, False, None): modified value
d8e48c850ad2 jp (input): log improvments + empty filter:
Goffi <goffi@goffi.org>
parents: 2278
diff changeset
177 False to skip the whole row
d8e48c850ad2 jp (input): log improvments + empty filter:
Goffi <goffi@goffi.org>
parents: 2278
diff changeset
178 None to ignore this argument (but continue row with other ones)
d8e48c850ad2 jp (input): log improvments + empty filter:
Goffi <goffi@goffi.org>
parents: 2278
diff changeset
179 """
2278
489efbda377c jp (input): input command first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
180 raise NotImplementedError
489efbda377c jp (input): input command first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
181
489efbda377c jp (input): input command first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
182
489efbda377c jp (input): input command first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
183 class Csv(InputCommon):
489efbda377c jp (input): input command first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
184
489efbda377c jp (input): input command first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
185 def __init__(self, host):
489efbda377c jp (input): input command first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
186 super(Csv, self).__init__(host, 'csv', _(u'comma-separated values'))
489efbda377c jp (input): input command first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
187
489efbda377c jp (input): input command first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
188 def add_parser_options(self):
489efbda377c jp (input): input command first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
189 InputCommon.add_parser_options(self)
489efbda377c jp (input): input command first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
190 self.parser.add_argument("-r", "--row", type=int, default=0, help=_(u"starting row (previous ones will be ignored)"))
489efbda377c jp (input): input command first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
191 self.parser.add_argument("-S", "--split", action='append_const', const=('split', None), dest='arguments', help=_(u"split value in several options"))
2282
d8e48c850ad2 jp (input): log improvments + empty filter:
Goffi <goffi@goffi.org>
parents: 2278
diff changeset
192 self.parser.add_argument("-E", "--empty", action='append', type=self.opt('empty'), dest='arguments',
d8e48c850ad2 jp (input): log improvments + empty filter:
Goffi <goffi@goffi.org>
parents: 2278
diff changeset
193 help=_(u"action to do on empty value ({choices})").format(choices=u', '.join(OPT_EMPTY_CHOICES)))
2278
489efbda377c jp (input): input command first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
194
2282
d8e48c850ad2 jp (input): log improvments + empty filter:
Goffi <goffi@goffi.org>
parents: 2278
diff changeset
195 def filter(self, filter_type, filter_arg, value):
2278
489efbda377c jp (input): input command first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
196 if filter_type == 'split':
489efbda377c jp (input): input command first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
197 return value.split()
2282
d8e48c850ad2 jp (input): log improvments + empty filter:
Goffi <goffi@goffi.org>
parents: 2278
diff changeset
198 elif filter_type == 'empty':
d8e48c850ad2 jp (input): log improvments + empty filter:
Goffi <goffi@goffi.org>
parents: 2278
diff changeset
199 if filter_arg == OPT_EMPTY_IGNORE:
d8e48c850ad2 jp (input): log improvments + empty filter:
Goffi <goffi@goffi.org>
parents: 2278
diff changeset
200 return value if value else None
d8e48c850ad2 jp (input): log improvments + empty filter:
Goffi <goffi@goffi.org>
parents: 2278
diff changeset
201 elif filter_arg == OPT_EMPTY_SKIP:
d8e48c850ad2 jp (input): log improvments + empty filter:
Goffi <goffi@goffi.org>
parents: 2278
diff changeset
202 return value if value else False
d8e48c850ad2 jp (input): log improvments + empty filter:
Goffi <goffi@goffi.org>
parents: 2278
diff changeset
203 else:
d8e48c850ad2 jp (input): log improvments + empty filter:
Goffi <goffi@goffi.org>
parents: 2278
diff changeset
204 self.parser.error(_(u"--empty value must be one of {choices}").format(choices=u', '.join(OPT_EMPTY_CHOICES)))
2278
489efbda377c jp (input): input command first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
205
489efbda377c jp (input): input command first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
206 super(Csv, self).filter(filter_type, filter_arg, value)
489efbda377c jp (input): input command first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
207
489efbda377c jp (input): input command first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
208 def start(self):
489efbda377c jp (input): input command first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
209 import csv
489efbda377c jp (input): input command first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
210 reader = csv.reader(sys.stdin)
489efbda377c jp (input): input command first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
211 for idx, row in enumerate(reader):
2282
d8e48c850ad2 jp (input): log improvments + empty filter:
Goffi <goffi@goffi.org>
parents: 2278
diff changeset
212 try:
d8e48c850ad2 jp (input): log improvments + empty filter:
Goffi <goffi@goffi.org>
parents: 2278
diff changeset
213 if idx < self.args.row:
d8e48c850ad2 jp (input): log improvments + empty filter:
Goffi <goffi@goffi.org>
parents: 2278
diff changeset
214 continue
d8e48c850ad2 jp (input): log improvments + empty filter:
Goffi <goffi@goffi.org>
parents: 2278
diff changeset
215 for value in row:
d8e48c850ad2 jp (input): log improvments + empty filter:
Goffi <goffi@goffi.org>
parents: 2278
diff changeset
216 self.addValue(value.decode(self.args.encoding))
d8e48c850ad2 jp (input): log improvments + empty filter:
Goffi <goffi@goffi.org>
parents: 2278
diff changeset
217 self.runCommand()
d8e48c850ad2 jp (input): log improvments + empty filter:
Goffi <goffi@goffi.org>
parents: 2278
diff changeset
218 except exceptions.CancelError:
d8e48c850ad2 jp (input): log improvments + empty filter:
Goffi <goffi@goffi.org>
parents: 2278
diff changeset
219 # this row has been cancelled, we skip it
2278
489efbda377c jp (input): input command first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
220 continue
489efbda377c jp (input): input command first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
221
489efbda377c jp (input): input command first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
222
489efbda377c jp (input): input command first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
223 class Input(base.CommandBase):
489efbda377c jp (input): input command first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
224 subcommands = (Csv,)
489efbda377c jp (input): input command first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
225
489efbda377c jp (input): input command first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
226 def __init__(self, host):
489efbda377c jp (input): input command first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
227 super(Input, self).__init__(host, 'input', use_profile=False, help=_(u'launch command with external input'))