diff --git a/operators/operators.py b/operators/operators.py index a5dbef6..43c476c 100644 --- a/operators/operators.py +++ b/operators/operators.py @@ -1,6 +1,5 @@ # SPDX-License-Identifier: GPL-2.0-or-later -import bpy import importlib import json import re @@ -9,53 +8,28 @@ from pprint import pprint import csv from datetime import datetime import os +from pathlib import Path +import bpy +from bpy.types import (Operator, Menu) +from bpy_extras.io_utils import ImportHelper +from bpy.props import (CollectionProperty, BoolProperty, EnumProperty, + IntProperty, StringProperty) +from bpy.types import PropertyGroup +from bl_operators.presets import AddPresetBase import vse_toolbox -from bpy_extras.io_utils import ImportHelper -from bpy.props import ( - CollectionProperty, - BoolProperty, - EnumProperty, - IntProperty, - StringProperty, -) -from bpy.types import ( - Operator, -) -from pathlib import Path -from vse_toolbox.constants import ( - ASSET_PREVIEWS, - CASTING_BUFFER, - CONFIG_DIR, - EDITS, - EDIT_SUFFIXES, - MOVIES, - MOVIE_SUFFIXES, - PREVIEWS_DIR, - SOUNDS, - SOUND_SUFFIXES, - TASK_ITEMS -) -from vse_toolbox.sequencer_utils import ( - clean_sequencer, - get_strips, - set_active_strip, - import_edit, - import_movie, - import_sound, - rename_strips, - render_strips, - set_channels, - get_channel_index, - new_text_strip, - get_strip_render_path, - get_strip_sequence_name -) +from vse_toolbox.constants import (ASSET_PREVIEWS, CASTING_BUFFER, CONFIG_DIR, + EDITS, EDIT_SUFFIXES, MOVIES, MOVIE_SUFFIXES, PREVIEWS_DIR, SOUNDS, + SOUND_SUFFIXES, TASK_ITEMS) -from vse_toolbox.bl_utils import get_addon_prefs, get_scene_settings, get_strip_settings -from vse_toolbox.file_utils import install_module, norm_name, norm_str, open_file +from vse_toolbox.sequencer_utils import (clean_sequencer, get_strips, set_active_strip, + import_edit, import_movie, import_sound, rename_strips, render_strips, set_channels, + get_channel_index, new_text_strip, get_strip_render_path, get_strip_sequence_name) + +from vse_toolbox.bl_utils import (get_addon_prefs, get_scene_settings, get_strip_settings) +from vse_toolbox.file_utils import (install_module, norm_name, norm_str, open_file) class VSETB_OT_tracker_connect(Operator): @@ -112,6 +86,15 @@ class VSETB_OT_export_spreadsheet(Operator): row.template_list("VSETB_UL_spreadsheet", "spreadsheet", project, "spreadsheet", project, "spreadsheet_index", rows=8) col_tool = row.column(align=True) + + #bpy.types.VSETB_PT_presets.draw_panel_header(col_tool) + #col_tool.operator('wm.call_menu', icon="PRESET").name = 'VSETB_MT_spreadsheet_presets' + #col_tool.operator('vse_toolbox.load_spreadsheet_preset', icon='PRESET', text="") + op = col_tool.operator('wm.call_panel', icon="PRESET", emboss=False, text='') + op.name = 'VSETB_PT_presets' + op.keep_open = False + + col_tool.separator() col_tool.operator('vse_toolbox.spreadsheet_move', icon='TRIA_UP', text="").direction = 'UP' col_tool.operator('vse_toolbox.spreadsheet_move', icon='TRIA_DOWN', text="").direction = 'DOWN' @@ -227,7 +210,7 @@ class VSETB_OT_export_spreadsheet(Operator): elif options.format == 'XLSX': try: import openpyxl - except ModuleNotFoundError(): + except ModuleNotFoundError: self.report({'INFO'}, 'Installing openpyxl') openpyxl = install_module('openpyxl') @@ -325,6 +308,11 @@ class VSETB_OT_upload_to_tracker(Operator): prefs = get_addon_prefs() settings = get_scene_settings() project = settings.active_project + episode = None + if settings.active_episode: + episode = settings.active_episode.id + + tracker = prefs.tracker status = self.status @@ -334,13 +322,13 @@ class VSETB_OT_upload_to_tracker(Operator): for strip in get_strips(channel='Shots', selected_only=True): sequence_name = get_strip_sequence_name(strip) shot_name = strip.name - sequence = tracker.get_sequence(sequence_name) + sequence = tracker.get_sequence(sequence_name, episode=episode) metadata = strip.vsetb_strip_settings.metadata.to_dict() #print(metadata) if not sequence: self.report({"INFO"}, f'Create sequence {sequence_name} in Kitsu') - sequence = tracker.new_sequence(sequence_name) + sequence = tracker.new_sequence(sequence_name, episode=episode) shot = tracker.get_shot(shot_name, sequence=sequence) if not shot: @@ -359,6 +347,7 @@ class VSETB_OT_upload_to_tracker(Operator): preview = Path(get_strip_render_path(strip, project.render_template)) #print(preview) if not preview.exists(): + print(f'The preview {preview} not exists') preview = None elif task.get('last_comment') and task['last_comment']['previews']: @@ -886,13 +875,77 @@ class VSETB_OT_set_sequencer(Operator): return {"FINISHED"} +class VSETB_OT_casting_replace(Operator): + bl_idname = "vse_toolbox.casting_replace" + bl_label = "Replace Asset" + bl_description = "Replace Asset of selected strips" + + old_asset : StringProperty() + new_asset : StringProperty() + + assets : CollectionProperty(type=PropertyGroup) + + def execute(self, context): + prefs = get_addon_prefs() + settings = get_scene_settings() + + new_asset = next(a for a in settings.active_project.assets if a.tracker_name == self.new_asset) + + for strip in get_strips('Shots', selected_only=True): + strip_settings = strip.vsetb_strip_settings + for asset_casting in strip_settings.casting: + if asset_casting.asset.tracker_name == self.old_asset: + + print(f'Replace casting on {strip.name}') + + asset_casting.name = new_asset.name + asset_casting.id = new_asset.id + asset_casting['_name'] = new_asset.label + + strip_settings.casting.update() + + self.assets.clear() + + return {'FINISHED'} + + def invoke(self, context, event): + settings = get_scene_settings() + project = settings.active_project + + self.assets.clear() + for asset in project.assets: + item = self.assets.add() + item.name = asset.tracker_name + + strip = context.active_sequence_strip + asset_casting_index = strip.vsetb_strip_settings.casting_index + active_asset = strip.vsetb_strip_settings.casting[asset_casting_index].asset + + self.old_asset = active_asset.tracker_name + self.new_asset = '' + + return context.window_manager.invoke_props_dialog(self) + # + + def draw(self, context): + scn = context.scene + settings = get_scene_settings() + + project = settings.active_project + + layout = self.layout + col = layout.column() + col.use_property_split = True + col.prop_search(self, 'old_asset', self, 'assets', text='Old Asset', icon='ASSET_MANAGER') + 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" @@ -930,7 +983,6 @@ class VSETB_OT_casting_add(Operator): item.name = asset.name item.id = project.assets[self.asset_name].id - item['_name'] = asset.label strip_settings.casting.update() @@ -1024,6 +1076,43 @@ class VSETB_OT_casting_move(Operator): return {"FINISHED"} +class VSETB_MT_spreadsheet_presets(Menu): + bl_label = 'Presets' + preset_subdir = 'vse_toolbox' + preset_operator = 'script.execute_preset' + draw = Menu.draw_preset + + +class VSETB_OT_add_spreadsheet_preset(AddPresetBase, Operator): + + bl_idname = "vse_toolbox.add_spreadsheet_preset" + bl_label = "Add Spreadsheet Preset" + bl_description = "Add Spreadsheet Preset" + bl_options = {"REGISTER", "UNDO"} + + preset_menu = 'VSETB_MT_spreadsheet_presets' + + #preset_menu = 'VSETB_OT_MT_spreadsheet_presets' + + # Common variable used for all preset values + #C.scene.vsetb_settings.active_project.spreadsheet_options + preset_defines = [ + 'scene = bpy.context.scene', + 'settings = scene.vsetb_settings', + 'project = settings.active_project' + ] + + # Properties to store in the preset + preset_values = [ + 'project.spreadsheet', + 'project.spreadsheet_options' + ] + + # Directory to store the presets + preset_subdir = 'vse_toolbox' + + + class VSETB_OT_spreadsheet_move(Operator): bl_idname = "vse_toolbox.spreadsheet_move" bl_label = "Move Spreadsheet items" @@ -1060,6 +1149,7 @@ class VSETB_OT_spreadsheet_move(Operator): return {"FINISHED"} + class VSETB_OT_copy_casting(Operator): bl_idname = "vse_toolbox.copy_casting" bl_label = "Copy Casting" @@ -1190,9 +1280,12 @@ classes = ( VSETB_OT_casting_add, VSETB_OT_casting_remove, VSETB_OT_casting_move, + VSETB_OT_add_spreadsheet_preset, + VSETB_MT_spreadsheet_presets, VSETB_OT_spreadsheet_move, VSETB_OT_copy_casting, VSETB_OT_paste_casting, + VSETB_OT_casting_replace, VSETB_OT_export_spreadsheet, VSETB_OT_import_files, VSETB_OT_load_assets, diff --git a/preferences.py b/preferences.py index c3b30f1..00a78c5 100644 --- a/preferences.py +++ b/preferences.py @@ -62,17 +62,16 @@ def load_trackers(): print(f'Could not register Tracker {name}') print(e) -def load_tracker_prefs(): - # FIXME Ça écrase les prefs à chaque quoi +def load_prefs(): prefs = get_addon_prefs() - tracker_prefs_file = os.getenv('TRACKER_PREFS') + prefs_config_file = prefs.config_path - if not tracker_prefs_file: + if not prefs_config_file: return - tracker_datas = read_file(os.path.expandvars(tracker_prefs_file)) + prefs_datas = read_file(os.path.expandvars(prefs_config_file)) - for tracker_data in tracker_datas: + for tracker_data in prefs_datas['trackers']: tracker_name = norm_str(tracker_data['name']) if not hasattr(prefs.trackers, tracker_name): continue @@ -87,6 +86,8 @@ def load_tracker_prefs(): continue setattr(tracker_pref, k, os.path.expandvars(v)) + prefs['tracker_name'] = prefs_datas['tracker_name'] + class Trackers(PropertyGroup): def __iter__(self): @@ -98,6 +99,7 @@ class VSETB_Prefs(AddonPreferences): trackers : PointerProperty(type=Trackers) expand_settings: BoolProperty(default=False) + config_path : StringProperty(subtype='FILE_PATH') @property def tracker(self): @@ -121,13 +123,15 @@ class VSETB_Prefs(AddonPreferences): subrow.operator("vse_toolbox.reload_addon", text='Reload Addon') if self.expand_settings: + box.prop(self, 'config_path', text='Config Path') box.prop(settings, 'tracker_name', text='Tracker') self.tracker.draw_prefs(box) - row = box.row() - row.operator("vse_toolbox.tracker_connect", text='Connect') + #row = box.row() + box.operator("vse_toolbox.tracker_connect", text='Connect') -classes=[ + +classes = [ Trackers, VSETB_Prefs, ] @@ -140,11 +144,15 @@ def register(): load_trackers() prefs = get_addon_prefs() - tracker_name = os.getenv('TRACKER_NAME') - if tracker_name is not None: - prefs['tracker_name'] = os.path.expandvars(norm_str(tracker_name, format=str.upper)) + #tracker_name = os.getenv('TRACKER_NAME') + #if tracker_name is not None: + # prefs['tracker_name'] = os.path.expandvars(norm_str(tracker_name, format=str.upper)) - load_tracker_prefs() + config_path = os.getenv('VSE_TOOLBOX_CONFIG') + if config_path: + prefs['config_path'] = os.path.expandvars(config_path) + + load_prefs() def unregister(): for cls in reversed(classes + TRACKERS): diff --git a/properties.py b/properties.py index beb3cea..13d579d 100644 --- a/properties.py +++ b/properties.py @@ -51,7 +51,8 @@ def on_project_updated(self, context): os.environ['TRACKER_PROJECT_ID'] = settings.active_project.id -def on_episode_updated(self, context): +def on_episode_updated(self, context): + settings = get_scene_settings() os.environ['TRACKER_EPISODE_ID'] = settings.active_episode.id def get_tracker_items(self, context): @@ -250,7 +251,7 @@ class Project(PropertyGroup): del Metadata.__annotations__[attr] for metadata_type in self.metadata_types: - if not metadata_type['entity_type'] == "SHOT": + if not metadata_type.entity_type == "SHOT": continue field_name = metadata_type.field_name @@ -406,7 +407,7 @@ class VSETB_PGT_strip_settings(PropertyGroup): description : StringProperty() -classes=( +classes = ( Asset, AssetCasting, SpreadsheetCell, @@ -428,6 +429,20 @@ classes=( from bpy.app.handlers import persistent + +def load_settings(): + prefs = get_addon_prefs() + prefs_config_file = prefs.config_path + + if not prefs_config_file: + return + + prefs_datas = read_file(os.path.expandvars(prefs_config_file)) + + #for cell in prefs_datas.get('spreadsheet', {}).get('cells', []): + + + @persistent def load_handler(dummy): settings = get_scene_settings() diff --git a/resources/trackers/kitsu.py b/resources/trackers/kitsu.py index 40d8d3e..9def90e 100644 --- a/resources/trackers/kitsu.py +++ b/resources/trackers/kitsu.py @@ -153,7 +153,7 @@ class Kitsu(Tracker): project = self.get_project(project) return gazu.asset.all_asset_types_for_project(project) - def get_sequence(self, sequence, project=None): + def get_sequence(self, sequence, episode=None, project=None): print(f'get_sequence({sequence=}, {project=})') project = self.get_project(project) @@ -161,7 +161,11 @@ class Kitsu(Tracker): if sequence_id: return sequence_id - return gazu.shot.get_sequence_by_name(project, sequence) + params = dict(project=project, sequence_name=sequence) + if episode: + params['episode'] = self.get_id(episode) + + return gazu.shot.get_sequence_by_name(**params) def get_shot(self, shot, sequence, project=None): print(f'get_shot({shot=}, {sequence=}, {project=})')