add --from-file to read arbitrarily many images and circumvent the maximum command length of the shell (closes: #95)
This commit is contained in:
parent
9cda595cd5
commit
ea2245757f
1 changed files with 60 additions and 8 deletions
|
@ -2343,6 +2343,31 @@ def parse_borderarg(string):
|
||||||
return h, v
|
return h, v
|
||||||
|
|
||||||
|
|
||||||
|
def from_file(path):
|
||||||
|
result = []
|
||||||
|
if path == "-":
|
||||||
|
content = sys.stdin.buffer.read()
|
||||||
|
else:
|
||||||
|
with open(path, "rb") as f:
|
||||||
|
content = f.read()
|
||||||
|
for path in content.split(b"\0"):
|
||||||
|
if path == b"":
|
||||||
|
continue
|
||||||
|
try:
|
||||||
|
# test-read a byte from it so that we can abort early in case
|
||||||
|
# we cannot read data from the file
|
||||||
|
with open(path, "rb") as im:
|
||||||
|
im.read(1)
|
||||||
|
except IsADirectoryError:
|
||||||
|
raise argparse.ArgumentTypeError('"%s" is a directory' % path)
|
||||||
|
except PermissionError:
|
||||||
|
raise argparse.ArgumentTypeError('"%s" permission denied' % path)
|
||||||
|
except FileNotFoundError:
|
||||||
|
raise argparse.ArgumentTypeError('"%s" does not exist' % path)
|
||||||
|
result.append(path)
|
||||||
|
return result
|
||||||
|
|
||||||
|
|
||||||
def input_images(path_expr):
|
def input_images(path_expr):
|
||||||
if path_expr == "-":
|
if path_expr == "-":
|
||||||
# we slurp in all data from stdin because we need to seek in it later
|
# we slurp in all data from stdin because we need to seek in it later
|
||||||
|
@ -3299,8 +3324,10 @@ Report bugs at https://gitlab.mister-muffin.de/josch/img2pdf/issues
|
||||||
"the Python Imaging Library (PIL). If no input images are given, then "
|
"the Python Imaging Library (PIL). If no input images are given, then "
|
||||||
'a single image is read from standard input. The special filename "-" '
|
'a single image is read from standard input. The special filename "-" '
|
||||||
"can be used once to read an image from standard input. To read a "
|
"can be used once to read an image from standard input. To read a "
|
||||||
'file in the current directory with the filename "-", pass it to '
|
'file in the current directory with the filename "-" (or with a '
|
||||||
'img2pdf by explicitly stating its relative path like "./-".',
|
'filename starting with "-"), pass it to img2pdf by explicitly '
|
||||||
|
'stating its relative path like "./-". Cannot be used together with '
|
||||||
|
"--from-file.",
|
||||||
)
|
)
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
"-v",
|
"-v",
|
||||||
|
@ -3319,6 +3346,19 @@ Report bugs at https://gitlab.mister-muffin.de/josch/img2pdf/issues
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
"--gui", dest="gui", action="store_true", help="run experimental tkinter gui"
|
"--gui", dest="gui", action="store_true", help="run experimental tkinter gui"
|
||||||
)
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
"--from-file",
|
||||||
|
metavar="FILE",
|
||||||
|
type=from_file,
|
||||||
|
default=[],
|
||||||
|
help="Read the list of images from FILE instead of passing them as "
|
||||||
|
"positional arguments. If this option is used, then the list of "
|
||||||
|
"positional arguments must be empty. The paths to the input images "
|
||||||
|
'in FILE are separated by NUL bytes. If FILE is "-" then the paths '
|
||||||
|
"are expected on standard input. This option is useful if you want "
|
||||||
|
"to pass more images than the maximum command length of your shell "
|
||||||
|
"permits. This option can be used with commands like `find -print0`.",
|
||||||
|
)
|
||||||
|
|
||||||
outargs = parser.add_argument_group(
|
outargs = parser.add_argument_group(
|
||||||
title="General output arguments",
|
title="General output arguments",
|
||||||
|
@ -3689,14 +3729,26 @@ and left/right, respectively. It is not possible to specify asymmetric borders.
|
||||||
args.pagesize, args.imgsize, args.border, args.fit, args.auto_orient
|
args.pagesize, args.imgsize, args.border, args.fit, args.auto_orient
|
||||||
)
|
)
|
||||||
|
|
||||||
# if no positional arguments were supplied, read a single image from
|
if len(args.images) > 0 and len(args.from_file) > 0:
|
||||||
# standard input
|
logger.error(
|
||||||
if len(args.images) == 0:
|
"%s: error: cannot use --from-file with positional arguments" % parser.prog
|
||||||
|
)
|
||||||
|
sys.exit(2)
|
||||||
|
elif len(args.images) == 0 and len(args.from_file) == 0:
|
||||||
|
# if no positional arguments were supplied, read a single image from
|
||||||
|
# standard input
|
||||||
logger.info("reading image from standard input")
|
logger.info("reading image from standard input")
|
||||||
try:
|
try:
|
||||||
args.images = [[sys.stdin.buffer.read()]]
|
images = [sys.stdin.buffer.read()]
|
||||||
except KeyboardInterrupt:
|
except KeyboardInterrupt:
|
||||||
sys.exit(0)
|
sys.exit(0)
|
||||||
|
elif len(args.images) > 0 and len(args.from_file) == 0:
|
||||||
|
# On windows, each positional argument can expand into multiple paths
|
||||||
|
# because we do globbing ourselves. Here we flatten the list of lists
|
||||||
|
# again.
|
||||||
|
images = chain.from_iterable(args.images)
|
||||||
|
elif len(args.images) == 0 and len(args.from_file) > 0:
|
||||||
|
images = args.from_file
|
||||||
|
|
||||||
# with the number of pages being equal to the number of images, the
|
# with the number of pages being equal to the number of images, the
|
||||||
# value passed to --viewer-initial-page must be between 1 and that number
|
# value passed to --viewer-initial-page must be between 1 and that number
|
||||||
|
@ -3708,7 +3760,7 @@ and left/right, respectively. It is not possible to specify asymmetric borders.
|
||||||
"greater than zero" % parser.prog
|
"greater than zero" % parser.prog
|
||||||
)
|
)
|
||||||
sys.exit(2)
|
sys.exit(2)
|
||||||
if args.viewer_initial_page > len(args.images):
|
if args.viewer_initial_page > len(images):
|
||||||
parser.print_usage(file=sys.stderr)
|
parser.print_usage(file=sys.stderr)
|
||||||
logger.error(
|
logger.error(
|
||||||
"%s: error: argument --viewer-initial-page: must be "
|
"%s: error: argument --viewer-initial-page: must be "
|
||||||
|
@ -3718,7 +3770,7 @@ and left/right, respectively. It is not possible to specify asymmetric borders.
|
||||||
|
|
||||||
try:
|
try:
|
||||||
convert(
|
convert(
|
||||||
*chain.from_iterable(args.images),
|
*images,
|
||||||
engine=args.engine,
|
engine=args.engine,
|
||||||
title=args.title,
|
title=args.title,
|
||||||
author=args.author,
|
author=args.author,
|
||||||
|
|
Loading…
Reference in a new issue