Export Csv

This commit is contained in:
Christophe SEUX
2023-04-21 21:44:05 +02:00
parent 299c240385
commit 02785f9ec0
5 changed files with 363 additions and 113 deletions
+208 -90
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):
@@ -118,11 +226,12 @@ class VSETB_OT_upload_to_tracker(Operator):
bl_description = "Upload selected strip to tracker"
bl_options = {"REGISTER", "UNDO"}
task: EnumProperty(items=get_task_type_items)
status: EnumProperty(items=get_task_status_items)
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):
@@ -502,12 +594,14 @@ class VSETB_OT_load_projects(Operator):
for asset_type_data in tracker.get_asset_types(project_data):
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,