From: Plom Heller Date: Sat, 4 Apr 2026 05:59:52 +0000 (+0200) Subject: Streamline exceptions with command option relevance messages. X-Git-Url: https://plomlompom.com/repos/booking/%22https:/validator.w3.org/todos?a=commitdiff_plain;h=8b8d2529dbb8354a863fa6026171b5a0160bd5ab;p=bookmaker Streamline exceptions with command option relevance messages. --- diff --git a/bookmaker.py b/bookmaker.py index c007d6b..36fe62b 100755 --- a/bookmaker.py +++ b/bookmaker.py @@ -52,8 +52,7 @@ class PageCrop: 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: @@ -94,8 +93,13 @@ class Nup4Geometry: 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(): @@ -161,60 +165,59 @@ 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 @@ -225,12 +228,12 @@ def validate_page_range(p_string, err_msg_prefix): 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: @@ -239,8 +242,8 @@ def validate_page_range(p_string, err_msg_prefix): 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): @@ -298,14 +301,15 @@ def validate_inputs_second_pass(args, pages_to_add): 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): @@ -557,8 +561,8 @@ def main(): 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) @@ -588,5 +592,5 @@ def main(): 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}')