Files
kefu/deploy/protocol-integration-20260916/apply.py
T
2026-09-21 10:34:06 +08:00

34 lines
2.4 KiB
Python

from pathlib import Path
import datetime,hashlib,json,shutil
folder=Path(__file__).resolve().parent;payload=folder/'payload';target=Path('C:/wechat_rpa').resolve()
assert target==Path('C:/wechat_rpa').resolve() and not target.is_symlink()
previous={r['path']:r for r in json.loads((folder/'manifest.json').read_text(encoding='utf-8'))}
def sha(path):return hashlib.sha256(path.read_bytes()).hexdigest()
manifest=[]
for path in sorted(payload.rglob('*')):
if not path.is_file():continue
relative=path.relative_to(payload).as_posix();destination=(target/relative).resolve()
assert destination.is_relative_to(target),relative
before=sha(destination) if destination.is_file() else None
if relative in previous:assert before==previous[relative]['before_sha256'],'Target changed: '+relative
else:assert before is None,'Unexpected existing file: '+relative
manifest.append({'path':relative,'sha256':sha(path),'before_sha256':before,'bytes':path.stat().st_size})
changed={r['path'] for r in manifest}
preserved={p.name:sha(p) for p in target.iterdir() if p.is_file() and p.suffix in {'.py','.ps1','.spec','.bat'} and p.name not in changed}
backup=target/'backups'/('integration-'+datetime.datetime.now().strftime('%Y%m%d-%H%M%S'))
assert backup.resolve().is_relative_to(target);backup.mkdir(parents=True,exist_ok=False)
for row in manifest:
if row['before_sha256'] is not None:
destination=backup/row['path'];destination.parent.mkdir(parents=True,exist_ok=True)
shutil.copyfile(target/row['path'],destination)
(backup/'manifest.json').write_text(json.dumps(manifest,ensure_ascii=False,indent=2),encoding='utf-8')
for row in manifest:
destination=target/row['path'];destination.parent.mkdir(parents=True,exist_ok=True)
shutil.copyfile(payload/row['path'],destination)
assert sha(destination)==row['sha256'],row['path']
for name,digest in preserved.items():assert sha(target/name)==digest,'Preserved program changed: '+name
record={'target':str(target),'backup':str(backup),'files':len(manifest),'preserved_programs':len(preserved),'manifest':manifest,'preserved':preserved}
(folder/'applied.json').write_text(json.dumps(record,ensure_ascii=False,indent=2),encoding='utf-8')
(target/'INTEGRATION_MANIFEST_20260916.json').write_text(json.dumps(record,ensure_ascii=False,indent=2),encoding='utf-8')
print(json.dumps({k:v for k,v in record.items() if k not in {'manifest','preserved'}},ensure_ascii=False))