AnasSarkiz/muse-voice-remote

Muse Voice Remote — bare ESP32-S3R8, 155 TOP JLCPCB parts with real supplier CAD, native 3D assembly and GLB exports. Revised 17 mm case allocation; 0.30 mm via drill /0.45 mm pad. Checked prototype PCB; mechanical, RF and MUSE qualification pending.

Version
1.3.2
License
unset
Stars
0

scripts/reassemble-assets.py

"""Reassemble original binary assets from a locally downloaded parts manifest."""
import hashlib,json,sys
from pathlib import Path,PurePosixPath

p=Path(sys.argv[1] if len(sys.argv)>1 else 'assets.json');root=p.parent
manifest=json.loads(p.read_text())
for name,asset in manifest['assets'].items():
 if Path(name).name!=name:raise ValueError('Invalid output name')
 chunks=[]
 for part in asset['parts']:
  rel=PurePosixPath(part['path'])
  if rel.is_absolute() or '..' in rel.parts:raise ValueError('Unsafe part path')
  b=(root/part['path']).read_bytes()
  if len(b)!=part['bytes'] or hashlib.sha256(b).hexdigest()!=part['sha256']:raise ValueError('Part integrity check failed')
  chunks.append(b)
 payload=b''.join(chunks)
 if len(payload)!=asset['bytes'] or hashlib.sha256(payload).hexdigest()!=asset['sha256']:raise ValueError('Full asset integrity check failed')
 output=root/name
 if output.exists() and output.read_bytes()!=payload:raise ValueError('Refusing to replace a different existing file')
 output.write_bytes(payload);print(f'{name}: {len(payload)} bytes, SHA-256 verified')