From 472622ff4b77d2cf19bc3340fa8f746d14d7cbd3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9Cchristopheseux=E2=80=9D?= <“seuxchristophe@hotmail.fr”> Date: Wed, 31 May 2023 12:52:35 +0200 Subject: [PATCH] static asset items, fix blender freeze --- constants.py | 2 + operators/casting.py | 14 +- operators/tracker.py | 78 +++++--- .../trackers/tracker_test/trackertest.py | 171 ------------------ ui/panels.py | 5 + 5 files changed, 66 insertions(+), 204 deletions(-) delete mode 100644 resources/trackers/tracker_test/trackertest.py diff --git a/constants.py b/constants.py index 3b5945e..aedc134 100644 --- a/constants.py +++ b/constants.py @@ -20,6 +20,8 @@ EDIT_SUFFIXES = ['.xml', '.edl'] MOVIE_SUFFIXES = ['.mov', '.mp4'] SOUND_SUFFIXES = ['.mp3', '.aaf', '.flac', '.wav'] +ASSET_ITEMS = [] + CONFIG_DIR = Path(appdirs.user_config_dir(__package__.split('.')[0])) PREVIEWS_DIR = CONFIG_DIR / 'thumbnails' diff --git a/operators/casting.py b/operators/casting.py index dddaa24..9c130f0 100644 --- a/operators/casting.py +++ b/operators/casting.py @@ -5,10 +5,11 @@ import bpy from bpy.types import Context, Event, PropertyGroup, Operator from bpy.props import (CollectionProperty, EnumProperty, StringProperty) -from vse_toolbox.constants import CASTING_BUFFER +from vse_toolbox.constants import CASTING_BUFFER, ASSET_ITEMS from vse_toolbox.sequencer_utils import get_strips from vse_toolbox.bl_utils import (get_addon_prefs, get_scene_settings, get_strip_settings) +from time import perf_counter class VSETB_OT_casting_replace(Operator): bl_idname = "vse_toolbox.casting_replace" @@ -75,20 +76,15 @@ class VSETB_OT_casting_replace(Operator): col.prop_search(self, 'new_asset', self, 'assets', text='New Asset', icon='ASSET_MANAGER') -def get_asset_items(self, context): - settings = get_scene_settings() - project = settings.active_project - - return [(a.id, a.label, '', i) for i, a in enumerate(project.assets)] - class VSETB_OT_casting_add(Operator): bl_idname = "vse_toolbox.casting_add" bl_label = "Casting Add" bl_description = "Add Asset to Castin" bl_options = {"REGISTER", "UNDO"} bl_property = "asset_name" - - asset_name : EnumProperty(name='', items=get_asset_items) + + asset_name : EnumProperty(name='', items=lambda s,c : ASSET_ITEMS) + #asset_name : EnumProperty(name='', items=get_scene_settings().active_project.get('asset_items', [])) @classmethod def poll(cls, context): active_strip = context.scene.sequence_editor.active_strip diff --git a/operators/tracker.py b/operators/tracker.py index ab3d83c..a980a9c 100644 --- a/operators/tracker.py +++ b/operators/tracker.py @@ -6,12 +6,13 @@ import bpy from bpy.types import (Operator, ) from bpy.props import (BoolProperty, EnumProperty, StringProperty) -from vse_toolbox.constants import (ASSET_PREVIEWS, PREVIEWS_DIR) +from vse_toolbox.constants import (ASSET_PREVIEWS, PREVIEWS_DIR, ASSET_ITEMS) from vse_toolbox.sequencer_utils import (get_strips, get_strip_render_path, get_strip_sequence_name) from vse_toolbox.bl_utils import (get_addon_prefs, get_scene_settings) from vse_toolbox.file_utils import (norm_name,) +from bpy.app.handlers import persistent class VSETB_OT_tracker_connect(Operator): @@ -85,7 +86,8 @@ class VSETB_OT_load_assets(Operator): if preview_id not in ASSET_PREVIEWS: ASSET_PREVIEWS.load(preview_id, preview_path.as_posix(), 'IMAGE', True) - + + set_asset_items() self.report({'INFO'}, f'Assets for {project.name} successfully loaded') return {"FINISHED"} @@ -106,26 +108,43 @@ class VSETB_OT_load_projects(Operator): prefs = get_addon_prefs() tracker = prefs.tracker - old_project_name = settings.project_name.replace(' ', '_').upper() + # old_project_name = settings.project_name.replace(' ', '_').upper() - old_episode_name = None - if settings.active_project: - old_episode_name = settings.active_project.episode_name.replace(' ', '_').upper() + # old_episode_name = None + # if settings.active_project: + # old_episode_name = settings.active_project.episode_name.replace(' ', '_').upper() - settings.projects.clear() + + + #settings.projects.clear() tracker.connect() - for project_data in tracker.get_projects(): - project = settings.projects.add() + project_datas = tracker.get_projects() + for project_data in project_datas: + project = settings.projects.get(project_data['name']) + if not project: + project = settings.projects.add() + project.type = project_data['production_type'].upper().replace(' ', '') project.name = project_data['name'] project.id = project_data['id'] if project.type == 'TVSHOW': - for episode_data in tracker.get_episodes(project_data): - episode = project.episodes.add() + episode_datas = tracker.get_episodes(project_data) + for episode_data in episode_datas: + episode = project.episodes.get(episode_data['name']) + + if not episode: + episode = project.episodes.add() + episode.name = episode_data['name'] episode.id = episode_data['id'] + + # Clear deleted episodes + ep_names = [e['name'] for e in episode_datas] + for ep in reversed(project.episodes): + if ep.name not in ep_names: + project.episodes.remove(list(project.episodes).index(ep)) for metadata_data in tracker.get_metadata_types(project_data): #pprint(metadata_data) @@ -158,22 +177,18 @@ class VSETB_OT_load_projects(Operator): project.set_spreadsheet() - for project in settings.projects: - if project.name.replace(' ', '_').upper() == old_project_name: - settings.project_name = project.name - - for episode in project.episodes: - if episode.name.replace(' ', '_').upper() == old_episode_name: - project.episode_name = episode.name - bpy.ops.vse_toolbox.load_settings() - #else: - # print('Could Not restore Project Name') + + # Remove deleted projects + project_names = [p['name'] for p in project_datas] + for project in reversed(settings.projects): + if project.name not in project_names: + settings.projects.remove(list(settings.projects).index(project)) + #if settings.active_project: # settings.active_project.set_strip_metadata() - #bpy.ops.vse_toolbox.load_assets() self.report({"INFO"}, 'Successfully Load Tracker Projects') @@ -367,6 +382,15 @@ class VSETB_OT_upload_to_tracker(Operator): return {"FINISHED"} +@persistent +def set_asset_items(scene=None): + ASSET_ITEMS.clear() + + settings = get_scene_settings() + if settings.active_project: + ASSET_ITEMS.extend([(a.id, a.label, '', i) for i, a in enumerate(settings.active_project.assets)]) + + classes = ( VSETB_OT_load_assets, VSETB_OT_load_projects, @@ -375,10 +399,16 @@ classes = ( VSETB_OT_upload_to_tracker, ) -def register(): +def register(): + if not bpy.app.background: + bpy.app.handlers.load_post.append(set_asset_items) + for cls in classes: bpy.utils.register_class(cls) def unregister(): for cls in reversed(classes): - bpy.utils.unregister_class(cls) \ No newline at end of file + bpy.utils.unregister_class(cls) + + if not bpy.app.background: + bpy.app.handlers.load_post.remove(set_asset_items) \ No newline at end of file diff --git a/resources/trackers/tracker_test/trackertest.py b/resources/trackers/tracker_test/trackertest.py deleted file mode 100644 index 9203e3b..0000000 --- a/resources/trackers/tracker_test/trackertest.py +++ /dev/null @@ -1,171 +0,0 @@ - -import bpy -import os -import re -import urllib3 -import traceback -import time - -from bpy.props import PointerProperty, StringProperty -from pathlib import Path -from vse_toolbox.bl_utils import get_addon_prefs, get_scene_settings -from vse_toolbox.file_utils import install_module, norm_str -from vse_toolbox.resources.trackers.tracker import Tracker - -gazu = install_module('gazu') - -class TrackerTest(Tracker): - name = "TrackerTest" - - url: StringProperty() - login: StringProperty() - password: StringProperty(subtype='PASSWORD') - custom_field: StringProperty(subtype='PASSWORD') - - project_name = None - - def draw_prefs(self, layout): - layout.prop(self, 'url', text='Url') - layout.prop(self, 'login', text='Login') - layout.prop(self, 'password', text='Password') - layout.prop(self, 'custom_field', text='Password') - - def get_projects(self): - return gazu.project.all_open_projects() - - def get_episodes(self, project): - return gazu.shot.all_episodes_for_project(project) - - def get_episode(self, name): - return gazu.shot.get_episode_by_name(self.project, name) - - def get_asset_types(self, project): - asset_types = gazu.asset.all_asset_types_for_project(project) - return {t['id']:t['name'] for t in asset_types} - - def get_assets(self, project): - asset_types = self.get_asset_types(project) - assets = gazu.asset.all_assets_for_project(project) - - for asset in assets: - asset['asset_type'] = asset_types[asset['entity_type_id']] - - return assets - - def get_metadata_types(self, project): - metadata = [] - for md in gazu.project.all_metadata_descriptors(project): - asset_type = md.get('asset_type') - field_name = md.get('field_name') - if asset_type and asset_type.lower() == 'shot' and field_name: - metadata.append(field_name) - - return metadata - - def download_preview(self, preview_id, filepath): - if isinstance(filepath, str): - filepath = Path(filepath) - - if filepath.exists(): - return - - filepath.parent.mkdir(parents=True, exist_ok=True) - gazu.files.download_preview_file_thumbnail(preview_id, filepath.as_posix()) - - def connect(self, url=None, login=None, password=None): - '''Connect to kitsu api using provided url, login and password''' - - urllib3.disable_warnings() - - if not self.url: - print(f'Kitsu Url: {self.url} is empty') - return - - url = self.url - if not url.endswith('/api'): - url += '/api' - - print(f'Info: Setting Host for kitsu {url}') - gazu.client.set_host(url) - - if not gazu.client.host_is_up(): - print('Error: Kitsu Host is down') - - try: - print(f'Info: Log in to kitsu as {self.login}') - res = gazu.log_in(self.login, self.password) - print(f'Info: Sucessfully login to Kitsu as {res["user"]["full_name"]}') - return res['user'] - except Exception as e: - print(f'Error: {traceback.format_exc()}') - - def get_asset_path(self, name, catalog, directory=None): - directory = directory or self.source_directory - return Path(directory, self.get_asset_relative_path(name, catalog)) - - def get_asset_info(self, data, asset_path): - modified = time.time_ns() - catalog = data['entity_type_name'].title() - asset_path = self.prop_rel_path(asset_path, 'source_directory') - - asset_info = dict( - filepath=asset_path, - modified=modified, - library_id=self.library.id, - assets=[dict( - catalog=catalog, - metadata=data.get('data', {}), - description=data['description'], - tags=[], - type=self.data_type, - name=data['name']) - ] - ) - - return asset_info - - def fetch(self): - """Gather in a list all assets found in the folder""" - print(f'Fetch Assets for {self.library.name}') - - self.connect() - - template_file = Template(self.template_file) - template_name = Template(self.template_name) - - project = gazu.client.fetch_first('projects', {'name': self.project_name}) - entity_types = gazu.client.fetch_all('entity-types') - entity_types_ids = {e['id']: e['name'] for e in entity_types} - - cache = self.read_cache() - - for asset_data in gazu.asset.all_assets_for_project(project): - asset_data['entity_type_name'] = entity_types_ids[asset_data.pop('entity_type_id')] - asset_name = asset_data['name'] - - asset_field_data = dict(asset_name=asset_name, type=asset_data['entity_type_name'], source_directory=self.source_directory) - - try: - asset_field_data.update(template_name.parse(asset_name)) - except Exception: - print(f'Warning: Could not parse {asset_name} with template {template_name}') - - asset_path = template_file.find(asset_field_data) - if not asset_path: - print(f'Warning: Could not find file for {template_file.format(asset_field_data)}') - continue - - - asset_path = self.prop_rel_path(asset_path, 'source_directory') - asset_cache_data = dict( - catalog=asset_data['entity_type_name'].title(), - metadata=asset_data.get('data', {}), - description=asset_data['description'], - tags=[], - type=self.data_type, - name=asset_data['name'] - ) - - cache.add_asset_cache(asset_cache_data, filepath=asset_path) - - return cache \ No newline at end of file diff --git a/ui/panels.py b/ui/panels.py index 5281491..82eb558 100644 --- a/ui/panels.py +++ b/ui/panels.py @@ -75,6 +75,11 @@ class VSETB_PT_strip(Panel): bl_label = "VSE ToolBox" #bl_order = 0 + @classmethod + def poll(cls, context): + strip = context.scene.sequence_editor.active_strip + return strip and get_channel_name(strip) == 'Shots' + def draw(self, context): prefs = get_addon_prefs() layout = self.layout