From 130ce33dceac86637590aaf6f96759fb3c1bd528 Mon Sep 17 00:00:00 2001 From: Jacob Erickson Date: Sat, 8 Jan 2022 12:03:09 -0800 Subject: [PATCH 1/6] Add save/load from png --- src/wireviz/wireviz.py | 36 ++++++++++++++++++++++++++---------- 1 file changed, 26 insertions(+), 10 deletions(-) diff --git a/src/wireviz/wireviz.py b/src/wireviz/wireviz.py index 95674945a..19eb75afa 100755 --- a/src/wireviz/wireviz.py +++ b/src/wireviz/wireviz.py @@ -8,6 +8,8 @@ from typing import Any, Tuple import yaml +from PIL import Image +from PIL.PngImagePlugin import PngInfo if __name__ == '__main__': sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..')) @@ -188,6 +190,7 @@ def check_designators(what, where): # helper function if file_out is not None: harness.output(filename=file_out, fmt=('png', 'svg'), view=False) + save_yaml_to_png(file_out,yaml_input) if return_types is not None: returns = [] @@ -230,6 +233,16 @@ def parse_cmdline(): parser.add_argument('--prepend-file', action='store', type=str, metavar='YAML_FILE') return parser.parse_args() +def save_yaml_to_png(file_out,yaml_input): + with Image.open(fp=f'{file_out}.png') as im: + txt = PngInfo() + txt.add_itxt('yaml',yaml_input,zip=True) + im.save(fp=f'{file_out}.png',pnginfo=txt) + +def read_yaml_from_png(file_in): + with Image.open(fp=f'{file_in}.png') as im: + im.load() + return im.text['yaml'] def main(): @@ -239,16 +252,19 @@ def main(): print(f'Error: input file {args.input_file} inaccessible or does not exist, check path') sys.exit(1) - with open_file_read(args.input_file) as fh: - yaml_input = fh.read() - - if args.prepend_file: - if not os.path.exists(args.prepend_file): - print(f'Error: prepend input file {args.prepend_file} inaccessible or does not exist, check path') - sys.exit(1) - with open_file_read(args.prepend_file) as fh: - prepend = fh.read() - yaml_input = prepend + yaml_input + if ".png" in args.input_file: + yaml_input = read_yaml_from_png(args.input_file.replace('.png','')) + else: + with open_file_read(args.input_file) as fh: + yaml_input = fh.read() + + if args.prepend_file: + if not os.path.exists(args.prepend_file): + print(f'Error: prepend input file {args.prepend_file} inaccessible or does not exist, check path') + sys.exit(1) + with open_file_read(args.prepend_file) as fh: + prepend = fh.read() + yaml_input = prepend + yaml_input if not args.output_file: file_out = args.input_file From df9abf25588037748c9634581b0bf4b84185754a Mon Sep 17 00:00:00 2001 From: Jacob Erickson Date: Sat, 8 Jan 2022 12:03:09 -0800 Subject: [PATCH 2/6] Add yaml extract from png --- src/wireviz/wireviz.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/wireviz/wireviz.py b/src/wireviz/wireviz.py index 19eb75afa..a970b93ad 100755 --- a/src/wireviz/wireviz.py +++ b/src/wireviz/wireviz.py @@ -254,6 +254,8 @@ def main(): if ".png" in args.input_file: yaml_input = read_yaml_from_png(args.input_file.replace('.png','')) + with open(args.input_file.replace('.png','_out.yaml'),'w') as fh: + fh.write(yaml_input) # Extract yaml to separate file else: with open_file_read(args.input_file) as fh: yaml_input = fh.read() From 0a8ef9f0992b41f253a4a7e30b0141e54255f84b Mon Sep 17 00:00:00 2001 From: Jacob Erickson Date: Sat, 8 Jan 2022 12:03:09 -0800 Subject: [PATCH 3/6] Change png load and argpares to pathlib styling Adjusted some typehints that linting was complaining about. --- src/wireviz/wireviz.py | 50 +++++++++++++++++++----------------------- 1 file changed, 22 insertions(+), 28 deletions(-) diff --git a/src/wireviz/wireviz.py b/src/wireviz/wireviz.py index a970b93ad..7173fd96b 100755 --- a/src/wireviz/wireviz.py +++ b/src/wireviz/wireviz.py @@ -5,7 +5,7 @@ import os from pathlib import Path import sys -from typing import Any, Tuple +from typing import Any, Tuple, Optional, Union import yaml from PIL import Image @@ -17,10 +17,10 @@ from wireviz import __version__ from wireviz.DataClasses import Metadata, Options, Tweak from wireviz.Harness import Harness -from wireviz.wv_helper import expand, open_file_read +from wireviz.wv_helper import expand, open_file_read, open_file_write -def parse(yaml_input: str, file_out: (str, Path) = None, return_types: (None, str, Tuple[str]) = None) -> Any: +def parse(yaml_input: str, file_out: Union[str, Path] = None, return_types: Optional[Union[str, Tuple[str]]] = None) -> Any: """ Parses yaml input string and does the high-level harness conversion @@ -210,7 +210,7 @@ def check_designators(what, where): # helper function return tuple(returns) if len(returns) != 1 else returns[0] -def parse_file(yaml_file: str, file_out: (str, Path) = None) -> None: +def parse_file(yaml_file: str, file_out: Union[str, Path] = None) -> None: with open_file_read(yaml_file) as file: yaml_input = file.read() @@ -227,56 +227,50 @@ def parse_cmdline(): description='Generate cable and wiring harness documentation from YAML descriptions', ) parser.add_argument('-V', '--version', action='version', version='%(prog)s ' + __version__) - parser.add_argument('input_file', action='store', type=str, metavar='YAML_FILE') - parser.add_argument('-o', '--output_file', action='store', type=str, metavar='OUTPUT') + parser.add_argument('input_file', action='store', type=Path, metavar='YAML_FILE') + parser.add_argument('-o', '--output_file', action='store', type=Path, metavar='OUTPUT') # Not implemented: parser.add_argument('--generate-bom', action='store_true', default=True) - parser.add_argument('--prepend-file', action='store', type=str, metavar='YAML_FILE') + parser.add_argument('--prepend-file', action='store', type=Path, metavar='YAML_FILE') return parser.parse_args() -def save_yaml_to_png(file_out,yaml_input): - with Image.open(fp=f'{file_out}.png') as im: +def save_yaml_to_png(file_out:Path, yaml_input): + file_out = file_out.with_suffix('.png') + with Image.open(fp=file_out) as im: txt = PngInfo() - txt.add_itxt('yaml',yaml_input,zip=True) - im.save(fp=f'{file_out}.png',pnginfo=txt) + txt.add_itxt('yaml', yaml_input,zip=True) + im.save(fp=file_out, pnginfo=txt) -def read_yaml_from_png(file_in): - with Image.open(fp=f'{file_in}.png') as im: +def read_yaml_from_png(file_in:Path): + with Image.open(fp=file_in.with_suffix('.png')) as im: im.load() return im.text['yaml'] def main(): args = parse_cmdline() - - if not os.path.exists(args.input_file): + input_file_base = args.input_file.parent / args.input_file.stem + if not args.input_file.is_file(): print(f'Error: input file {args.input_file} inaccessible or does not exist, check path') sys.exit(1) - if ".png" in args.input_file: - yaml_input = read_yaml_from_png(args.input_file.replace('.png','')) - with open(args.input_file.replace('.png','_out.yaml'),'w') as fh: + if ".png" == args.input_file.suffix: + yaml_input = read_yaml_from_png(input_file_base) + with open_file_write(input_file_base.parent / (input_file_base.stem + '_out.yaml')) as fh: fh.write(yaml_input) # Extract yaml to separate file else: with open_file_read(args.input_file) as fh: yaml_input = fh.read() if args.prepend_file: - if not os.path.exists(args.prepend_file): + if not args.prepend_file.is_file(): print(f'Error: prepend input file {args.prepend_file} inaccessible or does not exist, check path') sys.exit(1) with open_file_read(args.prepend_file) as fh: prepend = fh.read() yaml_input = prepend + yaml_input - if not args.output_file: - file_out = args.input_file - pre, _ = os.path.splitext(file_out) - file_out = pre # extension will be added by graphviz output function - else: - file_out = args.output_file - file_out = os.path.abspath(file_out) - - parse(yaml_input, file_out=file_out) + file_out = args.output_file if args.output_file else input_file_base + parse(yaml_input, file_out=file_out.resolve()) if __name__ == '__main__': From a80db2453d982466741ec40f264f5505b98b0ca1 Mon Sep 17 00:00:00 2001 From: Jacob Erickson Date: Tue, 11 Apr 2023 09:36:50 -0700 Subject: [PATCH 4/6] Add commandline option to hide yaml input from png data --- src/wireviz/wireviz.py | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/src/wireviz/wireviz.py b/src/wireviz/wireviz.py index 7173fd96b..21c3be087 100755 --- a/src/wireviz/wireviz.py +++ b/src/wireviz/wireviz.py @@ -20,7 +20,12 @@ from wireviz.wv_helper import expand, open_file_read, open_file_write -def parse(yaml_input: str, file_out: Union[str, Path] = None, return_types: Optional[Union[str, Tuple[str]]] = None) -> Any: +def parse( + yaml_input: str, + file_out: Union[str, Path] = None, + return_types: Optional[Union[str, Tuple[str]]] = None, + conceal_input: Optional[bool] = None, +) -> Any: """ Parses yaml input string and does the high-level harness conversion @@ -190,7 +195,7 @@ def check_designators(what, where): # helper function if file_out is not None: harness.output(filename=file_out, fmt=('png', 'svg'), view=False) - save_yaml_to_png(file_out,yaml_input) + save_yaml_to_png(file_out, yaml_input, conceal_input) if return_types is not None: returns = [] @@ -231,9 +236,12 @@ def parse_cmdline(): parser.add_argument('-o', '--output_file', action='store', type=Path, metavar='OUTPUT') # Not implemented: parser.add_argument('--generate-bom', action='store_true', default=True) parser.add_argument('--prepend-file', action='store', type=Path, metavar='YAML_FILE') - return parser.parse_args() + parser.add_argument('--conceal-input', action='store_false', metavar='PRESERVE_INPUT') + return parser.parse_cmd_args() -def save_yaml_to_png(file_out:Path, yaml_input): +def save_yaml_to_png(file_out:Path, yaml_input:str, conceal_input:bool): + if not conceal_input: + return file_out = file_out.with_suffix('.png') with Image.open(fp=file_out) as im: txt = PngInfo() @@ -246,14 +254,13 @@ def read_yaml_from_png(file_in:Path): return im.text['yaml'] def main(): - args = parse_cmdline() input_file_base = args.input_file.parent / args.input_file.stem if not args.input_file.is_file(): print(f'Error: input file {args.input_file} inaccessible or does not exist, check path') sys.exit(1) - if ".png" == args.input_file.suffix: + if ".png" == args.input_file.suffix: # Extract from png containing yaml data yaml_input = read_yaml_from_png(input_file_base) with open_file_write(input_file_base.parent / (input_file_base.stem + '_out.yaml')) as fh: fh.write(yaml_input) # Extract yaml to separate file @@ -267,10 +274,11 @@ def main(): sys.exit(1) with open_file_read(args.prepend_file) as fh: prepend = fh.read() - yaml_input = prepend + yaml_input + yaml_input = prepend + yaml_input + file_out = args.output_file if args.output_file else input_file_base - parse(yaml_input, file_out=file_out.resolve()) + parse(yaml_input, file_out=file_out.resolve(), conceal_input=args.conceal_input) if __name__ == '__main__': From 55fe8a645e8368782134b439d74a392e9c52d362 Mon Sep 17 00:00:00 2001 From: Jacob Erickson Date: Tue, 11 Apr 2023 09:50:17 -0700 Subject: [PATCH 5/6] Seperate prepend and standard yaml input files in png --- src/wireviz/wireviz.py | 30 +++++++++++++++++++----------- 1 file changed, 19 insertions(+), 11 deletions(-) diff --git a/src/wireviz/wireviz.py b/src/wireviz/wireviz.py index 21c3be087..1f2e91c6b 100755 --- a/src/wireviz/wireviz.py +++ b/src/wireviz/wireviz.py @@ -22,14 +22,16 @@ def parse( yaml_input: str, + prepend_yaml_input: str = '', file_out: Union[str, Path] = None, return_types: Optional[Union[str, Tuple[str]]] = None, - conceal_input: Optional[bool] = None, + conceal_input: bool = False, ) -> Any: """ Parses yaml input string and does the high-level harness conversion :param yaml_input: a string containing the yaml input data + :prepend_yaml_input: default '', a string containing the prepend file yaml input data :param file_out: :param return_types: if None, then returns None; if the value is a string, then a corresponding data format will be returned; if the value is a tuple of strings, @@ -38,9 +40,10 @@ def parse( - "png" - will return the PNG data - "svg" - will return the SVG data - "harness" - will return the `Harness` instance + :conceal_input: if True, raw yaml data will not be saved to png outputs """ - yaml_data = yaml.safe_load(yaml_input) + yaml_data = yaml.safe_load(prepend_yaml_input + yaml_input) harness = Harness( metadata = Metadata(**yaml_data.get('metadata', {})), @@ -239,19 +242,25 @@ def parse_cmdline(): parser.add_argument('--conceal-input', action='store_false', metavar='PRESERVE_INPUT') return parser.parse_cmd_args() -def save_yaml_to_png(file_out:Path, yaml_input:str, conceal_input:bool): +def save_yaml_to_png(file_out:Path, yaml_input:str, prepend_yaml_input:str, conceal_input:bool): if not conceal_input: return file_out = file_out.with_suffix('.png') with Image.open(fp=file_out) as im: txt = PngInfo() - txt.add_itxt('yaml', yaml_input,zip=True) + txt.add_itxt('prepend_yaml', prepend_yaml_input, zip=True) + txt.add_itxt('yaml', yaml_input, zip=True) im.save(fp=file_out, pnginfo=txt) def read_yaml_from_png(file_in:Path): with Image.open(fp=file_in.with_suffix('.png')) as im: im.load() - return im.text['yaml'] + yaml_input = im.text['yaml'] + prepend_yaml_input = im.text['prepend_yaml'] + for file_ending, file_data in [('_prepend_out.yaml',prepend_yaml_input),('out.yaml',yaml_input)]: + with open_file_write(file_in.parent / (file_in.stem + file_ending)) as fh: + fh.write(file_data) # Extract yaml to separate file + return prepend_yaml_input, yaml_input def main(): args = parse_cmdline() @@ -261,9 +270,7 @@ def main(): sys.exit(1) if ".png" == args.input_file.suffix: # Extract from png containing yaml data - yaml_input = read_yaml_from_png(input_file_base) - with open_file_write(input_file_base.parent / (input_file_base.stem + '_out.yaml')) as fh: - fh.write(yaml_input) # Extract yaml to separate file + prepend_yaml_input, yaml_input = read_yaml_from_png(input_file_base) else: with open_file_read(args.input_file) as fh: yaml_input = fh.read() @@ -273,12 +280,13 @@ def main(): print(f'Error: prepend input file {args.prepend_file} inaccessible or does not exist, check path') sys.exit(1) with open_file_read(args.prepend_file) as fh: - prepend = fh.read() - yaml_input = prepend + yaml_input + prepend_yaml_input = fh.read() + else: + prepend_yaml_input = '' file_out = args.output_file if args.output_file else input_file_base - parse(yaml_input, file_out=file_out.resolve(), conceal_input=args.conceal_input) + parse(yaml_input, prepend_yaml=prepend_yaml_input, file_out=file_out.resolve(), conceal_input=args.conceal_input) if __name__ == '__main__': From a35a4448662781cba54af12f6e5e34d47d105e34 Mon Sep 17 00:00:00 2001 From: Jacob Erickson Date: Wed, 12 Apr 2023 11:58:25 -0700 Subject: [PATCH 6/6] Add more flexibility for concealing input --- src/wireviz/wireviz.py | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/src/wireviz/wireviz.py b/src/wireviz/wireviz.py index 1f2e91c6b..2ea60049e 100755 --- a/src/wireviz/wireviz.py +++ b/src/wireviz/wireviz.py @@ -2,6 +2,7 @@ # -*- coding: utf-8 -*- import argparse +from enum import Enum import os from pathlib import Path import sys @@ -19,13 +20,19 @@ from wireviz.Harness import Harness from wireviz.wv_helper import expand, open_file_read, open_file_write +class ConcealEnum(Enum): + """Options for concealing input in cmd-line arguments""" + ALL = 'all' # Hides all input + PREPEND = 'prepend' # Hides just the prepend file + MAIN = 'main' # Hides just the main file + NONE = 'none' # Default, saves all input def parse( yaml_input: str, prepend_yaml_input: str = '', file_out: Union[str, Path] = None, return_types: Optional[Union[str, Tuple[str]]] = None, - conceal_input: bool = False, + conceal_input: ConcealEnum = ConcealEnum.NONE, ) -> Any: """ Parses yaml input string and does the high-level harness conversion @@ -40,7 +47,7 @@ def parse( - "png" - will return the PNG data - "svg" - will return the SVG data - "harness" - will return the `Harness` instance - :conceal_input: if True, raw yaml data will not be saved to png outputs + :conceal_input: defines which input files to conceal, if any """ yaml_data = yaml.safe_load(prepend_yaml_input + yaml_input) @@ -239,17 +246,19 @@ def parse_cmdline(): parser.add_argument('-o', '--output_file', action='store', type=Path, metavar='OUTPUT') # Not implemented: parser.add_argument('--generate-bom', action='store_true', default=True) parser.add_argument('--prepend-file', action='store', type=Path, metavar='YAML_FILE') - parser.add_argument('--conceal-input', action='store_false', metavar='PRESERVE_INPUT') + parser.add_argument('--conceal-input', choices=[choice.value for choice in ConcealEnum], default=ConcealEnum.NONE.value, metavar='CONCEAL_INPUT') return parser.parse_cmd_args() -def save_yaml_to_png(file_out:Path, yaml_input:str, prepend_yaml_input:str, conceal_input:bool): - if not conceal_input: +def save_yaml_to_png(file_out:Path, yaml_input:str, prepend_yaml_input:str, conceal_input:ConcealEnum): + if conceal_input == ConcealEnum.ALL: return file_out = file_out.with_suffix('.png') with Image.open(fp=file_out) as im: txt = PngInfo() - txt.add_itxt('prepend_yaml', prepend_yaml_input, zip=True) - txt.add_itxt('yaml', yaml_input, zip=True) + if conceal_input != ConcealEnum.PREPEND: + txt.add_itxt('prepend_yaml', prepend_yaml_input, zip=True) + if conceal_input != ConcealEnum.MAIN: + txt.add_itxt('yaml', yaml_input, zip=True) im.save(fp=file_out, pnginfo=txt) def read_yaml_from_png(file_in:Path): @@ -286,7 +295,7 @@ def main(): file_out = args.output_file if args.output_file else input_file_base - parse(yaml_input, prepend_yaml=prepend_yaml_input, file_out=file_out.resolve(), conceal_input=args.conceal_input) + parse(yaml_input, prepend_yaml=prepend_yaml_input, file_out=file_out.resolve(), conceal_input=ConcealEnum(args.conceal_input)) if __name__ == '__main__':