Merge branch 'develop' into feature/OP-4710_TVP-publishing-update

This commit is contained in:
Jakub Trllo 2023-02-10 18:37:01 +01:00
commit 2c2dd3d92e
6 changed files with 142 additions and 55 deletions

View file

@ -164,7 +164,6 @@ def get_linked_representation_id(
# Recursive graph lookup for inputs
{"$graphLookup": graph_lookup}
]
conn = get_project_connection(project_name)
result = conn.aggregate(query_pipeline)
referenced_version_ids = _process_referenced_pipeline_result(
@ -213,7 +212,7 @@ def _process_referenced_pipeline_result(result, link_type):
for output in sorted(outputs_recursive, key=lambda o: o["depth"]):
output_links = output.get("data", {}).get("inputLinks")
if not output_links:
if not output_links and output["type"] != "hero_version":
continue
# Leaf
@ -232,6 +231,9 @@ def _process_referenced_pipeline_result(result, link_type):
def _filter_input_links(input_links, link_type, correctly_linked_ids):
if not input_links: # to handle hero versions
return
for input_link in input_links:
if link_type and input_link["type"] != link_type:
continue

View file

@ -44,7 +44,7 @@ class AppendBlendLoader(plugin.AssetLoader):
"""
representations = ["blend"]
families = ["*"]
families = ["workfile"]
label = "Append Workfile"
order = 9
@ -68,7 +68,7 @@ class ImportBlendLoader(plugin.AssetLoader):
"""
representations = ["blend"]
families = ["*"]
families = ["workfile"]
label = "Import Workfile"
order = 9

View file

@ -34,12 +34,24 @@ class AddSyncSite(load.LoaderPlugin):
return self._sync_server
def load(self, context, name=None, namespace=None, data=None):
self.log.info("Adding {} to representation: {}".format(
data["site_name"], data["_id"]))
family = context["representation"]["context"]["family"]
project_name = data["project_name"]
repre_id = data["_id"]
""""Adds site skeleton information on representation_id
Looks for loaded containers for workfile, adds them site skeleton too
(eg. they should be downloaded too).
Args:
context (dict):
name (str):
namespace (str):
data (dict): expects {"site_name": SITE_NAME_TO_ADD}
"""
# self.log wont propagate
project_name = context["project"]["name"]
repre_doc = context["representation"]
family = repre_doc["context"]["family"]
repre_id = repre_doc["_id"]
site_name = data["site_name"]
print("Adding {} to representation: {}".format(
data["site_name"], repre_id))
self.sync_server.add_site(project_name, repre_id, site_name,
force=True)
@ -52,6 +64,8 @@ class AddSyncSite(load.LoaderPlugin):
)
for link_repre_id in links:
try:
print("Adding {} to linked representation: {}".format(
data["site_name"], link_repre_id))
self.sync_server.add_site(project_name, link_repre_id,
site_name,
force=False)

View file

