CSV export is working
This commit is contained in:
parent
d8225bd20d
commit
f1e75463f6
|
|
@ -0,0 +1,80 @@
|
||||||
|
import csv
|
||||||
|
import columns
|
||||||
|
from component import *
|
||||||
|
|
||||||
|
import os, shutil
|
||||||
|
|
||||||
|
#make a tmp copy of a given file
|
||||||
|
def TmpFileCopy(filename):
|
||||||
|
|
||||||
|
filename = os.path.abspath(filename)
|
||||||
|
|
||||||
|
if os.path.exists(filename) and os.path.isfile(filename):
|
||||||
|
shutil.copyfile(filename, filename + ".tmp")
|
||||||
|
|
||||||
|
def WriteCSV(filename, groups, source, version, date, headings = columns.ColumnList._COLUMNS_ALL, ignore=[], ignoreDNF=False, numberRows=True):
|
||||||
|
|
||||||
|
filename = os.path.abspath(filename)
|
||||||
|
|
||||||
|
#delimeter is assumed from file extension
|
||||||
|
if filename.endswith(".csv"):
|
||||||
|
delimiter = ","
|
||||||
|
elif filename.endswith(".tsv") or filename.endswith(".txt"):
|
||||||
|
delimiter = "\t"
|
||||||
|
else:
|
||||||
|
return
|
||||||
|
|
||||||
|
headings = [h for h in headings if h not in ignore] #copy across the headings
|
||||||
|
|
||||||
|
try:
|
||||||
|
#make a copy of the file
|
||||||
|
TmpFileCopy(filename)
|
||||||
|
|
||||||
|
with open(filename, "w") as f:
|
||||||
|
|
||||||
|
writer = csv.writer(f, delimiter=delimiter, lineterminator="\n")
|
||||||
|
|
||||||
|
if numberRows:
|
||||||
|
writer.writerow(["Component"] + headings)
|
||||||
|
else:
|
||||||
|
writer.writerow(headings)
|
||||||
|
|
||||||
|
count = 0
|
||||||
|
rowCount = 1
|
||||||
|
|
||||||
|
for i, group in enumerate(groups):
|
||||||
|
if ignoreDNF and not group.isFitted(): continue
|
||||||
|
|
||||||
|
row = group.getKicadRow(headings)
|
||||||
|
|
||||||
|
if numberRows:
|
||||||
|
row = [rowCount] + row
|
||||||
|
|
||||||
|
writer.writerow(row)
|
||||||
|
|
||||||
|
try:
|
||||||
|
count += group.getCount()
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
|
||||||
|
rowCount += 1
|
||||||
|
|
||||||
|
#blank rows
|
||||||
|
for i in range(5):
|
||||||
|
writer.writerow([])
|
||||||
|
|
||||||
|
writer.writerow(["Component Count:",componentCount])
|
||||||
|
writer.writerow(["Component Groups:",len(groups)])
|
||||||
|
writer.writerow(["Source:",source])
|
||||||
|
writer.writerow(["Version:",version])
|
||||||
|
writer.writerow(["Date:",date])
|
||||||
|
|
||||||
|
return True
|
||||||
|
|
||||||
|
except NameError:
|
||||||
|
pass
|
||||||
|
# except BaseException as e:
|
||||||
|
# print(str(e))
|
||||||
|
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
@ -55,7 +55,7 @@ class ColumnList:
|
||||||
|
|
||||||
#default columns
|
#default columns
|
||||||
#these columns are 'immutable'
|
#these columns are 'immutable'
|
||||||
_COLUMNS_DEFAULT = [
|
_COLUMNS_PROTECTED = [
|
||||||
Column.COL_DESCRIPTION,
|
Column.COL_DESCRIPTION,
|
||||||
Column.COL_PART,
|
Column.COL_PART,
|
||||||
Column.COL_REFERENCE,
|
Column.COL_REFERENCE,
|
||||||
|
|
@ -74,7 +74,7 @@ class ColumnList:
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return self.__str__()
|
return self.__str__()
|
||||||
|
|
||||||
def __init__(self, cols=_COLUMNS_DEFAULT):
|
def __init__(self, cols=_COLUMNS_ALL):
|
||||||
|
|
||||||
self.columns = []
|
self.columns = []
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,11 @@
|
||||||
from columns import ColumnList
|
from columns import ColumnList, Column
|
||||||
|
|
||||||
import units
|
import units
|
||||||
|
|
||||||
from sort import natural_sort
|
from sort import natural_sort
|
||||||
|
|
||||||
|
DNF = ["dnf", "do not fit", "nofit", "no stuff", "nostuff", "noload", "do not load"]
|
||||||
|
|
||||||
class Component():
|
class Component():
|
||||||
"""Class for a component, aka 'comp' in the xml netlist file.
|
"""Class for a component, aka 'comp' in the xml netlist file.
|
||||||
This component class is implemented by wrapping an xmlElement instance
|
This component class is implemented by wrapping an xmlElement instance
|
||||||
|
|
@ -249,7 +251,7 @@ class ComponentGroup():
|
||||||
#update a given field, based on some rules and such
|
#update a given field, based on some rules and such
|
||||||
def updateField(self, field, fieldData):
|
def updateField(self, field, fieldData):
|
||||||
|
|
||||||
if field in CSV_PROTECTED: return
|
if field in ColumnList._COLUMNS_PROTECTED: return
|
||||||
|
|
||||||
if (field == None or field == ""): return
|
if (field == None or field == ""): return
|
||||||
elif fieldData == "" or fieldData == None:
|
elif fieldData == "" or fieldData == None:
|
||||||
|
|
@ -262,9 +264,9 @@ class ComponentGroup():
|
||||||
print("Conflict:",self.fields[field],",",fieldData)
|
print("Conflict:",self.fields[field],",",fieldData)
|
||||||
self.fields[field] += " " + fieldData
|
self.fields[field] += " " + fieldData
|
||||||
|
|
||||||
def updateFields(self):
|
def updateFields(self, fields = ColumnList._COLUMNS_ALL):
|
||||||
|
|
||||||
for f in CSV_DEFAULT:
|
for f in fields:
|
||||||
|
|
||||||
#get info from each field
|
#get info from each field
|
||||||
for c in self.components:
|
for c in self.components:
|
||||||
|
|
@ -272,19 +274,14 @@ class ComponentGroup():
|
||||||
self.updateField(f, c.getField(f))
|
self.updateField(f, c.getField(f))
|
||||||
|
|
||||||
#update 'global' fields
|
#update 'global' fields
|
||||||
self.fields["Reference"] = self.getRefs()
|
self.fields[Column.COL_REFERENCE] = self.getRefs()
|
||||||
|
self.fields[Column.COL_GRP_QUANTITY] = self.getCount()
|
||||||
self.fields["Quantity"] = self.getCount()
|
self.fields[Column.COL_VALUE] = self.components[0].getValue()
|
||||||
|
self.fields[Column.COL_PART] = self.components[0].getPartName()
|
||||||
self.fields["Value"] = self.components[0].getValue()
|
self.fields[Column.COL_DESCRIPTION] = self.components[0].getDescription()
|
||||||
|
self.fields[Column.COL_DATASHEET] = self.components[0].getDatasheet()
|
||||||
self.fields["Part"] = self.components[0].getPartName()
|
self.fields[Column.COL_FP] = self.components[0].getFootprint().split(":")[-1]
|
||||||
|
self.fields[Column.COL_FP_LIB] = self.components[0].getFootprint().split(":")[0]
|
||||||
self.fields["Description"] = self.components[0].getDescription()
|
|
||||||
|
|
||||||
self.fields["Datasheet"] = self.components[0].getDatasheet()
|
|
||||||
|
|
||||||
self.fields["Footprint"] = self.components[0].getFootprint().split(":")[-1]
|
|
||||||
|
|
||||||
#return a dict of the CSV data based on the supplied columns
|
#return a dict of the CSV data based on the supplied columns
|
||||||
def getCSVRow(self, columns):
|
def getCSVRow(self, columns):
|
||||||
|
|
|
||||||
|
|
@ -78,12 +78,8 @@ ALIASES = [
|
||||||
["l, l_small", "inductor"]
|
["l, l_small", "inductor"]
|
||||||
]
|
]
|
||||||
|
|
||||||
DNF = ["dnf", "do not fit", "nofit", "no stuff", "nostuff", "noload", "do not load"]
|
|
||||||
|
|
||||||
#-----</Configure>---------------------------------------------------------------
|
#-----</Configure>---------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class xmlElement():
|
class xmlElement():
|
||||||
"""xml element which can represent all nodes of the netlist tree. It can be
|
"""xml element which can represent all nodes of the netlist tree. It can be
|
||||||
used to easily generate various output formats by propogating format
|
used to easily generate various output formats by propogating format
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,5 @@
|
||||||
|
import re
|
||||||
|
|
||||||
#'better' sorting function which sorts by NUMERICAL value not ASCII
|
#'better' sorting function which sorts by NUMERICAL value not ASCII
|
||||||
def natural_sort(string):
|
def natural_sort(string):
|
||||||
return [int(s) if s.isdigit() else s for s in re.split(r'(\d+)',string)]
|
return [int(s) if s.isdigit() else s for s in re.split(r'(\d+)',string)]
|
||||||
30
KiBOM_GUI.py
30
KiBOM_GUI.py
|
|
@ -8,7 +8,9 @@ import wx.grid
|
||||||
def Debug(*arg):
|
def Debug(*arg):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
sys.path.append(os.path.dirname(sys.argv[0]))
|
here = os.path.abspath(os.path.dirname(sys.argv[0]))
|
||||||
|
|
||||||
|
sys.path.append(here)
|
||||||
|
|
||||||
from KiBOM.columns import ColumnList
|
from KiBOM.columns import ColumnList
|
||||||
|
|
||||||
|
|
@ -64,6 +66,8 @@ class KiBOMFrame(wx.Frame):
|
||||||
def __init__(self, parent, title):
|
def __init__(self, parent, title):
|
||||||
wx.Frame.__init__(self, parent,title=title)
|
wx.Frame.__init__(self, parent,title=title)
|
||||||
|
|
||||||
|
wx.Image.AddHandler(wx.PNGHandler());
|
||||||
|
|
||||||
self.columns = ColumnList()
|
self.columns = ColumnList()
|
||||||
|
|
||||||
self.panel = wx.Panel(self)
|
self.panel = wx.Panel(self)
|
||||||
|
|
@ -101,15 +105,25 @@ class KiBOMFrame(wx.Frame):
|
||||||
#buttons to move/add/delete columns
|
#buttons to move/add/delete columns
|
||||||
self.colButtons = wx.BoxSizer(wx.HORIZONTAL)
|
self.colButtons = wx.BoxSizer(wx.HORIZONTAL)
|
||||||
|
|
||||||
self.moveColUp = wx.Button(self.panel, label="Up")
|
upImage = wx.Bitmap(here + "/bitmap/up.png", wx.BITMAP_TYPE_ANY)
|
||||||
self.moveColDown = wx.Button(self.panel, label="Down")
|
self.moveUp = wx.BitmapButton(self.panel, bitmap=upImage, size=upImage.GetSize())
|
||||||
self.newCol = wx.Button(self.panel, label="Add")
|
# self.moveUp.SetTip("Move the selected column up")
|
||||||
self.delCol = wx.Button(self.panel, label="Del")
|
|
||||||
|
downImage = wx.Bitmap(here + "/bitmap/down.png", wx.BITMAP_TYPE_ANY)
|
||||||
|
self.moveDown = wx.BitmapButton(self.panel, bitmap=downImage, size=downImage.GetSize())
|
||||||
|
# self.moveDown.setToolTip("Move the selected column down")
|
||||||
|
|
||||||
|
newImage = wx.Bitmap(here + "/bitmap/add.png", wx.BITMAP_TYPE_ANY)
|
||||||
|
self.newCol = wx.BitmapButton(self.panel, bitmap=newImage, size=newImage.GetSize())
|
||||||
|
# self.newCol.setToolTip("Add a new data column")
|
||||||
|
|
||||||
|
#delImage = wx.Bitmap("bitmap/del.png", wx.BITMAP_TYPE_ANY)
|
||||||
|
#self.delCol = wx.BitmapButton(self.panel, bitmap=delImage, size=delImage.GetSize())
|
||||||
|
|
||||||
#add the buttons
|
#add the buttons
|
||||||
self.colButtons.Add(self.moveColUp)
|
self.colButtons.Add(self.moveUp)
|
||||||
self.colButtons.Add(self.moveColDown)
|
self.colButtons.Add(self.moveDown)
|
||||||
self.colButtons.Add(self.delCol)
|
#self.colButtons.Add(self.delCol)
|
||||||
self.colButtons.Add(self.newCol)
|
self.colButtons.Add(self.newCol)
|
||||||
|
|
||||||
self.colListSizer.Add(self.colButtons)
|
self.colListSizer.Add(self.colButtons)
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue