Asset Pipeline: Store Asset Catalog in String #230

Merged
Nick Alberelli merged 6 commits from TinyNick/blender-studio-pipeline:fix/asset-catalog into main 2024-02-15 22:54:08 +01:00
5 changed files with 85 additions and 21 deletions
Showing only changes of commit 577d07d5df - Show all commits

View File

@ -2,6 +2,7 @@ import os
from pathlib import Path from pathlib import Path
import bpy import bpy
from typing import List from typing import List
from .config import verify_task_layer_json_data
asset_file_cache = None asset_file_cache = None
cat_data_cache = None cat_data_cache = None
@ -88,3 +89,18 @@ def get_asset_id(name: str) -> str:
for key, value in asset_cat_dict.items(): for key, value in asset_cat_dict.items():
if value == name: if value == name:
return key return key
def get_asset_name(id: str) -> str:
"""Get Asset Catalog UUID based on Asset Catalog Name
Args:
name (str): Asset Catalog Name
Returns:
str: Asset Catalog UUID or None if not found
"""
global asset_cat_dict
for key, value in asset_cat_dict.items():
if key == id:
return value

View File

@ -3,38 +3,53 @@ from pathlib import Path
import json import json
from . import constants from . import constants
# TODO could refactor this into a class, but only one instance of that class will be needed
TASK_LAYER_TYPES = {} TASK_LAYER_TYPES = {}
TRANSFER_DATA_DEFAULTS = {} TRANSFER_DATA_DEFAULTS = {}
ATTRIBUTE_DEFAULTS = {} ATTRIBUTE_DEFAULTS = {}
ASSET_CATALOG_ID = ""
def get_json_file(): def get_task_layer_json_filepath() -> Path:
directory = Path(bpy.data.filepath).parent directory = Path(bpy.data.filepath).parent
json_file_path = directory.joinpath(constants.TASK_LAYER_CONFIG_NAME) json_file_path = directory.joinpath(constants.TASK_LAYER_CONFIG_NAME)
if json_file_path.exists():
return json_file_path return json_file_path
def get_task_layer_dict(file_path_str="") -> dict:
if file_path_str == "":
json_file_path = get_task_layer_json_filepath()
else:
json_file_path = Path(file_path_str)
if not json_file_path.exists():
return return
return json.load(open(json_file_path))
def get_task_layer_presets_path(): def get_task_layer_presets_path():
return Path(__file__).parent.joinpath(constants.TASK_LAYER_CONFIG_DIR_NAME) return Path(__file__).parent.joinpath(constants.TASK_LAYER_CONFIG_DIR_NAME)
def verify_json_data(json_file_path=""): def verify_task_layer_json_data(json_file_path=""):
global TASK_LAYER_TYPES global TASK_LAYER_TYPES
global TRANSFER_DATA_DEFAULTS global TRANSFER_DATA_DEFAULTS
global ATTRIBUTE_DEFAULTS global ATTRIBUTE_DEFAULTS
directory = Path(bpy.data.filepath).parent global ASSET_CATALOG_ID
if json_file_path == "":
json_file_path = directory.joinpath(constants.TASK_LAYER_CONFIG_NAME) json_content = get_task_layer_dict(json_file_path)
if not json_file_path.exists():
if not json_content:
return return
json_file = open(json_file_path)
json_content = json.load(json_file)
try: try:
TASK_LAYER_TYPES = json_content["TASK_LAYER_TYPES"] TASK_LAYER_TYPES = json_content["TASK_LAYER_TYPES"]
TRANSFER_DATA_DEFAULTS = json_content["TRANSFER_DATA_DEFAULTS"] TRANSFER_DATA_DEFAULTS = json_content["TRANSFER_DATA_DEFAULTS"]
ATTRIBUTE_DEFAULTS = json_content["ATTRIBUTE_DEFAULTS"] ATTRIBUTE_DEFAULTS = json_content["ATTRIBUTE_DEFAULTS"]
# Asset Catalog is an optional value in task_layers.json and doesn't exist by default
if "ASSET_CATALOG_ID" in json_content:
ASSET_CATALOG_ID = json_content["ASSET_CATALOG_ID"]
return True return True
except KeyError: except KeyError:
return return
@ -47,3 +62,10 @@ def write_json_file(asset_path: Path, source_file_path: Path):
json_dump = json.dumps(json_content, indent=4) json_dump = json.dumps(json_content, indent=4)
with open(json_file_path, "w") as config_output: with open(json_file_path, "w") as config_output:
config_output.write(json_dump) config_output.write(json_dump)
def update_task_layer_json_data(task_layer_dict: dict):
filepath = get_task_layer_json_filepath()
with filepath.open("w") as json_file:
json.dump(task_layer_dict, json_file, indent=4)
verify_task_layer_json_data()

