Export Csv

pull/5/head
Christophe SEUX 2023-04-21 21:44:05 +02:00
parent 299c240385
commit 02785f9ec0
5 changed files with 363 additions and 113 deletions

View File

@ -5,6 +5,12 @@ import importlib
import json
import re
import time
from pprint import pprint
import csv
from datetime import datetime
import os
import vse_toolbox
from bpy_extras.io_utils import ImportHelper
@ -77,20 +83,122 @@ class VSETB_OT_tracker_connect(Operator):
return {"CANCELLED"}
class VSETB_OT_export_csv(Operator):
bl_idname = "vse_toolbox.export_csv"
bl_label = "Set Scene"
bl_description = "Set Scene for Breakdown"
class VSETB_OT_export_spreadsheet(Operator):
bl_idname = "vse_toolbox.export_spreadsheet"
bl_label = "Export Spreadsheet"
bl_description = "Export Shot data in a table as a csv or an xlsl"
bl_options = {"REGISTER", "UNDO"}
format : EnumProperty(items=[(i, i, '') for i in ('CSV', 'XLSL')])
separator : StringProperty(default='\\n')
delimiter : StringProperty(default=';')
export_path : StringProperty(default='//export')
@classmethod
def poll(cls, context):
return True
settings = get_scene_settings()
return settings.active_project
def invoke(self, context, event):
settings = get_scene_settings()
project = settings.active_project
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
row = layout.row()
row.template_list("VSETB_UL_spreadsheet", "spreadsheet", project, "spreadsheet", project, "spreadsheet_index", rows=8)
col_tool = row.column(align=True)
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'
col = layout.column()
col.use_property_split = True
col.prop(self, "separator", expand=True, text='Separator')
row = col.row(align=True)
row.prop(self, "format", expand=True, text='Format')
if self.format == 'CSV':
col.prop(self, "delimiter", expand=True, text='Delimiter')
col.prop(self, 'export_path')
def execute(self, context):
self.report({'ERROR'}, f'Export not implemented yet.')
#self.report({'ERROR'}, f'Export not implemented yet.')
prefs = get_addon_prefs()
settings = get_scene_settings()
project = settings.active_project
episode = settings.active_episode
return {"CANCELLED"}
cells = [cell for cell in project.spreadsheet if cell.enabled]
rows = []
# Header
rows.append([cell.export_name for cell in cells])
for strip in get_strips('Shots'):
row = []
for cell in cells:
if cell.is_metadata:
row += [getattr(strip.vsetb_strip_settings.metadata, cell.field_name)]
elif cell.field_name == 'EPISODE':
row += [settings.active_episode.name]
elif cell.field_name == 'SEQUENCE':
row += [get_strip_sequence_name(strip)]
elif cell.field_name == 'SHOT':
row += [strip.name]
elif cell.field_name == 'DESCRIPTION':
row += [strip.vsetb_strip_settings.description]
elif cell.field_name == 'FRAMES':
row += [strip.frame_final_duration]
rows.append(row)
#print(rows)
export_path = Path(os.path.abspath(bpy.path.abspath(self.export_path)))
export_name = export_path.name
if export_path.suffix or export_name.endswith('{ext}'):
export_path = export_path.parent
else: # It's a directory
if project.type == 'TVSHOW':
export_name = '{date}_{project}_{episode}_{tracker}_shots.{ext}'
else:
export_name = '{date}_{project}_{tracker}_shots.{ext}'
date = datetime.now().strftime('%Y_%m_%d')
project_name = project.name.replace(' ', '_').lower()
episode_name = episode.name.replace(' ', '_').lower() if episode else 'episode'
ext = self.format.lower()
export_name = export_name.format(date=date, project=project_name,
episode=episode_name, tracker=settings.tracker_name.lower(), ext=ext)
export_path = export_path / export_name
#2023_04_11_kitsu_boris_ep01_shots
export_path.parent.mkdir(parents=True, exist_ok=True)
print('Writing .csv file to', export_path)
with open(str(export_path), 'w', newline='\n', encoding='utf-8') as f:
writer = csv.writer(f)
for row in rows:
writer.writerow(row)
#if show_in_explorer:
# open_file(filepath, select=True)
return {"FINISHED"}
def get_task_status_items(self, context):
@ -121,8 +229,9 @@ class VSETB_OT_upload_to_tracker(Operator):
task : EnumProperty(items=get_task_type_items)
status : EnumProperty(items=get_task_status_items)
comment : StringProperty()
add_preview : BoolProperty(default=False)
add_preview : BoolProperty(default=True)
preview_mode : EnumProperty(items=[(m, m.title().replace('_', ' '), '') for m in ('ONLY_NEW', 'REPLACE', 'ADD')])
set_main_preview : BoolProperty(default=True)
casting : BoolProperty(default=True)
custom_data : BoolProperty(default=True)
@ -174,10 +283,8 @@ class VSETB_OT_upload_to_tracker(Operator):
sequence_name = get_strip_sequence_name(strip)
shot_name = strip.name
sequence = tracker.get_sequence(sequence_name)
metadata = strip.vsetb_strip_settings.metadata.to_dict()
print(metadata)
#print(metadata)
if not sequence:
self.report({"INFO"}, f'Create sequence {sequence_name} in Kitsu')
@ -198,49 +305,33 @@ class VSETB_OT_upload_to_tracker(Operator):
preview = None
if self.add_preview:
preview = Path(get_strip_render_path(strip, project.render_template))
#print(preview)
if not preview.exists():
preview = None
elif task['last_comment'].get('previews'):
elif task.get('last_comment') and task['last_comment']['previews']:
if self.preview_mode == 'REPLACE':
tracker.remove_comment(task['last_comment'])
elif self.preview_mode == 'ONLY_NEW':
preview = None
if status != 'CURRENT' or preview:
tracker.new_comment(task, comment=self.comment, status=status, preview=preview)
#print(f'{preview=}')
#print(f'{status=}')
if status or preview:
tracker.new_comment(task, comment=self.comment, status=status, preview=preview, set_main_preview=self.set_main_preview)
if self.custom_data:
tracker.update_data(shot, strip.vsetb_strip_settings.metadata.to_dict())
metadata = strip.vsetb_strip_settings.metadata.to_dict()
description = strip.vsetb_strip_settings.description
tracker.update_data(shot, metadata, frames=strip.frame_final_duration, description=description)
if self.casting:
casting = [{'asset_id': a.id, 'nb_occurences': a.instance} for a in strip.vsetb_strip_settings.casting]
tracker.update_casting(shot, casting)
return {"FINISHED"}
# if add_to_kitsu:
# shot_name = T['shot_tracker_name'].fields['shot'].format(data['shot'])
# seq_name = T['sequence_tracker_name'].fields['sequence'].format(data['sequence'])
# sequence = p.sequences.add(seq_name)
# shot = sequence.shots.add(shot_name)
# animatic_task = shot.tasks.add('animatic')
# animatic_task.comments.new(
# comment=f'Reel edit v{version:03d}',
# status='done',
# preview=movie_output,
# set_main_preview=True
# )
# shot_data = {
# 'fps': int(FPS),
# 'frame_in': strip.frame_final_start,
# 'frame_out': strip.frame_final_end-1,
# 'nb_frames': strip.frame_final_duration
# }
# shot.update_data(shot_data)
# return {"CANCELLED"}
class VSETB_OT_auto_select_files(Operator):
bl_idname = "import.auto_select_files"
@ -485,9 +576,10 @@ class VSETB_OT_load_projects(Operator):
episode.id = episode_data['id']
for metadata_data in tracker.get_shots_metadata(project_data):
#print(metadata_data)
pprint(metadata_data)
metadata_type = project.metadata_types.add()
metadata_type.name = metadata_data['field_name']
metadata_type.name = metadata_data['name']
metadata_type.field_name = metadata_data['field_name']
metadata_type['choices'] = metadata_data['choices']
for status_data in tracker.get_task_statuses(project_data):
@ -503,11 +595,13 @@ class VSETB_OT_load_projects(Operator):
asset_type = project.asset_types.add()
asset_type.name = asset_type_data['name']
project.set_spreadsheet()
for project in settings.projects:
print(project.name, project.name.replace(' ', '_').upper(), old_project_name)
#print(project.name, project.name.replace(' ', '_').upper(), old_project_name)
if project.name.replace(' ', '_').upper() == old_project_name:
print('Restore Project Name')
#print('Restore Project Name')
settings.project_name = project.name
#else:
# print('Could Not restore Project Name')
@ -545,8 +639,8 @@ class VSETB_OT_new_episode(Operator):
episode_name = settings.episode_template.format(index=int(self.episode_name))
print(self.episode_name)
print('episode_name: ', episode_name)
#print(self.episode_name)
#print('episode_name: ', episode_name)
episode = tracker.get_episode(episode_name)
if episode:
@ -805,11 +899,11 @@ class VSETB_OT_casting_remove(Operator):
class VSETB_OT_casting_move(Operator):
bl_idname = "vse_toolbox.casting_move"
bl_label = "Casting Actions"
bl_description = "Actions to Add, Remove, Move casting items"
bl_label = "Move Casting items"
bl_description = "Move Casting items"
bl_options = {"REGISTER", "UNDO"}
action: EnumProperty(
direction: EnumProperty(
items=(
('UP', "Up", ""),
('DOWN', "Down", ""),
@ -824,7 +918,7 @@ class VSETB_OT_casting_move(Operator):
if active_strip:
return True
def invoke(self, context, event):
def execute(self, context):
scn = context.scene
strip_settings = get_strip_settings()
@ -835,12 +929,12 @@ class VSETB_OT_casting_move(Operator):
except IndexError:
pass
else:
if self.action == 'DOWN' and idx < len(strip_settings.casting) - 1:
if self.direction == 'DOWN' and idx < len(strip_settings.casting) - 1:
item_next = strip_settings.casting[idx+1].name
strip_settings.casting.move(idx, idx+1)
strip_settings.casting_index += 1
elif self.action == 'UP' and idx >= 1:
elif self.direction == 'UP' and idx >= 1:
item_prev = strip_settings.casting[idx-1].name
strip_settings.casting.move(idx, idx-1)
strip_settings.casting_index -= 1
@ -851,9 +945,45 @@ class VSETB_OT_casting_move(Operator):
return {"FINISHED"}
class VSETB_OT_spreadsheet_move(Operator):
bl_idname = "vse_toolbox.spreadsheet_move"
bl_label = "Move Spreadsheet items"
bl_description = "Move Spreadsheet items"
bl_options = {"REGISTER", "UNDO"}
direction: EnumProperty(
items=(
('UP', "Up", ""),
('DOWN', "Down", ""),
)
)
def execute(self, context):
scn = context.scene
project = get_scene_settings().active_project
idx = project.spreadsheet_index
try:
item = project.spreadsheet[idx]
except IndexError:
pass
else:
if self.direction == 'DOWN' and idx < len(project.spreadsheet) - 1:
item_next = project.spreadsheet[idx+1].name
project.spreadsheet.move(idx, idx+1)
project.spreadsheet_index += 1
elif self.direction == 'UP' and idx >= 1:
item_prev = project.spreadsheet[idx-1].name
project.spreadsheet.move(idx, idx-1)
project.spreadsheet_index -= 1
return {"FINISHED"}
class VSETB_OT_copy_casting(Operator):
bl_idname = "vse_toolbox.copy_casting"
bl_label = "Casting Actions"
bl_label = "Copy Casting"
bl_description = "Copy Casting from active strip"
bl_options = {"REGISTER", "UNDO"}
@ -879,8 +1009,8 @@ class VSETB_OT_copy_casting(Operator):
class VSETB_OT_paste_casting(Operator):
bl_idname = "vse_toolbox.paste_casting"
bl_label = "Casting Actions"
bl_description = "Copy Casting from active strip"
bl_label = "Paste Casting"
bl_description = "Paste Casting to active strip"
bl_options = {"REGISTER", "UNDO"}
@classmethod
@ -932,50 +1062,37 @@ class VSETB_OT_set_stamps(Operator):
bpy.ops.sequencer.select_all(action='DESELECT')
crop_x = int(scn.render.resolution_x * 0.33)
crop_y = int(scn.render.resolution_y * 0.95)
crop_x = int(scn.render.resolution_x * 0.4)
crop_max_y = int(scn.render.resolution_y * 0.96)
crop_min_y = int(scn.render.resolution_y * 0.01)
stamp_params = dict(start=scn.frame_start, end=scn.frame_end,
font_size=22, y=0.015, box_margin=0.005, select=True, box_color=(0, 0, 0, 0.5))
# Project Name
project_strip_stamp = new_text_strip(
'project_name_stamp', channel=1, start=scn.frame_start, end=scn.frame_end,
text=settings.active_project.name, font_size=24,
x=0.01, y=0.01, align_x='LEFT', align_y='BOTTOM', select=True,
box_color=(0, 0, 0, 0.5), box_margin=0.005,
)
project_strip_stamp = new_text_strip('project_name_stamp', channel=1, **stamp_params,
text=settings.active_project.name, x=0.01, align_x='LEFT', align_y='BOTTOM')
project_strip_stamp.crop.max_x = crop_x * 2
project_strip_stamp.crop.max_y = crop_y
project_strip_stamp.crop.max_y = crop_max_y
project_strip_stamp.crop.min_y = crop_min_y
# Shot Name
shot_strip_stamp = new_text_strip(
f'shot_name_stamp', channel=2, start=scn.frame_start, end=scn.frame_end,
text='{active_shot_name}', font_size=24,
y=0.01, align_y='BOTTOM', select=True,
box_color=(0, 0, 0, 0.5), box_margin=0.005,
)
shot_strip_stamp = new_text_strip('shot_name_stamp', channel=2, **stamp_params,
text='{active_shot_name}', align_y='BOTTOM')
shot_strip_stamp.crop.min_x = crop_x
shot_strip_stamp.crop.max_x = crop_x
shot_strip_stamp.crop.max_y = crop_y
shot_strip_stamp.crop.max_y = crop_max_y
shot_strip_stamp.crop.min_y = crop_min_y
# Frame Range
frame_strip_stamp = new_text_strip(
'frame_range_stamp', channel=3, start=scn.frame_start, end=scn.frame_end,
text='{active_shot_frame} / {active_shot_duration}', font_size=24,
x=0.99, y=0.01, align_x='RIGHT', align_y='BOTTOM', select=True,
box_color=(0, 0, 0, 0.5), box_margin=0.005,
)
frame_strip_stamp = new_text_strip('frame_range_stamp', channel=3, **stamp_params,
text='{active_shot_frame} / {active_shot_duration}', x=0.99, align_x='RIGHT', align_y='BOTTOM')
frame_strip_stamp.crop.min_x = int(scn.render.resolution_x * 0.66)
frame_strip_stamp.crop.max_y = crop_y
# for shot_strip in get_strips('Shots'):
# # Shot Name
# shot_strip_stamp = new_text_strip(
# f'{shot_strip.name}_stamp', channel=3, start=shot_strip.frame_final_start, end=shot_strip.frame_final_end,
# text=shot_strip.name, font_size=24,
# y=0.01, align_y='BOTTOM', select=True,
# box_color=(0, 0, 0, 0.35), box_margin=0.005,
# )
frame_strip_stamp.crop.min_x = crop_x *2
frame_strip_stamp.crop.max_y = crop_max_y
frame_strip_stamp.crop.min_y = crop_min_y
bpy.ops.sequencer.meta_make()
stamps_strip = context.active_sequence_strip
@ -994,9 +1111,10 @@ classes = (
VSETB_OT_casting_add,
VSETB_OT_casting_remove,
VSETB_OT_casting_move,
VSETB_OT_spreadsheet_move,
VSETB_OT_copy_casting,
VSETB_OT_paste_casting,
VSETB_OT_export_csv,
VSETB_OT_export_spreadsheet,
VSETB_OT_import_files,
VSETB_OT_load_assets,
VSETB_OT_load_projects,

View File

@ -170,7 +170,7 @@ class VSETB_PT_exports(VSETB_main, Panel):
bl_options = {'DEFAULT_CLOSED'}
def draw_header_preset(self, context):
self.layout.operator('vse_toolbox.export_csv', icon='EXPORT', text='', emboss=False)
self.layout.operator('vse_toolbox.export_spreadsheet', icon='EXPORT', text='', emboss=False)
def draw(self, context):
prefs = get_addon_prefs()
@ -183,7 +183,7 @@ class VSETB_PT_exports(VSETB_main, Panel):
tracker_label = settings.tracker_name.title().replace('_', ' ')
layout.operator('vse_toolbox.upload_to_tracker', text=f'Upload to {tracker_label}', icon='EXPORT')
layout.operator('vse_toolbox.export_csv', text='Export csv', icon='SPREADSHEET')
layout.operator('vse_toolbox.export_spreadsheet', text='Export Spreadsheet', icon='SPREADSHEET')
class VSETB_PT_casting(VSETB_main, Panel):
@ -232,8 +232,8 @@ class VSETB_PT_casting(VSETB_main, Panel):
col_tool.operator('vse_toolbox.casting_add', icon='ADD', text="")
col_tool.operator('vse_toolbox.casting_remove', icon='REMOVE', text="")
col_tool.separator()
col_tool.operator('vse_toolbox.casting_move', icon='TRIA_UP', text="").action = 'UP'
col_tool.operator('vse_toolbox.casting_move', icon='TRIA_DOWN', text="").action = 'DOWN'
col_tool.operator('vse_toolbox.casting_move', icon='TRIA_UP', text="").direction = 'UP'
col_tool.operator('vse_toolbox.casting_move', icon='TRIA_DOWN', text="").direction = 'DOWN'
col_tool.separator()
col_tool.operator('vse_toolbox.copy_casting', icon='COPYDOWN', text="")
col_tool.operator('vse_toolbox.paste_casting', icon='PASTEDOWN', text="")
@ -260,6 +260,8 @@ class VSETB_PT_metadata(VSETB_main, Panel):
if not project:
return
layout.prop(strip_settings, 'description', text='DESCRIPTION')
#col = layout.column()
for key in strip_settings.metadata.__annotations__.keys():
layout.prop(strip_settings.metadata, key, text=key.upper())

View File

@ -57,6 +57,28 @@ def get_tracker_items(self, context):
return [(norm_str(a.__name__, format=str.upper), a.__name__, "", i) for i, a in enumerate(TRACKERS)]
class CollectionPropertyGroup(PropertyGroup):
def __iter__(self):
return (v for v in self.values())
def props(self):
return [p for p in self.bl_rna.properties if p.identifier not in ('rna_type', 'name')]
def keys(self):
return [k for k in self.bl_rna.properties.keys() if k not in ('rna_type', 'name')]
def values(self):
return [getattr(self, k) for k in self.keys()]
def items(self):
return self.to_dict().items()
def to_dict(self, use_name=True):
if use_name:
return {p.name: getattr(self, p.identifier) for p in self.props()}
else:
return {k: getattr(self, k) for k in self.keys()}
class Asset(PropertyGroup):
name : StringProperty(default='')
id : StringProperty(default='')
@ -80,17 +102,19 @@ class AssetCasting(PropertyGroup):
id : StringProperty(default='')
instance : IntProperty(default=1)
def __iter__(self):
return (getattr(self, p) for p in self.bl_rna.properties.keys() if p not in ('rna_type', 'name'))
@property
def asset(self):
settings = get_scene_settings()
project = settings.active_project
return project.assets.get(self.id)
def to_dict(self):
return {k: v for k,v in self.items()}
class SpreadsheetCell(PropertyGroup):
export_name : StringProperty()
enabled : BoolProperty(default=True)
is_metadata : BoolProperty(default=False)
field_name : StringProperty()
#type : EnumProperty(items=[(t, t, "")] for t in ('METADATA', 'STRIP_DATA'))
class AssetType(PropertyGroup):
@ -100,6 +124,7 @@ class AssetType(PropertyGroup):
class MetadataType(PropertyGroup):
choices = []
choice : EnumProperty(items=lambda s, c: [(c, c.replace(' ', '_').upper(), '') for c in s['choices']])
field_name : bpy.props.StringProperty()
class TaskType(PropertyGroup):
@ -110,11 +135,9 @@ class TaskStatus(PropertyGroup):
__annotations__ = {}
class Metadata(PropertyGroup):
class Metadata(CollectionPropertyGroup):
__annotations__ = {}
def to_dict(self):
return {p.name: getattr(self, p.identifier) for p in self.bl_rna.properties.keys() if p.name != 'RNA'}
class Episode(PropertyGroup):
id : StringProperty(default='')
@ -157,8 +180,30 @@ class Project(PropertyGroup):
task_types : CollectionProperty(type=TaskType)
task_statuses : CollectionProperty(type=TaskStatus)
spreadsheet : CollectionProperty(type=SpreadsheetCell)
spreadsheet_index : IntProperty(name='Spreadsheet Index', default=0)
type : StringProperty()
def set_spreadsheet(self):
cell_names = ['Sequence', 'Shot', 'Frames', 'Description']
if self.type == 'TVSHOW':
cell_names.insert(0, 'Episode')
for cell_name in cell_names:
cell = self.spreadsheet.add()
cell.name = cell_name
cell.export_name = cell_name
cell.field_name = cell_name.upper()
for metadata_type in self.metadata_types:
cell = self.spreadsheet.add()
cell.name = metadata_type.name
cell.export_name = metadata_type.name
cell.field_name = metadata_type.field_name
cell.is_metadata = True
def set_strip_metadata(self):
# Clear Metadatas
@ -167,16 +212,17 @@ class Project(PropertyGroup):
delattr(Metadata, attr)
del Metadata.__annotations__[attr]
for metadata_type in self.metadata_types:
prop_name = metadata_type.name
if metadata_type.get('choices'):
prop = bpy.props.EnumProperty(items=[(c, c.replace(' ', '_').upper(), '') for c in ['/'] + metadata_type['choices']])
else:
prop = bpy.props.StringProperty()
field_name = metadata_type.field_name
name = metadata_type.name
Metadata.__annotations__[prop_name] = prop
setattr(Metadata, prop_name, prop)
if metadata_type.get('choices'):
prop = bpy.props.EnumProperty(items=[(c, c, '') for c in ['/'] + metadata_type['choices']], name=name)
else:
prop = bpy.props.StringProperty(name=name)
Metadata.__annotations__[field_name] = prop
setattr(Metadata, field_name, prop)
class VSETB_UL_casting(UIList):
@ -242,6 +288,34 @@ class VSETB_UL_casting(UIList):
return filtered, ordered
class VSETB_UL_spreadsheet(UIList):
def draw_item(self, context, layout, data, item, icon, active_data,
active_propname, index):
settings = get_scene_settings()
project = settings.active_project
layout.use_property_split = True
layout.use_property_decorate = False
row = layout.row(align=True)
row.alignment = 'LEFT'
row.prop(item, 'enabled', text='')
layout.label(text=item.name)
layout.prop(item, 'export_name', text='')
def draw_filter(self, context, layout):
row = layout.row()
subrow = row.row(align=True)
subrow.prop(self, "filter_name", text="")
subrow.prop(self, "use_filter_invert", text="", icon='ARROW_LEFTRIGHT')
subrow.separator()
subrow.prop(self, "order_by_type", text="Order by Type", icon='MESH_DATA')
class VSETB_PGT_scene_settings(PropertyGroup):
projects : CollectionProperty(type=Project)
@ -287,11 +361,13 @@ class VSETB_PGT_strip_settings(PropertyGroup):
casting_index : IntProperty(name='Casting Index', default=0)
source_name : StringProperty(name='')
metadata : PointerProperty(type=Metadata)
description : StringProperty()
classes=(
Asset,
AssetCasting,
SpreadsheetCell,
AssetType,
TaskStatus,
Episode,
@ -299,6 +375,7 @@ classes=(
MetadataType,
TaskType,
Project,
VSETB_UL_spreadsheet,
VSETB_UL_casting,
VSETB_PGT_scene_settings,
VSETB_PGT_strip_settings,
@ -313,6 +390,7 @@ def load_handler(dummy):
settings = get_scene_settings()
if settings.active_project:
settings.active_project.set_strip_metadata()
#settings.active_project.set_spreadsheet()
os.environ['TRACKER_PROJECT_ID'] = settings.active_project.id

View File

@ -6,6 +6,7 @@ import urllib3
import traceback
import time
import uuid
from pprint import pprint
from bpy.props import PointerProperty, StringProperty
from pathlib import Path
@ -176,6 +177,20 @@ class Kitsu(Tracker):
return gazu.shot.get_shot_by_name(sequence, shot)
def get_asset(self, asset, asset_type=None, project=None):
#print('get_asset', "name", name, 'asset_type', asset_type)
asset_id = self.get_id(asset)
if asset_id:
return asset_id
project = self.get_project(project)
asset_type = self.get_id(asset_type)
asset = gazu.asset.get_asset_by_name(project, asset, asset_type)
return asset
def get_assets(self, project=None):
project = self.get_project(project)
assets = gazu.asset.all_assets_for_project(project)
@ -327,10 +342,41 @@ class Kitsu(Tracker):
else:
entity['data'].update(data)
#pprint(entity)
entity_data = gazu.client.put(f"data/entities/{entity_id}", entity)
return entity_data['data']
def get_casting(self, shot, project=None):
project = self.get_project(project)
project_id = self.get_id(project)
return gazu.casting.get_shot_casting({'id': self.get_id(shot), 'project_id': project_id})
def update_casting(self, shot, casting, clear=True, project=None):
project = self.get_project(project)
shot_id = self.get_id(shot)
norm_casting = []
if clear is False:
norm_casting += self.get_casting(shot, project)
for asset in casting:
if isinstance(asset, dict) and 'asset_id' in asset: # It's an asset instance
asset_id = asset['asset_id']
nb_occurences = asset['nb_occurences']
else: # It's an asset
asset = self.get_asset(asset)
nb_occurences = 1
cast = next((c for c in norm_casting if c['asset_id'] == asset_id), None)
if cast:
cast['nb_occurences'] += 1
else:
norm_casting.append({'asset_id': asset_id, 'nb_occurences': nb_occurences})
return gazu.casting.update_shot_casting(project, shot_id, norm_casting)
def draw_prefs(self, layout):
layout.prop(self, 'url', text='Url')
layout.prop(self, 'login', text='Login')

View File

@ -2,6 +2,7 @@
import re
from pathlib import Path
import os
import bpy
from bpy.app.handlers import persistent
@ -125,12 +126,15 @@ def set_channels():
def get_strip_render_path(strip, template):
scn = bpy.context.scene
return template.format(strip_name=strip.name, ext=Path(scn.render.frame_path()).suffix)
suffix = Path(scn.render.frame_path()).suffix
render_path = template.format(strip_name=strip.name, ext=suffix[1:])
return Path(os.path.abspath(bpy.path.abspath(render_path)))
def render_strips(strips, template):
scn = bpy.context.scene
scene_start = scn.frame_start
scene_end = scn.frame_end
render_path = scn.render.filepath
for strip in strips:
#print(render_template, strip.name, path)
@ -140,7 +144,8 @@ def render_strips(strips, template):
## render animatic
#strip_render_path = render_template.format(strip_name=strip.name, ext=Path(scn.render.frame_path()).suffix)
scn.render.filepath = get_strip_render_path(strip, template)
scn.render.filepath = str(get_strip_render_path(strip, template))
#print(scn.render.filepath)
print(f'Render Strip to {scn.render.filepath}')
#bpy.ops.render.render(animation=True)
@ -149,6 +154,7 @@ def render_strips(strips, template):
scn.frame_start = scene_start
scn.frame_end = scene_end
scn.render.filepath = render_path
def import_edit(filepath, adapter="cmx_3600", clean_sequencer=False):
import opentimelineio as otio