Files
kicad-symbol-exporter/exporter.py

104 lines
2.9 KiB
Python

import argparse
import re
import pprint as ppr
from kiutils.libraries import LibTable
from kiutils.symbol import SymbolLib
from kiutils.footprint import Footprint
import tomli
import tomli_w
import pathlib
import glob
printer = ppr.PrettyPrinter(width=900)
pprint = printer.pprint
debug = True
def parse_inputs():
parser = argparse.ArgumentParser()
parser.add_argument('input', type=str, help='input file')
parser.add_argument('output', type=str, help='output file')
parser.add_argument('-e', type=str, help='file containing replacements for the env vars (format: ENV = path)')
parser.add_argument('-s', action='store_true', default=False, help='save env vars to env.toml')
args = parser.parse_args()
return args
def main():
args = parse_inputs()
filename = args.input
envs = load_envs(args)
libs = table_to_dict(filename, envs)
if args.s:
with open('envs.toml', "wb") as f:
tomli_w.dump(envs, f)
with open(args.output, 'w+') as f:
for lib in libs.libs:
if libs.type == 'sym_lib_table':
write_syms_to_file(f, lib)
if libs.type == 'fp_lib_table':
write_fps_to_file(f, lib)
pass
def write_syms_to_file(f, lib):
if lib.type == 'KiCad':
syms = symbols_to_list(lib.uri)
if syms:
for sym in syms:
print(f'{lib.name}:{sym}')
f.write(f'{lib.name}:{sym}\n')
def write_fps_to_file(f, lib):
if lib.type == 'KiCad':
fps = footprints_to_list(lib.uri)
if fps:
for fp in fps:
print(f'{lib.name}:{fp}')
f.write(f'{lib.name}:{fp}\n')
def load_envs(args):
if args.e:
with open(args.e, 'rb') as settings:
envs = tomli.load(settings)
for k, v in envs.items():
envs[k] = pathlib.Path(v).as_posix()
return envs
else:
return None
def table_to_dict(filename, envs = None):
p = r'\${(.*)}'
lib = LibTable.from_file(filename)
# replace envs
for l in lib.libs:
m = re.search(p, l.uri)
if m: #found env
try:
l.uri = re.sub(p, fr'{envs[m.group(1)]}', l.uri) #replace it
except KeyError:
envs[m.group(1)] = pathlib.Path(input(f'Please enter the path for {m.group(1)}: ')).as_posix() # if not found, ask for replacement value
l.uri = re.sub(p, envs[m.group(1)], l.uri) # and replace it
return lib
def symbols_to_list(path):
sym = SymbolLib.from_file(path)
symlst = [s.entryName for s in sym.symbols if (s.inBom and not s.isPower)]
return symlst
def footprints_to_list(path):
fplst = [Footprint.from_file(mod).entryName
for mod in glob.glob(f'{path}/*.kicad_mod')
if not Footprint.from_file(mod).attributes.excludeFromBom]
return fplst
if __name__ == '__main__':
main()