Accumulated uncommitted work: GHOST Web backend, WebGL/GPU web layer, web workflow engine and protocol, tooling, docs and task records. Large generated evidence, user-testing archives, build snapshots and imported test assets remain untracked. Co-Authored-By: Claude Code <noreply@anthropic.com>
53 lines
3.8 KiB
Python
53 lines
3.8 KiB
Python
"""Source-derived WM recovery case; operate only on a separate working copy."""
|
|
import hashlib, json, pathlib, sys
|
|
import bpy
|
|
|
|
def run(input_path, work_dir):
|
|
input_path = str(pathlib.Path(input_path).resolve()); assert bpy.app.version == (5, 2, 0)
|
|
work = pathlib.Path(work_dir).resolve()
|
|
work.mkdir(parents=True, exist_ok=False)
|
|
source_sha256 = hashlib.sha256(pathlib.Path(input_path).read_bytes()).hexdigest()
|
|
assert bpy.ops.wm.open_mainfile(filepath=str(pathlib.Path(input_path).resolve()), load_ui=False, use_scripts=False) == {'FINISHED'}
|
|
marker = work / 'registered-script.json'
|
|
key = 'wbv2_native_recovery_script_executed'
|
|
assert key not in bpy.context.scene
|
|
text = bpy.data.texts.new('wbv2_native_recovery_trust.py')
|
|
text.write("import bpy,json\nfrom pathlib import Path\nbpy.context.scene[%r] = True\nPath(%r).write_text(json.dumps({'executed':True,'filepath':bpy.data.filepath}))\n" % (key, str(marker)))
|
|
text.use_module = True
|
|
original_images = {image.name: {'pixels': list(image.pixels[:4]), 'size': list(image.size)} for image in bpy.data.images if image.source == 'FILE'}
|
|
assert original_images and all(image['pixels'] and min(image['size']) > 0 for image in original_images.values())
|
|
autosave_dir = work / 'autosave'; autosave_dir.mkdir()
|
|
previous = (bpy.context.preferences.filepaths.temporary_directory, bpy.context.preferences.filepaths.auto_save_time)
|
|
try:
|
|
bpy.context.preferences.filepaths.temporary_directory = str(autosave_dir)
|
|
bpy.context.preferences.filepaths.auto_save_time = 60
|
|
assert bpy.ops.wm.save_as_mainfile(filepath=str(work / 'native-script-trust.blend'), relative_remap=True, check_existing=False) == {'FINISHED'}
|
|
assert bpy.ops.wm.save_auto_save() == {'FINISHED'}
|
|
assert not marker.exists() and key not in bpy.context.scene
|
|
autosaves = sorted(autosave_dir.glob('native-script-trust_*_autosave.blend'))
|
|
assert len(autosaves) == 1, [str(item) for item in autosaves]
|
|
autosave_sha256 = hashlib.sha256(autosaves[0].read_bytes()).hexdigest()
|
|
results = []
|
|
for allow in (False, True, False):
|
|
marker.unlink(missing_ok=True)
|
|
assert bpy.ops.wm.recover_auto_save(filepath=str(autosaves[0]), use_scripts=allow) == {'FINISHED'}
|
|
executed = marker.exists()
|
|
assert executed == allow and bool(bpy.context.scene.get(key, False)) == allow
|
|
assert pathlib.Path(bpy.data.filepath).resolve() == work / 'native-script-trust.blend'
|
|
images = {image.name: {'pixels': list(image.pixels[:4]), 'size': list(image.size)} for image in bpy.data.images if image.source == 'FILE'}
|
|
assert images == original_images
|
|
assert hashlib.sha256(autosaves[0].read_bytes()).hexdigest() == autosave_sha256
|
|
results.append({'useScripts': allow, 'executed': executed, 'sceneMarker': bool(bpy.context.scene.get(key, False)), 'scriptMarker': json.loads(marker.read_text()) if executed else None})
|
|
assert hashlib.sha256(pathlib.Path(input_path).read_bytes()).hexdigest() == source_sha256
|
|
return {'kind': 'source-derived-native-operator-case', 'platform': sys.platform, 'version': list(bpy.app.version), 'inputSha256': source_sha256, 'autosavePath': str(autosaves[0]), 'autosaveSha256': autosave_sha256, 'workingBlend': bpy.data.filepath, 'results': results, 'images': original_images}
|
|
finally:
|
|
bpy.context.preferences.filepaths.temporary_directory, bpy.context.preferences.filepaths.auto_save_time = previous
|
|
|
|
if __name__ == '__main__':
|
|
import argparse
|
|
parser = argparse.ArgumentParser()
|
|
parser.add_argument('--input', required=True)
|
|
parser.add_argument('--work-dir', required=True)
|
|
args = parser.parse_args(sys.argv[sys.argv.index('--') + 1:])
|
|
print('WBV2_NATIVE_AUTOSAVE_SCRIPT_TRUST', json.dumps(run(args.input, args.work_dir), sort_keys=True))
|