diff --git a/src/wireviz/wireviz.py b/src/wireviz/wireviz.py index 8076f78..fac305e 100755 --- a/src/wireviz/wireviz.py +++ b/src/wireviz/wireviz.py @@ -16,9 +16,9 @@ from wireviz.wv_dataclasses import AUTOGENERATED_PREFIX, Metadata, Options, Twea from wireviz.wv_harness import Harness from wireviz.wv_utils import ( expand, + file_read_text, get_single_key_and_value, is_arrow, - open_file_read, smart_file_resolve, ) @@ -419,7 +419,7 @@ def _get_yaml_data_and_path(inp: Union[str, Path, Dict]) -> Tuple[Dict, Path]: try: yaml_path = Path(inp).expanduser().resolve(strict=True) # if no FileNotFoundError exception happens, get file contents - yaml_str = open_file_read(yaml_path).read() + yaml_str = file_read_text(yaml_path) except (FileNotFoundError, OSError, ValueError) as e: # if inp is a long YAML string, Pathlib will normally raise # FileNotFoundError or OSError(errno = ENAMETOOLONG) when diff --git a/src/wireviz/wv_cli.py b/src/wireviz/wv_cli.py index eafc0ef..a1117ab 100644 --- a/src/wireviz/wv_cli.py +++ b/src/wireviz/wv_cli.py @@ -11,7 +11,7 @@ if __name__ == "__main__": import wireviz.wireviz as wv from wireviz import APP_NAME, __version__ -from wireviz.wv_utils import open_file_read +from wireviz.wv_utils import file_read_text format_codes = { # "c": "csv", # TODO: support CSV @@ -119,7 +119,7 @@ def wireviz(file, format, prepend, output_dir, output_name, version): raise Exception(f"Path is not a file:\n{prepend_file}") print("Prepend file:", prepend_file) - prepend_input += open_file_read(prepend_file).read() + "\n" + prepend_input += file_read_text(prepend_file) + "\n" else: prepend_input = "" @@ -140,7 +140,7 @@ def wireviz(file, format, prepend, output_dir, output_name, version): "Output file: ", f"{Path(_output_dir / _output_name)}.{output_formats_str}" ) - yaml_input = open_file_read(file).read() + yaml_input = file_read_text(file) file_dir = file.parent yaml_input = prepend_input + yaml_input diff --git a/src/wireviz/wv_harness.py b/src/wireviz/wv_harness.py index b81f24d..53b1c5c 100644 --- a/src/wireviz/wv_harness.py +++ b/src/wireviz/wv_harness.py @@ -40,7 +40,7 @@ from wireviz.wv_output import ( embed_svg_images_file, generate_html_output, ) -from wireviz.wv_utils import OLD_CONNECTOR_ATTR, bom2tsv, check_old, open_file_write +from wireviz.wv_utils import OLD_CONNECTOR_ATTR, bom2tsv, check_old, file_write_text @dataclass @@ -424,7 +424,8 @@ class Harness: # bomlist = [[]] if "tsv" in fmt: tsv = bom2tsv(bomlist) - open_file_write(f"{filename}.tsv").write(tsv) + file_write_text(f"{filename}.bom.tsv", tsv) + if "csv" in fmt: # TODO: implement CSV output (preferrably using CSV library) print("CSV output is not yet supported") diff --git a/src/wireviz/wv_output.py b/src/wireviz/wv_output.py index 0fbff9c..6f87918 100644 --- a/src/wireviz/wv_output.py +++ b/src/wireviz/wv_output.py @@ -9,9 +9,9 @@ import wireviz # for doing wireviz.__file__ from wireviz import APP_NAME, APP_URL, __version__ from wireviz.wv_dataclasses import Metadata, Options from wireviz.wv_utils import ( + file_read_text, + file_write_text, html_line_breaks, - open_file_read, - open_file_write, smart_file_resolve, ) @@ -95,14 +95,14 @@ def generate_html_output( # fall back to built-in simple template if no template was provided templatefile = Path(wireviz.__file__).parent / "templates/simple.html" - html = open_file_read(templatefile).read() + html = file_read_text(templatefile) # embed SVG diagram (only if used) def svgdata() -> str: return re.sub( "^<[?]xml [^?>]*[?]>[^<]*]*>", "", - open_file_read(f"{filename}.tmp.svg").read(), + file_read_text(f"{filename}.tmp.svg"), 1, ) @@ -186,4 +186,4 @@ def generate_html_output( pattern = re.compile("|".join(replacements_escaped)) html = pattern.sub(lambda match: replacements[match.group(0)], html) - open_file_write(f"{filename}.html").write(html) + file_write_text(f"{filename}.html", html) diff --git a/src/wireviz/wv_utils.py b/src/wireviz/wv_utils.py index c8f0439..1d364e3 100644 --- a/src/wireviz/wv_utils.py +++ b/src/wireviz/wv_utils.py @@ -151,18 +151,31 @@ def clean_whitespace(inp): def open_file_read(filename): + """Open utf-8 encoded text file for reading - remember closing it when finished""" # TODO: Intelligently determine encoding return open(filename, "r", encoding="UTF-8") def open_file_write(filename): + """Open utf-8 encoded text file for writing - remember closing it when finished""" return open(filename, "w", encoding="UTF-8") def open_file_append(filename): + """Open utf-8 encoded text file for appending - remember closing it when finished""" return open(filename, "a", encoding="UTF-8") +def file_read_text(filename: str) -> str: + """Read utf-8 encoded text file, close it, and return the text""" + return Path(filename).read_text(encoding="utf-8") + + +def file_write_text(filename: str, text: str) -> int: + """Write utf-8 encoded text file, close it, and return the number of characters written""" + return Path(filename).write_text(text, encoding="utf-8") + + def is_arrow(inp): """ Matches strings of one or multiple `-` or `=` (but not mixed)