jp: jp asyncio port:
/!\ this commit is huge. Jp is temporarily not working with `dbus` bridge /!\ This patch implements the port of jp to asyncio, so it is now correctly using the bridge asynchronously, and it can be used with bridges like `pb`. This also simplify the code, notably for things which were previously implemented with many callbacks (like pagination with RSM). During the process, some behaviours have been modified/fixed, in jp and backends, check diff for details.
This commit is contained in:
parent
5cee4fbab7
commit
76aadbb3fb
1 changed files with 3299 additions and 3300 deletions
|
|
@ -18,14 +18,16 @@
|
|||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
import subprocess
|
||||
import argparse
|
||||
import sys
|
||||
import shlex
|
||||
import asyncio
|
||||
from . import base
|
||||
from sat.core.i18n import _
|
||||
from sat.core import exceptions
|
||||
from sat_frontends.jp.constants import Const as C
|
||||
from sat.tools.common.ansi import ANSI as A
|
||||
import subprocess
|
||||
import argparse
|
||||
import sys
|
||||
|
||||
__commands__ = ["Input"]
|
||||
OPT_STDIN = "stdin"
|
||||
|
|
@ -105,10 +107,10 @@ class InputCommon(base.CommandBase):
|
|||
help=_("don't actually run commands but echo what would be launched"),
|
||||
)
|
||||
self.parser.add_argument(
|
||||
"--log", type=argparse.FileType("wb"), help=_("log stdout to FILE")
|
||||
"--log", type=argparse.FileType("w"), help=_("log stdout to FILE")
|
||||
)
|
||||
self.parser.add_argument(
|
||||
"--log-err", type=argparse.FileType("wb"), help=_("log stderr to FILE")
|
||||
"--log-err", type=argparse.FileType("w"), help=_("log stderr to FILE")
|
||||
)
|
||||
self.parser.add_argument("command", nargs=argparse.REMAINDER)
|
||||
|
||||
|
|
@ -166,15 +168,15 @@ class InputCommon(base.CommandBase):
|
|||
|
||||
for v in value:
|
||||
if arg_type == OPT_STDIN:
|
||||
self._stdin.append(v.encode("utf-8"))
|
||||
self._stdin.append(v)
|
||||
elif arg_type == OPT_SHORT:
|
||||
self._opts.append("-{}".format(arg_name))
|
||||
self._opts.append(v.encode("utf-8"))
|
||||
self._opts.append(v)
|
||||
elif arg_type == OPT_LONG:
|
||||
self._opts.append("--{}".format(arg_name))
|
||||
self._opts.append(v.encode("utf-8"))
|
||||
self._opts.append(v)
|
||||
elif arg_type == OPT_POS:
|
||||
self._pos.append(v.encode("utf-8"))
|
||||
self._pos.append(v)
|
||||
elif arg_type == OPT_IGNORE:
|
||||
pass
|
||||
else:
|
||||
|
|
@ -184,7 +186,7 @@ class InputCommon(base.CommandBase):
|
|||
).format(type_=arg_type, name=arg_name)
|
||||
)
|
||||
|
||||
def runCommand(self):
|
||||
async def runCommand(self):
|
||||
"""run requested command with parsed arguments"""
|
||||
if self.args_idx != len(self.args.arguments):
|
||||
self.disp(
|
||||
|
|
@ -200,7 +202,10 @@ class InputCommon(base.CommandBase):
|
|||
if self.args.debug:
|
||||
self.disp(
|
||||
A.color(
|
||||
C.A_SUBHEADER, _("values: "), A.RESET, ", ".join(self._values_ori)
|
||||
C.A_SUBHEADER,
|
||||
_("values: "),
|
||||
A.RESET,
|
||||
", ".join([shlex.quote(a) for a in self._values_ori])
|
||||
),
|
||||
2,
|
||||
)
|
||||
|
|
@ -209,34 +214,39 @@ class InputCommon(base.CommandBase):
|
|||
self.disp(A.color(C.A_SUBHEADER, "--- STDIN ---"))
|
||||
self.disp(stdin)
|
||||
self.disp(A.color(C.A_SUBHEADER, "-------------"))
|
||||
|
||||
self.disp(
|
||||
"{indent}{prog} {static} {options} {positionals}".format(
|
||||
indent=4 * " ",
|
||||
prog=sys.argv[0],
|
||||
static=" ".join(self.args.command),
|
||||
options=" ".join([o for o in self._opts]),
|
||||
positionals=" ".join([p for p in self._pos]),
|
||||
options=" ".join(shlex.quote(o) for o in self._opts),
|
||||
positionals=" ".join(shlex.quote(p) for p in self._pos),
|
||||
)
|
||||
)
|
||||
self.disp("\n")
|
||||
else:
|
||||
self.disp(" (" + ", ".join(self._values_ori) + ")", 2, no_lf=True)
|
||||
args = [sys.argv[0]] + self.args.command + self._opts + self._pos
|
||||
p = subprocess.Popen(
|
||||
args,
|
||||
p = await asyncio.create_subprocess_exec(
|
||||
*args,
|
||||
stdin=subprocess.PIPE,
|
||||
stdout=subprocess.PIPE,
|
||||
stderr=subprocess.PIPE,
|
||||
)
|
||||
(stdout, stderr) = p.communicate(stdin)
|
||||
stdout, stderr = await p.communicate(stdin.encode('utf-8'))
|
||||
log = self.args.log
|
||||
log_err = self.args.log_err
|
||||
log_tpl = "{command}\n{buff}\n\n"
|
||||
if log:
|
||||
log.write(log_tpl.format(command=" ".join(args), buff=stdout))
|
||||
log.write(log_tpl.format(
|
||||
command=" ".join(shlex.quote(a) for a in args),
|
||||
buff=stdout.decode('utf-8', 'replace')))
|
||||
if log_err:
|
||||
log_err.write(log_tpl.format(command=" ".join(args), buff=stderr))
|
||||
ret = p.wait()
|
||||
log_err.write(log_tpl.format(
|
||||
command=" ".join(shlex.quote(a) for a in args),
|
||||
buff=stderr.decode('utf-8', 'replace')))
|
||||
ret = p.returncode
|
||||
if ret == 0:
|
||||
self.disp(A.color(C.A_SUCCESS, _("OK")))
|
||||
else:
|
||||
|
|
@ -307,21 +317,25 @@ class Csv(InputCommon):
|
|||
|
||||
super(Csv, self).filter(filter_type, filter_arg, value)
|
||||
|
||||
def start(self):
|
||||
async def start(self):
|
||||
import csv
|
||||
|
||||
if self.args.encoding:
|
||||
sys.stdin.reconfigure(encoding=self.args.encoding, errors="replace")
|
||||
reader = csv.reader(sys.stdin)
|
||||
for idx, row in enumerate(reader):
|
||||
try:
|
||||
if idx < self.args.row:
|
||||
continue
|
||||
for value in row:
|
||||
self.addValue(value.decode(self.args.encoding))
|
||||
self.runCommand()
|
||||
self.addValue(value)
|
||||
await self.runCommand()
|
||||
except exceptions.CancelError:
|
||||
# this row has been cancelled, we skip it
|
||||
continue
|
||||
|
||||
self.host.quit()
|
||||
|
||||
|
||||
class Input(base.CommandBase):
|
||||
subcommands = (Csv,)
|
||||
|
|
|
|||
Loading…
Reference in a new issue