From 159f54347c8f28b0fd6c68ed14bd33de3dbbc917 Mon Sep 17 00:00:00 2001 From: Oliver Date: Tue, 14 Jun 2016 20:07:47 +1000 Subject: [PATCH] * Added option to hide file headers * Changed output to be a positional argument (required) * Added blank cell coloring to HTML output --- KiBOM/csv_writer.py | 38 ++++++++++++++++-------------- KiBOM/html_writer.py | 45 ++++++++++++++++++++--------------- KiBOM/preferences.py | 1 + KiBOM_CLI.py | 56 +++++++++++++++++++++++++++----------------- 4 files changed, 81 insertions(+), 59 deletions(-) diff --git a/KiBOM/csv_writer.py b/KiBOM/csv_writer.py index 1f7928f6..d294be41 100644 --- a/KiBOM/csv_writer.py +++ b/KiBOM/csv_writer.py @@ -36,10 +36,11 @@ def WriteCSV(filename, groups, net, headings, prefs): writer = csv.writer(f, delimiter=delimiter, lineterminator="\n") - if prefs.numberRows: - writer.writerow(["Component"] + headings) - else: - writer.writerow(headings) + if not prefs.hideHeaders: + if prefs.numberRows: + writer.writerow(["Component"] + headings) + else: + writer.writerow(headings) count = 0 rowCount = 1 @@ -63,19 +64,20 @@ def WriteCSV(filename, groups, net, headings, prefs): rowCount += 1 - #blank rows - for i in range(5): - writer.writerow([]) - - writer.writerow(["Component Groups:",nGroups]) - writer.writerow(["Component Count:",nTotal]) - writer.writerow(["Fitted Components:", nFitted]) - writer.writerow(["Number of PCBs:",prefs.boards]) - writer.writerow(["Total components:", nBuild]) - writer.writerow(["Schematic Version:",net.getVersion()]) - writer.writerow(["Schematic Date:",net.getSheetDate()]) - writer.writerow(["BoM Date:",net.getDate()]) - writer.writerow(["Schematic Source:",net.getSource()]) - writer.writerow(["KiCad Version:",net.getTool()]) + if not prefs.hideHeaders: + #blank rows + for i in range(5): + writer.writerow([]) + + writer.writerow(["Component Groups:",nGroups]) + writer.writerow(["Component Count:",nTotal]) + writer.writerow(["Fitted Components:", nFitted]) + writer.writerow(["Number of PCBs:",prefs.boards]) + writer.writerow(["Total components:", nBuild]) + writer.writerow(["Schematic Version:",net.getVersion()]) + writer.writerow(["Schematic Date:",net.getSheetDate()]) + writer.writerow(["BoM Date:",net.getDate()]) + writer.writerow(["Schematic Source:",net.getSource()]) + writer.writerow(["KiCad Version:",net.getTool()]) return True \ No newline at end of file diff --git a/KiBOM/html_writer.py b/KiBOM/html_writer.py index d6d83472..ef20f822 100644 --- a/KiBOM/html_writer.py +++ b/KiBOM/html_writer.py @@ -6,6 +6,7 @@ import os BG_GEN = "#E6FFEE" BG_KICAD = "#FFE6B3" BG_USER = "#E6F9FF" +BG_EMPTY = "#FF8080" #return a background color for a given column title def bgColor(col): @@ -58,24 +59,26 @@ def WriteHTML(filename, groups, net, headings, prefs): #PCB info - html.write("

KiBoM PCB Bill of Materials

\n") - html.write('\n') - html.write("\n".format(source=net.getSource())) - html.write("\n".format(date=net.getDate())) - html.write("\n".format(version=net.getVersion())) - html.write("\n".format(date=net.getSheetDate())) - html.write("\n".format(version=net.getTool())) - html.write("\n".format(n=nGroups)) - html.write("\n".format(n=nTotal)) - html.write("\n".format(n=nFitted)) - html.write("\n".format(n=prefs.boards)) - html.write("\n".format(n=prefs.boards, t=nBuild)) - html.write("
Source File{source}
BoM Date{date}
Schematic Version{version}
Schematic Date{date}
KiCad Version{version}
Component Groups{n}
Component Count (per PCB){n}
Fitted Components (per PCB){n}
Number of PCBs{n}
Total Component Count
(for {n} PCBs)
{t}
\n") - html.write("
\n") - html.write("

Component Groups

\n") - html.write('

Kicad Fields (default)

\n'.format(bg=BG_KICAD)) - html.write('

Generated Fields

\n'.format(bg=BG_GEN)) - html.write('

User Fields

\n'.format(bg=BG_USER)) + if not prefs.hideHeaders: + html.write("

KiBoM PCB Bill of Materials

