R2:底板 / 刀片布局布线脚本、快照、截图与规划文档更新(含外壳、打印件、布线归档)
Co-Authored-By: Claude Opus 5.5 <[email protected]>
这个提交包含在:
@@ -0,0 +1,70 @@
|
||||
#!/usr/bin/env python3
|
||||
"""把整个 EasyEDA 工程导成 .epro(zip)拉到本地并解包。
|
||||
|
||||
.epro 里含原理图 / PCB / **符号 / 封装 / 3D 模型**的源码 —— 页面源码里没有符号图形,
|
||||
所以生成 KiCad 符号库必须靠这个包。
|
||||
|
||||
桥接只能传 JSON,所以 JS 侧把文件缓存在 globalThis 上,分块 base64 回传。
|
||||
"""
|
||||
import base64, json, os, sys, zipfile
|
||||
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
|
||||
import eda
|
||||
|
||||
ROOT = os.path.dirname(os.path.abspath(__file__))
|
||||
OUT = os.path.join(ROOT, "eda_src")
|
||||
PROJ = "1e5745f4caff4b15a921694d2fd912e4"
|
||||
CHUNK = 384 * 1024 # 原始字节;base64 后约 512 KB 一块
|
||||
|
||||
PREP = '''
|
||||
const f = await eda.sys_FileManager.getProjectFileByProjectUuid("%s","PhoneRail",undefined,"epro");
|
||||
if(!f) return {size:0};
|
||||
globalThis.__epro = new Uint8Array(await f.arrayBuffer());
|
||||
return { size: globalThis.__epro.length, name: f.name };
|
||||
''' % PROJ
|
||||
|
||||
GRAB = '''
|
||||
const b = globalThis.__epro.subarray(%d, %d);
|
||||
let s=''; const N=0x8000;
|
||||
for(let i=0;i<b.length;i+=N) s += String.fromCharCode.apply(null, b.subarray(i,i+N));
|
||||
return btoa(s);
|
||||
'''
|
||||
|
||||
|
||||
def call(js, what, timeout=300):
|
||||
r = eda.run(js, timeout=timeout)
|
||||
if not r.get("success"):
|
||||
sys.exit(f"!! {what}: " + json.dumps(r, ensure_ascii=False)[:400])
|
||||
return r["result"]
|
||||
|
||||
|
||||
def main():
|
||||
os.makedirs(OUT, exist_ok=True)
|
||||
info = call(PREP, "导出工程包")
|
||||
size = info["size"]
|
||||
if not size:
|
||||
sys.exit("!! 工程包导出返回空")
|
||||
print(f"{info['name']} {size:,d} B")
|
||||
buf = bytearray()
|
||||
while len(buf) < size:
|
||||
end = min(len(buf) + CHUNK, size)
|
||||
buf += base64.b64decode(call(GRAB % (len(buf), end), f"取 {len(buf)}~{end}"))
|
||||
print(f" {len(buf):>9,d} / {size:,d}")
|
||||
if len(buf) != size:
|
||||
sys.exit(f"!! 长度不符 {len(buf)} != {size}")
|
||||
epro = os.path.join(OUT, "PhoneRail.epro")
|
||||
open(epro, "wb").write(buf)
|
||||
|
||||
d = os.path.join(OUT, "epro")
|
||||
os.makedirs(d, exist_ok=True)
|
||||
with zipfile.ZipFile(epro) as z:
|
||||
z.extractall(d)
|
||||
names = z.namelist()
|
||||
print(f"\n解包 {len(names)} 项 -> {d}")
|
||||
import collections
|
||||
top = collections.Counter(n.split("/")[0] for n in names if "/" in n)
|
||||
for k, v in top.most_common():
|
||||
print(f" {k:12s} {v}")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
在新工单中引用
屏蔽一个用户