Source code for cgl.plugins.otio.tools.summary

import sys
import os
import json
import traceback
from PySide6 import QtCore, QtWidgets

from cgl.plugins.otio.tools import extract_shots


[docs] class StoryBoardSummary(QtWidgets.QDialog): def __init__(self, timeline, shot_dict, parent=None): super(StoryBoardSummary, self).__init__(parent) self.setWindowFlag(QtCore.Qt.WindowStaysOnTopHint, True) self.result = False self.tree = QtWidgets.QTreeWidget() self.tree.setHeaderLabels(["Shot", "Path", "Relative Frame", "Absolute Frame"]) self.tree.setAlternatingRowColors(True) for name, psd_list in shot_dict.items(): w = QtWidgets.QTreeWidgetItem(self.tree) w.setText(0, name) for p, start_frame, global_start_frame, duration in psd_list: child = QtWidgets.QTreeWidgetItem(w) child.setText(0, os.path.basename(p)) child.setText(1, p) child.setText(2, str(start_frame)) child.setText(3, str(global_start_frame)) # otioview component self.timeline_view = timeline_widget.Timeline() self.timeline_view.set_timeline(timeline) self.button_box = QtWidgets.QDialogButtonBox( QtWidgets.QDialogButtonBox.Ok | QtWidgets.QDialogButtonBox.Cancel ) self.button_box.accepted.connect(self.accept) self.button_box.rejected.connect(self.close) button_layout = QtWidgets.QHBoxLayout() button_layout.addStretch() button_layout.addWidget(self.button_box) self.splitter = QtWidgets.QSplitter(QtCore.Qt.Vertical) self.splitter.addWidget(self.tree) self.splitter.addWidget(self.timeline_view) layout = QtWidgets.QVBoxLayout() layout.addWidget(self.splitter) layout.addLayout(button_layout) self.setLayout(layout) # Initialize self.resize(900, 500) self.tree.expandAll() col_count = self.tree.columnCount() for i in range(col_count): self.tree.resizeColumnToContents(i)
[docs] def accept(self): self.result = True self.close()
[docs] def confirm_summary(path_to_edit_file): app = QtWidgets.QApplication.instance() w = None if not app: app = QtWidgets.QApplication(sys.argv) try: timeline, shot_dict = extract_shots.simplify_timeline(path_to_edit_file) w = StoryBoardSummary(timeline, shot_dict) w.setWindowTitle("Shot Summary") w.exec() except Exception as e: tb = traceback.format_exc() print(path_to_edit_file) print(tb, e) QtWidgets.QMessageBox.critical( None, "Error!", f"Error reading file\n\n{path_to_edit_file}\n\n{tb}", QtWidgets.QMessageBox.Ok, ) return False return w.result if w else None
[docs] def show_summary_from_msd(path_to_msd, project_root_path): data = {} with open(path_to_msd) as f: data = json.load(f) assert data edit_file_path = None for ext in (".xml", ".aaf"): path = data.get("render_files", {}).get(ext, None) if not path: continue if isinstance(path, list): path = path[0] edit_file_path = os.path.join(project_root_path, path).replace("\\", "/") break assert edit_file_path confirm_summary(edit_file_path)
if __name__ == "__main__": xml_path = r"Z:/Alchemy/jhcs/ttas/VERSIONS/0/000/render/shots/103/s01/SEQ/edt/default/tmakota/000.000/high/MDC_103_MonsterOpposites_RC_251021.xml" # xml_path = sys.argv[1] confirm_summary(xml_path)