"""保存真人资产的非破坏性修订,保留首版图片、提示词及回执。""" import argparse import json from pathlib import Path import re import shutil import struct ROOT = Path(__file__).resolve().parent.parent LIVE = ROOT / '08_真人AI短剧' p = argparse.ArgumentParser() p.add_argument('--id', required=True) p.add_argument('--source', required=True) p.add_argument('--prompt-file', required=True) p.add_argument('--reference', action='append', default=[]) args = p.parse_args() registry = LIVE / '02_资产/全部资产任务.json' assets = json.loads(registry.read_text(encoding='utf8')) asset = next(a for a in assets if a['id'] == args.id) receipt_file = LIVE / '02_资产/生成回执' / (args.id + '.json') old = json.loads(receipt_file.read_text(encoding='utf8')) version = int(old.get('revision', 1)) + 1 old_path = LIVE / old['path'] new_path = old_path.with_name(re.sub(r'-V\d+-REVIEW\.png$', f'-V{version:02d}-REVIEW.png', old_path.name)) assert new_path != old_path and LIVE.resolve() in new_path.resolve().parents assert not new_path.exists(), '修订图已存在,拒绝覆盖' prompt = Path(args.prompt_file).read_text(encoding='utf8').rstrip('\n') raw = Path(args.source).read_bytes() assert raw[:8] == b'\x89PNG\r\n\x1a\n' size = list(struct.unpack('>II', raw[16:24])) history = receipt_file.parent / '历史' history.mkdir(exist_ok=True) archive = history / f'{args.id}-R{version-1:02d}.json' assert not archive.exists(), '历史回执已存在,拒绝覆盖' archive.write_text(json.dumps(old, ensure_ascii=False, indent=2)+'\n', encoding='utf8') prompt_dir = LIVE / '04_生成与后期/逐项出图提示词' original_prompt = prompt_dir / f'{args.id}-R{version-1:02d}.txt' if not original_prompt.exists(): original_prompt.write_text(old['prompt']+'\n', encoding='utf8') shutil.copy2(args.source, new_path) receipt = {**old, 'path': new_path.relative_to(LIVE).as_posix(), 'source': args.source, 'size': size, 'prompt': prompt, 'revision': version, 'references': args.reference, 'previous_receipt': archive.relative_to(LIVE).as_posix(), 'status': 'REVIEW', 'approved': False} receipt_file.write_text(json.dumps(receipt, ensure_ascii=False, indent=2)+'\n', encoding='utf8') (prompt_dir / (args.id+'.txt')).write_text(prompt+'\n', encoding='utf8') asset.update(path=receipt['path'], prompt=prompt, status='REVIEW') registry.write_text(json.dumps(assets, ensure_ascii=False, indent=2)+'\n', encoding='utf8') print(json.dumps({'id':args.id, 'revision':version, 'path':str(new_path)}, ensure_ascii=False))