mirror of
https://github.com/ynput/ayon-core.git
synced 2026-01-01 16:34:53 +01:00
Merge branch 'develop' into enhancement/OP-2956_move-host-install
This commit is contained in:
commit
328a35c166
55 changed files with 2088 additions and 731 deletions
|
|
@ -221,11 +221,17 @@ class ExtractBurnin(openpype.api.Extractor):
|
|||
filled_anatomy = anatomy.format_all(burnin_data)
|
||||
burnin_data["anatomy"] = filled_anatomy.get_solved()
|
||||
|
||||
# Add context data burnin_data.
|
||||
burnin_data["custom"] = (
|
||||
custom_data = copy.deepcopy(
|
||||
instance.data.get("customData") or {}
|
||||
)
|
||||
# Backwards compatibility (since 2022/04/07)
|
||||
custom_data.update(
|
||||
instance.data.get("custom_burnin_data") or {}
|
||||
)
|
||||
|
||||
# Add context data burnin_data.
|
||||
burnin_data["custom"] = custom_data
|
||||
|
||||
# Add source camera name to burnin data
|
||||
camera_name = repre.get("camera_name")
|
||||
if camera_name:
|
||||
|
|
|
|||
|
|
@ -188,8 +188,7 @@ class ExtractReview(pyblish.api.InstancePlugin):
|
|||
outputs_per_repres = self._get_outputs_per_representations(
|
||||
instance, profile_outputs
|
||||
)
|
||||
fill_data = copy.deepcopy(instance.data["anatomyData"])
|
||||
for repre, outputs in outputs_per_repres:
|
||||
for repre, outpu_defs in outputs_per_repres:
|
||||
# Check if input should be preconverted before processing
|
||||
# Store original staging dir (it's value may change)
|
||||
src_repre_staging_dir = repre["stagingDir"]
|
||||
|
|
@ -241,126 +240,143 @@ class ExtractReview(pyblish.api.InstancePlugin):
|
|||
self.log
|
||||
)
|
||||
|
||||
for _output_def in outputs:
|
||||
output_def = copy.deepcopy(_output_def)
|
||||
# Make sure output definition has "tags" key
|
||||
if "tags" not in output_def:
|
||||
output_def["tags"] = []
|
||||
|
||||
if "burnins" not in output_def:
|
||||
output_def["burnins"] = []
|
||||
|
||||
# Create copy of representation
|
||||
new_repre = copy.deepcopy(repre)
|
||||
# Make sure new representation has origin staging dir
|
||||
# - this is because source representation may change
|
||||
# it's staging dir because of ffmpeg conversion
|
||||
new_repre["stagingDir"] = src_repre_staging_dir
|
||||
|
||||
# Remove "delete" tag from new repre if there is
|
||||
if "delete" in new_repre["tags"]:
|
||||
new_repre["tags"].remove("delete")
|
||||
|
||||
# Add additional tags from output definition to representation
|
||||
for tag in output_def["tags"]:
|
||||
if tag not in new_repre["tags"]:
|
||||
new_repre["tags"].append(tag)
|
||||
|
||||
# Add burnin link from output definition to representation
|
||||
for burnin in output_def["burnins"]:
|
||||
if burnin not in new_repre.get("burnins", []):
|
||||
if not new_repre.get("burnins"):
|
||||
new_repre["burnins"] = []
|
||||
new_repre["burnins"].append(str(burnin))
|
||||
|
||||
self.log.debug(
|
||||
"Linked burnins: `{}`".format(new_repre.get("burnins"))
|
||||
try:
|
||||
self._render_output_definitions(
|
||||
instance, repre, src_repre_staging_dir, outpu_defs
|
||||
)
|
||||
|
||||
self.log.debug(
|
||||
"New representation tags: `{}`".format(
|
||||
new_repre.get("tags"))
|
||||
finally:
|
||||
# Make sure temporary staging is cleaned up and representation
|
||||
# has set origin stagingDir
|
||||
if do_convert:
|
||||
# Set staging dir of source representation back to previous
|
||||
# value
|
||||
repre["stagingDir"] = src_repre_staging_dir
|
||||
if os.path.exists(new_staging_dir):
|
||||
shutil.rmtree(new_staging_dir)
|
||||
|
||||
def _render_output_definitions(
|
||||
self, instance, repre, src_repre_staging_dir, outpu_defs
|
||||
):
|
||||
fill_data = copy.deepcopy(instance.data["anatomyData"])
|
||||
for _output_def in outpu_defs:
|
||||
output_def = copy.deepcopy(_output_def)
|
||||
# Make sure output definition has "tags" key
|
||||
if "tags" not in output_def:
|
||||
output_def["tags"] = []
|
||||
|
||||
if "burnins" not in output_def:
|
||||
output_def["burnins"] = []
|
||||
|
||||
# Create copy of representation
|
||||
new_repre = copy.deepcopy(repre)
|
||||
# Make sure new representation has origin staging dir
|
||||
# - this is because source representation may change
|
||||
# it's staging dir because of ffmpeg conversion
|
||||
new_repre["stagingDir"] = src_repre_staging_dir
|
||||
|
||||
# Remove "delete" tag from new repre if there is
|
||||
if "delete" in new_repre["tags"]:
|
||||
new_repre["tags"].remove("delete")
|
||||
|
||||
# Add additional tags from output definition to representation
|
||||
for tag in output_def["tags"]:
|
||||
if tag not in new_repre["tags"]:
|
||||
new_repre["tags"].append(tag)
|
||||
|
||||
# Add burnin link from output definition to representation
|
||||
for burnin in output_def["burnins"]:
|
||||
if burnin not in new_repre.get("burnins", []):
|
||||
if not new_repre.get("burnins"):
|
||||
new_repre["burnins"] = []
|
||||
new_repre["burnins"].append(str(burnin))
|
||||
|
||||
self.log.debug(
|
||||
"Linked burnins: `{}`".format(new_repre.get("burnins"))
|
||||
)
|
||||
|
||||
self.log.debug(
|
||||
"New representation tags: `{}`".format(
|
||||
new_repre.get("tags"))
|
||||
)
|
||||
|
||||
temp_data = self.prepare_temp_data(instance, repre, output_def)
|
||||
files_to_clean = []
|
||||
if temp_data["input_is_sequence"]:
|
||||
self.log.info("Filling gaps in sequence.")
|
||||
files_to_clean = self.fill_sequence_gaps(
|
||||
temp_data["origin_repre"]["files"],
|
||||
new_repre["stagingDir"],
|
||||
temp_data["frame_start"],
|
||||
temp_data["frame_end"])
|
||||
|
||||
# create or update outputName
|
||||
output_name = new_repre.get("outputName", "")
|
||||
output_ext = new_repre["ext"]
|
||||
if output_name:
|
||||
output_name += "_"
|
||||
output_name += output_def["filename_suffix"]
|
||||
if temp_data["without_handles"]:
|
||||
output_name += "_noHandles"
|
||||
|
||||
# add outputName to anatomy format fill_data
|
||||
fill_data.update({
|
||||
"output": output_name,
|
||||
"ext": output_ext
|
||||
})
|
||||
|
||||
try: # temporary until oiiotool is supported cross platform
|
||||
ffmpeg_args = self._ffmpeg_arguments(
|
||||
output_def, instance, new_repre, temp_data, fill_data
|
||||
)
|
||||
|
||||
temp_data = self.prepare_temp_data(
|
||||
instance, repre, output_def)
|
||||
files_to_clean = []
|
||||
if temp_data["input_is_sequence"]:
|
||||
self.log.info("Filling gaps in sequence.")
|
||||
files_to_clean = self.fill_sequence_gaps(
|
||||
temp_data["origin_repre"]["files"],
|
||||
new_repre["stagingDir"],
|
||||
temp_data["frame_start"],
|
||||
temp_data["frame_end"])
|
||||
|
||||
# create or update outputName
|
||||
output_name = new_repre.get("outputName", "")
|
||||
output_ext = new_repre["ext"]
|
||||
if output_name:
|
||||
output_name += "_"
|
||||
output_name += output_def["filename_suffix"]
|
||||
if temp_data["without_handles"]:
|
||||
output_name += "_noHandles"
|
||||
|
||||
# add outputName to anatomy format fill_data
|
||||
fill_data.update({
|
||||
"output": output_name,
|
||||
"ext": output_ext
|
||||
})
|
||||
|
||||
try: # temporary until oiiotool is supported cross platform
|
||||
ffmpeg_args = self._ffmpeg_arguments(
|
||||
output_def, instance, new_repre, temp_data, fill_data
|
||||
except ZeroDivisionError:
|
||||
# TODO recalculate width and height using OIIO before
|
||||
# conversion
|
||||
if 'exr' in temp_data["origin_repre"]["ext"]:
|
||||
self.log.warning(
|
||||
(
|
||||
"Unsupported compression on input files."
|
||||
" Skipping!!!"
|
||||
),
|
||||
exc_info=True
|
||||
)
|
||||
except ZeroDivisionError:
|
||||
if 'exr' in temp_data["origin_repre"]["ext"]:
|
||||
self.log.debug("Unsupported compression on input " +
|
||||
"files. Skipping!!!")
|
||||
return
|
||||
raise NotImplementedError
|
||||
return
|
||||
raise NotImplementedError
|
||||
|
||||
subprcs_cmd = " ".join(ffmpeg_args)
|
||||
subprcs_cmd = " ".join(ffmpeg_args)
|
||||
|
||||
# run subprocess
|
||||
self.log.debug("Executing: {}".format(subprcs_cmd))
|
||||
# run subprocess
|
||||
self.log.debug("Executing: {}".format(subprcs_cmd))
|
||||
|
||||
openpype.api.run_subprocess(
|
||||
subprcs_cmd, shell=True, logger=self.log
|
||||
)
|
||||
openpype.api.run_subprocess(
|
||||
subprcs_cmd, shell=True, logger=self.log
|
||||
)
|
||||
|
||||
# delete files added to fill gaps
|
||||
if files_to_clean:
|
||||
for f in files_to_clean:
|
||||
os.unlink(f)
|
||||
# delete files added to fill gaps
|
||||
if files_to_clean:
|
||||
for f in files_to_clean:
|
||||
os.unlink(f)
|
||||
|
||||
new_repre.update({
|
||||
"name": "{}_{}".format(output_name, output_ext),
|
||||
"outputName": output_name,
|
||||
"outputDef": output_def,
|
||||
"frameStartFtrack": temp_data["output_frame_start"],
|
||||
"frameEndFtrack": temp_data["output_frame_end"],
|
||||
"ffmpeg_cmd": subprcs_cmd
|
||||
})
|
||||
new_repre.update({
|
||||
"name": "{}_{}".format(output_name, output_ext),
|
||||
"outputName": output_name,
|
||||
"outputDef": output_def,
|
||||
"frameStartFtrack": temp_data["output_frame_start"],
|
||||
"frameEndFtrack": temp_data["output_frame_end"],
|
||||
"ffmpeg_cmd": subprcs_cmd
|
||||
})
|
||||
|
||||
# Force to pop these key if are in new repre
|
||||
new_repre.pop("preview", None)
|
||||
new_repre.pop("thumbnail", None)
|
||||
if "clean_name" in new_repre.get("tags", []):
|
||||
new_repre.pop("outputName")
|
||||
# Force to pop these key if are in new repre
|
||||
new_repre.pop("preview", None)
|
||||
new_repre.pop("thumbnail", None)
|
||||
if "clean_name" in new_repre.get("tags", []):
|
||||
new_repre.pop("outputName")
|
||||
|
||||
# adding representation
|
||||
self.log.debug(
|
||||
"Adding new representation: {}".format(new_repre)
|
||||
)
|
||||
instance.data["representations"].append(new_repre)
|
||||
|
||||
# Cleanup temp staging dir after procesisng of output definitions
|
||||
if do_convert:
|
||||
temp_dir = repre["stagingDir"]
|
||||
shutil.rmtree(temp_dir)
|
||||
# Set staging dir of source representation back to previous
|
||||
# value
|
||||
repre["stagingDir"] = src_repre_staging_dir
|
||||
# adding representation
|
||||
self.log.debug(
|
||||
"Adding new representation: {}".format(new_repre)
|
||||
)
|
||||
instance.data["representations"].append(new_repre)
|
||||
|
||||
def input_is_sequence(self, repre):
|
||||
"""Deduce from representation data if input is sequence."""
|
||||
|
|
|
|||
|
|
@ -158,13 +158,15 @@ class ExtractReviewSlate(openpype.api.Extractor):
|
|||
])
|
||||
|
||||
if use_legacy_code:
|
||||
format_args = []
|
||||
codec_args = repre["_profile"].get('codec', [])
|
||||
output_args.extend(codec_args)
|
||||
# preset's output data
|
||||
output_args.extend(repre["_profile"].get('output', []))
|
||||
else:
|
||||
# Codecs are copied from source for whole input
|
||||
codec_args = self._get_codec_args(repre)
|
||||
format_args, codec_args = self._get_format_codec_args(repre)
|
||||
output_args.extend(format_args)
|
||||
output_args.extend(codec_args)
|
||||
|
||||
# make sure colors are correct
|
||||
|
|
@ -266,8 +268,14 @@ class ExtractReviewSlate(openpype.api.Extractor):
|
|||
"-safe", "0",
|
||||
"-i", conc_text_path,
|
||||
"-c", "copy",
|
||||
output_path
|
||||
]
|
||||
# NOTE: Added because of OP Atom demuxers
|
||||
# Add format arguments if there are any
|
||||
# - keep format of output
|
||||
if format_args:
|
||||
concat_args.extend(format_args)
|
||||
# Add final output path
|
||||
concat_args.append(output_path)
|
||||
|
||||
# ffmpeg concat subprocess
|
||||
self.log.debug(
|
||||
|
|
@ -338,7 +346,7 @@ class ExtractReviewSlate(openpype.api.Extractor):
|
|||
|
||||
return vf_back
|
||||
|
||||
def _get_codec_args(self, repre):
|
||||
def _get_format_codec_args(self, repre):
|
||||
"""Detect possible codec arguments from representation."""
|
||||
codec_args = []
|
||||
|
||||
|
|
@ -361,13 +369,9 @@ class ExtractReviewSlate(openpype.api.Extractor):
|
|||
return codec_args
|
||||
|
||||
source_ffmpeg_cmd = repre.get("ffmpeg_cmd")
|
||||
codec_args.extend(
|
||||
get_ffmpeg_format_args(ffprobe_data, source_ffmpeg_cmd)
|
||||
)
|
||||
codec_args.extend(
|
||||
get_ffmpeg_codec_args(
|
||||
ffprobe_data, source_ffmpeg_cmd, logger=self.log
|
||||
)
|
||||
format_args = get_ffmpeg_format_args(ffprobe_data, source_ffmpeg_cmd)
|
||||
codec_args = get_ffmpeg_codec_args(
|
||||
ffprobe_data, source_ffmpeg_cmd, logger=self.log
|
||||
)
|
||||
|
||||
return codec_args
|
||||
return format_args, codec_args
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ import errno
|
|||
import six
|
||||
import re
|
||||
import shutil
|
||||
from collections import deque, defaultdict
|
||||
|
||||
from bson.objectid import ObjectId
|
||||
from pymongo import DeleteOne, InsertOne
|
||||
|
|
@ -1116,18 +1117,17 @@ class IntegrateAssetNew(pyblish.api.InstancePlugin):
|
|||
rec["sites"].append(meta)
|
||||
already_attached_sites[meta["name"]] = None
|
||||
|
||||
# add alternative sites
|
||||
rec, already_attached_sites = self._add_alternative_sites(
|
||||
system_sync_server_presets, already_attached_sites, rec)
|
||||
|
||||
# add skeleton for site where it should be always synced to
|
||||
for always_on_site in always_accesible:
|
||||
for always_on_site in set(always_accesible):
|
||||
if always_on_site not in already_attached_sites.keys():
|
||||
meta = {"name": always_on_site.strip()}
|
||||
rec["sites"].append(meta)
|
||||
already_attached_sites[meta["name"]] = None
|
||||
|
||||
# add alternative sites
|
||||
rec = self._add_alternative_sites(system_sync_server_presets,
|
||||
already_attached_sites,
|
||||
rec)
|
||||
|
||||
log.debug("final sites:: {}".format(rec["sites"]))
|
||||
|
||||
return rec
|
||||
|
|
@ -1158,22 +1158,60 @@ class IntegrateAssetNew(pyblish.api.InstancePlugin):
|
|||
"""
|
||||
conf_sites = system_sync_server_presets.get("sites", {})
|
||||
|
||||
alt_site_pairs = self._get_alt_site_pairs(conf_sites)
|
||||
|
||||
already_attached_keys = list(already_attached_sites.keys())
|
||||
for added_site in already_attached_keys:
|
||||
real_created = already_attached_sites[added_site]
|
||||
for alt_site in alt_site_pairs.get(added_site, []):
|
||||
if alt_site in already_attached_sites.keys():
|
||||
continue
|
||||
meta = {"name": alt_site}
|
||||
# alt site inherits state of 'created_dt'
|
||||
if real_created:
|
||||
meta["created_dt"] = real_created
|
||||
rec["sites"].append(meta)
|
||||
already_attached_sites[meta["name"]] = real_created
|
||||
|
||||
return rec, already_attached_sites
|
||||
|
||||
def _get_alt_site_pairs(self, conf_sites):
|
||||
"""Returns dict of site and its alternative sites.
|
||||
|
||||
If `site` has alternative site, it means that alt_site has 'site' as
|
||||
alternative site
|
||||
Args:
|
||||
conf_sites (dict)
|
||||
Returns:
|
||||
(dict): {'site': [alternative sites]...}
|
||||
"""
|
||||
alt_site_pairs = defaultdict(list)
|
||||
for site_name, site_info in conf_sites.items():
|
||||
alt_sites = set(site_info.get("alternative_sites", []))
|
||||
already_attached_keys = list(already_attached_sites.keys())
|
||||
for added_site in already_attached_keys:
|
||||
if added_site in alt_sites:
|
||||
if site_name in already_attached_keys:
|
||||
continue
|
||||
meta = {"name": site_name}
|
||||
real_created = already_attached_sites[added_site]
|
||||
# alt site inherits state of 'created_dt'
|
||||
if real_created:
|
||||
meta["created_dt"] = real_created
|
||||
rec["sites"].append(meta)
|
||||
already_attached_sites[meta["name"]] = real_created
|
||||
alt_site_pairs[site_name].extend(alt_sites)
|
||||
|
||||
return rec
|
||||
for alt_site in alt_sites:
|
||||
alt_site_pairs[alt_site].append(site_name)
|
||||
|
||||
for site_name, alt_sites in alt_site_pairs.items():
|
||||
sites_queue = deque(alt_sites)
|
||||
while sites_queue:
|
||||
alt_site = sites_queue.popleft()
|
||||
|
||||
# safety against wrong config
|
||||
# {"SFTP": {"alternative_site": "SFTP"}
|
||||
if alt_site == site_name or alt_site not in alt_site_pairs:
|
||||
continue
|
||||
|
||||
for alt_alt_site in alt_site_pairs[alt_site]:
|
||||
if (
|
||||
alt_alt_site != site_name
|
||||
and alt_alt_site not in alt_sites
|
||||
):
|
||||
alt_sites.append(alt_alt_site)
|
||||
sites_queue.append(alt_alt_site)
|
||||
|
||||
return alt_site_pairs
|
||||
|
||||
def handle_destination_files(self, integrated_file_sizes, mode):
|
||||
""" Clean destination files
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue