From 5be72545941ab0ba6a64133d1ffee2a09507340b Mon Sep 17 00:00:00 2001 From: "Salvador E. Tropea" Date: Sat, 1 Aug 2020 18:31:26 -0300 Subject: [PATCH] Now the row number column is a regular column. Its name is `Row` and you can put everywhere. No `number_rows` option needed or special cases, is just another column --- kiplot/bom/bom.py | 10 +++++++ kiplot/bom/columnlist.py | 12 ++++++--- kiplot/bom/csv_writer.py | 12 +-------- kiplot/bom/html_writer.py | 6 ----- kiplot/bom/xlsx_writer.py | 25 ++++-------------- kiplot/out_bom.py | 9 ++----- tests/test_plot/test_int_bom.py | 26 +++++-------------- .../int_bom_column_rename_csv.kiplot.yaml | 2 +- .../int_bom_column_rename_html.kiplot.yaml | 2 +- .../int_bom_column_rename_xlsx.kiplot.yaml | 2 +- .../int_bom_column_rename_xml.kiplot.yaml | 2 +- .../int_bom_column_sensitive.kiplot.yaml | 1 - tests/yaml_samples/int_bom_join_1.kiplot.yaml | 1 + .../int_bom_no_number_rows.kiplot.yaml | 10 ++++++- 14 files changed, 47 insertions(+), 73 deletions(-) diff --git a/kiplot/bom/bom.py b/kiplot/bom/bom.py index 859fdd0b..2ed35981 100644 --- a/kiplot/bom/bom.py +++ b/kiplot/bom/bom.py @@ -365,6 +365,16 @@ def group_components(cfg, components): # Sort the groups # First priority is the Type of component (e.g. R?, U?, L?) groups = sorted(groups, key=lambda g: [g.components[0].ref_prefix, get_value_sort(g.components[0])]) + # Enumerate the groups + c = 1 + dnf = 1 + for g in groups: + if cfg.ignore_dnf and not g.is_fitted(): + g.update_field('Row', str(dnf)) + dnf += 1 + else: + g.update_field('Row', str(c)) + c += 1 return groups diff --git a/kiplot/bom/columnlist.py b/kiplot/bom/columnlist.py index a952d947..054ccf24 100644 --- a/kiplot/bom/columnlist.py +++ b/kiplot/bom/columnlist.py @@ -27,6 +27,8 @@ class ColumnList: COL_DATASHEET_L = COL_DATASHEET.lower() COL_SHEETPATH = 'Sheetpath' COL_SHEETPATH_L = COL_SHEETPATH.lower() + COL_ROW_NUMBER = 'Row' + COL_ROW_NUMBER_L = COL_ROW_NUMBER.lower() # Default columns for groups COL_GRP_QUANTITY = 'Quantity Per PCB' @@ -37,13 +39,15 @@ class ColumnList: COL_GRP_BUILD_QUANTITY_L = COL_GRP_BUILD_QUANTITY.lower() # Generated columns - COLUMNS_GEN_L = [ - COL_GRP_QUANTITY_L, - COL_GRP_BUILD_QUANTITY_L, - ] + COLUMNS_GEN_L = { + COL_GRP_QUANTITY_L: 1, + COL_GRP_BUILD_QUANTITY_L: 1, + COL_ROW_NUMBER_L: 1, + } # Default columns COLUMNS_DEFAULT = [ + COL_ROW_NUMBER, COL_DESCRIPTION, COL_PART, COL_PART_LIB, diff --git a/kiplot/bom/csv_writer.py b/kiplot/bom/csv_writer.py index 8305bc7c..efd7fe7d 100644 --- a/kiplot/bom/csv_writer.py +++ b/kiplot/bom/csv_writer.py @@ -31,14 +31,7 @@ def write_csv(filename, ext, groups, headings, head_names, cfg): writer = csv.writer(f, delimiter=delimiter, lineterminator="\n") # Headers if not cfg.hide_headers: - if cfg.number_rows: - comp = "Component" - comp_lc = comp.lower() - if comp_lc in cfg.column_rename: - comp = cfg.column_rename[comp_lc] - writer.writerow([comp] + head_names) - else: - writer.writerow(head_names) + writer.writerow(head_names) # Body count = 0 row_count = 1 @@ -46,9 +39,6 @@ def write_csv(filename, ext, groups, headings, head_names, cfg): if cfg.ignore_dnf and not group.is_fitted(): continue row = group.get_row(headings) - # Row number - if cfg.number_rows: - row = [str(row_count)] + row writer.writerow(row) count += group.get_count() row_count += 1 diff --git a/kiplot/bom/html_writer.py b/kiplot/bom/html_writer.py index 08cf9251..a1dd91b4 100644 --- a/kiplot/bom/html_writer.py +++ b/kiplot/bom/html_writer.py @@ -38,8 +38,6 @@ def html_table(html, groups, headings, head_names, cfg, link_datasheet, link_dig html.write('\n') # Row titles: html.write("\n") - if cfg.number_rows: - html.write("\t\n") for i, h in enumerate(head_names): # Cell background color bg = bg_color(headings[i]) @@ -53,10 +51,6 @@ def html_table(html, groups, headings, head_names, cfg, link_datasheet, link_dig row = group.get_row(headings) row_count += 1 html.write("\n") - # Row number - if cfg.number_rows: - html.write('\t\n'.format(n=row_count)) - for n, r in enumerate(row): # A link to Digi-Key? if link_digikey and headings[n] in link_digikey: diff --git a/kiplot/bom/xlsx_writer.py b/kiplot/bom/xlsx_writer.py index 130b5e39..6590c2ab 100644 --- a/kiplot/bom/xlsx_writer.py +++ b/kiplot/bom/xlsx_writer.py @@ -46,9 +46,8 @@ def add_info(worksheet, column_widths, row, formats, text, value): value = str(value) else: worksheet.write_string(row, 1, value, formats[1]) - value_l = len(value) - if value_l > column_widths[1]: - column_widths[1] = value_l + column_widths[0] = max(len(text), column_widths[0]) + column_widths[1] = max(len(value), column_widths[1]) return row + 1 @@ -68,25 +67,13 @@ def write_xlsx(filename, groups, col_fields, head_names, cfg): workbook = Workbook(filename) worksheet = workbook.add_worksheet() - if cfg.number_rows: - comp = "Component" - if comp.lower() in cfg.column_rename: - comp = cfg.column_rename[comp.lower()] - row_headings = [comp] + head_names - else: - row_headings = head_names - # Headings + row_headings = head_names cellformats = {} column_widths = {} for i in range(len(row_headings)): cellformats[i] = workbook.add_format(DEFAULT_FMT) - bg = None - if cfg.number_rows: - if i > 0: - bg = bg_color(col_fields[i-1]) - else: - bg = bg_color(col_fields[i]) + bg = bg_color(col_fields[i]) if bg: cellformats[i].set_bg_color(bg) column_widths[i] = len(row_headings[i]) + 10 @@ -106,9 +93,6 @@ def write_xlsx(filename, groups, col_fields, head_names, cfg): continue # Get the data row row = group.get_row(col_fields) - # Add row number - if cfg.number_rows: - row = [str(row_count)] + row # Fill the row for i in range(len(row)): cell = row[i] @@ -131,6 +115,7 @@ def write_xlsx(filename, groups, col_fields, head_names, cfg): title_fmt.set_bold() formats = [title_fmt, cellformat_left] + # TODO: Language? row_count = add_info(worksheet, column_widths, row_count, formats, "Component Groups:", cfg.n_groups) row_count = add_info(worksheet, column_widths, row_count, formats, "Component Count:", cfg.n_total) row_count = add_info(worksheet, column_widths, row_count, formats, "Fitted Components:", cfg.n_fitted) diff --git a/kiplot/out_bom.py b/kiplot/out_bom.py index af1f90fd..f861e67b 100644 --- a/kiplot/out_bom.py +++ b/kiplot/out_bom.py @@ -93,8 +93,6 @@ class BoMOptions(BaseOptions): """ Generate a separated section for DNF (Do Not Fit) components (HTML only) """ self.use_alt = False """ Print grouped references in the alternate compressed style eg: R1-R7,R18 """ - self.number_rows = True - """ First column is the row number """ self.group_connectors = True """ Connectors with the same footprints will be grouped together, independent of the name of the connector """ self.test_regex = True @@ -208,9 +206,8 @@ class BoMOptions(BaseOptions): # This is tricky # Lower case available columns valid_columns = self._get_columns() + valid_columns.append(ColumnList.COL_ROW_NUMBER) valid_columns_l = {c.lower(): c for c in valid_columns} - # Special row number column - valid_columns_l['component'] = 'Component' logger.debug("Valid columns: "+str(valid_columns)) # Create the different lists columns = [] @@ -233,9 +230,6 @@ class BoMOptions(BaseOptions): raise KiPlotConfigurationError('Invalid column name `{}`'.format(new_col)) columns.append(new_col) columns_l[new_col.lower()] = new_col - # TODO less magic, more explicit - if 'component' in columns_l: - del columns_l['component'] # Create a list of the columns we don't want self.ignore = [c for c in valid_columns_l.keys() if c not in columns_l] # And this is the ordered list with the case style defined by the user @@ -264,6 +258,7 @@ class BoM(BaseOutput): # noqa: F821 are loaded from the schematic. Important differences with KiBoM output: - All options are in the main `options` section, not in `conf` subsection. + - The `Component` column is named `Row` and works just like any other column. This output is what you get from the 'Tools/Generate Bill of Materials' menu in eeschema. """ def __init__(self): super().__init__() diff --git a/tests/test_plot/test_int_bom.py b/tests/test_plot/test_int_bom.py index 181997f0..e51aea48 100644 --- a/tests/test_plot/test_int_bom.py +++ b/tests/test_plot/test_int_bom.py @@ -15,7 +15,6 @@ Tests of Internal BoM files - ignore_dnf = 0 - html_generate_dnf = 0 - use_alt = 1 -- number_rows = 0 - COLUMN_RENAME - CSV - HTML @@ -56,7 +55,7 @@ BOM_DIR = 'BoM' REF_COLUMN_NAME = 'References' REF_COLUMN_NAME_R = 'Referencias' QTY_COLUMN_NAME = 'Quantity Per PCB' -COMP_COLUMN_NAME = 'Component' +COMP_COLUMN_NAME = 'Row' COMP_COLUMN_NAME_R = 'Renglón' KIBOM_TEST_HEAD = [COMP_COLUMN_NAME, 'Description', 'Part', REF_COLUMN_NAME, 'Value', 'Footprint', QTY_COLUMN_NAME, 'Datasheet', 'Config'] @@ -130,9 +129,7 @@ def test_int_bom_simple_html(): assert len(headers) == 2 # Test both tables has the same headings and they are the expected assert headers[0] == headers[1] - head_no_comp = deepcopy(KIBOM_TEST_HEAD) - head_no_comp[0] = '' # HTML numbered column doesn't have a name - assert headers[0] == head_no_comp + assert headers[0] == KIBOM_TEST_HEAD # Look for reference and quantity columns ref_column = headers[0].index(REF_COLUMN_NAME) qty_column = headers[0].index(QTY_COLUMN_NAME) @@ -161,8 +158,6 @@ def test_int_bom_simple_xml(): rows, header = ctx.load_xml(out) # Columns get sorted by name, so we need to take care of it for c in KIBOM_TEST_HEAD: - if c == COMP_COLUMN_NAME: - continue assert adapt_xml(c) in header, "Missing column "+c ref_column = header.index(adapt_xml(REF_COLUMN_NAME)) qty_column = header.index(adapt_xml(QTY_COLUMN_NAME)) @@ -224,7 +219,7 @@ def test_int_bom_datasheet_link(): assert len(headers) == 2 # Test both tables has the same headings and they are the expected assert headers[0] == headers[1] - assert headers[0] == ['', 'References', 'Part', 'Value', 'Quantity Per PCB', 'digikey#', 'manf#'] + assert headers[0] == ['References', 'Part', 'Value', 'Quantity Per PCB', 'digikey#', 'manf#'] # Look for reference and quantity columns ref_column = headers[0].index(REF_COLUMN_NAME) part_column = headers[0].index('Part') @@ -253,7 +248,7 @@ def test_int_bom_digikey_link(): assert len(headers) == 2 # Test both tables has the same headings and they are the expected assert headers[0] == headers[1] - assert headers[0] == ['', 'References', 'Part', 'Value', 'Quantity Per PCB', 'digikey#', 'manf#'] + assert headers[0] == ['References', 'Part', 'Value', 'Quantity Per PCB', 'digikey#', 'manf#'] # Look for reference and quantity columns ref_column = headers[0].index(REF_COLUMN_NAME) dk_column = headers[0].index('digikey#') @@ -322,10 +317,7 @@ def test_int_bom_html_generate_dnf(): # Test we got the normal and DNF tables assert len(rows) == 1 assert len(headers) == 1 - # Test both tables has the same headings and they are the expected - head_no_comp = deepcopy(KIBOM_TEST_HEAD) - head_no_comp[0] = '' # HTML numbered column doesn't have a name - assert headers[0] == head_no_comp + assert headers[0] == KIBOM_TEST_HEAD # Look for reference and quantity columns ref_column = headers[0].index(REF_COLUMN_NAME) qty_column = headers[0].index(QTY_COLUMN_NAME) @@ -351,7 +343,7 @@ def test_int_bom_use_alt(): def test_int_bom_no_number_rows(): - """ number_rows: false """ + """ Was number_rows: false, now is different """ prj = 'kibom-test' ext = 'csv' ctx = context.TestContextSCH('test_int_bom_no_number_rows', prj, 'int_bom_no_number_rows', BOM_DIR) @@ -386,9 +378,7 @@ def test_int_bom_column_rename_html(): ctx.run() out = prj + '-bom.' + ext rows, headers = ctx.load_html(out) - head_no_comp = deepcopy(KIBOM_RENAME_HEAD) - head_no_comp[0] = '' # HTML numbered column doesn't have a name - assert headers[0] == head_no_comp + assert headers[0] == KIBOM_RENAME_HEAD ref_column = headers[0].index(REF_COLUMN_NAME_R) check_kibom_test_netlist(rows[0], ref_column, LINKS_GROUPS, LINKS_EXCLUDE, LINKS_COMPONENTS) ctx.clean_up() @@ -403,8 +393,6 @@ def test_int_bom_column_rename_xml(): rows, header = ctx.load_xml(out) # Columns get sorted by name, so we need to take care of it for c in KIBOM_RENAME_HEAD: - if c == COMP_COLUMN_NAME_R: - continue assert adapt_xml(c) in header, "Missing column "+c ref_column = header.index(REF_COLUMN_NAME_R) check_kibom_test_netlist(rows, ref_column, LINKS_GROUPS, LINKS_EXCLUDE, LINKS_COMPONENTS) diff --git a/tests/yaml_samples/int_bom_column_rename_csv.kiplot.yaml b/tests/yaml_samples/int_bom_column_rename_csv.kiplot.yaml index 7ba74246..0dc22c1c 100644 --- a/tests/yaml_samples/int_bom_column_rename_csv.kiplot.yaml +++ b/tests/yaml_samples/int_bom_column_rename_csv.kiplot.yaml @@ -10,7 +10,7 @@ outputs: options: format: CSV columns: - - field: Component + - field: Row name: Renglón - field: References name: Referencias diff --git a/tests/yaml_samples/int_bom_column_rename_html.kiplot.yaml b/tests/yaml_samples/int_bom_column_rename_html.kiplot.yaml index bb692326..a6667819 100644 --- a/tests/yaml_samples/int_bom_column_rename_html.kiplot.yaml +++ b/tests/yaml_samples/int_bom_column_rename_html.kiplot.yaml @@ -10,7 +10,7 @@ outputs: options: format: HTML columns: - - field: Component + - field: Row name: Renglón - field: References name: Referencias diff --git a/tests/yaml_samples/int_bom_column_rename_xlsx.kiplot.yaml b/tests/yaml_samples/int_bom_column_rename_xlsx.kiplot.yaml index 1d34b00d..f19632e5 100644 --- a/tests/yaml_samples/int_bom_column_rename_xlsx.kiplot.yaml +++ b/tests/yaml_samples/int_bom_column_rename_xlsx.kiplot.yaml @@ -10,7 +10,7 @@ outputs: options: format: XLSX columns: - - field: Component + - field: Row name: Renglón - field: References name: Referencias diff --git a/tests/yaml_samples/int_bom_column_rename_xml.kiplot.yaml b/tests/yaml_samples/int_bom_column_rename_xml.kiplot.yaml index 345649ae..4a65ad2e 100644 --- a/tests/yaml_samples/int_bom_column_rename_xml.kiplot.yaml +++ b/tests/yaml_samples/int_bom_column_rename_xml.kiplot.yaml @@ -10,7 +10,7 @@ outputs: options: format: XML columns: - - field: Component + - field: Row name: Renglón - field: References name: Referencias diff --git a/tests/yaml_samples/int_bom_column_sensitive.kiplot.yaml b/tests/yaml_samples/int_bom_column_sensitive.kiplot.yaml index 1a8ec328..3c0a91e2 100644 --- a/tests/yaml_samples/int_bom_column_sensitive.kiplot.yaml +++ b/tests/yaml_samples/int_bom_column_sensitive.kiplot.yaml @@ -9,7 +9,6 @@ outputs: dir: BoM options: format: CSV - number_rows: false columns: - references - value diff --git a/tests/yaml_samples/int_bom_join_1.kiplot.yaml b/tests/yaml_samples/int_bom_join_1.kiplot.yaml index d8c1ffab..6fa2ca31 100644 --- a/tests/yaml_samples/int_bom_join_1.kiplot.yaml +++ b/tests/yaml_samples/int_bom_join_1.kiplot.yaml @@ -10,6 +10,7 @@ outputs: options: format: CSV columns: + - Row - References - Part - field: Value diff --git a/tests/yaml_samples/int_bom_no_number_rows.kiplot.yaml b/tests/yaml_samples/int_bom_no_number_rows.kiplot.yaml index 5534d7e0..8f79647b 100644 --- a/tests/yaml_samples/int_bom_no_number_rows.kiplot.yaml +++ b/tests/yaml_samples/int_bom_no_number_rows.kiplot.yaml @@ -8,6 +8,14 @@ outputs: type: bom dir: BoM options: - number_rows: false format: CSV + columns: + - Description + - Part + - References + - Value + - Footprint + - Quantity Per PCB + - Datasheet + - Config
{n}