app
KiCad Library Manager
Public Made by Adomby adom
Organize your KiCad symbol / footprint / 3D libraries fast — three priority views, inline editing, live previews, and one-click sync.
master
import os, re, json, sys
at_re = re.compile(r'\(at\s+(-?[\d.]+)\s+(-?[\d.]+)')
size_re = re.compile(r'\(size\s+(-?[\d.]+)\s+(-?[\d.]+)\)')
type_re = re.compile(r'(?:"(?:[^"\\]|\\.)*"|\S+)\s+(\w+)')
def fingerprint(text):
pads = []
for chunk in text.split('(pad ')[1:]:
m = type_re.match(chunk)
ptype = m.group(1) if m else ''
a = at_re.search(chunk); s = size_re.search(chunk)
if not a or not s: continue
pads.append((ptype, float(a.group(1)), float(a.group(2)), float(s.group(1)), float(s.group(2))))
if not pads: return None
n = len(pads); smd = sum(1 for p in pads if p[0] == 'smd')
minx = min(p[1]-p[3]/2 for p in pads); maxx = max(p[1]+p[3]/2 for p in pads)
miny = min(p[2]-p[4]/2 for p in pads); maxy = max(p[2]+p[4]/2 for p in pads)
sw = sorted(p[3] for p in pads); sh = sorted(p[4] for p in pads)
pitch = float('inf'); cap = pads[:60]
for i in range(len(cap)):
for j in range(i+1, len(cap)):
d = ((cap[i][1]-cap[j][1])**2 + (cap[i][2]-cap[j][2])**2) ** 0.5
if 0.01 < d < pitch: pitch = d
if pitch == float('inf'): pitch = 0
r = lambda x: round(x, 2)
return {'n': n, 'smd': smd, 'tht': n-smd, 'bw': r(maxx-minx), 'bh': r(maxy-miny),
'padW': r(sw[len(sw)//2]), 'padH': r(sh[len(sh)//2]), 'pitch': r(pitch)}
out = []
for d in sys.argv[1:]:
if not os.path.isdir(d): continue
for entry in os.listdir(d):
if not entry.endswith('.pretty'): continue
nick = entry[:-7]; pdir = os.path.join(d, entry)
for f in os.listdir(pdir):
if not f.endswith('.kicad_mod'): continue
try: t = open(os.path.join(pdir, f), encoding='utf-8', errors='ignore').read()
except Exception: continue
fp = fingerprint(t)
if fp: out.append({'id': nick+':'+f[:-10], 'name': f[:-10], 'nick': nick, 'fp': fp})
sys.stdout.write(json.dumps(out))