start renaming adapter -> library_type

master
“christopheseux” 2023-01-03 13:53:01 +01:00
parent e538c997a9
commit 060aa80c9b
4 changed files with 147 additions and 540 deletions

View File

@ -920,7 +920,7 @@ class ACTIONLIB_OT_store_anim_pose(Operator):
)
## Define Tags
tags = [t.strip() for t in self.tags.split(',')]
tags = [t.strip() for t in self.tags.split(',') if t]
tag_range = f'f{self.frame_start}'
is_single_frame = True
if self.action_type == 'ANIM':
@ -1025,10 +1025,10 @@ class ACTIONLIB_OT_store_anim_pose(Operator):
self.action_to_asset(asset_action)
#lib.adapter.new_asset()
#Saving the preview
self.render_preview(img_path, video_path)
with context.temp_override(id=asset_action):
bpy.ops.ed.lib_id_load_custom_preview(
filepath=str(img_path)
@ -1036,15 +1036,17 @@ class ACTIONLIB_OT_store_anim_pose(Operator):
lib.adapter.write_asset(asset=asset_action, asset_path=asset_path)
# asset_description = lib.adapter.get_asset_description(dict(
# author=prefs.author,
# assets=[dict(
# name=asset_action.name,
# description=self.description,
# catalog=self.catalog,
# tags=self.tags.split(',')
# )]), asset_path
# )
asset_data = lib.adapter.get_asset_data(asset_action)
diff = [dict(asset_data,
image=str(img_path),
filepath=str(asset_path),
type='ACTION',
library_id=lib.id,
catalog=self.catalog,
operation='ADD'
)]
# lib.adapter.write_description_file(asset_description, asset_path)
# Restore action and cleanup
@ -1057,7 +1059,7 @@ class ACTIONLIB_OT_store_anim_pose(Operator):
# TODO Write a proper method for this
diff_path = Path(bpy.app.tempdir, 'diff.json')
diff = [dict(a, operation='ADD') for a in lib.adapter.norm_cache([asset_description])]
#diff = [dict(a, operation='ADD') for a in [asset_description])]
diff_path.write_text(json.dumps(diff, indent=4))
bpy.ops.assetlib.bundle(name=lib.name, diff=str(diff_path), blocking=True)

View File

@ -28,8 +28,6 @@ class AssetLibraryAdapter(PropertyGroup):
#def __init__(self):
name = "Base Adapter"
#library = None
#bundle_directory : StringProperty()
@property
def library(self):
@ -42,22 +40,6 @@ class AssetLibraryAdapter(PropertyGroup):
def bundle_directory(self):
return self.library.library_path
# @property
# def blend_depth(self):
# return self.library.blend_depth
# @property
# def template_image(self):
# return Template(self.library.template_image)
# @property
# def template_video(self):
# return Template(self.library.template_video)
# @property
# def template_description(self):
# return Template(self.library.template_description)
@property
def data_type(self):
return self.library.data_type
@ -73,12 +55,10 @@ class AssetLibraryAdapter(PropertyGroup):
@property
def cache_file(self):
return Path(self.bundle_directory) / f"blender_assets.{self.library.id}.json"
#return get_asset_datas_file(self.library_path)
@property
def tmp_cache_file(self):
return Path(bpy.app.tempdir) / f"blender_assets.{self.library.id}.json"
#return get_asset_datas_file(self.library_path)
@property
def diff_file(self):
@ -151,19 +131,22 @@ class AssetLibraryAdapter(PropertyGroup):
return load_datablocks(src, names=names, type=type, link=link, expr=expr, assets_only=assets_only)
def get_asset_data(self, asset):
"""Extract asset information on a datablock"""
return dict(
name=asset.name,
author=asset.asset_data.author,
tags=list(asset.asset_data.tags.keys()),
metadata=dict(asset.asset_data),
description=asset.asset_data.description,
)
def get_asset_relative_path(self, name, catalog):
'''Get a relative path for the asset'''
name = self.norm_file_name(name)
return Path(catalog, name, name).with_suffix('.blend')
#def _get_file_name(self, name, filepath):
# '''Ensure having a unique name per asset if in the same folder by prefixing with the blend_file name'''
# file_name = name
# if filepath.stem != name:
# file_name = f'{file_name}_{name}'
#
# return file_name
def get_active_asset_library(self):
asset_handle = bpy.context.asset_file_handle
prefs = get_addon_prefs()
@ -205,6 +188,12 @@ class AssetLibraryAdapter(PropertyGroup):
def get_video_path(self, name, catalog, filepath):
raise Exception('Need to be defined in the adapter')
def new_asset(self, asset, asset_data):
raise Exception('Need to be defined in the adapter')
def remove_asset(self, asset, asset_data):
raise Exception('Need to be defined in the adapter')
def format_asset_data(self, data):
"""Get a dict for use in template fields"""
@ -215,7 +204,6 @@ class AssetLibraryAdapter(PropertyGroup):
'catalog_name': data['catalog'].replace('/', '_'),
}
def format_path(self, template, data={}, **kargs):
if not template:
return None
@ -242,92 +230,6 @@ class AssetLibraryAdapter(PropertyGroup):
if paths:
return Path(paths[0])
# def get_template_path(self, template, name, asset_path, catalog, **kargs):
# if not template:
# return None
# if template.startswith('.'): #the template is relative
# template = Path(asset_path, template).as_posix()
# params = {
# 'asset_name': name,
# 'asset_path': Path(asset_path),
# 'catalog': catalog,
# 'catalog_name': catalog.replace('/', '_'),
# }
# params.update(kargs)
# return self.format_path(template, **params)
# def get_description_path(self, name, asset_path, catalog, **kargs) -> Path:
# """"Get the path of the json or yaml describing all assets data in one file"""
# return self.get_template_path(self.library.template_description, name, asset_path, catalog)
# def get_image_path(self, name, asset_path, catalog, **kargs) -> Path:
# return self.get_template_path(self.library.template_image, name, asset_path, catalog)
# def get_video_path(self, name, asset_path, catalog, **kargs) -> Path:
# return self.get_template_path(self.library.template_video, name, asset_path, catalog)
'''
def get_path(self, type, name, asset_path, template=None) -> Path:
if not template:
template = getattr(self, f'{type}_template')
if isinstance(template, str):
template = Template(template)
filepath = Path(asset_path)
params = {
'bundle_dir': self.library.bundle_directory,
'conform_dir': self.library.conform.directory,
'rel_path': '',
'catalog':'',
'catalog_name':'',
'name': name
}
return self.format_path(template, params)#(filepath / template.format(name=name, path=Path(asset_path))).resolve()
#def get_image_path(self, name, asset_path):
# filepath = Path(asset_path)
# image_name = self._get_file_name(name, asset_path)
# return (filepath / self.template_image.format(name=image_name)).resolve()
def get_cache_image_path(self, name, catalog) -> Path:
""""Get the the cache path of a image for asset without an externalized image"""
name = self.norm_file_name(name)
return Path(self.library_path, '.previews', f"{catalog.replace('/', '_')}_{name}").with_suffix(('.png'))
def get_cache_image(self, name, catalog):
cache_image_path = self.get_cache_image_path(name, catalog)
if cache_image_path.exists():
return cache_image_path
'''
#def get_video_path(self, name, asset_path):
# filepath = Path(asset_path)
# video_name = self._get_file_name(name, asset_path)
# return (filepath / self.template_video.format(name=video_name)).resolve()
'''
def get_image(self, name, asset_path):
image_path = self.get_path('image', name, asset_path)
if image_path.exists():
return image_path
def get_video(self, name, asset_path):
video_path = self.get_path('video', name, asset_path)
if video_path.exists():
return video_path
'''
def read_asset_description_file(self, asset_path) -> dict:
"""Read the description file of the asset"""
@ -339,6 +241,9 @@ class AssetLibraryAdapter(PropertyGroup):
return write_file(description_path, asset_data)
def write_asset(self, asset, asset_path):
Path(asset_path).parent.mkdir(exist_ok=True, parents=True)
bpy.data.libraries.write(
str(asset_path),
{asset},
@ -434,17 +339,9 @@ class AssetLibraryAdapter(PropertyGroup):
self.module_type.gui.draw_header(layout)
def draw_context_menu(self, layout):
"""Draw the context menu of the Asset Browser Window"""
#layout.separator()
"""Draw the context menu of the Asset Browser Window"""
self.module_type.gui.draw_context_menu(layout)
# def group_key(self, asset_data):
# """Key used to group assets inside one blend"""
# catalog_parts = asset_data['catalog'].split('/') + [asset_data['name']]
# return catalog_parts[:self.library.blend_depth]
def generate_blend_preview(self, asset_description):
asset_name = asset_description['name']
catalog = asset_description['catalog']
@ -492,46 +389,49 @@ class AssetLibraryAdapter(PropertyGroup):
asset_path = self.format_path(asset_description['filepath'])
# Check if a source video exists and if so copying it in the new directory
for asset_data in asset_description['assets']:
dst_asset_path = self.get_asset_bundle_path(asset_data)
dst_video_path = self.format_path(self.library.template_video, asset_data, filepath=dst_asset_path) #Template(src_video_path).find(asset_data, asset_path=dst_asset_path, **self.format_data)
if self.library.template_video:
for asset_data in asset_description['assets']:
dst_asset_path = self.get_asset_bundle_path(asset_data)
dst_video_path = self.format_path(self.library.template_video, asset_data, filepath=dst_asset_path) #Template(src_video_path).find(asset_data, asset_path=dst_asset_path, **self.format_data)
if dst_video_path.exists():
print(f'The dest video {dst_video_path} already exist')
continue
if dst_video_path.exists():
print(f'The dest video {dst_video_path} already exist')
continue
src_video_template = asset_data.get('video')
if not src_video_template:
continue
src_video_path = self.find_path(src_video_template, asset_data, filepath=asset_path)#Template(src_video_path).find(asset_data, asset_path=dst_asset_path, **self.format_data)
if src_video_path:
self.copy_file(src_video_path, dst_video_path)
print(f'Copy video from {src_video_path} to {dst_video_path}')
src_video_template = asset_data.get('video')
if not src_video_template:
continue
src_video_path = self.find_path(src_video_template, asset_data, filepath=asset_path)#Template(src_video_path).find(asset_data, asset_path=dst_asset_path, **self.format_data)
if src_video_path:
print(f'Copy video from {src_video_path} to {dst_video_path}')
self.copy_file(src_video_path, dst_video_path)
# Check if asset as a preview image or need it to be generated
asset_data_names = {}
for asset_data in asset_description['assets']:
name = asset_data['name']
dst_asset_path = self.get_asset_bundle_path(asset_data)
dst_image_path = self.format_path(self.library.template_image, asset_data, filepath=dst_asset_path)
if dst_image_path.exists():
print(f'The dest image {dst_image_path} already exist')
continue
# Check if a source image exists and if so copying it in the new directory
src_image_template = asset_data.get('image')
if src_image_template:
src_image_path = self.find_path(src_image_template, asset_data, filepath=asset_path)
if self.library.template_image:
for asset_data in asset_description['assets']:
name = asset_data['name']
dst_asset_path = self.get_asset_bundle_path(asset_data)
if src_image_path:
self.copy_file(src_image_path, dst_image_path)
#print(f'Copy image from {src_image_path} to {dst_image_path}')
return
dst_image_path = self.format_path(self.library.template_image, asset_data, filepath=dst_asset_path)
if dst_image_path.exists():
print(f'The dest image {dst_image_path} already exist')
continue
# Check if a source image exists and if so copying it in the new directory
src_image_template = asset_data.get('image')
if src_image_template:
src_image_path = self.find_path(src_image_template, asset_data, filepath=asset_path)
#Store in a dict all asset_data that does not have preview
asset_data_names[name] = dict(asset_data, image_path=dst_image_path)
if src_image_path:
self.copy_file(src_image_path, dst_image_path)
#print(f'Copy image from {src_image_path} to {dst_image_path}')
return
#Store in a dict all asset_data that does not have preview
asset_data_names[name] = dict(asset_data, image_path=dst_image_path)
if not asset_data_names:
@ -622,7 +522,7 @@ class AssetLibraryAdapter(PropertyGroup):
image_path = self.find_path(image_template, asset_data, filepath=asset_path)
if image_path:
print(f'Set asset preview for {image_path} for {asset}')
#print(f'Set asset preview for {image_path} for {asset}')
with bpy.context.temp_override(id=asset):
bpy.ops.ed.lib_id_load_custom_preview(
filepath=str(image_path)
@ -656,13 +556,12 @@ class AssetLibraryAdapter(PropertyGroup):
def set_asset_tags(self, asset, asset_data):
"""Create asset tags base on provided data"""
tags = asset_data.get('tags', [])
if tags:
#Clear all tags first
if 'tags' in asset_data:
for tag in asset.asset_data.tags[:]:
asset.asset_data.tags.remove(tag)
for tag in tags:
for tag in asset_data['tags']:
if not tag:
continue
asset.asset_data.tags.new(tag, skip_if_exists=True)
@ -670,9 +569,9 @@ class AssetLibraryAdapter(PropertyGroup):
def set_asset_info(self, asset, asset_data):
"""Set asset description base on provided data"""
#print(asset_data.get('description', ''))
asset.asset_data.author = asset_data.get('author') or ''
asset.asset_data.description = asset_data.get('description') or ''
for key in ('author', 'description'):
if key in asset_data:
setattr(asset.asset_data, key, asset_data.get(key) or '')
def get_asset_bundle_path(self, asset_data):
@ -870,15 +769,4 @@ class AssetLibraryAdapter(PropertyGroup):
annotations = self.__class__.__annotations__
for k, v in annotations.items():
layout.prop(self, k, text=bpy.path.display_name(k))
'''
def format_path(self, template, **kargs):
params = dict(
bundle_dir=Path(self.bundle_directory),
**kargs,
**self.to_dict(),
)
return Template(template).format(params).resolve()
'''

View File

@ -28,16 +28,7 @@ class ScanFolderLibrary(AssetLibraryAdapter):
template_image : StringProperty()
template_video : StringProperty()
template_description : StringProperty()
#blend_depth : IntProperty()
#externalize_preview : BoolProperty(default=True)
#def draw_header(self, layout):
# '''Draw the header of the Asset Browser Window'''
# layout.separator()
# layout.operator("actionlib.store_anim_pose", text='Add Action', icon='FILE_NEW')
#def update(self):
#
def get_asset_path(self, name, catalog, directory=None):
directory = directory or self.source_directory
catalog = self.norm_file_name(catalog)
@ -55,47 +46,22 @@ class ScanFolderLibrary(AssetLibraryAdapter):
name = self.norm_file_name(name)
return self.format_path(self.template_video, dict(name=name, catalog=catalog, filepath=filepath))
'''
def get_asset_description(self, asset, catalog, modified):
asset_path = self.get_asset_relative_path(name=asset.name, catalog=catalog)
asset_name = self.norm_file_name(asset.name)
asset_description = dict(
filepath='{source_directory}/' + asset_path.as_posix(),
modified=modified,
library_id=self.library.id,
assets=[]
)
asset_description['assets'].append(dict(
catalog=catalog,
metadata=dict(asset.asset_data),
tags=asset.asset_data.tags.keys(),
type=self.data_type,
image=str(self.template_image.format(name=asset_name)),
video=str(self.template_video.format(name=asset_name)),
name=asset.name)
)
return asset_description
'''
def get_asset_description(self, data, asset_path):
def format_asset_description(self, asset_description, asset_path):
asset_path = self.prop_rel_path(asset_path, 'source_directory')
modified = data.get('modified', time.time_ns())
modified = asset_description.get('modified', time.time_ns())
if self.data_type == 'FILE':
return dict(
filepath=asset_path,
author=data.get('author'),
author=asset_description.get('author'),
modified=modified,
catalog=data['catalog'],
catalog=asset_description['catalog'],
tags=[],
description=asset_description.get('description', ''),
type=self.data_type,
image=self.template_image,
name=data['name']
name=asset_description['name']
)
return dict(
@ -103,267 +69,18 @@ class ScanFolderLibrary(AssetLibraryAdapter):
modified=modified,
library_id=self.library.id,
assets=[dict(
catalog=asset_data['catalog'],
author=data.get('author'),
catalog=asset_data.get('catalog', asset_description['catalog']),
author=asset_data.get('author'),
metadata=asset_data.get('metadata', {}),
description=asset_data.get('description'),
description=asset_data.get('description', ''),
tags=asset_data.get('tags', []),
type=self.data_type,
image=self.template_image,
video=self.template_video,
name=asset_data['name']) for asset_data in data['assets']
name=asset_data['name']) for asset_data in asset_description['assets']
]
)
def _find_blend_files(self):
'''Get a sorted list of all blender files found matching the template'''
template = Template(self.template)
print(f'Search for blend using glob template: {template.glob_pattern}')
source_directory = Path(os.path.expandvars(self.source_directory))
print(f'Scanning Folder {source_directory}...')
blend_files = list(source_directory.glob(template.glob_pattern))
blend_files.sort()
return blend_files
'''
def _group_key(self, asset_data):
"""Group assets inside one blend"""
catalog_parts = asset_data['catalog'].split('/') + [asset_data['name']]
return catalog_parts[:self.blend_depth]
def bundle(self, cache_diff=None):
"""Group all asset in one or multiple blends for the asset browser"""
if self.data_type not in ('FILE', 'ACTION'):
print(f'{self.data_type} is not supported yet')
return
lib_path = self.library_path
catalog_data = self.read_catalog() # TODO remove unused catalog
#asset_file_datas = self.fetch() # TODO replace to only change new assets
if not cache_diff:
# Get list of all modifications
cache, cache_diff = self.diff()
self.write_cache(cache)
elif isinstance(cache_diff, (Path, str)):
cache_diff = json.loads(Path(cache_diff).read_text(encoding='utf-8'))
if self.blend_depth == 0:
groups = [(cache_diff)]
else:
cache_diff.sort(key=self._group_key)
groups = groupby(cache_diff, key=self._group_key)
# #print(cache_diff)
# print('\n')
# for sub_path, asset_datas in groups:
# print('\n')
# print(f'{sub_path=}')
# print(f'asset_datas={list(asset_datas)}')
# raise Exception()
#progress = 0
total_assets = len(cache_diff)
print(f'total_assets={total_assets}')
if total_assets == 0:
print('No assets found')
return
i = 0
for sub_path, asset_datas in groups:
# print('\n')
# print(f'{sub_path=}')
# print(f'asset_datas={list(asset_datas)}')
# print('\n')
blend_name = sub_path[-1].replace(' ', '_').lower()
blend_path = Path(lib_path, *sub_path, blend_name).with_suffix('.blend')
if blend_path.exists():
print(f'Opening existing bundle blend: {blend_path}')
bpy.ops.wm.open_mainfile(filepath=str(blend_path))
else:
print(f'Create new bundle blend to: {blend_path}')
bpy.ops.wm.read_homefile(use_empty=True)
for asset_data in asset_datas:
if total_assets <= 100 or i % int(total_assets / 10) == 0:
print(f'Progress: {int(i / total_assets * 100)+1}')
operation = asset_data.get('operation', 'ADD')
asset = getattr(bpy.data, self.data_types).get(asset_data['name'])
if operation == 'REMOVE':
if asset:
getattr(bpy.data, self.data_types).remove(asset)
else:
print(f'ERROR : Remove Asset: {asset_data["name"]} not found in {blend_path}')
continue
elif operation == 'MODIFY':
if not asset:
print(f'WARNING: Modifiy Asset: {asset_data["name"]} not found in {blend_path} it will be created')
elif operation == 'ADD' or not asset:
if asset:
#raise Exception(f"Asset {asset_data['name']} Already in Blend")
getattr(bpy.data, self.data_types).remove(asset)
#print(f"INFO: Add new asset: {asset_data['name']}")
asset = getattr(bpy.data, self.data_types).new(name=asset_data['name'])
else:
print(f'operation {operation} not supported should be in (ADD, REMOVE, MODIFIED)')
continue
asset.asset_mark()
# Load external preview if exists
#template_image = Template(asset_data['preview'])
image_path = Path(asset_data['image'])
if not image_path.is_absolute():
image_path = Path(asset_data['filepath'], image_path)
image_path = self.format_path(image_path.as_posix())
if image_path and image_path.exists():
with bpy.context.temp_override(id=asset):
bpy.ops.ed.lib_id_load_custom_preview(
filepath=str(image_path)
)
#else:
# print(f'Preview {image_path} not found for asset {asset}')
asset.asset_data.description = asset_data.get('description', '')
catalog_name = asset_data['catalog']
catalog = catalog_data.get(catalog_name)
if not catalog:
catalog = {'id': str(uuid.uuid4()), 'name': catalog_name}
catalog_data[catalog_name] = catalog
asset.asset_data.catalog_id = catalog['id']
metadata = asset_data.get('metadata', {})
library_id = self.library.id
if 'library_id' in asset_data:
library_id = asset_data['library_id']
metadata['.library_id'] = library_id
#print(metadata)
metadata['filepath'] = asset_data['filepath']
for k, v in metadata.items():
asset.asset_data[k] = v
# Set tags if specified the asset_description
tags = asset_data.get('tags', [])
if tags:
for tag in asset.asset_data.tags[:]:
asset.asset_data.tags.remove(tag)
for tag in tags:
if not tag:
continue
asset.asset_data.tags.new(tag, skip_if_exists=True)
i += 1
print(f'Saving Blend to {blend_path}')
blend_path.parent.mkdir(exist_ok=True, parents=True)
bpy.ops.wm.save_as_mainfile(filepath=str(blend_path), compress=True)
self.write_catalog(catalog_data)
bpy.ops.wm.quit_blender()
'''
'''
def conform(self, directory, templates):
"""Split each assets per blend and externalize preview"""
print(f'Conforming {self.library.name} to {directory}')
if self.data_type not in ('FILE', 'ACTION'):
print(f'{self.data_type} is not supported yet')
return
#lib_path = self.library_path
source_directory = Path(os.path.expandvars(self.source_directory))
catalog_data = self.read_catalog(filepath=source_directory)
catalog_ids = {v['id']: {'path': k, 'name': v['name']} for k,v in catalog_data.items()}
directory = Path(directory).resolve()
template_image = templates.get('image') or self.template_image
template_video = templates.get('video') or self.template_video
# Get list of all modifications
for blend_file in self._find_blend_files():
modified = blend_file.stat().st_mtime_ns
print(f'Scanning blendfile {blend_file}...')
with bpy.data.libraries.load(str(blend_file), link=True, assets_only=True) as (data_from, data_to):
asset_names = getattr(data_from, self.data_types)
print(f'Found {len(asset_names)} {self.data_types} inside')
setattr(data_to, self.data_types, asset_names)
assets = getattr(data_to, self.data_types)
#print('assets', assets)
for asset in assets:
#TODO options for choose beetween asset catalog and filepath directory
asset_catalog_data = catalog_ids.get(asset.asset_data.catalog_id)
if not asset_catalog_data:
print(f'No catalog found for asset {asset.name}')
asset_catalog_data = {"path": blend_file.parent.relative_to(source_directory).as_posix()}
catalog_path = asset_catalog_data['path']
asset_path = self.get_asset_path(name=asset.name, catalog=catalog_path, directory=directory)
asset_description = self.get_asset_description(asset, catalog=catalog_path, modified=modified)
self.write_description_file(asset_description, asset_path)
#Write blend file containing only one asset
self.write_asset(asset=asset, asset_path=asset_path)
# Copy image if source image found else write the asset preview
src_image_path = self.get_path('image', name=asset.name, asset_path=blend_file, template=template_image)
dst_image_path = self.get_path('image', name=asset.name, asset_path=asset_path)
if src_image_path.exists():
self.copy_file(src_image_path, dst_image_path)
else:
self.write_preview(asset.preview, dst_image_path)
# Copy video if source video found
src_video_path = self.get_path('video', name=asset.name, asset_path=blend_file, template=template_video)
#print('src_video_path', src_video_path)
if src_video_path.exists():
dst_video_path = self.get_path('video', name=asset.name, asset_path=asset_path)
self.copy_file(src_video_path, dst_video_path)
self.write_catalog(catalog_data, filepath=directory)
'''
def fetch(self):
"""Gather in a list all assets found in the folder"""
@ -377,17 +94,8 @@ class ScanFolderLibrary(AssetLibraryAdapter):
cache = self.read_cache() or []
print(f'Search for blend using glob template: {template_file.glob_pattern}')
print(f'Scanning Folder {source_directory}...')
#blend_files = list(source_directory.glob(template.glob_pattern))
# Remove delete blends for the list
#blend_paths = [self.prop_rel_path(f, 'source_directory') for f in blend_files]
#print('blend_paths', blend_paths)
#cache = []
#blend_paths = []
new_cache = []
for asset_path in template_file.glob(source_directory):#sorted(blend_files):
@ -407,11 +115,11 @@ class ScanFolderLibrary(AssetLibraryAdapter):
field_data = template_file.parse(rel_path)
catalogs = [v for k,v in sorted(field_data.items()) if k.isdigit()]
catalogs = [c.replace('_', ' ').title() for c in catalogs]
#catalogs = [c.replace('_', ' ').title() for c in catalogs]
asset_name = field_data.get('asset_name', asset_path.stem)
asset_datas = {
asset_description = {
"name": asset_name,
"catalog": '/'.join(catalogs),
"assets": [],
@ -419,12 +127,12 @@ class ScanFolderLibrary(AssetLibraryAdapter):
}
if self.data_type == 'FILE':
asset_description = self.get_asset_description(asset_datas, asset_path)
asset_description = self.format_asset_description(asset_description, asset_path)
new_cache.append(asset_description)
continue
# Now check if there is a asset description file
asset_description_path = self.find_path(self.template_description, asset_datas, filepath=asset_path)
asset_description_path = self.find_path(self.template_description, asset_description, filepath=asset_path)
if asset_description_path:
new_cache.append(self.read_file(asset_description_path))
continue
@ -439,33 +147,19 @@ class ScanFolderLibrary(AssetLibraryAdapter):
#if not catalog_path:
# print(f'No catalog found for asset {asset.name}')
catalog_path = asset_datas['catalog']#asset_path.relative_to(self.source_directory).as_posix()
#catalog_path = asset_description['catalog']#asset_path.relative_to(self.source_directory).as_posix()
asset_datas['assets'] += [dict(
catalog=catalog_path,
tags=asset.asset_data.tags.keys(),
metadata=dict(asset.asset_data),
type=self.data_type,
name=asset.name
)]
# For now the catalog used is the one extract from the template file
asset_description['assets'].append(self.get_asset_data(asset))
getattr(bpy.data, self.data_types).remove(asset)
asset_description = self.get_asset_description(asset_datas, asset_path)
asset_description = self.format_asset_description(asset_description, asset_path)
new_cache.append(asset_description)
#cache = [a for a in cache if a['filepath'] in blend_paths]
#for a in asset_data:
# print(a)
#print(asset_data)
new_cache.sort(key=lambda x:x['filepath'])
return new_cache
# Write json data file to store all asset found
#print(f'Writing asset data file to, {asset_data_path}')
#asset_data_path.write_text(json.dumps(asset_data, indent=4))

View File

@ -84,6 +84,7 @@ class ASSETLIB_OT_edit_data(Operator):
catalog: StringProperty(name='Catalog', update=asset_warning_callback, options={'TEXTEDIT_UPDATE'})
name: StringProperty(name='Name', update=asset_warning_callback, options={'TEXTEDIT_UPDATE'})
tags: StringProperty(name='Tags', description='Tags need to separate with a comma (,)')
description: StringProperty(name='Description')
@classmethod
def poll(cls, context):
@ -101,35 +102,50 @@ class ASSETLIB_OT_edit_data(Operator):
new_name = lib.adapter.norm_file_name(self.name)
new_asset_path = lib.adapter.get_asset_path(name=new_name, catalog=self.catalog)
#asset_data = lib.adapter.get_asset_data(self.asset)
asset_data = dict(
tags=[t.strip() for t in self.tags.split(',') if t],
description=self.description,
)
#lib.adapter.set_asset_catalog(asset, asset_data, catalog_data)
self.asset.name = self.name
lib.adapter.set_asset_tags(self.asset, asset_data)
lib.adapter.set_asset_info(self.asset, asset_data)
self.old_asset_path.unlink()
lib.adapter.write_asset(asset=self.asset, asset_path=new_asset_path)
if self.old_image_path.exists():
new_img_path = lib.adapter.get_path('image', new_name, new_asset_path)
new_img_path = lib.adapter.get_image_path(new_name, self.catalog, new_asset_path)
self.old_image_path.rename(new_img_path)
if self.old_video_path.exists():
new_video_path = lib.adapter.get_path('video', new_name, new_asset_path)
new_video_path = lib.adapter.get_video_path(new_name, self.catalog, new_asset_path)
self.old_video_path.rename(new_video_path)
if self.old_description_path.exists():
self.old_description_path.unlink()
#if self.old_description_path.exists():
# self.old_description_path.unlink()
new_asset_description = lib.adapter.get_asset_description(
asset=self.asset,
catalog=self.catalog,
modified=time.time_ns()
)
lib.adapter.write_description_file(new_asset_description, new_asset_path)
if not list(self.old_asset_path.parent.iterdir()):
try:
self.old_asset_path.parent.rmdir()
except Exception: #The folder is not empty
pass
diff_path = Path(bpy.app.tempdir, 'diff.json')
diff = [dict(name=self.old_asset_name, catalog=self.old_catalog, filepath=str(self.old_asset_path), operation='REMOVE')]
diff = [dict(self.old_asset_description, operation='REMOVE')]
diff += [dict(lib.adapter.norm_asset_datas([new_asset_description])[0], operation='ADD')]
asset_data = lib.adapter.get_asset_data(self.asset)
diff += [dict(asset_data,
image=str(new_img_path),
filepath=str(new_asset_path),
type=lib.data_type,
library_id=lib.id,
catalog=self.catalog,
operation='ADD'
)]
print(diff)
diff_path.write_text(json.dumps(diff, indent=4), encoding='utf-8')
@ -151,6 +167,7 @@ class ASSETLIB_OT_edit_data(Operator):
layout.prop(self, "catalog", text="Catalog")
layout.prop(self, "name", text="Name")
layout.prop(self, 'tags')
layout.prop(self, 'description')
#layout.prop()
@ -184,25 +201,31 @@ class ASSETLIB_OT_edit_data(Operator):
self.asset = load_datablocks(self.old_asset_path, self.old_asset_name, type=lib.data_types)
self.old_image_path = lib.adapter.get_path('image', self.old_asset_name, self.old_asset_path)
self.old_video_path = lib.adapter.get_path('video', self.old_asset_name, self.old_asset_path)
self.old_description_path = lib.adapter.get_description_path(self.old_asset_path)
self.old_asset_description = lib.adapter.read_asset_description_file(self.old_asset_path)
self.old_asset_description = lib.adapter.norm_asset_datas([self.old_asset_description])[0]
if not self.asset:
self.report({'ERROR'}, 'No asset found')
self.name = self.old_asset_name
self.tags = ', '.join(self.asset.asset_data.tags.keys())
self.description = asset_handle.asset_data.description
tags = [t.strip() for t in self.asset.asset_data.tags.keys() if t]
self.tags = ', '.join(tags)
#asset_path
self.catalog = catalog_ids[asset_handle.asset_data.catalog_id]['path']
self.old_catalog = catalog_ids[asset_handle.asset_data.catalog_id]['path']
self.catalog = self.old_catalog
self.old_image_path = lib.adapter.get_image_path(name=self.name, catalog=self.catalog, filepath=self.old_asset_path)
self.old_video_path = lib.adapter.get_video_path(name=self.name, catalog=self.catalog, filepath=self.old_asset_path)
#self.old_description_path = lib.adapter.get_description_path(self.old_asset_path)
#self.old_asset_description = lib.adapter.read_asset_description_file(self.old_asset_path)
#self.old_asset_description = lib.adapter.norm_asset_datas([self.old_asset_description])[0]
return context.window_manager.invoke_props_dialog(self)
return context.window_manager.invoke_props_dialog(self, width=450)
def cancel(self, context):
print('Cancel Edit Data, removing the asset')