master
barrett-land Publish 1.2.0 2beee58 2mo ago
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))