Export Csv
This commit is contained in:
+208
-90
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user