@ -3,7 +3,10 @@ from openpype.pipeline import load
class RemoveSyncSite(load.LoaderPlugin):
"""Remove sync site and its files on representation"""
"""Remove sync site and its files on representation.
Removes files only on local site!
"""
representations = ["*"]
families = ["*"]
@ -24,13 +27,18 @@ class RemoveSyncSite(load.LoaderPlugin):
return self._sync_server
def load(self, context, name=None, namespace=None, data=None):
self.log.info("Removing {} on representation: {}".format(
data["site_name"], data["_id"]))
self.sync_server.remove_site(data["project_name"],
data["_id"],
data["site_name"],
project_name = context["project"]["name"]
repre_doc = context["representation"]
repre_id = repre_doc["_id"]
site_name = data["site_name"]
print("Removing {} on representation: {}".format(site_name, repre_id))
self.sync_server.remove_site(project_name,
repre_id,
site_name,
True)
self.log.debug("Site added.")
self.log.debug("Site removed.")
def filepath_from_context(self, context):
"""No real file loading"""

View file

@ -506,6 +506,43 @@ class IntegrateAsset(pyblish.api.InstancePlugin):
return version_doc
def _validate_repre_files(self, files, is_sequence_representation):
"""Validate representation files before transfer preparation.
Check if files contain only filenames instead of full paths and check
if sequence don't contain more than one sequence or has remainders.
Args:
files (Union[str, List[str]]): Files from representation.
is_sequence_representation (bool): Files are for sequence.
Raises:
KnownPublishError: If validations don't pass.
"""
if not files:
return
if not is_sequence_representation:
files = [files]
if any(os.path.isabs(fname) for fname in files):
raise KnownPublishError("Given file names contain full paths")
if not is_sequence_representation:
return
src_collections, remainders = clique.assemble(files)
if len(files) < 2 or len(src_collections) != 1 or remainders:
raise KnownPublishError((
"Files of representation does not contain proper"
" sequence files.\nCollected collections: {}"
"\nCollected remainders: {}"
).format(
", ".join([str(col) for col in src_collections]),
", ".join([str(rem) for rem in remainders])
))
def prepare_representation(self, repre,
template_name,
existing_repres_by_name,
@ -587,7 +624,7 @@ class IntegrateAsset(pyblish.api.InstancePlugin):
is_udim = bool(repre.get("udim"))
# handle publish in place
if "originalDirname" in template:
if "{originalDirname}" in template:
# store as originalDirname only original value without project root
# if instance collected originalDirname is present, it should be
# used for all represe
@ -606,24 +643,64 @@ class IntegrateAsset(pyblish.api.InstancePlugin):
template_data["originalDirname"] = without_root
is_sequence_representation = isinstance(files, (list, tuple))
if is_sequence_representation:
# Collection of files (sequence)
if any(os.path.isabs(fname) for fname in files):
raise KnownPublishError("Given file names contain full paths")
self._validate_repre_files(files, is_sequence_representation)
# Output variables of conditions below:
# - transfers (List[Tuple[str, str]]): src -> dst filepaths to copy
# - repre_context (Dict[str, Any]): context data used to fill template
# - template_data (Dict[str, Any]): source data used to fill template
# - to add required data to 'repre_context' not used for
# formatting
# - anatomy_filled (Dict[str, Any]): filled anatomy of last file
# - to fill 'publishDir' on instance.data -> not ideal
# Treat template with 'orignalBasename' in special way
if "{originalBasename}" in template:
# Remove 'frame' from template data
template_data.pop("frame", None)
# Find out first frame string value
first_index_padded = None
if not is_udim and is_sequence_representation:
col = clique.assemble(files)[0][0]
sorted_frames = tuple(sorted(col.indexes))
# First frame used for end value
first_frame = sorted_frames[0]
# Get last frame for padding
last_frame = sorted_frames[-1]
# Use padding from collection of length of last frame as string
padding = max(col.padding, len(str(last_frame)))
first_index_padded = get_frame_padded(
frame=first_frame,
padding=padding
)
# Convert files to list for single file as remaining part is only
# transfers creation (iteration over files)
if not is_sequence_representation:
files = [files]
repre_context = None
transfers = []
for src_file_name in files:
template_data["originalBasename"], _ = os.path.splitext(
src_file_name)
anatomy_filled = anatomy.format(template_data)
dst = anatomy_filled[template_name]["path"]
src = os.path.join(stagingdir, src_file_name)
transfers.append((src, dst))
if repre_context is None:
repre_context = dst.used_values
if not is_udim and first_index_padded is not None:
repre_context["frame"] = first_index_padded
elif is_sequence_representation:
# Collection of files (sequence)
src_collections, remainders = clique.assemble(files)
if len(files) < 2 or len(src_collections) != 1 or remainders:
raise KnownPublishError((
"Files of representation does not contain proper"
" sequence files.\nCollected collections: {}"
"\nCollected remainders: {}"
).format(
", ".join([str(col) for col in src_collections]),
", ".join([str(rem) for rem in remainders])
))
src_collection = src_collections[0]
template_data["originalBasename"] = src_collection.head[:-1]
destination_indexes = list(src_collection.indexes)
# Use last frame for minimum padding
# - that should cover both 'udim' and 'frame' minimum padding
@ -645,11 +722,8 @@ class IntegrateAsset(pyblish.api.InstancePlugin):
# In case source are published in place we need to
# skip renumbering
repre_frame_start = repre.get("frameStart")
if (
"originalBasename" not in template
and repre_frame_start is not None
):
index_frame_start = int(repre["frameStart"])
if repre_frame_start is not None:
index_frame_start = int(repre_frame_start)
# Shift destination sequence to the start frame
destination_indexes = [
index_frame_start + idx
@ -705,15 +779,6 @@ class IntegrateAsset(pyblish.api.InstancePlugin):
else:
# Single file
fname = files
if os.path.isabs(fname):
self.log.error(
"Filename in representation is filepath {}".format(fname)
)
raise KnownPublishError(
"This is a bug. Representation file name is full path"
)
template_data["originalBasename"], _ = os.path.splitext(fname)
# Manage anatomy template data
template_data.pop("frame", None)
if is_udim:
@ -725,7 +790,7 @@ class IntegrateAsset(pyblish.api.InstancePlugin):
dst = os.path.normpath(template_filled)
# Single file transfer
src = os.path.join(stagingdir, fname)
src = os.path.join(stagingdir, files)
transfers = [(src, dst)]
# todo: Are we sure the assumption each representation

View file

@ -1480,23 +1480,21 @@ class RepresentationWidget(QtWidgets.QWidget):
repre_ids = []
data_by_repre_id = {}
selected_side = action_representation.get("selected_side")
site_name = "{}_site_name".format(selected_side)
is_sync_loader = tools_lib.is_sync_loader(loader)
for item in items:
item_id = item.get("_id")
repre_ids.append(item_id)
repre_id = item["_id"]
repre_ids.append(repre_id)
if not is_sync_loader:
continue
site_name = "{}_site_name".format(selected_side)
data_site_name = item.get(site_name)
if not data_site_name:
continue
data_by_repre_id[item_id] = {
"_id": item_id,
"site_name": data_site_name,
"project_name": self.dbcon.active_project()
data_by_repre_id[repre_id] = {
"site_name": data_site_name
}
repre_contexts = get_repres_contexts(repre_ids, self.dbcon)
@ -1586,8 +1584,8 @@ def _load_representations_by_loader(loader, repre_contexts,
version_name = version_doc.get("name")
try:
if data_by_repre_id:
_id = repre_context["representation"]["_id"]
data = data_by_repre_id.get(_id)
repre_id = repre_context["representation"]["_id"]
data = data_by_repre_id.get(repre_id)
options.update(data)
load_with_repre_context(
loader,