Add basic metadata and options to Harness
Resolves the basic part of #158.
This commit is contained in:
parent
da56841290
commit
d1b007f913
@ -20,6 +20,7 @@ ConnectorMultiplier = PlainText # = Literal['pincount', 'populated']
|
|||||||
CableMultiplier = PlainText # = Literal['wirecount', 'terminations', 'length', 'total_length']
|
CableMultiplier = PlainText # = Literal['wirecount', 'terminations', 'length', 'total_length']
|
||||||
ImageScale = PlainText # = Literal['false', 'true', 'width', 'height', 'both']
|
ImageScale = PlainText # = Literal['false', 'true', 'width', 'height', 'both']
|
||||||
Color = PlainText # Two-letter color name = Literal[wv_colors._color_hex.keys()]
|
Color = PlainText # Two-letter color name = Literal[wv_colors._color_hex.keys()]
|
||||||
|
ColorMode = PlainText # = Literal['full', 'FULL', 'hex', 'HEX', 'short', 'SHORT', 'ger', 'GER']
|
||||||
ColorScheme = PlainText # Color scheme name = Literal[wv_colors.COLOR_CODES.keys()]
|
ColorScheme = PlainText # Color scheme name = Literal[wv_colors.COLOR_CODES.keys()]
|
||||||
|
|
||||||
# Type combinations
|
# Type combinations
|
||||||
@ -30,6 +31,19 @@ NoneOrMorePins = Union[Pin, Tuple[Pin, ...], None] # None, one, or a tuple of pi
|
|||||||
OneOrMoreWires = Union[Wire, Tuple[Wire, ...]] # One or a tuple of wires
|
OneOrMoreWires = Union[Wire, Tuple[Wire, ...]] # One or a tuple of wires
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class Metadata:
|
||||||
|
title: PlainText
|
||||||
|
description: Optional[MultilineHypertext] = None
|
||||||
|
notes: Optional[MultilineHypertext] = None
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class Options:
|
||||||
|
color_mode: ColorMode = 'SHORT'
|
||||||
|
mini_bom_mode: bool = True
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
class Image:
|
class Image:
|
||||||
gv_dir: InitVar[Path] # Directory of .gv file injected as context during parsing
|
gv_dir: InitVar[Path] # Directory of .gv file injected as context during parsing
|
||||||
|
|||||||
@ -4,12 +4,13 @@
|
|||||||
from graphviz import Graph
|
from graphviz import Graph
|
||||||
from collections import Counter
|
from collections import Counter
|
||||||
from typing import List, Union
|
from typing import List, Union
|
||||||
|
from dataclasses import dataclass
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from itertools import zip_longest
|
from itertools import zip_longest
|
||||||
import re
|
import re
|
||||||
|
|
||||||
from wireviz import wv_colors, __version__, APP_NAME, APP_URL
|
from wireviz import wv_colors, __version__, APP_NAME, APP_URL
|
||||||
from wireviz.DataClasses import Connector, Cable
|
from wireviz.DataClasses import Metadata, Options, Connector, Cable
|
||||||
from wireviz.wv_colors import get_color_hex
|
from wireviz.wv_colors import get_color_hex
|
||||||
from wireviz.wv_gv_html import nested_html_table, html_colorbar, html_image, \
|
from wireviz.wv_gv_html import nested_html_table, html_colorbar, html_image, \
|
||||||
html_caption, remove_links, html_line_breaks
|
html_caption, remove_links, html_line_breaks
|
||||||
@ -20,11 +21,12 @@ from wireviz.wv_helper import awg_equiv, mm2_equiv, tuplelist2tsv, flatten2d, \
|
|||||||
open_file_read, open_file_write
|
open_file_read, open_file_write
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
class Harness:
|
class Harness:
|
||||||
|
metadata: Metadata
|
||||||
|
options: Options
|
||||||
|
|
||||||
def __init__(self):
|
def __post_init__(self):
|
||||||
self.color_mode = 'SHORT'
|
|
||||||
self.mini_bom_mode = True
|
|
||||||
self.connectors = {}
|
self.connectors = {}
|
||||||
self.cables = {}
|
self.cables = {}
|
||||||
self._bom = [] # Internal Cache for generated bom
|
self._bom = [] # Internal Cache for generated bom
|
||||||
@ -225,7 +227,7 @@ class Harness:
|
|||||||
wireinfo = []
|
wireinfo = []
|
||||||
if cable.show_wirenumbers:
|
if cable.show_wirenumbers:
|
||||||
wireinfo.append(str(i))
|
wireinfo.append(str(i))
|
||||||
colorstr = wv_colors.translate_color(connection_color, self.color_mode)
|
colorstr = wv_colors.translate_color(connection_color, self.options.color_mode)
|
||||||
if colorstr:
|
if colorstr:
|
||||||
wireinfo.append(colorstr)
|
wireinfo.append(colorstr)
|
||||||
if cable.wirelabels:
|
if cable.wirelabels:
|
||||||
@ -361,7 +363,7 @@ class Harness:
|
|||||||
with open_file_write(f'{filename}.bom.tsv') as file:
|
with open_file_write(f'{filename}.bom.tsv') as file:
|
||||||
file.write(tuplelist2tsv(bomlist))
|
file.write(tuplelist2tsv(bomlist))
|
||||||
# HTML output
|
# HTML output
|
||||||
generate_html_output(filename, bomlist)
|
generate_html_output(filename, bomlist, self.metadata)
|
||||||
|
|
||||||
def bom(self):
|
def bom(self):
|
||||||
if not self._bom:
|
if not self._bom:
|
||||||
|
|||||||
@ -13,6 +13,7 @@ if __name__ == '__main__':
|
|||||||
sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..'))
|
sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..'))
|
||||||
|
|
||||||
from wireviz import __version__
|
from wireviz import __version__
|
||||||
|
from wireviz.DataClasses import Metadata, Options
|
||||||
from wireviz.Harness import Harness
|
from wireviz.Harness import Harness
|
||||||
from wireviz.wv_helper import expand, open_file_read
|
from wireviz.wv_helper import expand, open_file_read
|
||||||
|
|
||||||
@ -34,7 +35,11 @@ def parse(yaml_input: str, file_out: (str, Path) = None, return_types: (None, st
|
|||||||
|
|
||||||
yaml_data = yaml.safe_load(yaml_input)
|
yaml_data = yaml.safe_load(yaml_input)
|
||||||
|
|
||||||
harness = Harness()
|
# Assign default metadata.title here to avoid needing file_out in Metadata.__post_init__().
|
||||||
|
harness = Harness(
|
||||||
|
Metadata(**{'title': Path(file_out).stem, **yaml_data.get('metadata', {})}),
|
||||||
|
Options(**yaml_data.get('options', {})),
|
||||||
|
)
|
||||||
|
|
||||||
# add items
|
# add items
|
||||||
sections = ['connectors', 'cables', 'connections']
|
sections = ['connectors', 'cables', 'connections']
|
||||||
|
|||||||
@ -14,7 +14,7 @@ def get_additional_component_table(harness, component: Union[Connector, Cable])
|
|||||||
rows.append(["Additional components"])
|
rows.append(["Additional components"])
|
||||||
for extra in component.additional_components:
|
for extra in component.additional_components:
|
||||||
qty = extra.qty * component.get_qty_multiplier(extra.qty_multiplier)
|
qty = extra.qty * component.get_qty_multiplier(extra.qty_multiplier)
|
||||||
if harness.mini_bom_mode:
|
if harness.options.mini_bom_mode:
|
||||||
id = get_bom_index(harness, extra.description, extra.unit, extra.manufacturer, extra.mpn, extra.pn)
|
id = get_bom_index(harness, extra.description, extra.unit, extra.manufacturer, extra.mpn, extra.pn)
|
||||||
rows.append(component_table_entry(f'#{id} ({extra.type.rstrip()})', qty, extra.unit))
|
rows.append(component_table_entry(f'#{id} ({extra.type.rstrip()})', qty, extra.unit))
|
||||||
else:
|
else:
|
||||||
|
|||||||
@ -2,21 +2,26 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
from typing import List, Union
|
||||||
import re
|
import re
|
||||||
|
|
||||||
from wireviz import __version__, APP_NAME, APP_URL
|
from wireviz import __version__, APP_NAME, APP_URL
|
||||||
|
from wireviz.DataClasses import Metadata
|
||||||
from wireviz.wv_helper import flatten2d, open_file_read, open_file_write
|
from wireviz.wv_helper import flatten2d, open_file_read, open_file_write
|
||||||
|
|
||||||
def generate_html_output(filename: (str, Path), bom_list):
|
def generate_html_output(filename: Union[str, Path], bom_list: List[List[str]], metadata: Metadata):
|
||||||
with open_file_write(f'{filename}.html') as file:
|
with open_file_write(f'{filename}.html') as file:
|
||||||
file.write('<!DOCTYPE html>\n')
|
file.write('<!DOCTYPE html>\n')
|
||||||
file.write('<html lang="en"><head>\n')
|
file.write('<html lang="en"><head>\n')
|
||||||
file.write(' <meta charset="UTF-8">\n')
|
file.write(' <meta charset="UTF-8">\n')
|
||||||
file.write(f' <meta name="generator" content="{APP_NAME} {__version__} - {APP_URL}">\n')
|
file.write(f' <meta name="generator" content="{APP_NAME} {__version__} - {APP_URL}">\n')
|
||||||
file.write(f' <title>{APP_NAME} Diagram and BOM</title>\n')
|
file.write(f' <title>{metadata.title}</title>\n')
|
||||||
file.write('</head><body style="font-family:Arial">\n')
|
file.write('</head><body style="font-family:Arial">\n')
|
||||||
|
|
||||||
file.write('<h1>Diagram</h1>')
|
file.write(f'<h1>{metadata.title}</h1>\n')
|
||||||
|
if metadata.description:
|
||||||
|
file.write(f'<p>{metadata.description}</p>\n')
|
||||||
|
file.write('<h2>Diagram</h2>\n')
|
||||||
with open_file_read(f'{filename}.svg') as svg:
|
with open_file_read(f'{filename}.svg') as svg:
|
||||||
file.write(re.sub(
|
file.write(re.sub(
|
||||||
'^<[?]xml [^?>]*[?]>[^<]*<!DOCTYPE [^>]*>',
|
'^<[?]xml [^?>]*[?]>[^<]*<!DOCTYPE [^>]*>',
|
||||||
@ -25,7 +30,7 @@ def generate_html_output(filename: (str, Path), bom_list):
|
|||||||
for svgdata in svg:
|
for svgdata in svg:
|
||||||
file.write(svgdata)
|
file.write(svgdata)
|
||||||
|
|
||||||
file.write('<h1>Bill of Materials</h1>')
|
file.write('<h2>Bill of Materials</h2>\n')
|
||||||
listy = flatten2d(bom_list)
|
listy = flatten2d(bom_list)
|
||||||
file.write('<table style="border:1px solid #000000; font-size: 14pt; border-spacing: 0px">')
|
file.write('<table style="border:1px solid #000000; font-size: 14pt; border-spacing: 0px">')
|
||||||
file.write('<tr>')
|
file.write('<tr>')
|
||||||
@ -39,6 +44,9 @@ def generate_html_output(filename: (str, Path), bom_list):
|
|||||||
align = 'text-align:right; ' if listy[0][i] == 'Qty' else ''
|
align = 'text-align:right; ' if listy[0][i] == 'Qty' else ''
|
||||||
file.write(f'<td style="{align}border:1px solid #000000; padding: 4px">{item_str}</td>')
|
file.write(f'<td style="{align}border:1px solid #000000; padding: 4px">{item_str}</td>')
|
||||||
file.write('</tr>')
|
file.write('</tr>')
|
||||||
file.write('</table>')
|
file.write('</table>\n')
|
||||||
|
|
||||||
|
if metadata.notes:
|
||||||
|
file.write(f'<h2>Notes</h2>\n<p>{metadata.notes}</p>\n')
|
||||||
|
|
||||||
file.write('</body></html>')
|
file.write('</body></html>')
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user