# -*- coding: utf-8 -*- # Copyright (c) 2020-2021 Salvador E. Tropea # Copyright (c) 2020-2021 Instituto Nacional de TecnologĂ­a Industrial # Copyright (c) 2016-2020 Oliver Henry Walters (@SchrodingersGat) # License: MIT # Project: KiBot (formerly KiPlot) # Adapted from: https://github.com/SchrodingersGat/KiBoM """ CSV Writer: Generates a CSV, TSV or TXT BoM file. """ import csv def write_stats(writer, cfg): if len(cfg.aggregate) == 1: # Only one project if not cfg.csv.hide_pcb_info: prj = cfg.aggregate[0] writer.writerow(["Project info:"]) writer.writerow(["Schematic:", prj.name]) writer.writerow(["Variant:", cfg.variant.name]) writer.writerow(["Revision:", prj.sch.revision]) writer.writerow(["Date:", prj.sch.date]) writer.writerow(["KiCad Version:", cfg.kicad_version]) if not cfg.csv.hide_stats_info: writer.writerow(["Statistics:"]) writer.writerow(["Component Groups:", cfg.n_groups]) writer.writerow(["Component Count:", cfg.n_total]) writer.writerow(["Fitted Components:", cfg.n_fitted]) writer.writerow(["Number of PCBs:", cfg.number]) writer.writerow(["Total Components:", cfg.n_build]) else: # Multiple projects if not cfg.csv.hide_pcb_info: prj = cfg.aggregate[0] writer.writerow(["Project info:"]) writer.writerow(["Variant:", cfg.variant.name]) writer.writerow(["KiCad Version:", cfg.kicad_version]) if not cfg.csv.hide_stats_info: writer.writerow(["Global statistics:"]) writer.writerow(["Component Groups:", cfg.n_groups]) writer.writerow(["Component Count:", cfg.n_total]) writer.writerow(["Fitted Components:", cfg.n_fitted]) writer.writerow(["Number of PCBs:", cfg.number]) writer.writerow(["Total Components:", cfg.n_build]) # Individual stats for prj in cfg.aggregate: if not cfg.csv.hide_pcb_info: writer.writerow(["Project info:", prj.sch.title]) writer.writerow(["Schematic:", prj.name]) writer.writerow(["Revision:", prj.sch.revision]) writer.writerow(["Date:", prj.sch.date]) if prj.sch.company: writer.writerow(["Company:", prj.sch.company]) if prj.ref_id: writer.writerow(["ID", prj.ref_id]) if not cfg.csv.hide_stats_info: writer.writerow(["Statistics:", prj.sch.title]) writer.writerow(["Component Groups:", prj.comp_groups]) writer.writerow(["Component Count:", prj.comp_total]) writer.writerow(["Fitted Components:", prj.comp_fitted]) writer.writerow(["Number of PCBs:", prj.number]) writer.writerow(["Total Components:", prj.comp_build]) def write_csv(filename, ext, groups, headings, head_names, cfg): """ Write BoM out to a CSV file filename = path to output file (must be a .csv, .txt or .tsv file) groups = [list of ComponentGroup groups] headings = [list of headings to search for data in the BoM file] head_names = [list of headings to display in the BoM file] cfg = BoMOptions object with all the configuration """ # Delimeter is assumed from file extension # Override delimiter if separator specified if ext == "csv" and cfg.csv.separator: delimiter = cfg.csv.separator else: if ext == "csv": delimiter = "," elif ext == "tsv" or ext == "txt": delimiter = "\t" if cfg.csv.quote_all: quoting = csv.QUOTE_ALL else: quoting = csv.QUOTE_MINIMAL with open(filename, "wt") as f: writer = csv.writer(f, delimiter=delimiter, lineterminator="\n", quoting=quoting) # Headers writer.writerow(head_names) # Body for group in groups: if cfg.ignore_dnf and not group.is_fitted(): continue row = group.get_row(headings) writer.writerow(row) # PCB info if not (cfg.csv.hide_pcb_info and cfg.csv.hide_stats_info): # Add some blank rows for i in range(5): writer.writerow([]) # The info write_stats(writer, cfg) return True