From 77f9ec3cac92f2a1f0fe0a8160ce79a7e652c358 Mon Sep 17 00:00:00 2001 From: nan Date: Thu, 9 Jul 2026 11:53:09 +0800 Subject: [PATCH] feat: Enhance asset library management with status checks and error handling --- src/bioxelnodes/__init__.py | 2 + src/bioxelnodes/asset_library.py | 67 ++++++++++++++++++++++++++++-- src/bioxelnodes/operators/layer.py | 6 +++ src/bioxelnodes/operators/misc.py | 20 +++++++-- src/bioxelnodes/panels.py | 19 ++++++++- 5 files changed, 106 insertions(+), 8 deletions(-) diff --git a/src/bioxelnodes/__init__.py b/src/bioxelnodes/__init__.py index 01735ff..fe7a9b8 100644 --- a/src/bioxelnodes/__init__.py +++ b/src/bioxelnodes/__init__.py @@ -2,6 +2,7 @@ import bpy import bpy.utils.previews as previews from .constants import PREVIEW_COLLECTIONS +from .asset_library import remove_bioxel_asset_library_if_exists from .props import _bioxel_layer_items, _update_layer_gallery, _update_snapshot_z from . import auto_load @@ -47,6 +48,7 @@ def register(): def unregister(): + remove_bioxel_asset_library_if_exists() unregister_cli_commands() menus.remove() auto_load.unregister() diff --git a/src/bioxelnodes/asset_library.py b/src/bioxelnodes/asset_library.py index b5ba70f..2efdbce 100644 --- a/src/bioxelnodes/asset_library.py +++ b/src/bioxelnodes/asset_library.py @@ -1,10 +1,20 @@ import bpy from pathlib import Path -from .constants import NODE_LIB_DIRPATH +from .constants import LATEST_NODE_LIB_PATH, NODE_LIB_DIRPATH, NODE_LIB_FILENAME ASSET_LIBRARY_NAME = "O Bioxel" +ASSET_LIBRARY_READY = "READY" +ASSET_LIBRARY_OUTDATED = "OUTDATED" +ASSET_LIBRARY_MISSING = "MISSING" + +STATUS_MESSAGES = { + "missing": "O Bioxel asset library is not installed.", + "missing_blend": "O Bioxel node library file is missing.", + "outdated": "O Bioxel node library needs update.", + "ready": "O Bioxel asset library is ready.", +} def _asset_library_path(): @@ -19,6 +29,26 @@ def _asset_libraries(): return bpy.context.preferences.filepaths.asset_libraries +def _find_bioxel_asset_library(): + lib_path = _normalized_path(_asset_library_path()) + named_lib = None + + for lib in _asset_libraries(): + try: + if _normalized_path(lib.path) == lib_path: + return lib + if lib.name == ASSET_LIBRARY_NAME: + named_lib = lib + except Exception: + continue + + return named_lib + + +def _node_lib_path_for_library(lib): + return _normalized_path(lib.path) / NODE_LIB_FILENAME + + def get_bioxel_asset_library(): lib_path = _normalized_path(_asset_library_path()) @@ -32,16 +62,47 @@ def get_bioxel_asset_library(): return None +def get_bioxel_asset_library_status(): + lib = _find_bioxel_asset_library() + lib_path = _normalized_path(_asset_library_path()) + + if lib is None: + return {"code": ASSET_LIBRARY_MISSING, "reason": "missing", + "message": STATUS_MESSAGES["missing"]} + + try: + installed_lib_path = _normalized_path(lib.path) + except Exception: + return {"code": ASSET_LIBRARY_MISSING, "reason": "missing", + "message": STATUS_MESSAGES["missing"]} + + if not _node_lib_path_for_library(lib).is_file(): + return {"code": ASSET_LIBRARY_MISSING, "reason": "missing_blend", + "message": STATUS_MESSAGES["missing_blend"]} + + if installed_lib_path != lib_path: + return {"code": ASSET_LIBRARY_OUTDATED, "reason": "outdated", + "message": STATUS_MESSAGES["outdated"]} + + return {"code": ASSET_LIBRARY_READY, "reason": "ready", + "message": STATUS_MESSAGES["ready"]} + + def has_bioxel_asset_library(): - return get_bioxel_asset_library() is not None + return get_bioxel_asset_library_status()["code"] in { + ASSET_LIBRARY_READY, + ASSET_LIBRARY_OUTDATED, + } def add_bioxel_asset_library(): if not NODE_LIB_DIRPATH.exists(): raise FileNotFoundError(f"Node library path does not exist: {NODE_LIB_DIRPATH}") + if not LATEST_NODE_LIB_PATH.is_file(): + raise FileNotFoundError(f"Node library file does not exist: {LATEST_NODE_LIB_PATH}") prefs = _asset_libraries() - lib = get_bioxel_asset_library() + lib = _find_bioxel_asset_library() if lib is None: for item in prefs: diff --git a/src/bioxelnodes/operators/layer.py b/src/bioxelnodes/operators/layer.py index cc95bdc..6593cfa 100644 --- a/src/bioxelnodes/operators/layer.py +++ b/src/bioxelnodes/operators/layer.py @@ -3,6 +3,7 @@ import shutil import bpy +from ..asset_library import ASSET_LIBRARY_MISSING, get_bioxel_asset_library_status from ..node import add_bioxel_node, get_layer_nodes, get_main_node_group from ..utils import refresh_bioxel_panels from ..layer import get_layer_caches, set_layer_caches @@ -91,6 +92,11 @@ class AddLayerNode(bpy.types.Operator): cache_id: bpy.props.StringProperty() # type: ignore # 图层ID def execute(self, context): + status = get_bioxel_asset_library_status() + if status["code"] == ASSET_LIBRARY_MISSING: + self.report({"ERROR"}, status["message"]) + return {"CANCELLED"} + # 获取图层数据 caches = get_layer_caches() diff --git a/src/bioxelnodes/operators/misc.py b/src/bioxelnodes/operators/misc.py index a61541e..132b896 100644 --- a/src/bioxelnodes/operators/misc.py +++ b/src/bioxelnodes/operators/misc.py @@ -5,7 +5,12 @@ import bpy from pathlib import Path import shutil -from ..asset_library import add_bioxel_asset_library +from ..asset_library import ( + ASSET_LIBRARY_OUTDATED, + ASSET_LIBRARY_READY, + add_bioxel_asset_library, + get_bioxel_asset_library_status, +) from ..constants import LATEST_NODE_LIB_PATH from ..utils import ( get_all_layer_objs, @@ -138,8 +143,17 @@ class AddAssetLibrary(bpy.types.Operator): if area.type == "NODE_EDITOR": area.tag_redraw() - self.report({"INFO"}, "O Bioxel asset library is ready.") - return {"FINISHED"} + status = get_bioxel_asset_library_status() + if status["code"] == ASSET_LIBRARY_READY: + self.report({"INFO"}, status["message"]) + return {"FINISHED"} + + if status["code"] == ASSET_LIBRARY_OUTDATED: + self.report({"WARNING"}, status["message"]) + return {"FINISHED"} + + self.report({"ERROR"}, status["message"]) + return {"CANCELLED"} # 定义虚无化切换操作 diff --git a/src/bioxelnodes/panels.py b/src/bioxelnodes/panels.py index dd8308b..40591e2 100644 --- a/src/bioxelnodes/panels.py +++ b/src/bioxelnodes/panels.py @@ -1,7 +1,12 @@ from pathlib import Path import bpy -from .asset_library import has_bioxel_asset_library +from .asset_library import ( + ASSET_LIBRARY_OUTDATED, + ASSET_LIBRARY_READY, + get_bioxel_asset_library_status, + has_bioxel_asset_library, +) from .node import get_layer_nodes, get_main_node_group from .utils import load_icon from .layer import get_layer_caches @@ -78,13 +83,23 @@ class HeaderPanel(bpy.types.Panel, BioxelPanelBase): def draw(self, context): layout = self.layout + status = get_bioxel_asset_library_status() - if not has_bioxel_asset_library(): + if status["code"] == ASSET_LIBRARY_OUTDATED: + layout.operator( + AddAssetLibrary.bl_idname, + text="Update Nodes Library", + icon="ASSET_MANAGER", + ) + layout.label(text=status["message"], icon="INFO") + + elif status["code"] != ASSET_LIBRARY_READY: layout.operator( AddAssetLibrary.bl_idname, text="Add Nodes Library", icon="ASSET_MANAGER", ) + layout.label(text=status["message"], icon="INFO") return layout.operator(