Skip to content
This repository has been archived by the owner on Sep 20, 2024. It is now read-only.

Commit

Permalink
feat(global): rework family filtering for hiero editorial
Browse files Browse the repository at this point in the history
  • Loading branch information
jakubjezek001 committed Nov 18, 2020
1 parent f043633 commit 2c2e434
Show file tree
Hide file tree
Showing 5 changed files with 578 additions and 1 deletion.
1 change: 1 addition & 0 deletions pype/plugins/ftrack/publish/integrate_ftrack_instances.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ class IntegrateFtrackInstance(pyblish.api.InstancePlugin):
'nukescript': 'comp',
'write': 'render',
'review': 'mov',
'clip': 'mov',
'plate': 'img',
'audio': 'audio',
'workfile': 'scene',
Expand Down
3 changes: 2 additions & 1 deletion pype/plugins/global/publish/integrate_new.py
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,8 @@ def process(self, instance):
self.integrated_file_sizes = {}
if [ef for ef in self.exclude_families
if instance.data["family"] in ef]:
return
if "hiero" not in pyblish.api.registered_hosts():
return

try:
self.register(instance)
Expand Down
56 changes: 56 additions & 0 deletions pype/plugins/hiero/publish/collect_assetbuilds.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
from pyblish import api
from avalon import io


class CollectAssetBuilds(api.ContextPlugin):
"""Collect asset from tags.
Tag is expected to have name of the asset and metadata:
{
"family": "assetbuild"
}
"""

# Run just after CollectClip
order = api.CollectorOrder + 0.02
label = "Collect AssetBuilds"
hosts = ["hiero"]

def process(self, context):
asset_builds = {}
for asset in io.find({"type": "asset"}):
if asset["data"]["entityType"] == "AssetBuild":
self.log.debug("Found \"{}\" in database.".format(asset))
asset_builds[asset["name"]] = asset

for instance in context:
if instance.data["family"] != "clip":
continue

# Exclude non-tagged instances.
tagged = False
asset_names = []
for tag in instance.data["tags"]:
family = dict(tag["metadata"]).get("tag.family", "")
if family.lower() == "assetbuild":
asset_names.append(tag["name"])
tagged = True

if not tagged:
self.log.debug(
"Skipping \"{}\" because its not tagged with "
"\"assetbuild\"".format(instance)
)
continue

# Collect asset builds.
data = {"assetbuilds": []}
for name in asset_names:
data["assetbuilds"].append(
asset_builds[name]
)
self.log.debug(
"Found asset builds: {}".format(data["assetbuilds"])
)

instance.data.update(data)
259 changes: 259 additions & 0 deletions pype/plugins/hiero/publish/collect_review.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,259 @@
from pyblish import api
import os
import re
import clique


class CollectReview(api.InstancePlugin):
"""Collect review from tags.
Tag is expected to have metadata:
{
"family": "review"
"track": "trackName"
}
"""

# Run just before CollectSubsets
order = api.CollectorOrder + 0.1022
label = "Collect Review"
hosts = ["hiero"]
families = ["plate"]

def process(self, instance):
is_sequence = instance.data["isSequence"]

# Exclude non-tagged instances.
tagged = False
for tag in instance.data["tags"]:
family = dict(tag["metadata"]).get("tag.family", "")
if family.lower() == "review":
tagged = True
track = dict(tag["metadata"]).get("tag.track")
break

if not tagged:
self.log.debug(
"Skipping \"{}\" because its not tagged with "
"\"review\"".format(instance)
)
return

if not track:
self.log.debug((
"Skipping \"{}\" because tag is not having"
"`track` in metadata"
).format(instance))
return

# add to representations
if not instance.data.get("representations"):
instance.data["representations"] = list()

if track in instance.data["track"]:
self.log.debug("Review will work on `subset`: {}".format(
instance.data["subset"]))

# change families
instance.data["family"] = "plate"
instance.data["families"] = ["review", "ftrack"]

self.version_data(instance)
self.create_thumbnail(instance)

rev_inst = instance

else:
self.log.debug("Track item on plateMain")
rev_inst = None
for inst in instance.context[:]:
if inst.data["track"] != track:
continue

if inst.data["item"].name() != instance.data["item"].name():
continue

rev_inst = inst
break

if rev_inst is None:
raise RuntimeError((
"TrackItem from track name `{}` has to"
"be also selected"
).format(track))

instance.data["families"].append("review")

file_path = rev_inst.data.get("sourcePath")
file_dir = os.path.dirname(file_path)
file = os.path.basename(file_path)
ext = os.path.splitext(file)[-1]

# detect if sequence
if not is_sequence:
# is video file
files = file
else:
files = list()
source_first = instance.data["sourceFirst"]
self.log.debug("_ file: {}".format(file))
spliter, padding = self.detect_sequence(file)
self.log.debug("_ spliter, padding: {}, {}".format(
spliter, padding))
base_name = file.split(spliter)[0]
collection = clique.Collection(base_name, ext, padding, set(range(
int(source_first + rev_inst.data.get("sourceInH")),
int(source_first + rev_inst.data.get("sourceOutH") + 1))))
self.log.debug("_ collection: {}".format(collection))
real_files = os.listdir(file_dir)
for item in collection:
if item not in real_files:
continue
files.append(item)

