zoom_vertical = A4_HEIGHT / (A4_HEIGHT - self.bottom - self.top)
if zoom_horizontal > 1 > zoom_vertical\
or zoom_horizontal < 1 < zoom_vertical:
- raise HandledException(
- '-c: crops would create opposing zoom directions')
+ raise ArgFail('c', 'crops would create opposing zoom directions')
if zoom_horizontal + zoom_vertical > 2:
self.zoom = min(zoom_horizontal, zoom_vertical)
else:
self.shrink_for_spine = 1 - spine_part_of_page
-class HandledException(Exception):
- pass
+class ArgFail(Exception):
+ 'Collects relevant command character, followed by explanation.'
+
+ def __init__(self, arg_char, msg, *args, **kwargs):
+ super().__init__(*args, **kwargs)
+ self.arg_char = arg_char
+ self.msg = msg
def parse_args():
def validate_inputs_first_pass(args):
for filename in args.input_file:
if not os.path.isfile(filename):
- raise HandledException(f'-i: {filename} is not a file')
+ raise ArgFail('i', f'{filename} is not a file')
try:
with open(filename, 'rb') as file:
pypdf.PdfReader(file)
except pypdf.errors.PdfStreamError:
- raise HandledException(
- f'-i: cannot interpret {filename} as PDF file')
+ raise ArgFail('i', f'cannot interpret {filename} as PDF file')
if args.page_range:
for p_string in args.page_range:
- validate_page_range(p_string, '-p')
+ validate_page_range(p_string, 'p')
if len(args.page_range) > len(args.input_file):
- raise HandledException(
- '-p: more --page_range arguments than --input_file arguments')
+ raise ArgFail(
+ 'p',
+ 'more --page_range arguments than --input_file arguments')
if args.crops:
for c_string in args.crops:
initial_split = c_string.split(':')
if len(initial_split) > 2:
- raise HandledException(
- f'-c: cropping string has multiple ":": {c_string}')
+ raise ArgFail('c',
+ f'cropping string has multiple ":": {c_string}')
page_range, crops = split_crops_string(c_string)
crops = crops.split(',')
if page_range:
- validate_page_range(page_range, '-c')
+ validate_page_range(page_range, 'c')
if len(crops) != 4:
- raise HandledException(
- '-c: cropping does not contain exactly three ",": '
- + c_string)
+ raise ArgFail(
+ 'c',
+ f'cropping does not contain exactly three ",": {c_string}')
for crop in crops:
try:
float(crop)
except ValueError:
- raise HandledException(
- f'-c: non-number crop in: {c_string}')
+ raise ArgFail('c', f'non-number crop in: {c_string}')
if args.rotate_page:
for r in args.rotate_page:
try:
int(r)
except ValueError:
- raise HandledException(f'-r: non-integer value: {r}')
+ raise ArgFail('r', f'non-integer value: {r}')
if r < 1:
- raise HandledException(f'-r: value must not be <1: {r}')
+ raise ArgFail('r', 'value must not be <1: {r}')
try:
float(args.print_margin)
except ValueError:
- raise HandledException(f'-m: non-float value: {args.print_margin}')
+ raise ArgFail('m', f'non-float value: {args.print_margin}')
-def validate_page_range(p_string, err_msg_prefix):
- prefix = f'{err_msg_prefix}: page range string'
+def validate_page_range(p_string, arg_char):
+ prefix = 'page range string'
if '-' not in p_string:
- raise HandledException(f'{prefix} lacks "-": {p_string}')
+ raise ArgFail(arg_char, f'{prefix} lacks "-": {p_string}')
tokens = p_string.split('-')
if len(tokens) > 2:
- raise HandledException(f'{prefix} has too many "-": {p_string}')
+ raise ArgFail(arg_char, f'{prefix} has too many "-": {p_string}')
for i, token in enumerate(tokens):
if token == '':
continue
try:
int(token)
except ValueError:
- raise HandledException(
- f'{prefix} carries value neither integer, '
- f'nor "start", nor "end": {p_string}')
+ raise ArgFail(arg_char,
+ f'{prefix} carries value neither integer, '
+ f'nor "start", nor "end": {p_string}')
if int(token) < 1:
- raise HandledException(
- f'{prefix} carries page number <1: {p_string}')
+ raise ArgFail(arg_char,
+ f'{prefix} carries page number <1: {p_string}')
start = -1
end = -1
try:
except ValueError:
pass
if start > end > 0:
- raise HandledException(
- f'{prefix} has higher start than end value: {p_string}')
+ raise ArgFail(arg_char,
+ f'{prefix} has higher start than end value: {p_string}')
def split_crops_string(c_string):
if page_range:
_, end = parse_page_range(page_range, pages_to_add)
if end > len(pages_to_add):
- raise HandledException(
- f'-c: page range goes beyond number of pages '
- f'we\'re building: {page_range}')
+ raise ArgFail('c',
+ 'page range goes beyond number of pages '
+ f'we\'re building: {page_range}')
if args.rotate_page:
for r in args.rotate_page:
if r > len(pages_to_add):
- raise HandledException('-r: page number beyond number of '
- f'pages we\'re building: {r}')
+ raise ArgFail('r',
+ 'page number beyond number of '
+ f'pages we\'re building: {r}')
def rotate_pages(args_rotate_page, pages_to_add):
try:
from reportlab.pdfgen.canvas import Canvas
except ImportError:
- raise HandledException(
- '-n: need reportlab.pdfgen.canvas installed for --nup4')
+ raise ArgFail('n',
+ 'need reportlab.pdfgen.canvas installed for --nup4')
pages_to_add, opened_files = read_inputs_to_pagelist(args.input_file,
args.page_range)
validate_inputs_second_pass(args, pages_to_add)
if __name__ == '__main__':
try:
main()
- except HandledException as e:
- handled_error_exit(e)
+ except ArgFail as e:
+ handled_error_exit(f'-{e.arg_char}: {e.msg}')