\n") + html.write('\n') + html.write("\n".format(source=net.getSource())) + html.write("\n".format(date=net.getDate())) + html.write("\n".format(version=net.getVersion())) + html.write("\n".format(date=net.getSheetDate())) + html.write("\n".format(version=net.getTool())) + html.write("\n".format(n=nGroups)) + html.write("\n".format(n=nTotal)) + html.write("\n".format(n=nFitted)) + html.write("\n".format(n=prefs.boards)) + html.write("\n".format(n=prefs.boards, t=nBuild)) + html.write("
Source File{source}
BoM Date{date}
Schematic Version{version}
Schematic Date{date}
KiCad Version{version}
Component Groups{n}
Component Count (per PCB){n}
Fitted Components (per PCB){n}
Number of PCBs{n}
Total Component Count
(for {n} PCBs)
{t}
\n") + html.write("
\n") + html.write("

Component Groups

\n") + html.write('

Kicad Fields (default)

\n'.format(bg=BG_KICAD)) + html.write('

Generated Fields

\n'.format(bg=BG_GEN)) + html.write('

User Fields

\n'.format(bg=BG_USER)) + html.write('

Empty Fields

\n'.format(bg=BG_EMPTY)) #component groups html.write('\n') @@ -109,7 +112,11 @@ def WriteHTML(filename, groups, net, headings, prefs): html.write('\t\n'.format(n=rowCount)) for n, r in enumerate(row): - bg = bgColor(headings[n]) + + if len(r) == 0: + bg = BG_EMPTY + else: + bg = bgColor(headings[n]) html.write('\t\n'.format(bg=' bgcolor={c}'.format(c=bg) if bg else '', val=link(r))) diff --git a/KiBOM/preferences.py b/KiBOM/preferences.py index 70e5acac..c79a6dc6 100644 --- a/KiBOM/preferences.py +++ b/KiBOM/preferences.py @@ -49,6 +49,7 @@ class BomPref: self.useRegex = True #Test various columns with regex self.compareFootprints = True #test footprints when comparing components self.boards = 1 + self.hideHeaders = False self.verbose = False #by default, is not verbose self.configurations = [] #list of various configurations diff --git a/KiBOM_CLI.py b/KiBOM_CLI.py index 50d9d90a..e4a3169e 100644 --- a/KiBOM_CLI.py +++ b/KiBOM_CLI.py @@ -31,9 +31,10 @@ def say(*arg): parser = argparse.ArgumentParser(description="KiBOM Bill of Materials generator script") parser.add_argument("netlist", help='xml netlist file. Use "%%I" when running from within KiCad') -parser.add_argument("--output", "-o", help='BoM output file name.\nUse "%%O" when running from within KiCad to use the default output name (csv file).\nFor e.g. HTML output, use "%%O.html"\r\nIf output file is unspecified, default output filename (csv format) will be used', default=None) -parser.add_argument("--boards", "-b", help="Number of boards to build (default = 1)", type=int, default=1) +parser.add_argument("output", default="", help='BoM output file name.\nUse "%%O" when running from within KiCad to use the default output name (csv file).\nFor e.g. HTML output, use "%%O.html"') +parser.add_argument("-b", "--boards", help="Number of boards to build (default = 1)", type=int, default=1) parser.add_argument("-v", "--verbose", help="Enable verbose output", action='count') +parser.add_argument("-n", "--noheader", help="Do not generate file headers; data only.", action='count') parser.add_argument("--cfg", help="BoM config file (script will try to use 'bom.ini' if not specified here)") args = parser.parse_args() @@ -48,25 +49,6 @@ verbose = args.verbose is not None input_file = os.path.abspath(input_file) say("Input:",input_file) - -output_file = args.output - -if output_file is None: - output_file = input_file.replace(".xml","_bom.csv") - -#enfore a proper extension -valid = False -extensions = [".xml",".csv",".txt",".tsv",".html"] -for e in extensions: - if output_file.endswith(e): - valid = True - break -if not valid: - close("Extension must be one of",extensions) - -output_file = os.path.abspath(output_file) - -say("Output:",output_file) #look for a config file! #bom.ini by default @@ -83,6 +65,8 @@ pref = BomPref() #pass various command-line options through pref.verbose = verbose pref.boards = args.boards +if args.noheader: + pref.hideHeaders = True if os.path.exists(config_file): pref.Read(config_file) @@ -115,14 +99,42 @@ for g in groups: for f in g.fields: columns.AddColumn(f) +#don't add 'boards' column if only one board is specified if pref.boards <= 1: columns.RemoveColumn(ColumnList.COL_GRP_BUILD_QUANTITY) say("Removing:",ColumnList.COL_GRP_BUILD_QUANTITY) + +#todo +write_to_bom = True +result = True #Finally, write the BoM out to file -result = WriteBoM(output_file, groups, net, columns.columns, pref) +if write_to_bom: + + output_file = args.output + + if output_file is None: + output_file = input_file.replace(".xml","_bom.csv") + + #enfore a proper extension + valid = False + extensions = [".xml",".csv",".txt",".tsv",".html"] + for e in extensions: + if output_file.endswith(e): + valid = True + break + if not valid: + close("Extension must be one of",extensions) + + output_file = os.path.abspath(output_file) + + say("Output:",output_file) + + result = WriteBoM(output_file, groups, net, columns.columns, pref) if result: sys.exit(0) else: sys.exit(-1) + +
{n}{val}