Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Resolve: loading editorial package as timeline #515

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
from pathlib import Path

from ayon_core.pipeline import (
load,
get_representation_path,
)

from ayon_core.hosts.resolve.api import lib


class LoadEditorialPackage(load.LoaderPlugin):
"""Load editorial package to timeline.

Loading timeline from OTIO file included media sources
and timeline structure.
"""

product_types = {"editorial_pkg"}

representations = {"*"}
extensions = {"otio"}

label = "Load as Timeline"
order = -10
icon = "ei.align-left"
color = "orange"

def load(self, context, name, namespace, data):
files = get_representation_path(context["representation"])

search_folder_path = Path(files).parent / "resources"

project = lib.get_current_project()
media_pool = project.GetMediaPool()

# create versioned bin for editorial package
version_name = context["version"]["name"]
bin_name = f"{name}_{version_name}"
lib.create_bin(bin_name)

import_options = {
"timelineName": "Editorial Package Timeline",
"importSourceClips": True,
"sourceClipsPath": search_folder_path.as_posix(),
}

timeline = media_pool.ImportTimelineFromFile(files, import_options)
print("Timeline imported: ", timeline)

def update(self, container, context):
# TODO: implement update method in future
pass
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,13 @@ class EditorialPackageCreator(TrayPublishCreator):
"""Creates instance for OTIO file from published folder.

Folder contains OTIO file and exported .mov files. Process should publish
whole folder as single `editorial_pckg` product type and (possibly) convert
whole folder as single `editorial_pkg` product type and (possibly) convert
.mov files into different format and copy them into `publish` `resources`
subfolder.
"""
identifier = "editorial_pckg"
identifier = "editorial_pkg"
label = "Editorial package"
product_type = "editorial_pckg"
product_type = "editorial_pkg"
description = "Publish folder with OTIO file and resources"

# Position batch creator after simple creators
Expand Down Expand Up @@ -89,8 +89,8 @@ def get_instance_attr_defs(self):
def get_detail_description(self):
return """# Publish folder with OTIO file and video clips

Folder contains OTIO file and exported .mov files. Process should
publish whole folder as single `editorial_pckg` product type and
(possibly) convert .mov files into different format and copy them into
Folder contains OTIO file and exported .mov files. Process should
publish whole folder as single `editorial_pkg` product type and
(possibly) convert .mov files into different format and copy them into
`publish` `resources` subfolder.
"""
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
"""Produces instance.data["editorial_pckg"] data used during integration.
"""Produces instance.data["editorial_pkg"] data used during integration.

Requires:
instance.data["creator_attributes"]["path"] - from creator

Provides:
instance -> editorial_pckg (dict):
instance -> editorial_pkg (dict):
folder_path (str)
otio_path (str) - from dragged folder
resource_paths (list)
Expand All @@ -24,7 +24,7 @@ class CollectEditorialPackage(pyblish.api.InstancePlugin):
order = pyblish.api.CollectorOrder - 0.1

hosts = ["traypublisher"]
families = ["editorial_pckg"]
families = ["editorial_pkg"]

def process(self, instance):
folder_path = instance.data["creator_attributes"]["folder_path"]
Expand All @@ -34,14 +34,14 @@ def process(self, instance):
))
return

instance.data["editorial_pckg"] = {}
instance.data["editorial_pckg"]["folder_path"] = folder_path
instance.data["editorial_pkg"] = {}
instance.data["editorial_pkg"]["folder_path"] = folder_path

otio_path, resource_paths = (
self._get_otio_and_resource_paths(folder_path))

instance.data["editorial_pckg"]["otio_path"] = otio_path
instance.data["editorial_pckg"]["resource_paths"] = resource_paths
instance.data["editorial_pkg"]["otio_path"] = otio_path
instance.data["editorial_pkg"]["resource_paths"] = resource_paths

def _get_otio_and_resource_paths(self, folder_path):
otio_path = None
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,27 +20,27 @@ class ExtractEditorialPckgConversion(publish.Extractor):
label = "Extract Editorial Package"
order = pyblish.api.ExtractorOrder - 0.45
hosts = ["traypublisher"]
families = ["editorial_pckg"]
families = ["editorial_pkg"]

