[postprocessor:exec] improve; add command-line option (#421)
This commit is contained in:
@@ -27,6 +27,15 @@ class ConfigConstAction(argparse.Action):
|
||||
namespace.options.append(((self.dest,), self.const))
|
||||
|
||||
|
||||
class AppendCommandAction(argparse.Action):
|
||||
def __call__(self, parser, namespace, values, option_string=None):
|
||||
items = getattr(namespace, self.dest, None) or []
|
||||
val = self.const.copy()
|
||||
val["command"] = values
|
||||
items.append(val)
|
||||
setattr(namespace, self.dest, items)
|
||||
|
||||
|
||||
class DeprecatedConfigConstAction(argparse.Action):
|
||||
"""Set argparse const values as config values + deprecation warning"""
|
||||
def __call__(self, parser, namespace, values, option_string=None):
|
||||
@@ -303,6 +312,12 @@ def build_parser():
|
||||
action="append_const", const={"name": "zip"},
|
||||
help="Store downloaded files in a ZIP archive",
|
||||
)
|
||||
postprocessor.add_argument(
|
||||
"--exec",
|
||||
dest="postprocessors", metavar="CMD",
|
||||
action=AppendCommandAction, const={"name": "exec"},
|
||||
help="Execute CMD for each downloaded file",
|
||||
)
|
||||
postprocessor.add_argument(
|
||||
"--ugoira-conv",
|
||||
dest="postprocessors",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Copyright 2018 Mike Fährmann
|
||||
# Copyright 2018-2019 Mike Fährmann
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License version 2 as
|
||||
@@ -9,7 +9,9 @@
|
||||
"""Execute processes"""
|
||||
|
||||
from .common import PostProcessor
|
||||
from .. import util
|
||||
import subprocess
|
||||
import shlex
|
||||
|
||||
|
||||
class ExecPP(PostProcessor):
|
||||
@@ -17,27 +19,60 @@ class ExecPP(PostProcessor):
|
||||
def __init__(self, pathfmt, options):
|
||||
PostProcessor.__init__(self)
|
||||
|
||||
try:
|
||||
self.args = options["command"]
|
||||
self.args[0] # test if 'args' is subscriptable
|
||||
except (KeyError, IndexError, TypeError):
|
||||
raise TypeError("option 'command' must be a non-empty list")
|
||||
args = options["command"]
|
||||
|
||||
if isinstance(args, str):
|
||||
self.args = util.Formatter(args.replace("{}", "{_temppath}"))
|
||||
self.shell = True
|
||||
self._format = self._format_args_string
|
||||
else:
|
||||
for i, arg in enumerate(args):
|
||||
if "{}" in arg:
|
||||
args[i] = arg.replace("{}", "{_temppath}")
|
||||
self.args = [util.Formatter(arg) for arg in args]
|
||||
self.shell = False
|
||||
self._format = self._format_args_list
|
||||
|
||||
if options.get("async", False):
|
||||
self._exec = subprocess.Popen
|
||||
self._exec = self._exec_async
|
||||
|
||||
def run(self, pathfmt):
|
||||
self._exec([
|
||||
arg.format_map(pathfmt.keywords)
|
||||
for arg in self.args
|
||||
])
|
||||
kwdict = pathfmt.kwdict
|
||||
kwdict["_directory"] = pathfmt.realdirectory
|
||||
kwdict["_filename"] = pathfmt.filename
|
||||
kwdict["_temppath"] = pathfmt.temppath
|
||||
kwdict["_path"] = pathfmt.realpath
|
||||
self._exec(self._format(kwdict))
|
||||
|
||||
def _format_args_list(self, kwdict):
|
||||
return [arg.format_map(kwdict) for arg in self.args]
|
||||
|
||||
def _format_args_string(self, kwdict):
|
||||
return self.args.format_map(_quote(kwdict))
|
||||
|
||||
def _exec(self, args):
|
||||
retcode = subprocess.Popen(args).wait()
|
||||
retcode = subprocess.Popen(args, shell=self.shell).wait()
|
||||
if retcode:
|
||||
self.log.warning(
|
||||
"executing '%s' returned non-zero exit status %d",
|
||||
" ".join(args), retcode)
|
||||
"executing '%s' returned with non-zero exit status (%d)",
|
||||
" ".join(args) if isinstance(args, list) else args, retcode)
|
||||
|
||||
def _exec_async(self, args):
|
||||
subprocess.Popen(args, shell=self.shell)
|
||||
|
||||
|
||||
def _quote(kwdict):
|
||||
"""Create a copy of 'kwdict' and apply shlex.quote to its string values"""
|
||||
kwdict = kwdict.copy()
|
||||
for key, value in kwdict.items():
|
||||
cls = value.__class__
|
||||
if cls is str:
|
||||
kwdict[key] = shlex.quote(value)
|
||||
elif cls is list:
|
||||
kwdict[key] = shlex.quote(", ".join(value))
|
||||
elif cls is dict:
|
||||
kwdict[key] = _quote(value)
|
||||
return kwdict
|
||||
|
||||
|
||||
__postprocessor__ = ExecPP
|
||||
|
||||
Reference in New Issue
Block a user