Merge pull request #4157 from ynput/feature/OP-4504_Publishing-Register-publishes-without-copying-them

Publish: register publishes without copying them
This commit is contained in:
Petr Kalis 2023-01-09 18:41:36 +01:00 committed by GitHub
commit 61d255a606
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
10 changed files with 246 additions and 33 deletions

View file

@ -270,6 +270,8 @@ class IntegrateAsset(pyblish.api.InstancePlugin):
)
instance.data["versionEntity"] = version
anatomy = instance.context.data["anatomy"]
# Get existing representations (if any)
existing_repres_by_name = {
repre_doc["name"].lower(): repre_doc
@ -303,13 +305,17 @@ class IntegrateAsset(pyblish.api.InstancePlugin):
# .ma representation. Those destination paths are pre-defined, etc.
# todo: should we move or simplify this logic?
resource_destinations = set()
for src, dst in instance.data.get("transfers", []):
file_transactions.add(src, dst, mode=FileTransaction.MODE_COPY)
resource_destinations.add(os.path.abspath(dst))
for src, dst in instance.data.get("hardlinks", []):
file_transactions.add(src, dst, mode=FileTransaction.MODE_HARDLINK)
resource_destinations.add(os.path.abspath(dst))
file_copy_modes = [
("transfers", FileTransaction.MODE_COPY),
("hardlinks", FileTransaction.MODE_HARDLINK)
]
for files_type, copy_mode in file_copy_modes:
for src, dst in instance.data.get(files_type, []):
self._validate_path_in_project_roots(anatomy, dst)
file_transactions.add(src, dst, mode=copy_mode)
resource_destinations.add(os.path.abspath(dst))
# Bulk write to the database
# We write the subset and version to the database before the File
@ -342,7 +348,6 @@ class IntegrateAsset(pyblish.api.InstancePlugin):
# Compute the resource file infos once (files belonging to the
# version instance instead of an individual representation) so
# we can re-use those file infos per representation
anatomy = instance.context.data["anatomy"]
resource_file_infos = self.get_files_info(resource_destinations,
sites=sites,
anatomy=anatomy)
@ -529,6 +534,20 @@ class IntegrateAsset(pyblish.api.InstancePlugin):
template_data["representation"] = repre["name"]
template_data["ext"] = repre["ext"]
stagingdir = repre.get("stagingDir")
if not stagingdir:
# Fall back to instance staging dir if not explicitly
# set for representation in the instance
self.log.debug((
"Representation uses instance staging dir: {}"
).format(instance_stagingdir))
stagingdir = instance_stagingdir
if not stagingdir:
raise KnownPublishError(
"No staging directory set for representation: {}".format(repre)
)
# optionals
# retrieve additional anatomy data from representation if exists
for key, anatomy_key in {
@ -548,20 +567,6 @@ class IntegrateAsset(pyblish.api.InstancePlugin):
if value is not None:
template_data[anatomy_key] = value
stagingdir = repre.get("stagingDir")
if not stagingdir:
# Fall back to instance staging dir if not explicitly
# set for representation in the instance
self.log.debug((
"Representation uses instance staging dir: {}"
).format(instance_stagingdir))
stagingdir = instance_stagingdir
if not stagingdir:
raise KnownPublishError(
"No staging directory set for representation: {}".format(repre)
)
self.log.debug("Anatomy template name: {}".format(template_name))
anatomy = instance.context.data["anatomy"]
publish_template_category = anatomy.templates[template_name]
@ -569,6 +574,25 @@ class IntegrateAsset(pyblish.api.InstancePlugin):
is_udim = bool(repre.get("udim"))
# handle publish in place
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
# from temp to final
original_directory = (
instance.data.get("originalDirname") or instance_stagingdir)
_rootless = self.get_rootless_path(anatomy, original_directory)
if _rootless == original_directory:
raise KnownPublishError((
"Destination path '{}' ".format(original_directory) +
"must be in project dir"
))
relative_path_start = _rootless.rfind('}') + 2
without_root = _rootless[relative_path_start:]
template_data["originalDirname"] = without_root
is_sequence_representation = isinstance(files, (list, tuple))
if is_sequence_representation:
# Collection of files (sequence)
@ -587,6 +611,7 @@ class IntegrateAsset(pyblish.api.InstancePlugin):
))
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
@ -671,12 +696,11 @@ class IntegrateAsset(pyblish.api.InstancePlugin):
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:
template_data["udim"] = repre["udim"][0]
# Construct destination filepath from template
anatomy_filled = anatomy.format(template_data)
template_filled = anatomy_filled[template_name]["path"]
@ -890,3 +914,21 @@ class IntegrateAsset(pyblish.api.InstancePlugin):
"hash": source_hash(path),
"sites": sites
}
def _validate_path_in_project_roots(self, anatomy, file_path):
"""Checks if 'file_path' starts with any of the roots.
Used to check that published path belongs to project, eg. we are not
trying to publish to local only folder.
Args:
anatomy (Anatomy)
file_path (str)
Raises
(KnownPublishError)
"""
path = self.get_rootless_path(anatomy, file_path)
if not path:
raise KnownPublishError((
"Destination path '{}' ".format(file_path) +
"must be in project dir"
))