From 8159b029d573ffdc22e556caafae6bc96843986e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Samohel?= Date: Tue, 10 Dec 2019 12:25:24 +0000 Subject: [PATCH 01/19] (genera) fixing subprocess function to allow pass through Popen.subprocess arguments. Also adding better output for running subprocess --- pype/lib.py | 33 ++++++++++++++++++++++----------- 1 file changed, 22 insertions(+), 11 deletions(-) diff --git a/pype/lib.py b/pype/lib.py index c8fade7f4a..8772608b38 100644 --- a/pype/lib.py +++ b/pype/lib.py @@ -14,24 +14,35 @@ log = logging.getLogger(__name__) # Special naming case for subprocess since its a built-in method. -def _subprocess(args): +def _subprocess(*args, **kwargs): """Convenience method for getting output errors for subprocess.""" # make sure environment contains only strings - env = {k: str(v) for k, v in os.environ.items()} + filtered_env = {k: str(v) for k, v in os.environ.items()} - proc = subprocess.Popen( - args, - stdout=subprocess.PIPE, - stderr=subprocess.STDOUT, - stdin=subprocess.PIPE, - env=env - ) + # set overrides + kwargs['stdout'] = kwargs.get('stdout', subprocess.PIPE) + kwargs['stderr'] = kwargs.get('stderr', subprocess.STDOUT) + kwargs['stdin'] = kwargs.get('stdin', subprocess.PIPE) + kwargs['env'] = kwargs.get('env',filtered_env) - output = proc.communicate()[0] + proc = subprocess.Popen(*args, **kwargs) + + output, error = proc.communicate() + + if output: + output = output.decode("utf-8") + output += "\n" + for line in output.strip().split("\n"): + log.info(line) + + if error: + error = error.decode("utf-8") + error += "\n" + for line in error.strip().split("\n"): + log.error(line) if proc.returncode != 0: - log.error(output) raise ValueError("\"{}\" was not successful: {}".format(args, output)) return output From bc9e7833b0b5403fe3b1fc3778a8a0bbd7c0ffd5 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Tue, 10 Dec 2019 14:32:28 +0100 Subject: [PATCH 02/19] width of Lighting button is not so complicated to set and ton size is default to 8pt --- .../widgets/widget_component_item.py | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/pype/standalonepublish/widgets/widget_component_item.py b/pype/standalonepublish/widgets/widget_component_item.py index 78287ccf37..0fd72cc70e 100644 --- a/pype/standalonepublish/widgets/widget_component_item.py +++ b/pype/standalonepublish/widgets/widget_component_item.py @@ -308,14 +308,15 @@ class ComponentItem(QtWidgets.QFrame): class LightingButton(QtWidgets.QPushButton): lightingbtnstyle = """ QPushButton { + font: %(font_size_pt)spt; text-align: center; color: #777777; background-color: transparent; border-width: 1px; border-color: #777777; border-style: solid; - padding-top: 2px; - padding-bottom: 2px; + padding-top: 0px; + padding-bottom: 0px; padding-left: 3px; padding-right: 3px; border-radius: 3px; @@ -351,14 +352,11 @@ class LightingButton(QtWidgets.QPushButton): color: #4BF543; } """ - def __init__(self, text, *args, **kwargs): - super().__init__(text, *args, **kwargs) - self.setStyleSheet(self.lightingbtnstyle) + def __init__(self, text, font_size_pt=8, *args, **kwargs): + super(LightingButton, self).__init__(text, *args, **kwargs) + self.setStyleSheet(self.lightingbtnstyle % { + "font_size_pt": font_size_pt + }) self.setCheckable(True) - preview_font_metrics = self.fontMetrics().boundingRect(text) - width = preview_font_metrics.width() + 16 - height = preview_font_metrics.height() + 5 - self.setMaximumWidth(width) - self.setMaximumHeight(height) From eac2629fcb27728396dc63b55de00f11cd006408 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Thu, 12 Dec 2019 11:26:12 +0100 Subject: [PATCH 03/19] use FFMPEG_PATH environ to get path to ffmpeg and ffprobe --- pype/scripts/otio_burnin.py | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/pype/scripts/otio_burnin.py b/pype/scripts/otio_burnin.py index 01dc76aacf..1b2c2a04aa 100644 --- a/pype/scripts/otio_burnin.py +++ b/pype/scripts/otio_burnin.py @@ -9,6 +9,21 @@ from pype import api as pype log = pype.Logger().get_logger("BurninWrapper", "burninwrap") +ffmpeg_path = os.environ.get("FFMPEG_PATH") +if ffmpeg_path and os.path.exists(ffmpeg_path): + # add separator "/" or "\" to be prepared for next part + ffmpeg_path += os.path.sep +else: + ffmpeg_path = "" + +FFMPEG = ( + '{} -loglevel panic -i %(input)s %(filters)s %(args)s%(output)s' +).format(os.path.normpath(ffmpeg_path + "ffmpeg")) +FFPROBE = ( + '{} -v quiet -print_format json -show_format -show_streams %(source)s' +).format(os.path.normpath(ffmpeg_path + "ffprobe")) + + class ModifiedBurnins(ffmpeg_burnins.Burnins): ''' This is modification of OTIO FFmpeg Burnin adapter. From 54c76b3b7f0358e9a8943524d22ce215cd006740 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Thu, 12 Dec 2019 11:26:55 +0100 Subject: [PATCH 04/19] copied _streams method from otio adapter to be able to use ffprobe full path --- pype/scripts/otio_burnin.py | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/pype/scripts/otio_burnin.py b/pype/scripts/otio_burnin.py index 1b2c2a04aa..dd62c59bec 100644 --- a/pype/scripts/otio_burnin.py +++ b/pype/scripts/otio_burnin.py @@ -1,5 +1,7 @@ import os import datetime +import subprocess +import json import opentimelineio_contrib.adapters.ffmpeg_burnins as ffmpeg_burnins from pypeapp.lib import config from pype import api as pype @@ -24,6 +26,19 @@ FFPROBE = ( ).format(os.path.normpath(ffmpeg_path + "ffprobe")) +def _streams(source): + """Reimplemented from otio burnins to be able use full path to ffprobe + :param str source: source media file + :rtype: [{}, ...] + """ + command = FFPROBE % {'source': source} + proc = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE) + out = proc.communicate()[0] + if proc.returncode != 0: + raise RuntimeError("Failed to run: %s" % command) + return json.loads(out)['streams'] + + class ModifiedBurnins(ffmpeg_burnins.Burnins): ''' This is modification of OTIO FFmpeg Burnin adapter. From fdf4182155e53f77e25fa32088f3776a9995f8b4 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Thu, 12 Dec 2019 11:27:22 +0100 Subject: [PATCH 05/19] replace FFMPEG string in command method --- pype/scripts/otio_burnin.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pype/scripts/otio_burnin.py b/pype/scripts/otio_burnin.py index dd62c59bec..d215bea55e 100644 --- a/pype/scripts/otio_burnin.py +++ b/pype/scripts/otio_burnin.py @@ -217,7 +217,7 @@ class ModifiedBurnins(ffmpeg_burnins.Burnins): if self.filter_string: filters = '-vf "{}"'.format(self.filter_string) - return (ffmpeg_burnins.FFMPEG % { + return (FFMPEG % { 'input': self.source, 'output': output, 'args': '%s ' % args if args else '', @@ -398,7 +398,7 @@ def burnins_from_data(input_path, codec_data, output_path, data, overwrite=True) codec_args = '' if codec_data is not []: codec_args = " ".join(codec_data) - + burnin.render(output_path, args=codec_args, overwrite=overwrite) From 978e05b536debcc928d39376690a14558c25a198 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Thu, 12 Dec 2019 11:27:47 +0100 Subject: [PATCH 06/19] get streams before super init in Burnin class is called --- pype/scripts/otio_burnin.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/pype/scripts/otio_burnin.py b/pype/scripts/otio_burnin.py index d215bea55e..3e8cb3b0c4 100644 --- a/pype/scripts/otio_burnin.py +++ b/pype/scripts/otio_burnin.py @@ -91,6 +91,9 @@ class ModifiedBurnins(ffmpeg_burnins.Burnins): } def __init__(self, source, streams=None, options_init=None): + if not streams: + streams = _streams(source) + super().__init__(source, streams) if options_init: self.options_init.update(options_init) From 0841d91eef7584e729b58db8d3b2c8340d7e2b3a Mon Sep 17 00:00:00 2001 From: Milan Kolar Date: Mon, 16 Dec 2019 14:13:31 +0100 Subject: [PATCH 07/19] fix which import --- pype/scripts/publish_filesequence.py | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/pype/scripts/publish_filesequence.py b/pype/scripts/publish_filesequence.py index 7ad7318831..5517cfeb4c 100644 --- a/pype/scripts/publish_filesequence.py +++ b/pype/scripts/publish_filesequence.py @@ -4,7 +4,16 @@ import os import logging import subprocess import platform -from shutil import which +try: + from shutil import which +except ImportError: + # we are in python < 3.3 + def which(command): + path = os.getenv('PATH') + for p in path.split(os.path.pathsep): + p = os.path.join(p, command) + if os.path.exists(p) and os.access(p, os.X_OK): + return p handler = logging.basicConfig() log = logging.getLogger("Publish Image Sequences") From 19cf990fbdf1b24c481ad9ac6b6fa74419331a0d Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Mon, 16 Dec 2019 17:35:23 +0100 Subject: [PATCH 08/19] added template data to burnins data --- pype/plugins/global/publish/extract_burnin.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/pype/plugins/global/publish/extract_burnin.py b/pype/plugins/global/publish/extract_burnin.py index 95a7144081..33935b4272 100644 --- a/pype/plugins/global/publish/extract_burnin.py +++ b/pype/plugins/global/publish/extract_burnin.py @@ -32,6 +32,7 @@ class ExtractBurnin(pype.api.Extractor): frame_start = int(instance.data.get("frameStart") or 0) frame_end = int(instance.data.get("frameEnd") or 1) duration = frame_end - frame_start + 1 + prep_data = { "username": instance.context.data['user'], "asset": os.environ['AVALON_ASSET'], @@ -39,8 +40,14 @@ class ExtractBurnin(pype.api.Extractor): "frame_start": frame_start, "frame_end": frame_end, "duration": duration, - "version": version + "version": version, + "comment": instance.context.data.get("comment"), + "intent": instance.context.data.get("intent") } + # Update data with template data + template_data = instance.data.get("assumedTemplateData") or {} + prep_data.update(template_data) + self.log.debug("__ prep_data: {}".format(prep_data)) for i, repre in enumerate(instance.data["representations"]): self.log.debug("__ i: `{}`, repre: `{}`".format(i, repre)) From 1286edfc25c717815d16bb8bb18d7d6a98268b30 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Mon, 16 Dec 2019 17:36:10 +0100 Subject: [PATCH 09/19] added filled anatomy to burnin data to be able use `anatomy[...][...]` in burnin presets --- pype/plugins/global/publish/extract_burnin.py | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/pype/plugins/global/publish/extract_burnin.py b/pype/plugins/global/publish/extract_burnin.py index 33935b4272..06a62dd98b 100644 --- a/pype/plugins/global/publish/extract_burnin.py +++ b/pype/plugins/global/publish/extract_burnin.py @@ -1,5 +1,6 @@ import os import json +import copy import pype.api import pyblish @@ -48,6 +49,9 @@ class ExtractBurnin(pype.api.Extractor): template_data = instance.data.get("assumedTemplateData") or {} prep_data.update(template_data) + # get anatomy project + anatomy = instance.context.data['anatomy'] + self.log.debug("__ prep_data: {}".format(prep_data)) for i, repre in enumerate(instance.data["representations"]): self.log.debug("__ i: `{}`, repre: `{}`".format(i, repre)) @@ -69,11 +73,17 @@ class ExtractBurnin(pype.api.Extractor): ) self.log.debug("__ full_burnin_path: {}".format(full_burnin_path)) + # create copy of prep_data for anatomy formatting + _prep_data = copy.deepcopy(prep_data) + _prep_data["representation"] = repre["name"] + _prep_data["anatomy"] = ( + anatomy.format_all(_prep_data).get("solved") or {} + ) burnin_data = { "input": full_movie_path.replace("\\", "/"), "codec": repre.get("codec", []), "output": full_burnin_path.replace("\\", "/"), - "burnin_data": prep_data + "burnin_data": _prep_data } self.log.debug("__ burnin_data2: {}".format(burnin_data)) From d78166a0da72d2a736be3c7b4bfc5da4fa38fff1 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Mon, 16 Dec 2019 17:49:42 +0100 Subject: [PATCH 10/19] replace backslash in hierararchy which may cause issues in burnin path --- pype/plugins/global/publish/collect_templates.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pype/plugins/global/publish/collect_templates.py b/pype/plugins/global/publish/collect_templates.py index 9b0c03fdee..48623eec22 100644 --- a/pype/plugins/global/publish/collect_templates.py +++ b/pype/plugins/global/publish/collect_templates.py @@ -75,7 +75,7 @@ class CollectTemplates(pyblish.api.InstancePlugin): "asset": asset_name, "subset": subset_name, "version": version_number, - "hierarchy": hierarchy, + "hierarchy": hierarchy.replace("\\", "/"), "representation": "TEMP"} instance.data["template"] = template From 813673dd504eb0f83648daea606a00ae4ac8de86 Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Thu, 12 Dec 2019 16:04:26 +0100 Subject: [PATCH 11/19] fix(global): comma missing `gizmo` family From f06857c42e8376f2f9b63efb77fb37846fd83c05 Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Wed, 18 Dec 2019 14:56:57 +0100 Subject: [PATCH 12/19] fix(nuke): didn't collect all publishable isntaces --- pype/plugins/nuke/publish/collect_instances.py | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/pype/plugins/nuke/publish/collect_instances.py b/pype/plugins/nuke/publish/collect_instances.py index cffe415058..c5fb289a1e 100644 --- a/pype/plugins/nuke/publish/collect_instances.py +++ b/pype/plugins/nuke/publish/collect_instances.py @@ -86,11 +86,13 @@ class CollectNukeInstances(pyblish.api.ContextPlugin): node.end() family = avalon_knob_data["family"] - families = avalon_knob_data.get("families") - if families: - families = [families] + families = list() + families_ak = avalon_knob_data.get("families") + + if families_ak: + families.append(families_ak) else: - families = [family] + families.append(family) # Get format format = root['format'].value() @@ -100,7 +102,7 @@ class CollectNukeInstances(pyblish.api.ContextPlugin): if node.Class() not in "Read": if "render" not in node.knobs().keys(): - families.insert(0, family) + pass elif node["render"].value(): self.log.info("flagged for render") add_family = "render.local" From 73e50fa03fcc6efccbcf49cfac120e3dbb4bf01a Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Sun, 5 Jan 2020 14:24:56 +0100 Subject: [PATCH 13/19] change label to see whole label value --- pype/ftrack/actions/action_seed.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pype/ftrack/actions/action_seed.py b/pype/ftrack/actions/action_seed.py index cf0a4b0445..5cbc5d1cec 100644 --- a/pype/ftrack/actions/action_seed.py +++ b/pype/ftrack/actions/action_seed.py @@ -9,7 +9,7 @@ class SeedDebugProject(BaseAction): #: Action identifier. identifier = "seed.debug.project" #: Action label. - label = "SeedDebugProject" + label = "Seed Debug Project" #: Action description. description = "Description" #: priority From 0024688a449a81919ab4b3331126a4f451a112ff Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Sun, 5 Jan 2020 14:25:50 +0100 Subject: [PATCH 14/19] convert input values to integer and set to 0 if not successful --- pype/ftrack/actions/action_seed.py | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/pype/ftrack/actions/action_seed.py b/pype/ftrack/actions/action_seed.py index 5cbc5d1cec..260e854d14 100644 --- a/pype/ftrack/actions/action_seed.py +++ b/pype/ftrack/actions/action_seed.py @@ -265,6 +265,11 @@ class SeedDebugProject(BaseAction): def create_assets(self, project, asset_count): self.log.debug("*** Creating assets:") + try: + asset_count = int(asset_count) + except ValueError: + asset_count = 0 + main_entity = self.session.create("Folder", { "name": "Assets", "parent": project @@ -305,6 +310,19 @@ class SeedDebugProject(BaseAction): def create_shots(self, project, seq_count, shots_count): self.log.debug("*** Creating shots:") + + # Convert counts to integers + try: + seq_count = int(seq_count) + except ValueError: + seq_count = 0 + + try: + shots_count = int(shots_count) + except ValueError: + shots_count = 0 + + # Create Folder "Shots" main_entity = self.session.create("Folder", { "name": "Shots", "parent": project From 080f1f6819d09b5c7d9ca8c3f3bc061998e9933b Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Sun, 5 Jan 2020 14:26:13 +0100 Subject: [PATCH 15/19] check if input values of seeder are greater than 0 --- pype/ftrack/actions/action_seed.py | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/pype/ftrack/actions/action_seed.py b/pype/ftrack/actions/action_seed.py index 260e854d14..1238e73e72 100644 --- a/pype/ftrack/actions/action_seed.py +++ b/pype/ftrack/actions/action_seed.py @@ -270,6 +270,10 @@ class SeedDebugProject(BaseAction): except ValueError: asset_count = 0 + if asset_count <= 0: + self.log.debug("No assets to create") + return + main_entity = self.session.create("Folder", { "name": "Assets", "parent": project @@ -322,6 +326,18 @@ class SeedDebugProject(BaseAction): except ValueError: shots_count = 0 + # Check if both are higher than 0 + missing = [] + if seq_count <= 0: + missing.append("sequences") + + if shots_count <= 0: + missing.append("shots") + + if missing: + self.log.debug("No {} to create".format(" and ".join(missing))) + return + # Create Folder "Shots" main_entity = self.session.create("Folder", { "name": "Shots", From 6d1b064d0b2593bcdba2914e40b75a2cf820f3fb Mon Sep 17 00:00:00 2001 From: Milan Kolar Date: Mon, 6 Jan 2020 12:19:56 +0100 Subject: [PATCH 16/19] add previous behaviour as default --- .../ftrack/events/event_version_to_task_statuses.py | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/pype/ftrack/events/event_version_to_task_statuses.py b/pype/ftrack/events/event_version_to_task_statuses.py index 1f5f1514d7..0d2a3130c0 100644 --- a/pype/ftrack/events/event_version_to_task_statuses.py +++ b/pype/ftrack/events/event_version_to_task_statuses.py @@ -62,9 +62,12 @@ class VersionToTaskStatus(BaseEvent): # Lower version status name and check if has mapping version_status = version_status_orig.lower() - new_status_names = status_mapping.get(version_status) - if not new_status_names: - continue + new_status_names = [] + mapped = status_mapping.get(version_status) + if mapped: + new_status_names.extend(list(mapped)) + + new_status_names.append(version_status) self.log.debug( "Processing AssetVersion status change: [ {} ]".format( @@ -72,10 +75,6 @@ class VersionToTaskStatus(BaseEvent): ) ) - # Backwards compatibility (convert string to list) - if isinstance(new_status_names, str): - new_status_names = [new_status_names] - # Lower all names from presets new_status_names = [name.lower() for name in new_status_names] From 25d2e135d9e78a8c2680b421cc08312f328f1ae6 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Mon, 6 Jan 2020 15:48:19 +0100 Subject: [PATCH 17/19] add custom attributes key to assetversion data in integrate frant instances --- pype/plugins/ftrack/publish/integrate_ftrack_instances.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/pype/plugins/ftrack/publish/integrate_ftrack_instances.py b/pype/plugins/ftrack/publish/integrate_ftrack_instances.py index 5e680a172a..5b8c195730 100644 --- a/pype/plugins/ftrack/publish/integrate_ftrack_instances.py +++ b/pype/plugins/ftrack/publish/integrate_ftrack_instances.py @@ -125,6 +125,12 @@ class IntegrateFtrackInstance(pyblish.api.InstancePlugin): "thumbnail": comp['thumbnail'] } + # Add custom attributes for AssetVersion + assetversion_cust_attrs = {} + component_item["assetversion_data"]["custom_attributes"] = ( + assetversion_cust_attrs + ) + componentList.append(component_item) # Create copy with ftrack.unmanaged location if thumb or prev if comp.get('thumbnail') or comp.get('preview') \ From abe9334d5d4adf6962983bff4a8fc2939b0f4d9b Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Mon, 6 Jan 2020 15:49:18 +0100 Subject: [PATCH 18/19] add intent value from context to custom attributes if is set --- pype/plugins/ftrack/publish/integrate_ftrack_instances.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/pype/plugins/ftrack/publish/integrate_ftrack_instances.py b/pype/plugins/ftrack/publish/integrate_ftrack_instances.py index 5b8c195730..78583b0a2f 100644 --- a/pype/plugins/ftrack/publish/integrate_ftrack_instances.py +++ b/pype/plugins/ftrack/publish/integrate_ftrack_instances.py @@ -127,6 +127,10 @@ class IntegrateFtrackInstance(pyblish.api.InstancePlugin): # Add custom attributes for AssetVersion assetversion_cust_attrs = {} + intent_val = instance.context.data.get("intent") + if intent_val: + assetversion_cust_attrs["intent"] = intent_val + component_item["assetversion_data"]["custom_attributes"] = ( assetversion_cust_attrs ) From c71fc909cef6bd6536656a9abfcbd9ce36bc2fad Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Mon, 6 Jan 2020 15:49:34 +0100 Subject: [PATCH 19/19] set asset version custom attributes if there are any --- .../ftrack/publish/integrate_ftrack_api.py | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/pype/plugins/ftrack/publish/integrate_ftrack_api.py b/pype/plugins/ftrack/publish/integrate_ftrack_api.py index 9fe4fddebf..337562c1f5 100644 --- a/pype/plugins/ftrack/publish/integrate_ftrack_api.py +++ b/pype/plugins/ftrack/publish/integrate_ftrack_api.py @@ -144,8 +144,11 @@ class IntegrateFtrackApi(pyblish.api.InstancePlugin): "version": 0, "asset": asset_entity, } - - assetversion_data.update(data.get("assetversion_data", {})) + _assetversion_data = data.get("assetversion_data", {}) + assetversion_cust_attrs = _assetversion_data.pop( + "custom_attributes", {} + ) + assetversion_data.update(_assetversion_data) assetversion_entity = session.query( self.query("AssetVersion", assetversion_data) @@ -182,6 +185,18 @@ class IntegrateFtrackApi(pyblish.api.InstancePlugin): existing_assetversion_metadata.update(assetversion_metadata) assetversion_entity["metadata"] = existing_assetversion_metadata + # Adding Custom Attributes + for attr, val in assetversion_cust_attrs.items(): + if attr in assetversion_entity["custom_attributes"]: + assetversion_entity["custom_attributes"][attr] = val + continue + + self.log.warning(( + "Custom Attrubute \"{0}\"" + " is not available for AssetVersion." + " Can't set it's value to: \"{1}\"" + ).format(attr, str(val))) + # Have to commit the version and asset, because location can't # determine the final location without. try: