refactor and fixes for episode handling gav

This commit is contained in:
2026-09-01 15:44:11 +02:00
parent 01fccc63d9
commit 4e29c0e699
7 changed files with 448 additions and 164 deletions
+53 -7
View File
@@ -205,6 +205,7 @@ class VSETB_OT_load_projects(Operator):
#print(metadata_data)
task_status = project.task_statuses.add()
task_status.name = status_data['short_name'].upper()
task_status.is_done = status_data.get('is_done', False)
project.task_types.clear()
for task_type_data in tracker.get_shot_task_types(project_data):
@@ -228,7 +229,10 @@ class VSETB_OT_load_projects(Operator):
if project.name not in project_names:
settings.projects.remove(list(settings.projects).index(project))
if self.ctrl or not settings.get('projects_loaded'):
# ``load_projects`` can also be called programmatically (for example
# from the upload dialog), bypassing ``invoke`` and therefore not
# initializing ``self.ctrl``.
if getattr(self, 'ctrl', False) or not settings.get('projects_loaded'):
bpy.ops.vse_toolbox.load_settings()
if prev_project_name != '/' and prev_project_name in settings.projects:
@@ -293,11 +297,19 @@ class VSETB_OT_new_episode(Operator):
class VSETB_OT_upload_to_tracker(Operator):
bl_idname = "vse_toolbox.upload_to_tracker"
bl_label = "Upload to tracker"
bl_description = "Upload selected strip to tracker"
bl_description = (
"Upload the selected strips on the Shots track to the tracker. "
"Creates missing sequences, shots and tasks, posts a comment "
'(with a preview, rendered if "Render Strips" is enabled) and '
"updates frames, metadata, casting and task comments."
)
bl_options = {"REGISTER", "UNDO"}
@classmethod
def poll(cls, context):
if not get_strips(channel='Shots', selected_only=True):
cls.poll_message_set('Select at least one shot strip')
return False
return True
def invoke(self, context, event):
@@ -307,7 +319,14 @@ class VSETB_OT_upload_to_tracker(Operator):
tracker = prefs.tracker
tracker.connect()
# Loading the toolbox config can create the selected project locally,
# but does not populate its tracker metadata. In that case the task
# enum has no items even though Kitsu has shot task types configured.
if self.project and not self.project.task_types:
bpy.ops.vse_toolbox.load_projects()
self.project = settings.active_project
#self.bl_label = f"Upload to {settings.tracker_name.title()}"
return context.window_manager.invoke_props_dialog(self, width=350)
@@ -363,10 +382,26 @@ class VSETB_OT_upload_to_tracker(Operator):
format_data = {**settings.format_data, **self.project.format_data}
status = upload_to_tracker.status
if status == 'CURRENT':
keep_current_status = status == 'CURRENT'
if keep_current_status:
status = None
# ``CURRENT`` means preserve an existing task's status. A newly
# created task has no current status, so use Kitsu's done metadata for
# the first upload (prefer DONE when several statuses are marked done).
default_new_task_status = None
if keep_current_status:
done_statuses = [s for s in self.project.task_statuses if s.is_done]
default_new_task_status = next(
(s.name for s in done_statuses if s.name.lower() == 'done'),
done_statuses[0].name if done_statuses else None,
)
shot_strips = get_strips(channel='Shots', selected_only=True)
if not shot_strips:
self.report({'WARNING'}, 'Select at least one shot strip to upload')
return {'CANCELLED'}
context.window_manager.progress_begin(0, len(shot_strips))
for i, strip in enumerate(shot_strips):
@@ -392,7 +427,11 @@ class VSETB_OT_upload_to_tracker(Operator):
task = tracker.get_task(upload_to_tracker.task, entity=shot)
if not task:
task = tracker.new_task(shot, task_type=upload_to_tracker.task)
task = tracker.new_task(
shot,
task_type=upload_to_tracker.task,
status=default_new_task_status or status,
)
preview = None
if upload_to_tracker.add_preview:
@@ -439,9 +478,16 @@ class VSETB_OT_upload_to_tracker(Operator):
if upload_to_tracker.custom_data:
params['custom_data'] = metadata
params['description'] = strip_settings.description
if upload_to_tracker.update_frames:
# Blender's frame_final_end is exclusive, while Kitsu's
# frame_out is inclusive. Keep both the explicit range and
# the duration in sync with the uploaded strip.
params['frames'] = strip.frame_final_duration
params.setdefault('custom_data', {}).update({
'frame_in': strip.frame_final_start,
'frame_out': strip.frame_final_end - 1,
})
if params:
tracker.update_data(shot, **params)