View File

@ -26,6 +26,7 @@ from .sync import (
) )
from .asset_catalog import get_asset_catalog_items, get_asset_id from .asset_catalog import get_asset_catalog_items, get_asset_id
from .config import verify_task_layer_json_data
class ASSETPIPE_OT_create_new_asset(bpy.types.Operator): class ASSETPIPE_OT_create_new_asset(bpy.types.Operator):
@ -65,7 +66,7 @@ class ASSETPIPE_OT_create_new_asset(bpy.types.Operator):
# Dynamically Create Task Layer Bools # Dynamically Create Task Layer Bools
self._asset_pipe = context.scene.asset_pipeline self._asset_pipe = context.scene.asset_pipeline
config.verify_json_data(Path(self._asset_pipe.task_layer_config_type)) config.verify_task_layer_json_data(self._asset_pipe.task_layer_config_type)
all_task_layers = self._asset_pipe.all_task_layers all_task_layers = self._asset_pipe.all_task_layers
all_task_layers.clear() all_task_layers.clear()
@ -961,6 +962,7 @@ class ASSETPIPE_OT_refresh_asset_cat(bpy.types.Operator):
def execute(self, context: bpy.types.Context): def execute(self, context: bpy.types.Context):
get_asset_catalog_items(reload=True) get_asset_catalog_items(reload=True)
verify_task_layer_json_data()
self.report({'INFO'}, "Asset Catalogs Refreshed!") self.report({'INFO'}, "Asset Catalogs Refreshed!")
return {'FINISHED'} return {'FINISHED'}

View File

