Files
workinf_Blender_Wasm/tools/web/generate-blender-editor-inventory.py
mes123456 10640aeb3c
Some checks failed
M6 deployable RC / quick (push) Has been cancelled
M6 deployable RC / chromium (push) Has been cancelled
M6 deployable RC / release (push) Has been cancelled
Govern task context and advance execution pointer
2026-08-20 06:02:43 -04:00

130 lines
5.3 KiB
Python

#!/usr/bin/env python3
"""Generate deterministic Blender 5.2 editor, space, workspace, and keymap inventory."""
import hashlib
import json
import pathlib
import sys
import bpy
def text(value):
return value.decode("utf-8", errors="replace") if isinstance(value, bytes) else str(value)
def sha256_file(path):
digest = hashlib.sha256()
with open(path, "rb") as handle:
for chunk in iter(lambda: handle.read(1024 * 1024), b""):
digest.update(chunk)
return digest.hexdigest()
def enum_info(rna_type, property_name):
entries = []
for item in rna_type.bl_rna.properties[property_name].enum_items:
entries.append({"identifier": item.identifier, "name": text(item.name), "description": text(item.description), "value": item.value})
entries.sort(key=lambda entry: entry["identifier"])
return entries
def property_info(prop):
result = {"identifier": prop.identifier, "type": prop.type, "readOnly": bool(prop.is_readonly)}
if hasattr(prop, "array_length"):
result["arrayLength"] = prop.array_length
return result
def space_types():
entries = []
for class_name in sorted(name for name in dir(bpy.types) if name.startswith("Space")):
cls = getattr(bpy.types, class_name)
try:
if not isinstance(cls, type) or cls is bpy.types.Space or not issubclass(cls, bpy.types.Space):
continue
rna = getattr(cls, "bl_rna", None)
if not rna:
continue
props = [property_info(prop) for prop in rna.properties if prop.identifier != "rna_type"]
props.sort(key=lambda prop: prop["identifier"])
entries.append({"className": class_name, "rnaIdentifier": text(rna.identifier), "properties": props})
except (AttributeError, RuntimeError, TypeError):
continue
return entries
def keymaps():
bpy.utils.keyconfig_init()
keyconfig = bpy.context.window_manager.keyconfigs.default
maps = []
for keymap in sorted(keyconfig.keymaps, key=lambda value: f"{value.name}:{value.space_type}:{value.region_type}"):
items = []
for item in keymap.keymap_items:
items.append({
"idname": text(item.idname),
"type": text(item.type),
"value": text(item.value),
"ctrl": bool(item.ctrl),
"shift": bool(item.shift),
"alt": bool(item.alt),
"oskey": bool(item.oskey),
"any": bool(item.any),
"repeat": bool(item.repeat),
"keyModifier": text(item.key_modifier),
"direction": text(item.direction),
"mapType": text(item.map_type),
"active": bool(item.active),
})
items.sort(key=lambda item: tuple(item.values()))
maps.append({"name": text(keymap.name), "spaceType": text(keymap.space_type), "regionType": text(keymap.region_type), "modal": bool(keymap.is_modal), "items": items})
return maps
def main():
if "--" not in sys.argv or len(sys.argv[sys.argv.index("--") + 1:]) != 1:
raise SystemExit("usage: blender --background --factory-startup --python generate-blender-editor-inventory.py -- OUTPUT.json")
output = pathlib.Path(sys.argv[sys.argv.index("--") + 1]).resolve()
version = tuple(int(value) for value in bpy.app.version)
if version != (5, 2, 0):
raise RuntimeError(f"expected Blender 5.2.0, got {version}")
areas = enum_info(bpy.types.Area, "type")
regions = enum_info(bpy.types.Region, "type")
spaces = enum_info(bpy.types.Space, "type")
workspace_modes = enum_info(bpy.types.WorkSpace, "object_mode")
space_classes = space_types()
maps = keymaps()
binary_path = pathlib.Path(bpy.app.binary_path).resolve()
inventory = {
"schemaVersion": 1,
"task": "M15-01E",
"operation": "BLENDER_EDITOR_INVENTORY",
"sourceAnchor": "blender-5.2.0/source/blender/editors",
"runtime": {
"blenderVersion": text(bpy.app.version_string),
"versionTuple": list(version),
"buildHash": text(bpy.app.build_hash),
"buildBranch": text(bpy.app.build_branch),
"buildPlatform": text(bpy.app.build_platform),
"buildType": text(bpy.app.build_type),
"buildDate": text(bpy.app.build_date),
"buildTime": text(bpy.app.build_time),
"binarySha256": sha256_file(binary_path),
},
"summary": {"areaTypeCount": len(areas), "regionTypeCount": len(regions), "spaceTypeCount": len(spaces), "spaceClassCount": len(space_classes), "workspaceModeCount": len(workspace_modes), "keymapCount": len(maps), "keymapItemCount": sum(len(keymap["items"]) for keymap in maps)},
"areaTypes": areas,
"regionTypes": regions,
"spaceTypes": spaces,
"spaceClasses": space_classes,
"workspaceModes": workspace_modes,
"keymaps": maps,
"nextTask": "M15-01F",
}
output.parent.mkdir(parents=True, exist_ok=True)
output.write_text(json.dumps(inventory, indent=2, sort_keys=True) + "\n", encoding="utf-8")
print(f"blender-editor-inventory-generated areas={len(areas)} regions={len(regions)} spaces={len(spaces)} keymaps={len(maps)} items={inventory['summary']['keymapItemCount']} output={output}")
if __name__ == "__main__":
main()