def process(self, instance):
editorial_pckg_data = instance.data.get("editorial_pckg")
editorial_pkg_data = instance.data.get("editorial_pkg")

otio_path = editorial_pckg_data["otio_path"]
otio_path = editorial_pkg_data["otio_path"]
otio_basename = os.path.basename(otio_path)
staging_dir = self.staging_dir(instance)

editorial_pckg_repre = {
'name': "editorial_pckg",
editorial_pkg_repre = {
'name': "editorial_pkg",
'ext': "otio",
'files': otio_basename,
"stagingDir": staging_dir,
}
otio_staging_path = os.path.join(staging_dir, otio_basename)

instance.data["representations"].append(editorial_pckg_repre)
instance.data["representations"].append(editorial_pkg_repre)

publish_resource_folder = self._get_publish_resource_folder(instance)
resource_paths = editorial_pckg_data["resource_paths"]
resource_paths = editorial_pkg_data["resource_paths"]
transfers = self._get_transfers(resource_paths,
publish_resource_folder)

Expand All @@ -61,13 +61,13 @@ def process(self, instance):
source_to_rootless = self._get_resource_path_mapping(instance,
transfers)

otio_data = editorial_pckg_data["otio_data"]
otio_data = editorial_pkg_data["otio_data"]
otio_data = self._replace_target_urls(otio_data, source_to_rootless)

opentimelineio.adapters.write_to_file(otio_data, otio_staging_path)

self.log.info("Added Editorial Package representation: {}".format(
editorial_pckg_repre))
editorial_pkg_repre))

def _get_publish_resource_folder(self, instance):
"""Calculates publish folder and create it."""
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import os
import opentimelineio
from opentimelineio.exceptions import UnsupportedSchemaError


import pyblish.api
from ayon_core.pipeline import PublishValidationError
Expand All @@ -17,26 +19,35 @@ class ValidateEditorialPackage(pyblish.api.InstancePlugin):
order = pyblish.api.ValidatorOrder - 0.49

hosts = ["traypublisher"]
families = ["editorial_pckg"]
families = ["editorial_pkg"]

def process(self, instance):
editorial_pckg_data = instance.data.get("editorial_pckg")
if not editorial_pckg_data:
editorial_pkg_data = instance.data.get("editorial_pkg")
if not editorial_pkg_data:
raise PublishValidationError("Editorial package not collected")

folder_path = editorial_pckg_data["folder_path"]
folder_path = editorial_pkg_data["folder_path"]

otio_path = editorial_pckg_data["otio_path"]
otio_path = editorial_pkg_data["otio_path"]
if not otio_path:
raise PublishValidationError(
f"Folder {folder_path} missing otio file")

resource_paths = editorial_pckg_data["resource_paths"]
resource_paths = editorial_pkg_data["resource_paths"]

resource_file_names = {os.path.basename(path)
for path in resource_paths}

otio_data = opentimelineio.adapters.read_from_file(otio_path)
try:
otio_data = opentimelineio.adapters.read_from_file(otio_path)
except UnsupportedSchemaError as e:
raise PublishValidationError(
f"Unsupported schema in otio file '{otio_path}'."
"Version of your OpenTimelineIO library is too old."
"Please update it to the latest version."
f"Current version is '{opentimelineio.__version__}', "
"but required is at least 0.16.0."
) from e

target_urls = self._get_all_target_urls(otio_data)
missing_files = set()
Expand All @@ -50,7 +61,7 @@ def process(self, instance):
f"Otio file contains missing files `{missing_files}`.\n\n"
f"Please add them to `{folder_path}` and republish.")

instance.data["editorial_pckg"]["otio_data"] = otio_data
instance.data["editorial_pkg"]["otio_data"] = otio_data

def _get_all_target_urls(self, otio_data):
target_urls = []
Expand Down
2 changes: 1 addition & 1 deletion server_addon/traypublisher/package.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
name = "traypublisher"
title = "TrayPublisher"
version = "0.2.0"
version = "0.2.1"

client_dir = "ayon_traypublisher"

Expand Down