# change label
instance.data["label"] = "{0} - {1} - ({2})".format(
instance.data['asset'], instance.data["subset"], ext
)

self.log.debug("Instance review: {}".format(rev_inst.data["name"]))

# adding representation for review mov
representation = {
"files": files,
"stagingDir": file_dir,
"frameStart": rev_inst.data.get("sourceIn"),
"frameEnd": rev_inst.data.get("sourceOut"),
"frameStartFtrack": rev_inst.data.get("sourceInH"),
"frameEndFtrack": rev_inst.data.get("sourceOutH"),
"step": 1,
"fps": rev_inst.data.get("fps"),
"name": "review",
"tags": ["review", "ftrackreview"],
"ext": ext[1:]
}

media_duration = instance.data.get("mediaDuration")
clip_duration_h = instance.data.get("clipDurationH")

if media_duration > clip_duration_h:
self.log.debug("Media duration higher: {}".format(
(media_duration - clip_duration_h)))
representation.update({
"frameStart": instance.data.get("sourceInH"),
"frameEnd": instance.data.get("sourceOutH"),
"tags": ["_cut-bigger", "delete"]
})
elif media_duration < clip_duration_h:
self.log.debug("Media duration higher: {}".format(
(media_duration - clip_duration_h)))
representation.update({
"frameStart": instance.data.get("sourceInH"),
"frameEnd": instance.data.get("sourceOutH"),
"tags": ["_cut-smaller", "delete"]
})

instance.data["representations"].append(representation)

self.log.debug("Added representation: {}".format(representation))

def create_thumbnail(self, instance):
item = instance.data["item"]

source_path = instance.data["sourcePath"]
source_file = os.path.basename(source_path)
spliter, padding = self.detect_sequence(source_file)

if spliter:
head, ext = source_file.split(spliter)
else:
head, ext = os.path.splitext(source_file)

# staging dir creation
staging_dir = os.path.dirname(
source_path)

media_duration = instance.data.get("mediaDuration")
clip_duration_h = instance.data.get("clipDurationH")
self.log.debug("__ media_duration: {}".format(media_duration))
self.log.debug("__ clip_duration_h: {}".format(clip_duration_h))

thumb_frame = int(instance.data["sourceIn"] + (
(instance.data["sourceOut"] - instance.data["sourceIn"]) / 2))

thumb_file = "{}thumbnail{}{}".format(head, thumb_frame, ".png")
thumb_path = os.path.join(staging_dir, thumb_file)
self.log.debug("__ thumb_path: {}".format(thumb_path))

self.log.debug("__ thumb_frame: {}".format(thumb_frame))
self.log.debug(
"__ sourceIn: `{}`".format(instance.data["sourceIn"]))

thumbnail = item.thumbnail(thumb_frame).save(
thumb_path,
format='png'
)
self.log.debug(
"__ thumbnail: `{}`, frame: `{}`".format(thumbnail, thumb_frame))

self.log.debug("__ thumbnail: {}".format(thumbnail))
thumb_representation = {
'files': thumb_file,
'stagingDir': staging_dir,
'name': "thumbnail",
'thumbnail': True,
'ext': "png"
}
instance.data["representations"].append(
thumb_representation)

def version_data(self, instance):
item = instance.data["item"]

transfer_data = [
"handleStart", "handleEnd", "sourceIn", "sourceOut",
"frameStart", "frameEnd", "sourceInH", "sourceOutH",
"clipIn", "clipOut", "clipInH", "clipOutH", "asset",
"track"
]

version_data = dict()
# pass data to version
version_data.update({k: instance.data[k] for k in transfer_data})

if 'version' in instance.data:
version_data["version"] = instance.data["version"]

# add to data of representation
version_data.update({
"colorspace": item.sourceMediaColourTransform(),
"families": instance.data["families"],
"subset": instance.data["subset"],
"fps": instance.context.data["fps"]
})
instance.data["versionData"] = version_data

instance.data["source"] = instance.data["sourcePath"]

def detect_sequence(self, file):
""" Get identificating pater for image sequence
Can find file.0001.ext, file.%02d.ext, file.####.ext
Return:
string: any matching sequence patern
int: padding of sequnce numbering
"""
foundall = re.findall(
r"(#+)|(%\d+d)|(?<=[^a-zA-Z0-9])(\d+)(?=\.\w+$)", file)
if foundall:
found = sorted(list(set(foundall[0])))[-1]

if "%" in found:
padding = int(re.findall(r"\d+", found)[-1])
else:
padding = len(found)

return found, padding
else:
return None, None
Loading

0 comments on commit 2c2e434

Please sign in to comment.