@ -2,10 +2,11 @@ import bpy
import os import os
from typing import List from typing import List
from . import constants from . import constants
from .config import get_task_layer_presets_path from . import config
from pathlib import Path from pathlib import Path
from .prefs import get_addon_prefs from .prefs import get_addon_prefs
from .asset_catalog import get_asset_catalog_items from .asset_catalog import get_asset_catalog_items, get_asset_name, get_asset_id
import json
""" NOTE Items in these properties groups should be generated by a function that finds the """ NOTE Items in these properties groups should be generated by a function that finds the
avaliable task layers from the task_layer.json file that needs to be created. avaliable task layers from the task_layer.json file that needs to be created.
@ -16,7 +17,7 @@ def get_task_layer_presets(self, context):
prefs = get_addon_prefs() prefs = get_addon_prefs()
user_tls = Path(prefs.custom_task_layers_dir) user_tls = Path(prefs.custom_task_layers_dir)
presets_dir = get_task_layer_presets_path() presets_dir = config.get_task_layer_presets_path()
items = [] items = []
for file in presets_dir.glob('*.json'): for file in presets_dir.glob('*.json'):
@ -126,7 +127,7 @@ class AssetPipeline(bpy.types.PropertyGroup):
task_layer_config_type: bpy.props.EnumProperty( task_layer_config_type: bpy.props.EnumProperty(
name="Task Layer Preset", name="Task Layer Preset",
items=get_task_layer_presets, items=get_task_layer_presets,
) ) # type: ignore
temp_file: bpy.props.StringProperty(name="Pre-Sync Backup") temp_file: bpy.props.StringProperty(name="Pre-Sync Backup")
source_file: bpy.props.StringProperty(name="File that started Sync") source_file: bpy.props.StringProperty(name="File that started Sync")
@ -157,17 +158,32 @@ class AssetPipeline(bpy.types.PropertyGroup):
attribute_ui_bool: bpy.props.BoolProperty(name="Show/Hide Attributes", default=False) attribute_ui_bool: bpy.props.BoolProperty(name="Show/Hide Attributes", default=False)
file_parent_ui_bool: bpy.props.BoolProperty(name="Show/Hide Parent", default=False) file_parent_ui_bool: bpy.props.BoolProperty(name="Show/Hide Parent", default=False)
def get_asset_catalogs(self, context, edit_text: str): def set_asset_catalog_name(self, input):
task_layer_dict = config.get_task_layer_dict()
task_layer_dict["ASSET_CATALOG_ID"] = get_asset_id(input)
config.update_task_layer_json_data(task_layer_dict)
self['asset_catalog_name'] = input
def get_asset_catalog_name(self):
if config.ASSET_CATALOG_ID != "":
asset_name = get_asset_name(config.ASSET_CATALOG_ID)
if asset_name is None:
return ""
return asset_name
return self['asset_catalog_name']
def get_asset_catalogs_search(self, context, edit_text: str):
return get_asset_catalog_items() return get_asset_catalog_items()
asset_catalog_name: bpy.props.StringProperty( asset_catalog_name: bpy.props.StringProperty(
name="Catalog", name="Catalog",
search=get_asset_catalogs, get=get_asset_catalog_name,
set=set_asset_catalog_name,
search=get_asset_catalogs_search,
search_options={'SORT'}, search_options={'SORT'},
description="Select Asset Library Catalog for the current Asset, this value will be updated each time you Push to an 'Active' Publish", description="Select Asset Library Catalog for the current Asset, this value will be updated each time you Push to an 'Active' Publish",
) # type: ignore ) # type: ignore
@bpy.app.handlers.persistent @bpy.app.handlers.persistent
def set_asset_collection_name_post_file_load(_): def set_asset_collection_name_post_file_load(_):
# Version the PointerProperty to the StringProperty, and the left-over pointer. # Version the PointerProperty to the StringProperty, and the left-over pointer.
@ -180,6 +196,12 @@ def set_asset_collection_name_post_file_load(_):
del scene.asset_pipeline['asset_collection'] del scene.asset_pipeline['asset_collection']
@bpy.app.handlers.persistent
def refresh_asset_catalog(_):
get_asset_catalog_items()
config.verify_task_layer_json_data()
classes = ( classes = (
AssetTransferData, AssetTransferData,
AssetTransferDataTemp, AssetTransferDataTemp,
@ -198,6 +220,7 @@ def register():
name="Surrender Ownership", default=False name="Surrender Ownership", default=False
) )
bpy.app.handlers.load_post.append(set_asset_collection_name_post_file_load) bpy.app.handlers.load_post.append(set_asset_collection_name_post_file_load)
bpy.app.handlers.load_post.append(refresh_asset_catalog)
def unregister(): def unregister():
@ -207,3 +230,4 @@ def unregister():
del bpy.types.Scene.asset_pipeline del bpy.types.Scene.asset_pipeline
del bpy.types.ID.asset_id_owner del bpy.types.ID.asset_id_owner
bpy.app.handlers.load_post.remove(set_asset_collection_name_post_file_load) bpy.app.handlers.load_post.remove(set_asset_collection_name_post_file_load)
bpy.app.handlers.load_post.remove(refresh_asset_catalog)

View File

@ -3,7 +3,7 @@ import bpy
from pathlib import Path from pathlib import Path
from .merge.transfer_data.transfer_ui import draw_transfer_data from .merge.transfer_data.transfer_ui import draw_transfer_data
from .merge.task_layer import draw_task_layer_selection from .merge.task_layer import draw_task_layer_selection
from .config import verify_json_data from .config import verify_task_layer_json_data
from .prefs import get_addon_prefs from .prefs import get_addon_prefs
from . import constants from . import constants
from .merge.publish import is_staged_publish from .merge.publish import is_staged_publish
@ -45,7 +45,7 @@ class ASSETPIPE_PT_sync(bpy.types.Panel):
return return
# TODO Move this call out of the UI because we keep re-loading this file every draw # TODO Move this call out of the UI because we keep re-loading this file every draw
if not verify_json_data(): if not verify_task_layer_json_data():
layout.label(text="Task Layer Config is invalid", icon="ERROR") layout.label(text="Task Layer Config is invalid", icon="ERROR")
return return