Merge pull request #1 from aakatz3/refactor/csv-tsv
[refactor] Use the csv library to generate properly escaped TSV files
This commit is contained in:
commit
85c196f151
@ -100,10 +100,11 @@ $ wireviz ~/path/to/file/mywire.yml
|
||||
This will output the following files
|
||||
|
||||
```
|
||||
mywire.gv GraphViz output
|
||||
mywire.gv Raw GraphViz DOT file output of wiring diagram
|
||||
mywire.svg Wiring diagram as vector image
|
||||
mywire.png Wiring diagram as raster image
|
||||
mywire.bom.tsv BOM (bill of materials) as tab-separated text file
|
||||
mywire.bom.csv BOM (bill of materials) as comma-separated, excel-format text file
|
||||
mywire.html HTML page with wiring diagram and BOM embedded
|
||||
```
|
||||
|
||||
|
||||
@ -3,9 +3,9 @@
|
||||
|
||||
from wireviz.DataClasses import Connector, Cable
|
||||
from graphviz import Graph
|
||||
from wireviz import wv_colors, wv_helper
|
||||
from wireviz import wv_colors, wv_helper, bom_helper
|
||||
from wireviz.wv_colors import get_color_hex
|
||||
from wireviz.wv_helper import awg_equiv, mm2_equiv, tuplelist2tsv, \
|
||||
from wireviz.wv_helper import awg_equiv, mm2_equiv, \
|
||||
nested_html_table, flatten2d, index_if_list, html_line_breaks, \
|
||||
graphviz_line_breaks, remove_line_breaks, open_file_read, open_file_write
|
||||
from collections import Counter
|
||||
@ -67,7 +67,7 @@ class Harness:
|
||||
font = 'arial'
|
||||
dot.attr('graph', rankdir='LR',
|
||||
ranksep='2',
|
||||
bgcolor='white',
|
||||
bgcolor=wv_colors.COLOR_BACKGROUND,
|
||||
nodesep='0.33',
|
||||
fontname=font)
|
||||
dot.attr('node', shape='record',
|
||||
@ -297,12 +297,12 @@ class Harness:
|
||||
graph.save(filename=f'{filename}.gv')
|
||||
# bom output
|
||||
bom_list = self.bom_list()
|
||||
with open_file_write(f'{filename}.bom.tsv') as file:
|
||||
file.write(tuplelist2tsv(bom_list))
|
||||
# todo: support user choices of BOM format (probably also graphviz outputs, html outputs)
|
||||
bom_helper.generate_bom_outputs(filename,bom_list, [bom_helper.WIREVIZ_TSV, bom_helper.EXCEL_CSV])
|
||||
# HTML output
|
||||
with open_file_write(f'{filename}.html') as file:
|
||||
file.write('<!DOCTYPE html>\n')
|
||||
file.write('<html><head><meta charset="UTF-8"></head><body style="font-family:Arial">')
|
||||
file.write(f'<html><head><meta charset="UTF-8"></head><body style="font-family:Arial;background-color:{wv_colors.COLOR_BACKGROUND}">')
|
||||
|
||||
file.write('<h1>Diagram</h1>')
|
||||
with open_file_read(f'{filename}.svg') as svg:
|
||||
|
||||
49
src/wireviz/bom_helper.py
Normal file
49
src/wireviz/bom_helper.py
Normal file
@ -0,0 +1,49 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
import csv
|
||||
from wireviz import wv_helper
|
||||
from wireviz.wv_helper import open_file_write
|
||||
|
||||
EXCEL_CSV = csv.excel
|
||||
EXCEL_TSV = csv.excel_tab
|
||||
UNIX_CSV = csv.unix_dialect
|
||||
WIREVIZ_TSV = type('Wireviz BOM', (csv.Dialect, object), dict(
|
||||
delimiter='\t',
|
||||
doublequote=True,
|
||||
escapechar=None,
|
||||
lineterminator='\n',
|
||||
quoting=0,
|
||||
skipinitialspace=False,
|
||||
strict=False,
|
||||
quotechar='"'
|
||||
))
|
||||
csv.register_dialect('Wireviz BOM', WIREVIZ_TSV)
|
||||
|
||||
_csv_formats = { EXCEL_CSV, UNIX_CSV }
|
||||
_tsv_formats = { EXCEL_TSV, WIREVIZ_TSV }
|
||||
|
||||
_csv_ext = '.bom.csv'
|
||||
_tsv_ext = '.bom.tsv'
|
||||
|
||||
def generate_bom_outputs(base_filename, bomdata, formats=None):
|
||||
if formats is None:
|
||||
formats = [EXCEL_CSV, WIREVIZ_TSV]
|
||||
elif isinstance(formats, csv.Dialect):
|
||||
formats = [formats]
|
||||
elif not isinstance(formats, list):
|
||||
raise TypeError
|
||||
expanded_csv_names = len(_csv_formats.intersection(set(formats))) > 1
|
||||
expanded_tsv_names = len(_tsv_formats.intersection(set(formats))) > 1
|
||||
|
||||
for fmt in formats:
|
||||
if fmt in _csv_formats:
|
||||
file = csv.writer(open_file_write(base_filename + ("_" + fmt.__name__ if expanded_csv_names else "") + _csv_ext, fmt.lineterminator), fmt)
|
||||
|
||||
elif fmt in _tsv_formats:
|
||||
file = csv.writer(open_file_write(base_filename + ("_"+fmt.__name__ if expanded_tsv_names else "") + _tsv_ext, fmt.lineterminator), fmt)
|
||||
else:
|
||||
raise KeyError("Unknown BOM Format Specified")
|
||||
file.writerows(wv_helper.flatten2d(bomdata))
|
||||
|
||||
# TODO: Possibly refactor other BOM output operations, such as HTML, into here?
|
||||
@ -74,10 +74,11 @@ def build_tutorials():
|
||||
|
||||
file.write(f'\n\n')
|
||||
|
||||
file.write(f'[Bill of Materials](tutorial{outfile_name}.bom.tsv)\n\n\n')
|
||||
file.write(f'[Bill of Materials - TSV](tutorial{outfile_name}.bom.tsv)\n\n')
|
||||
file.write(f'[Bill of Materials - CSV](tutorial{outfile_name}.bom.csv)\n\n\n')
|
||||
|
||||
def clean_examples():
|
||||
generated_extensions = ['.gv', '.png', '.svg', '.html', '.bom.tsv']
|
||||
generated_extensions = ['.gv', '.png', '.svg', '.html', '.bom.tsv', '.bom.csv']
|
||||
|
||||
for filepath in [examples_path, demos_path, tutorials_path]:
|
||||
print(filepath)
|
||||
|
||||
@ -98,12 +98,13 @@ _color_ger = {
|
||||
}
|
||||
|
||||
|
||||
color_default = '#ffffff'
|
||||
COLOR_DEFAULT = '#ffffff'
|
||||
COLOR_BACKGROUND = '#ffffff'
|
||||
|
||||
|
||||
def get_color_hex(input, pad=False):
|
||||
if input is None or input == '':
|
||||
return [color_default]
|
||||
return [COLOR_DEFAULT]
|
||||
if len(input) == 4: # give wires with EXACTLY 2 colors that striped/banded look
|
||||
input = input + input[:2]
|
||||
# hacky style fix: give single color wires a triple-up so that wires are the same size
|
||||
@ -113,7 +114,7 @@ def get_color_hex(input, pad=False):
|
||||
output = [_color_hex[input[i:i + 2]] for i in range(0, len(input), 2)]
|
||||
except KeyError:
|
||||
print("Unknown color specified")
|
||||
output = [color_default]
|
||||
output = [COLOR_DEFAULT]
|
||||
return output
|
||||
|
||||
|
||||
|
||||
@ -113,8 +113,7 @@ def remove_line_breaks(inp):
|
||||
return inp.replace('\n', ' ').rstrip() if isinstance(inp, str) else inp
|
||||
|
||||
def open_file_read(filename):
|
||||
# TODO: Intelligently determine encoding
|
||||
return open(filename, 'r', encoding='UTF-8')
|
||||
|
||||
def open_file_write(filename):
|
||||
return open(filename, 'w', encoding='UTF-8')
|
||||
def open_file_write(filename, newline='\n'):
|
||||
return open(filename, 'w', encoding='UTF-8', newline=newline)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user