71 行
2.3 KiB
Python
71 行
2.3 KiB
Python
#!/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()
|