Files

19 lines
2.9 KiB
Python

from pathlib import Path
import json,hashlib,zipfile,time
r=Path('/Users/korizatou114/Projects/とりにく工房ゲーム制作部');a=r/'artifacts/original-completion-2026-10-02';e=r/'docs/plans/original-completion-2026-10-02/execution/drive-offload-old-windows-r09-20261015';e.mkdir(exist_ok=False);names=['windows-current1299-optional-capture-release-candidate-r01-46fc6c398e3d42a4a0a55646d495b070','windows-current1299-unsorted-membership-release-candidate-r01-4a758a1bb6f24fbfb0b1a5dff56d0421','p02-03-r05-windows-export-native-r03'];items=[]
def sha(p):
with p.open('rb')as f:return hashlib.file_digest(f,'sha256').hexdigest()
for name in names:
p=a/name;z=p/'TheTree-Windows-current-source-release-candidate.zip';integrity=json.loads((p/'package-integrity.json').read_text());process=json.loads((p/'export-process.json').read_text());assert process['passed']and process['native_process']['owned_popen_ended']and process['native_process']['exit_code']==0;assert sha(z)==integrity['zip_sha256'];st=z.stat();files=[];directories=[]
with zipfile.ZipFile(z)as archive:
for info in archive.infolist():
assert not info.is_dir();path=Path(info.filename);assert not path.is_absolute()and '..'not in path.parts;source=p/'distribution'/path;assert source.is_file()and not source.is_symlink();digest=hashlib.sha256()
with archive.open(info)as f:
for chunk in iter(lambda:f.read(1024**2),b''):digest.update(chunk)
h=digest.hexdigest();s=source.stat();assert h==sha(source)==integrity['members'][info.filename]and s.st_size==info.file_size;files.append({'relative_path':info.filename,'sha256':h,'bytes':s.st_size,'mode':s.st_mode&0o777,'mtime_ns':s.st_mtime_ns})
assert set(x['relative_path']for x in files)=={str(x.relative_to(p/'distribution'))for x in (p/'distribution').rglob('*')if x.is_file()}
for source in [p/'distribution']+sorted(x for x in (p/'distribution').rglob('*')if x.is_dir()):
s=source.stat();directories.append({'path':'.'if source==p/'distribution'else str(source.relative_to(p/'distribution')),'mode':s.st_mode&0o777,'mtime_ns':s.st_mtime_ns})
items.append({'name':name,'source':str(p),'zip':{'path':str(z),'sha256':integrity['zip_sha256'],'bytes':st.st_size,'mode':st.st_mode&0o777,'mtime_ns':st.st_mtime_ns},'files':files,'directories':directories,'export_actual_pid':process['actual_pid'],'export_ended':True,'cloud':None})
result={'scope':'Only three historical 2026-10-10-era Windows ZIPs and their byte-identical extracted distribution copies. Keep export proof/source/receipts locally. These are not same-current-final-Windows acceptance.','items':items,'full_zip_and_all_extracted_members_verified':True,'new_original_acceptance_credit':0,'local_retirement_pending_cloud_readback':True};(e/'MANIFEST.pending.json').write_text(json.dumps(result,ensure_ascii=False,indent=2)+'\n');print({'archives':len(items),'zip_upload_bytes':sum(x['zip']['bytes']for x in items),'extracted_bytes':sum(f['bytes']for x in items for f in x['files'])})