From 2f6ca5a2385bd3073961cf49bca220e9d3fb88b9 Mon Sep 17 00:00:00 2001 From: Petr Kalis Date: Fri, 18 Oct 2024 18:35:27 +0200 Subject: [PATCH 01/34] Implemented explicit frames for simple files representations --- .../pipeline/farm/pyblish_functions.py | 79 ++++++++++++++++--- 1 file changed, 69 insertions(+), 10 deletions(-) diff --git a/client/ayon_core/pipeline/farm/pyblish_functions.py b/client/ayon_core/pipeline/farm/pyblish_functions.py index 98951b2766..5908644dca 100644 --- a/client/ayon_core/pipeline/farm/pyblish_functions.py +++ b/client/ayon_core/pipeline/farm/pyblish_functions.py @@ -7,7 +7,7 @@ import attr import ayon_api import clique -from ayon_core.lib import Logger +from ayon_core.lib import Logger, collect_frames from ayon_core.pipeline import get_current_project_name, get_representation_path from ayon_core.pipeline.create import get_product_name from ayon_core.pipeline.farm.patterning import match_aov_pattern @@ -295,11 +295,17 @@ def _add_review_families(families): return families -def prepare_representations(skeleton_data, exp_files, anatomy, aov_filter, - skip_integration_repre_list, - do_not_add_review, - context, - color_managed_plugin): +def prepare_representations( + skeleton_data, + exp_files, + anatomy, + aov_filter, + skip_integration_repre_list, + do_not_add_review, + context, + color_managed_plugin, + frames_to_render +): """Create representations for file sequences. This will return representations of expected files if they are not @@ -315,6 +321,8 @@ def prepare_representations(skeleton_data, exp_files, anatomy, aov_filter, skip_integration_repre_list (list): exclude specific extensions, do_not_add_review (bool): explicitly skip review color_managed_plugin (publish.ColormanagedPyblishPluginMixin) + frames_to_render (str): implicit or explicit range of frames to render + this value is sent to Deadline in JobInfo.Frames Returns: list of representations @@ -325,6 +333,8 @@ def prepare_representations(skeleton_data, exp_files, anatomy, aov_filter, log = Logger.get_logger("farm_publishing") + frames_to_render = _get_real_frames_to_render(frames_to_render) + # create representation for every collected sequence for collection in collections: ext = collection.tail.lstrip(".") @@ -361,18 +371,21 @@ def prepare_representations(skeleton_data, exp_files, anatomy, aov_filter, " This may cause issues on farm." ).format(staging)) - frame_start = int(skeleton_data.get("frameStartHandle")) + frame_start = int(frames_to_render[0]) + frame_end = int(frames_to_render[-1]) if skeleton_data.get("slate"): frame_start -= 1 + files = _get_real_files_to_rendered(collection, frames_to_render) + # explicitly disable review by user preview = preview and not do_not_add_review rep = { "name": ext, "ext": ext, - "files": [os.path.basename(f) for f in list(collection)], + "files": files, "frameStart": frame_start, - "frameEnd": int(skeleton_data.get("frameEndHandle")), + "frameEnd": frame_end, # If expectedFile are absolute, we need only filenames "stagingDir": staging, "fps": skeleton_data.get("fps"), @@ -413,10 +426,13 @@ def prepare_representations(skeleton_data, exp_files, anatomy, aov_filter, " This may cause issues on farm." ).format(staging)) + files = _get_real_files_to_rendered( + [os.path.basename(remainder)], frames_to_render) + rep = { "name": ext, "ext": ext, - "files": os.path.basename(remainder), + "files": files[0], "stagingDir": staging, } @@ -453,6 +469,49 @@ def prepare_representations(skeleton_data, exp_files, anatomy, aov_filter, return representations +def _get_real_frames_to_render(frames): + """Returns list of frames that should be rendered. + + Artists could want to selectively render only particular frames + """ + frames_to_render = [] + for frame in frames.split(","): + if "-" in frame: + splitted = frame.split("-") + frames_to_render.extend(range(int(splitted[0]), int(splitted[1]))) + else: + frames_to_render.append(frame) + return [str(frame_to_render) for frame_to_render in frames_to_render] + + +def _get_real_files_to_rendered(collection, frames_to_render): + """Use expected files based on real frames_to_render. + + Artists might explicitly set frames they want to render via Publisher UI. + This uses this value to filter out files + Args: + frames_to_render (list): of str '1001' + """ + files = [os.path.basename(f) for f in list(collection)] + file_name, extracted_frame = list(collect_frames(files).items())[0] + if extracted_frame: + found_frame_pattern_length = len(extracted_frame) + normalized_frames_to_render = set() + for frame_to_render in frames_to_render: + normalized_frames_to_render.add( + str(frame_to_render).zfill(found_frame_pattern_length) + ) + + filtered_files = [] + for file_name in files: + if any(frame in file_name + for frame in normalized_frames_to_render): + filtered_files.append(file_name) + + files = filtered_files + return files + + def create_instances_for_aov(instance, skeleton, aov_filter, skip_integration_repre_list, do_not_add_review): From 8a074daa2bb226de239d6d8291069c8796398086 Mon Sep 17 00:00:00 2001 From: Petr Kalis Date: Mon, 4 Nov 2024 16:56:41 +0100 Subject: [PATCH 02/34] Fix single frame render --- client/ayon_core/pipeline/farm/pyblish_functions.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/client/ayon_core/pipeline/farm/pyblish_functions.py b/client/ayon_core/pipeline/farm/pyblish_functions.py index 5908644dca..c70967dfc1 100644 --- a/client/ayon_core/pipeline/farm/pyblish_functions.py +++ b/client/ayon_core/pipeline/farm/pyblish_functions.py @@ -478,7 +478,8 @@ def _get_real_frames_to_render(frames): for frame in frames.split(","): if "-" in frame: splitted = frame.split("-") - frames_to_render.extend(range(int(splitted[0]), int(splitted[1]))) + frames_to_render.extend( + range(int(splitted[0]), int(splitted[1])+1)) else: frames_to_render.append(frame) return [str(frame_to_render) for frame_to_render in frames_to_render] From 87bb613b751ea508ae54a9813bf6eb5852ca5b6b Mon Sep 17 00:00:00 2001 From: Petr Kalis Date: Thu, 7 Nov 2024 17:38:00 +0100 Subject: [PATCH 03/34] Added optionality to new argument in method signature --- client/ayon_core/pipeline/farm/pyblish_functions.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/ayon_core/pipeline/farm/pyblish_functions.py b/client/ayon_core/pipeline/farm/pyblish_functions.py index c70967dfc1..e9f179c668 100644 --- a/client/ayon_core/pipeline/farm/pyblish_functions.py +++ b/client/ayon_core/pipeline/farm/pyblish_functions.py @@ -304,7 +304,7 @@ def prepare_representations( do_not_add_review, context, color_managed_plugin, - frames_to_render + frames_to_render=None ): """Create representations for file sequences. From 863c6f51871f089acfba690ee58ac4af95a14a21 Mon Sep 17 00:00:00 2001 From: "robin@ynput.io" Date: Tue, 12 Nov 2024 16:04:25 -0500 Subject: [PATCH 04/34] Allow CSV ingest to create new shots. --- .../plugins/publish/collect_hierarchy.py | 18 +++++++++++------- .../publish/extract_hierarchy_to_ayon.py | 2 +- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/client/ayon_core/plugins/publish/collect_hierarchy.py b/client/ayon_core/plugins/publish/collect_hierarchy.py index 2ae3cc67f3..e4b4dd408f 100644 --- a/client/ayon_core/plugins/publish/collect_hierarchy.py +++ b/client/ayon_core/plugins/publish/collect_hierarchy.py @@ -13,8 +13,8 @@ class CollectHierarchy(pyblish.api.ContextPlugin): label = "Collect Hierarchy" order = pyblish.api.CollectorOrder - 0.076 - families = ["shot"] - hosts = ["resolve", "hiero", "flame"] + families = ["shot", "csv_ingest_shot"] + hosts = ["resolve", "hiero", "flame", "traypublisher"] def process(self, context): project_name = context.data["projectName"] @@ -38,8 +38,9 @@ def process(self, context): ): continue - # exclude if not masterLayer True - if not instance.data.get("heroTrack"): + # exclude if not CSV ingest shot and not masterLayer True + if ("csv_ingest_shot" not in families and + not instance.data.get("heroTrack")): continue shot_data = { @@ -49,7 +50,10 @@ def process(self, context): "folder_type": "Shot", "tasks": instance.data.get("tasks") or {}, "comments": instance.data.get("comments", []), - "attributes": { + } + + if "csv_ingest_shot" not in families: + shot_data["attributes"] = { "handleStart": instance.data["handleStart"], "handleEnd": instance.data["handleEnd"], "frameStart": instance.data["frameStart"], @@ -60,8 +64,8 @@ def process(self, context): "resolutionWidth": instance.data["resolutionWidth"], "resolutionHeight": instance.data["resolutionHeight"], "pixelAspect": instance.data["pixelAspect"], - }, - } + } + # Split by '/' for AYON where asset is a path name = instance.data["folderPath"].split("/")[-1] actual = {name: shot_data} diff --git a/client/ayon_core/plugins/publish/extract_hierarchy_to_ayon.py b/client/ayon_core/plugins/publish/extract_hierarchy_to_ayon.py index a169affc66..390ce36126 100644 --- a/client/ayon_core/plugins/publish/extract_hierarchy_to_ayon.py +++ b/client/ayon_core/plugins/publish/extract_hierarchy_to_ayon.py @@ -22,7 +22,7 @@ class ExtractHierarchyToAYON(pyblish.api.ContextPlugin): order = pyblish.api.ExtractorOrder - 0.01 label = "Extract Hierarchy To AYON" - families = ["clip", "shot"] + families = ["clip", "shot", "csv_ingest_shot"] def process(self, context): if not context.data.get("hierarchyContext"): From f6547264fbcbd293036a4e23059e2774114c441c Mon Sep 17 00:00:00 2001 From: "robin@ynput.io" Date: Tue, 12 Nov 2024 16:30:55 -0500 Subject: [PATCH 05/34] Fix lint. --- client/ayon_core/plugins/publish/collect_hierarchy.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/ayon_core/plugins/publish/collect_hierarchy.py b/client/ayon_core/plugins/publish/collect_hierarchy.py index e4b4dd408f..3340430345 100644 --- a/client/ayon_core/plugins/publish/collect_hierarchy.py +++ b/client/ayon_core/plugins/publish/collect_hierarchy.py @@ -64,7 +64,7 @@ def process(self, context): "resolutionWidth": instance.data["resolutionWidth"], "resolutionHeight": instance.data["resolutionHeight"], "pixelAspect": instance.data["pixelAspect"], - } + } # Split by '/' for AYON where asset is a path name = instance.data["folderPath"].split("/")[-1] From d2229fbb156bd9f74fc31b0a1c30d1b648f6d727 Mon Sep 17 00:00:00 2001 From: Robin De Lillo Date: Mon, 18 Nov 2024 08:16:02 -0500 Subject: [PATCH 06/34] Apply suggestions from code review Co-authored-by: Jakub Trllo <43494761+iLLiCiTiT@users.noreply.github.com> --- client/ayon_core/plugins/publish/collect_hierarchy.py | 11 +++++++---- .../plugins/publish/extract_hierarchy_to_ayon.py | 1 - 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/client/ayon_core/plugins/publish/collect_hierarchy.py b/client/ayon_core/plugins/publish/collect_hierarchy.py index 3340430345..531b6a1d76 100644 --- a/client/ayon_core/plugins/publish/collect_hierarchy.py +++ b/client/ayon_core/plugins/publish/collect_hierarchy.py @@ -13,7 +13,6 @@ class CollectHierarchy(pyblish.api.ContextPlugin): label = "Collect Hierarchy" order = pyblish.api.CollectorOrder - 0.076 - families = ["shot", "csv_ingest_shot"] hosts = ["resolve", "hiero", "flame", "traypublisher"] def process(self, context): @@ -38,9 +37,12 @@ def process(self, context): ): continue - # exclude if not CSV ingest shot and not masterLayer True - if ("csv_ingest_shot" not in families and - not instance.data.get("heroTrack")): + # Skip if is not a hero track + # - skip check for traypubliser CSV ingest + if ( + not instance.data.get("heroTrack") + and "csv_ingest_shot" not in families + ): continue shot_data = { @@ -52,6 +54,7 @@ def process(self, context): "comments": instance.data.get("comments", []), } + # TODO Fill in reason why we don't set attributes for csv_ingest_shot if "csv_ingest_shot" not in families: shot_data["attributes"] = { "handleStart": instance.data["handleStart"], diff --git a/client/ayon_core/plugins/publish/extract_hierarchy_to_ayon.py b/client/ayon_core/plugins/publish/extract_hierarchy_to_ayon.py index 390ce36126..25467fd94f 100644 --- a/client/ayon_core/plugins/publish/extract_hierarchy_to_ayon.py +++ b/client/ayon_core/plugins/publish/extract_hierarchy_to_ayon.py @@ -22,7 +22,6 @@ class ExtractHierarchyToAYON(pyblish.api.ContextPlugin): order = pyblish.api.ExtractorOrder - 0.01 label = "Extract Hierarchy To AYON" - families = ["clip", "shot", "csv_ingest_shot"] def process(self, context): if not context.data.get("hierarchyContext"): From 4a4377b489c643f6a4a60edebfcf7b9c59c4079b Mon Sep 17 00:00:00 2001 From: "robin@ynput.io" Date: Mon, 18 Nov 2024 13:38:21 -0500 Subject: [PATCH 07/34] Rework to avoid csv_ingest_shot family. --- .../plugins/publish/collect_hierarchy.py | 51 ++++++++++--------- .../publish/collect_otio_frame_ranges.py | 4 ++ 2 files changed, 32 insertions(+), 23 deletions(-) diff --git a/client/ayon_core/plugins/publish/collect_hierarchy.py b/client/ayon_core/plugins/publish/collect_hierarchy.py index 531b6a1d76..5e3be3d86d 100644 --- a/client/ayon_core/plugins/publish/collect_hierarchy.py +++ b/client/ayon_core/plugins/publish/collect_hierarchy.py @@ -31,18 +31,14 @@ def process(self, context): product_type = instance.data["productType"] families = instance.data["families"] - # exclude other families then self.families with intersection - if not set(self.families).intersection( - set(families + [product_type]) - ): + # exclude other families then "shot" with intersection + if "shot" not in (families + [product_type]): + self.log.debug("Skipping not a shot: {}".format(families)) continue # Skip if is not a hero track - # - skip check for traypubliser CSV ingest - if ( - not instance.data.get("heroTrack") - and "csv_ingest_shot" not in families - ): + if not instance.data.get("heroTrack"): + self.log.debug("Skipping not a shot from hero track") continue shot_data = { @@ -54,20 +50,29 @@ def process(self, context): "comments": instance.data.get("comments", []), } - # TODO Fill in reason why we don't set attributes for csv_ingest_shot - if "csv_ingest_shot" not in families: - shot_data["attributes"] = { - "handleStart": instance.data["handleStart"], - "handleEnd": instance.data["handleEnd"], - "frameStart": instance.data["frameStart"], - "frameEnd": instance.data["frameEnd"], - "clipIn": instance.data["clipIn"], - "clipOut": instance.data["clipOut"], - "fps": instance.data["fps"], - "resolutionWidth": instance.data["resolutionWidth"], - "resolutionHeight": instance.data["resolutionHeight"], - "pixelAspect": instance.data["pixelAspect"], - } + shot_data["attributes"] = {} + SHOT_ATTRS = ( + "handleStart", + "handleEnd", + "frameStart", + "frameEnd", + "clipIn", + "clipOut", + "fps", + "resolutionWidth", + "resolutionHeight", + "pixelAspect", + ) + for shot_attr in SHOT_ATTRS: + if shot_attr not in instance.data: + # Shot attribute might not be defined (e.g. CSV ingest) + self.log.debug( + "%s shot attribute is not defined for instance.", + shot_attr + ) + continue + + shot_data["attributes"][shot_attr] = instance.data[shot_attr] # Split by '/' for AYON where asset is a path name = instance.data["folderPath"].split("/")[-1] diff --git a/client/ayon_core/plugins/publish/collect_otio_frame_ranges.py b/client/ayon_core/plugins/publish/collect_otio_frame_ranges.py index d1c8d03212..62b4cefec6 100644 --- a/client/ayon_core/plugins/publish/collect_otio_frame_ranges.py +++ b/client/ayon_core/plugins/publish/collect_otio_frame_ranges.py @@ -29,6 +29,10 @@ def process(self, instance): otio_range_with_handles ) + if not instance.data.get("otioClip"): + self.log.debug("Skipping collect OTIO frame range.") + return + # get basic variables otio_clip = instance.data["otioClip"] workfile_start = instance.data["workfileFrameStart"] From ff56393da87def3555cbebacb9d6907e27c2f523 Mon Sep 17 00:00:00 2001 From: "robin@ynput.io" Date: Mon, 18 Nov 2024 13:40:09 -0500 Subject: [PATCH 08/34] Fix linting. --- client/ayon_core/plugins/publish/collect_hierarchy.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/ayon_core/plugins/publish/collect_hierarchy.py b/client/ayon_core/plugins/publish/collect_hierarchy.py index 5e3be3d86d..4c606fdc10 100644 --- a/client/ayon_core/plugins/publish/collect_hierarchy.py +++ b/client/ayon_core/plugins/publish/collect_hierarchy.py @@ -61,7 +61,7 @@ def process(self, context): "fps", "resolutionWidth", "resolutionHeight", - "pixelAspect", + "pixelAspect", ) for shot_attr in SHOT_ATTRS: if shot_attr not in instance.data: From 83cc964ca041a95d6af426c39ec7b92ee7706bc5 Mon Sep 17 00:00:00 2001 From: Robin De Lillo Date: Tue, 19 Nov 2024 08:07:52 -0500 Subject: [PATCH 09/34] Apply suggestions from code review Co-authored-by: Jakub Trllo <43494761+iLLiCiTiT@users.noreply.github.com> --- client/ayon_core/plugins/publish/collect_hierarchy.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/client/ayon_core/plugins/publish/collect_hierarchy.py b/client/ayon_core/plugins/publish/collect_hierarchy.py index 4c606fdc10..39501a9ed5 100644 --- a/client/ayon_core/plugins/publish/collect_hierarchy.py +++ b/client/ayon_core/plugins/publish/collect_hierarchy.py @@ -64,7 +64,8 @@ def process(self, context): "pixelAspect", ) for shot_attr in SHOT_ATTRS: - if shot_attr not in instance.data: + attr_value = instance.data.get(shot_attr) + if attr_value is None: # Shot attribute might not be defined (e.g. CSV ingest) self.log.debug( "%s shot attribute is not defined for instance.", @@ -72,7 +73,7 @@ def process(self, context): ) continue - shot_data["attributes"][shot_attr] = instance.data[shot_attr] + shot_data["attributes"][shot_attr] = attr_value # Split by '/' for AYON where asset is a path name = instance.data["folderPath"].split("/")[-1] From 70a38a6b1a3025ad653c2338dccfb30bdc9e0249 Mon Sep 17 00:00:00 2001 From: "robin@ynput.io" Date: Tue, 19 Nov 2024 08:22:13 -0500 Subject: [PATCH 10/34] Fix linting. --- client/ayon_core/plugins/publish/collect_hierarchy.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/ayon_core/plugins/publish/collect_hierarchy.py b/client/ayon_core/plugins/publish/collect_hierarchy.py index 39501a9ed5..cae89bd6bf 100644 --- a/client/ayon_core/plugins/publish/collect_hierarchy.py +++ b/client/ayon_core/plugins/publish/collect_hierarchy.py @@ -65,7 +65,7 @@ def process(self, context): ) for shot_attr in SHOT_ATTRS: attr_value = instance.data.get(shot_attr) - if attr_value is None: + if attr_value is None: # Shot attribute might not be defined (e.g. CSV ingest) self.log.debug( "%s shot attribute is not defined for instance.", From 26e5c2f52b05fd09c681305ffc151a3863aafbc5 Mon Sep 17 00:00:00 2001 From: "robin@ynput.io" Date: Tue, 19 Nov 2024 09:28:16 -0500 Subject: [PATCH 11/34] Adjust folder type creation in collect_hierarchy. --- client/ayon_core/plugins/publish/collect_hierarchy.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/client/ayon_core/plugins/publish/collect_hierarchy.py b/client/ayon_core/plugins/publish/collect_hierarchy.py index cae89bd6bf..00f5c06c0b 100644 --- a/client/ayon_core/plugins/publish/collect_hierarchy.py +++ b/client/ayon_core/plugins/publish/collect_hierarchy.py @@ -43,9 +43,8 @@ def process(self, context): shot_data = { "entity_type": "folder", - # WARNING Default folder type is hardcoded - # suppose that all instances are Shots - "folder_type": "Shot", + # WARNING unless overwritten, default folder type is hardcoded to shot + "folder_type": instance.data.get("folder_type") or "Shot", "tasks": instance.data.get("tasks") or {}, "comments": instance.data.get("comments", []), } From 582dce426fb2005fe8878e69a5f191a87ba4e073 Mon Sep 17 00:00:00 2001 From: Petr Kalis Date: Thu, 21 Nov 2024 12:35:24 +0100 Subject: [PATCH 12/34] Fix typo --- client/ayon_core/tools/creator/widgets.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/ayon_core/tools/creator/widgets.py b/client/ayon_core/tools/creator/widgets.py index 53a2ee1080..09f4e1fa32 100644 --- a/client/ayon_core/tools/creator/widgets.py +++ b/client/ayon_core/tools/creator/widgets.py @@ -104,7 +104,7 @@ def __init__(self): def validate(self, text, pos): results = super(ProductNameValidator, self).validate(text, pos) - if results[0] == self.Invalid: + if results[0] == self.invalid: self.invalid.emit(self.invalid_chars(text)) return results From 5ccdfc258a97e519e97cac5ac0d254678f27f1aa Mon Sep 17 00:00:00 2001 From: Petr Kalis Date: Thu, 21 Nov 2024 12:36:21 +0100 Subject: [PATCH 13/34] Fix plugins returning empty list --- client/ayon_core/tools/pyblish_pype/model.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/client/ayon_core/tools/pyblish_pype/model.py b/client/ayon_core/tools/pyblish_pype/model.py index 3a402f386e..7c242c817a 100644 --- a/client/ayon_core/tools/pyblish_pype/model.py +++ b/client/ayon_core/tools/pyblish_pype/model.py @@ -780,6 +780,8 @@ def restore_checkstates(self): def update_with_result(self, result): instance = result["instance"] + if isinstance(instance, list): + instance = instance.pop() if instance else None if instance is None: instance_id = self.controller.context.id else: @@ -976,6 +978,8 @@ def prepare_records(self, result, suspend_logs): prepared_records = [] instance_name = None instance = result["instance"] + if isinstance(instance, list): + instance = instance.pop() if instance else None if instance is not None: instance_name = instance.data["name"] From c56cd07e67b22b4e34cf6c246229150799fa5ab0 Mon Sep 17 00:00:00 2001 From: Petr Kalis Date: Thu, 21 Nov 2024 12:47:37 +0100 Subject: [PATCH 14/34] Provided backward compatibility for prepare_representations --- client/ayon_core/pipeline/farm/pyblish_functions.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/client/ayon_core/pipeline/farm/pyblish_functions.py b/client/ayon_core/pipeline/farm/pyblish_functions.py index e9f179c668..e236ec6c3d 100644 --- a/client/ayon_core/pipeline/farm/pyblish_functions.py +++ b/client/ayon_core/pipeline/farm/pyblish_functions.py @@ -333,7 +333,13 @@ def prepare_representations( log = Logger.get_logger("farm_publishing") - frames_to_render = _get_real_frames_to_render(frames_to_render) + if frames_to_render is not None: + frames_to_render = _get_real_frames_to_render(frames_to_render) + else: + # Backwards compatibility for older logic + frame_start = int(skeleton_data.get("frameStartHandle")) + frame_end = int(skeleton_data.get("frameEndHandle")) + frames_to_render = list(range(frame_start, frame_end + 1)) # create representation for every collected sequence for collection in collections: From c2716872d43d20f1e7de051375244893cd192d38 Mon Sep 17 00:00:00 2001 From: Petr Kalis Date: Thu, 21 Nov 2024 12:49:24 +0100 Subject: [PATCH 15/34] Do not convert to str unnecessary Co-authored-by: Jakub Trllo <43494761+iLLiCiTiT@users.noreply.github.com> --- client/ayon_core/pipeline/farm/pyblish_functions.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/client/ayon_core/pipeline/farm/pyblish_functions.py b/client/ayon_core/pipeline/farm/pyblish_functions.py index e9f179c668..aa69633a22 100644 --- a/client/ayon_core/pipeline/farm/pyblish_functions.py +++ b/client/ayon_core/pipeline/farm/pyblish_functions.py @@ -482,7 +482,8 @@ def _get_real_frames_to_render(frames): range(int(splitted[0]), int(splitted[1])+1)) else: frames_to_render.append(frame) - return [str(frame_to_render) for frame_to_render in frames_to_render] + frames_to_render.sort() + return frames_to_render def _get_real_files_to_rendered(collection, frames_to_render): From de88260ddac22419b3a87606aaae08bfc9ec4e09 Mon Sep 17 00:00:00 2001 From: Petr Kalis Date: Thu, 21 Nov 2024 12:50:23 +0100 Subject: [PATCH 16/34] frames_to_render are now list of integers Co-authored-by: Jakub Trllo <43494761+iLLiCiTiT@users.noreply.github.com> --- client/ayon_core/pipeline/farm/pyblish_functions.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/ayon_core/pipeline/farm/pyblish_functions.py b/client/ayon_core/pipeline/farm/pyblish_functions.py index aa69633a22..876a5b504f 100644 --- a/client/ayon_core/pipeline/farm/pyblish_functions.py +++ b/client/ayon_core/pipeline/farm/pyblish_functions.py @@ -481,7 +481,7 @@ def _get_real_frames_to_render(frames): frames_to_render.extend( range(int(splitted[0]), int(splitted[1])+1)) else: - frames_to_render.append(frame) + frames_to_render.append(int(frame)) frames_to_render.sort() return frames_to_render From 630d2d49130a9cea142aea999203fc00106a269d Mon Sep 17 00:00:00 2001 From: Petr Kalis Date: Thu, 21 Nov 2024 12:50:36 +0100 Subject: [PATCH 17/34] frames_to_render are now list of integers Co-authored-by: Jakub Trllo <43494761+iLLiCiTiT@users.noreply.github.com> --- client/ayon_core/pipeline/farm/pyblish_functions.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/client/ayon_core/pipeline/farm/pyblish_functions.py b/client/ayon_core/pipeline/farm/pyblish_functions.py index 876a5b504f..6740950d78 100644 --- a/client/ayon_core/pipeline/farm/pyblish_functions.py +++ b/client/ayon_core/pipeline/farm/pyblish_functions.py @@ -371,8 +371,8 @@ def prepare_representations( " This may cause issues on farm." ).format(staging)) - frame_start = int(frames_to_render[0]) - frame_end = int(frames_to_render[-1]) + frame_start = frames_to_render[0] + frame_end = frames_to_render[-1] if skeleton_data.get("slate"): frame_start -= 1 From 5f3175258725853011ab4b9eb2c58c1fc6959eda Mon Sep 17 00:00:00 2001 From: Petr Kalis Date: Thu, 21 Nov 2024 12:50:59 +0100 Subject: [PATCH 18/34] Used comprehension Co-authored-by: Jakub Trllo <43494761+iLLiCiTiT@users.noreply.github.com> --- client/ayon_core/pipeline/farm/pyblish_functions.py | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/client/ayon_core/pipeline/farm/pyblish_functions.py b/client/ayon_core/pipeline/farm/pyblish_functions.py index 6740950d78..09df371371 100644 --- a/client/ayon_core/pipeline/farm/pyblish_functions.py +++ b/client/ayon_core/pipeline/farm/pyblish_functions.py @@ -498,11 +498,10 @@ def _get_real_files_to_rendered(collection, frames_to_render): file_name, extracted_frame = list(collect_frames(files).items())[0] if extracted_frame: found_frame_pattern_length = len(extracted_frame) - normalized_frames_to_render = set() - for frame_to_render in frames_to_render: - normalized_frames_to_render.add( - str(frame_to_render).zfill(found_frame_pattern_length) - ) + normalized_frames_to_render = { + str(frame_to_render).zfill(found_frame_pattern_length) + for frame_to_render in frames_to_render + } filtered_files = [] for file_name in files: From fd20885ac26366b996c2b14d102cbefdc3a75341 Mon Sep 17 00:00:00 2001 From: Petr Kalis Date: Thu, 21 Nov 2024 12:51:12 +0100 Subject: [PATCH 19/34] Used comprehension Co-authored-by: Jakub Trllo <43494761+iLLiCiTiT@users.noreply.github.com> --- .../ayon_core/pipeline/farm/pyblish_functions.py | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/client/ayon_core/pipeline/farm/pyblish_functions.py b/client/ayon_core/pipeline/farm/pyblish_functions.py index 09df371371..4ba088f92c 100644 --- a/client/ayon_core/pipeline/farm/pyblish_functions.py +++ b/client/ayon_core/pipeline/farm/pyblish_functions.py @@ -503,13 +503,14 @@ def _get_real_files_to_rendered(collection, frames_to_render): for frame_to_render in frames_to_render } - filtered_files = [] - for file_name in files: - if any(frame in file_name - for frame in normalized_frames_to_render): - filtered_files.append(file_name) - - files = filtered_files + files = [ + filename + for filename in files + if any( + frame in filename + for frame in normalized_frames_to_render + ) + ] return files From 80ab628d44b083f168e1a7e822f4f1145d40145b Mon Sep 17 00:00:00 2001 From: Petr Kalis Date: Thu, 21 Nov 2024 12:52:51 +0100 Subject: [PATCH 20/34] Changed condition to bail early --- .../pipeline/farm/pyblish_functions.py | 28 ++++++++++--------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/client/ayon_core/pipeline/farm/pyblish_functions.py b/client/ayon_core/pipeline/farm/pyblish_functions.py index e236ec6c3d..37a018e116 100644 --- a/client/ayon_core/pipeline/farm/pyblish_functions.py +++ b/client/ayon_core/pipeline/farm/pyblish_functions.py @@ -501,21 +501,23 @@ def _get_real_files_to_rendered(collection, frames_to_render): """ files = [os.path.basename(f) for f in list(collection)] file_name, extracted_frame = list(collect_frames(files).items())[0] - if extracted_frame: - found_frame_pattern_length = len(extracted_frame) - normalized_frames_to_render = set() - for frame_to_render in frames_to_render: - normalized_frames_to_render.add( - str(frame_to_render).zfill(found_frame_pattern_length) - ) + if not extracted_frame: + return files + + found_frame_pattern_length = len(extracted_frame) + normalized_frames_to_render = set() + for frame_to_render in frames_to_render: + normalized_frames_to_render.add( + str(frame_to_render).zfill(found_frame_pattern_length) + ) - filtered_files = [] - for file_name in files: - if any(frame in file_name - for frame in normalized_frames_to_render): - filtered_files.append(file_name) + filtered_files = [] + for file_name in files: + if any(frame in file_name + for frame in normalized_frames_to_render): + filtered_files.append(file_name) - files = filtered_files + files = filtered_files return files From 0c5777910a7e96acde12cdf11b7df86d67e6a5e2 Mon Sep 17 00:00:00 2001 From: Petr Kalis Date: Thu, 21 Nov 2024 14:26:07 +0100 Subject: [PATCH 21/34] Revert "Fix plugins returning empty list" This reverts commit 5ccdfc258a97e519e97cac5ac0d254678f27f1aa. --- client/ayon_core/tools/pyblish_pype/model.py | 4 ---- 1 file changed, 4 deletions(-) diff --git a/client/ayon_core/tools/pyblish_pype/model.py b/client/ayon_core/tools/pyblish_pype/model.py index 7c242c817a..3a402f386e 100644 --- a/client/ayon_core/tools/pyblish_pype/model.py +++ b/client/ayon_core/tools/pyblish_pype/model.py @@ -780,8 +780,6 @@ def restore_checkstates(self): def update_with_result(self, result): instance = result["instance"] - if isinstance(instance, list): - instance = instance.pop() if instance else None if instance is None: instance_id = self.controller.context.id else: @@ -978,8 +976,6 @@ def prepare_records(self, result, suspend_logs): prepared_records = [] instance_name = None instance = result["instance"] - if isinstance(instance, list): - instance = instance.pop() if instance else None if instance is not None: instance_name = instance.data["name"] From 962df74e640f9661489b2ac6433a55d913fcd07d Mon Sep 17 00:00:00 2001 From: Petr Kalis Date: Thu, 21 Nov 2024 14:27:06 +0100 Subject: [PATCH 22/34] Better RegularExpressionValidatorClass.Invalid used --- client/ayon_core/tools/creator/widgets.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/ayon_core/tools/creator/widgets.py b/client/ayon_core/tools/creator/widgets.py index 09f4e1fa32..96ce899881 100644 --- a/client/ayon_core/tools/creator/widgets.py +++ b/client/ayon_core/tools/creator/widgets.py @@ -104,7 +104,7 @@ def __init__(self): def validate(self, text, pos): results = super(ProductNameValidator, self).validate(text, pos) - if results[0] == self.invalid: + if results[0] == RegularExpressionValidatorClass.Invalid: self.invalid.emit(self.invalid_chars(text)) return results From 63592f9e2bb799350338e5f29e39cdc59bd28077 Mon Sep 17 00:00:00 2001 From: Petr Kalis Date: Thu, 21 Nov 2024 14:32:54 +0100 Subject: [PATCH 23/34] Used comprehension Co-authored-by: Jakub Trllo <43494761+iLLiCiTiT@users.noreply.github.com> --- client/ayon_core/pipeline/farm/pyblish_functions.py | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/client/ayon_core/pipeline/farm/pyblish_functions.py b/client/ayon_core/pipeline/farm/pyblish_functions.py index e1d83a175e..e3470f4c41 100644 --- a/client/ayon_core/pipeline/farm/pyblish_functions.py +++ b/client/ayon_core/pipeline/farm/pyblish_functions.py @@ -507,11 +507,10 @@ def _get_real_files_to_rendered(collection, frames_to_render): return files found_frame_pattern_length = len(extracted_frame) - normalized_frames_to_render = set() - for frame_to_render in frames_to_render: - normalized_frames_to_render.add( - str(frame_to_render).zfill(found_frame_pattern_length) - ) + normalized_frames_to_render = { + str(frame_to_render).zfill(found_frame_pattern_length) + for frame_to_render in frames_to_render + } filtered_files = [] for file_name in files: From 112c4bdc0eec32f7d140964a911d88c5926a27e7 Mon Sep 17 00:00:00 2001 From: Petr Kalis Date: Thu, 21 Nov 2024 14:33:08 +0100 Subject: [PATCH 24/34] Used comprehension Co-authored-by: Jakub Trllo <43494761+iLLiCiTiT@users.noreply.github.com> --- .../ayon_core/pipeline/farm/pyblish_functions.py | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/client/ayon_core/pipeline/farm/pyblish_functions.py b/client/ayon_core/pipeline/farm/pyblish_functions.py index e3470f4c41..16364a17ee 100644 --- a/client/ayon_core/pipeline/farm/pyblish_functions.py +++ b/client/ayon_core/pipeline/farm/pyblish_functions.py @@ -512,14 +512,14 @@ def _get_real_files_to_rendered(collection, frames_to_render): for frame_to_render in frames_to_render } - filtered_files = [] - for file_name in files: - if any(frame in file_name - for frame in normalized_frames_to_render): - filtered_files.append(file_name) - - files = filtered_files - return files + return [ + file_name + for file_name in files + if any( + frame in file_name + for frame in normalized_frames_to_render + ) + ] def create_instances_for_aov(instance, skeleton, aov_filter, From c1b83046b7d7bfc3d0284f1134d4966bebda872a Mon Sep 17 00:00:00 2001 From: Ynbot Date: Thu, 21 Nov 2024 13:33:12 +0000 Subject: [PATCH 25/34] [Automated] Add generated package files to main --- client/ayon_core/version.py | 2 +- package.py | 2 +- pyproject.toml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/client/ayon_core/version.py b/client/ayon_core/version.py index 63f7de04dc..e75a940be9 100644 --- a/client/ayon_core/version.py +++ b/client/ayon_core/version.py @@ -1,3 +1,3 @@ # -*- coding: utf-8 -*- """Package declaring AYON addon 'core' version.""" -__version__ = "1.0.8+dev" +__version__ = "1.0.9" diff --git a/package.py b/package.py index bbfcc51019..c4da1ded1e 100644 --- a/package.py +++ b/package.py @@ -1,6 +1,6 @@ name = "core" title = "Core" -version = "1.0.8+dev" +version = "1.0.9" client_dir = "ayon_core" diff --git a/pyproject.toml b/pyproject.toml index e29aa08c6d..1a7882bdb5 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -5,7 +5,7 @@ [tool.poetry] name = "ayon-core" -version = "1.0.8+dev" +version = "1.0.9" description = "" authors = ["Ynput Team "] readme = "README.md" From 8bfcd92f1c7383bd069c7e259f3ebcdbeb8cab41 Mon Sep 17 00:00:00 2001 From: Ynbot Date: Thu, 21 Nov 2024 13:33:50 +0000 Subject: [PATCH 26/34] [Automated] Update version in package.py for develop --- client/ayon_core/version.py | 2 +- package.py | 2 +- pyproject.toml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/client/ayon_core/version.py b/client/ayon_core/version.py index e75a940be9..ab8c9424fa 100644 --- a/client/ayon_core/version.py +++ b/client/ayon_core/version.py @@ -1,3 +1,3 @@ # -*- coding: utf-8 -*- """Package declaring AYON addon 'core' version.""" -__version__ = "1.0.9" +__version__ = "1.0.9+dev" diff --git a/package.py b/package.py index c4da1ded1e..b90db4cde4 100644 --- a/package.py +++ b/package.py @@ -1,6 +1,6 @@ name = "core" title = "Core" -version = "1.0.9" +version = "1.0.9+dev" client_dir = "ayon_core" diff --git a/pyproject.toml b/pyproject.toml index 1a7882bdb5..f2d09d925d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -5,7 +5,7 @@ [tool.poetry] name = "ayon-core" -version = "1.0.9" +version = "1.0.9+dev" description = "" authors = ["Ynput Team "] readme = "README.md" From ddf0a2b00a6cad3677924ec25ef6341daeb92001 Mon Sep 17 00:00:00 2001 From: Jakub Trllo <43494761+iLLiCiTiT@users.noreply.github.com> Date: Thu, 21 Nov 2024 15:00:43 +0100 Subject: [PATCH 27/34] force to use older opencolorio than 2.4.0 --- client/pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/pyproject.toml b/client/pyproject.toml index a0be9605b6..20b51ff219 100644 --- a/client/pyproject.toml +++ b/client/pyproject.toml @@ -15,6 +15,6 @@ qtawesome = "0.7.3" aiohttp-middlewares = "^2.0.0" Click = "^8" OpenTimelineIO = "0.16.0" -opencolorio = "^2.3.2" +opencolorio = "<2.4.0" Pillow = "9.5.0" websocket-client = ">=0.40.0,<2" From 5b35547072b89f25c4c53d41612fa7d5b27b1d6f Mon Sep 17 00:00:00 2001 From: Jakub Trllo <43494761+iLLiCiTiT@users.noreply.github.com> Date: Thu, 21 Nov 2024 15:10:57 +0100 Subject: [PATCH 28/34] fix syntax of version requirement --- client/pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/pyproject.toml b/client/pyproject.toml index 20b51ff219..edf7f57317 100644 --- a/client/pyproject.toml +++ b/client/pyproject.toml @@ -15,6 +15,6 @@ qtawesome = "0.7.3" aiohttp-middlewares = "^2.0.0" Click = "^8" OpenTimelineIO = "0.16.0" -opencolorio = "<2.4.0" +opencolorio = "^2.3.2,<2.4.0" Pillow = "9.5.0" websocket-client = ">=0.40.0,<2" From 207b1961a441b4d13df7eac7e80faf39b4468ace Mon Sep 17 00:00:00 2001 From: Jakub Trllo <43494761+iLLiCiTiT@users.noreply.github.com> Date: Mon, 25 Nov 2024 10:35:21 +0100 Subject: [PATCH 29/34] support all errors in ruff linter --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index f2d09d925d..d09fabf8b2 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -68,7 +68,7 @@ target-version = "py39" [tool.ruff.lint] # Enable Pyflakes (`F`) and a subset of the pycodestyle (`E`) codes by default. -select = ["E4", "E7", "E9", "F", "W"] +select = ["E", "F", "W"] ignore = [] # Allow fix for all enabled rules (when `--fix`) is provided. From d30d5b541994a2243d41252a44459d39d0696123 Mon Sep 17 00:00:00 2001 From: Jakub Trllo <43494761+iLLiCiTiT@users.noreply.github.com> Date: Mon, 25 Nov 2024 10:37:05 +0100 Subject: [PATCH 30/34] fix line lengths --- client/ayon_core/addon/base.py | 4 +-- client/ayon_core/cli.py | 3 +- client/ayon_core/lib/attribute_definitions.py | 4 ++- client/ayon_core/pipeline/create/context.py | 14 ++++++--- .../ayon_core/pipeline/create/product_name.py | 6 +++- client/ayon_core/pipeline/editorial.py | 13 ++++++-- .../pipeline/farm/pyblish_functions.py | 20 +++++++++--- .../plugins/publish/collect_hierarchy.py | 3 +- .../plugins/publish/extract_otio_review.py | 31 ++++++++++++------- .../publish/validate_unique_subsets.py | 10 +++--- client/ayon_core/scripts/otio_burnin.py | 17 ++++++---- client/ayon_core/settings/lib.py | 3 +- client/ayon_core/tools/creator/widgets.py | 4 ++- .../tools/launcher/models/actions.py | 6 ++-- .../tools/loader/ui/_multicombobox.py | 6 +++- .../tools/loader/ui/products_model.py | 6 ++-- .../publisher/widgets/overview_widget.py | 4 ++- .../publisher/widgets/product_context.py | 6 ++-- .../tools/publisher/widgets/tasks_model.py | 4 +-- client/ayon_core/tools/publisher/window.py | 6 +++- .../tools/sceneinventory/models/containers.py | 4 +-- client/ayon_core/tools/utils/lib.py | 7 +++-- server/settings/publish_plugins.py | 21 +++++++++---- server/settings/tools.py | 8 +++-- .../editorial/test_extract_otio_review.py | 31 +++++++++++-------- 25 files changed, 159 insertions(+), 82 deletions(-) diff --git a/client/ayon_core/addon/base.py b/client/ayon_core/addon/base.py index 982626ad9d..364a84cb7b 100644 --- a/client/ayon_core/addon/base.py +++ b/client/ayon_core/addon/base.py @@ -535,8 +535,8 @@ def ensure_is_process_ready( Implementation of this method is optional. Note: - The logic can be similar to logic in tray, but tray does not require - to be logged in. + The logic can be similar to logic in tray, but tray does not + require to be logged in. Args: process_context (ProcessContext): Context of child diff --git a/client/ayon_core/cli.py b/client/ayon_core/cli.py index b80b243db2..6b4a1f824f 100644 --- a/client/ayon_core/cli.py +++ b/client/ayon_core/cli.py @@ -146,7 +146,8 @@ def publish_report_viewer(): @main_cli.command() @click.argument("output_path") @click.option("--project", help="Define project context") -@click.option("--folder", help="Define folder in project (project must be set)") +@click.option( + "--folder", help="Define folder in project (project must be set)") @click.option( "--strict", is_flag=True, diff --git a/client/ayon_core/lib/attribute_definitions.py b/client/ayon_core/lib/attribute_definitions.py index e1381944f6..e8327a45b6 100644 --- a/client/ayon_core/lib/attribute_definitions.py +++ b/client/ayon_core/lib/attribute_definitions.py @@ -616,7 +616,9 @@ def serialize(self): return data @staticmethod - def prepare_enum_items(items: "EnumItemsInputType") -> List["EnumItemDict"]: + def prepare_enum_items( + items: "EnumItemsInputType" + ) -> List["EnumItemDict"]: """Convert items to unified structure. Output is a list where each item is dictionary with 'value' diff --git a/client/ayon_core/pipeline/create/context.py b/client/ayon_core/pipeline/create/context.py index 6bfd64b822..e29971415d 100644 --- a/client/ayon_core/pipeline/create/context.py +++ b/client/ayon_core/pipeline/create/context.py @@ -1283,12 +1283,16 @@ def bulk_value_changes(self, sender=None): @contextmanager def bulk_pre_create_attr_defs_change(self, sender=None): - with self._bulk_context("pre_create_attrs_change", sender) as bulk_info: + with self._bulk_context( + "pre_create_attrs_change", sender + ) as bulk_info: yield bulk_info @contextmanager def bulk_create_attr_defs_change(self, sender=None): - with self._bulk_context("create_attrs_change", sender) as bulk_info: + with self._bulk_context( + "create_attrs_change", sender + ) as bulk_info: yield bulk_info @contextmanager @@ -1946,9 +1950,9 @@ def remove_instances(self, instances, sender=None): creator are just removed from context. Args: - instances (List[CreatedInstance]): Instances that should be removed. - Remove logic is done using creator, which may require to - do other cleanup than just remove instance from context. + instances (List[CreatedInstance]): Instances that should be + removed. Remove logic is done using creator, which may require + to do other cleanup than just remove instance from context. sender (Optional[str]): Sender of the event. """ diff --git a/client/ayon_core/pipeline/create/product_name.py b/client/ayon_core/pipeline/create/product_name.py index eaeef6500e..0daec8a7ad 100644 --- a/client/ayon_core/pipeline/create/product_name.py +++ b/client/ayon_core/pipeline/create/product_name.py @@ -1,5 +1,9 @@ import ayon_api -from ayon_core.lib import StringTemplate, filter_profiles, prepare_template_data +from ayon_core.lib import ( + StringTemplate, + filter_profiles, + prepare_template_data, +) from ayon_core.settings import get_project_settings from .constants import DEFAULT_PRODUCT_TEMPLATE diff --git a/client/ayon_core/pipeline/editorial.py b/client/ayon_core/pipeline/editorial.py index a49a981d2a..2928ef5f63 100644 --- a/client/ayon_core/pipeline/editorial.py +++ b/client/ayon_core/pipeline/editorial.py @@ -222,6 +222,9 @@ def remap_range_on_file_sequence(otio_clip, in_out_range): source_range = otio_clip.source_range available_range_rate = available_range.start_time.rate media_in = available_range.start_time.value + available_range_start_frame = ( + available_range.start_time.to_frames() + ) # Temporary. # Some AYON custom OTIO exporter were implemented with relative @@ -230,7 +233,7 @@ def remap_range_on_file_sequence(otio_clip, in_out_range): # while we are updating those. if ( is_clip_from_media_sequence(otio_clip) - and otio_clip.available_range().start_time.to_frames() == media_ref.start_frame + and available_range_start_frame == media_ref.start_frame and source_range.start_time.to_frames() < media_ref.start_frame ): media_in = 0 @@ -303,8 +306,12 @@ def get_media_range_with_retimes(otio_clip, handle_start, handle_end): rounded_av_rate = round(available_range_rate, 2) rounded_src_rate = round(source_range.start_time.rate, 2) if rounded_av_rate != rounded_src_rate: - conformed_src_in = source_range.start_time.rescaled_to(available_range_rate) - conformed_src_duration = source_range.duration.rescaled_to(available_range_rate) + conformed_src_in = source_range.start_time.rescaled_to( + available_range_rate + ) + conformed_src_duration = source_range.duration.rescaled_to( + available_range_rate + ) conformed_source_range = otio.opentime.TimeRange( start_time=conformed_src_in, duration=conformed_src_duration diff --git a/client/ayon_core/pipeline/farm/pyblish_functions.py b/client/ayon_core/pipeline/farm/pyblish_functions.py index 16364a17ee..559561c827 100644 --- a/client/ayon_core/pipeline/farm/pyblish_functions.py +++ b/client/ayon_core/pipeline/farm/pyblish_functions.py @@ -8,7 +8,10 @@ import ayon_api import clique from ayon_core.lib import Logger, collect_frames -from ayon_core.pipeline import get_current_project_name, get_representation_path +from ayon_core.pipeline import ( + get_current_project_name, + get_representation_path, +) from ayon_core.pipeline.create import get_product_name from ayon_core.pipeline.farm.patterning import match_aov_pattern from ayon_core.pipeline.publish import KnownPublishError @@ -771,9 +774,14 @@ def _create_instances_for_aov(instance, skeleton, aov_filter, additional_data, project_settings = instance.context.data.get("project_settings") - use_legacy_product_name = True try: - use_legacy_product_name = project_settings["core"]["tools"]["creator"]["use_legacy_product_names_for_renders"] # noqa: E501 + use_legacy_product_name = ( + project_settings + ["core"] + ["tools"] + ["creator"] + ["use_legacy_product_names_for_renders"] + ) except KeyError: warnings.warn( ("use_legacy_for_renders not found in project settings. " @@ -789,7 +797,9 @@ def _create_instances_for_aov(instance, skeleton, aov_filter, additional_data, dynamic_data=dynamic_data) else: - product_name, group_name = get_product_name_and_group_from_template( + ( + product_name, group_name + ) = get_product_name_and_group_from_template( task_entity=instance.data["taskEntity"], project_name=instance.context.data["projectName"], host_name=instance.context.data["hostName"], @@ -932,7 +942,7 @@ def _collect_expected_files_for_aov(files): # but we really expect only one collection. # Nothing else make sense. if len(cols) != 1: - raise ValueError("Only one image sequence type is expected.") # noqa: E501 + raise ValueError("Only one image sequence type is expected.") return list(cols[0]) diff --git a/client/ayon_core/plugins/publish/collect_hierarchy.py b/client/ayon_core/plugins/publish/collect_hierarchy.py index 00f5c06c0b..266c2e1458 100644 --- a/client/ayon_core/plugins/publish/collect_hierarchy.py +++ b/client/ayon_core/plugins/publish/collect_hierarchy.py @@ -43,7 +43,8 @@ def process(self, context): shot_data = { "entity_type": "folder", - # WARNING unless overwritten, default folder type is hardcoded to shot + # WARNING unless overwritten, default folder type is hardcoded + # to shot "folder_type": instance.data.get("folder_type") or "Shot", "tasks": instance.data.get("tasks") or {}, "comments": instance.data.get("comments", []), diff --git a/client/ayon_core/plugins/publish/extract_otio_review.py b/client/ayon_core/plugins/publish/extract_otio_review.py index b222c6efc3..fb9b269258 100644 --- a/client/ayon_core/plugins/publish/extract_otio_review.py +++ b/client/ayon_core/plugins/publish/extract_otio_review.py @@ -129,26 +129,33 @@ def process(self, instance): res_data[key] = value break - self.to_width, self.to_height = res_data["width"], res_data["height"] - self.log.debug("> self.to_width x self.to_height: {} x {}".format( - self.to_width, self.to_height - )) + self.to_width, self.to_height = ( + res_data["width"], res_data["height"] + ) + self.log.debug( + "> self.to_width x self.to_height:" + f" {self.to_width} x {self.to_height}" + ) available_range = r_otio_cl.available_range() + available_range_start_frame = ( + available_range.start_time.to_frames() + ) processing_range = None self.actual_fps = available_range.duration.rate start = src_range.start_time.rescaled_to(self.actual_fps) duration = src_range.duration.rescaled_to(self.actual_fps) + src_frame_start = src_range.start_time.to_frames() # Temporary. - # Some AYON custom OTIO exporter were implemented with relative - # source range for image sequence. Following code maintain - # backward-compatibility by adjusting available range + # Some AYON custom OTIO exporter were implemented with + # relative source range for image sequence. Following code + # maintain backward-compatibility by adjusting available range # while we are updating those. if ( is_clip_from_media_sequence(r_otio_cl) - and available_range.start_time.to_frames() == media_ref.start_frame - and src_range.start_time.to_frames() < media_ref.start_frame + and available_range_start_frame == media_ref.start_frame + and src_frame_start < media_ref.start_frame ): available_range = otio.opentime.TimeRange( otio.opentime.RationalTime(0, rate=self.actual_fps), @@ -246,7 +253,8 @@ def process(self, instance): # Extraction via FFmpeg. else: path = media_ref.target_url - # Set extract range from 0 (FFmpeg ignores embedded timecode). + # Set extract range from 0 (FFmpeg ignores + # embedded timecode). extract_range = otio.opentime.TimeRange( otio.opentime.RationalTime( ( @@ -414,7 +422,8 @@ def _render_segment(self, sequence=None, to defined image sequence format. Args: - sequence (list): input dir path string, collection object, fps in list + sequence (list): input dir path string, collection object, + fps in list. video (list)[optional]: video_path string, otio_range in list gap (int)[optional]: gap duration end_offset (int)[optional]: offset gap frame start in frames diff --git a/client/ayon_core/plugins/publish/validate_unique_subsets.py b/client/ayon_core/plugins/publish/validate_unique_subsets.py index 4badeb8112..4067dd75a5 100644 --- a/client/ayon_core/plugins/publish/validate_unique_subsets.py +++ b/client/ayon_core/plugins/publish/validate_unique_subsets.py @@ -11,8 +11,8 @@ class ValidateProductUniqueness(pyblish.api.ContextPlugin): """Validate all product names are unique. This only validates whether the instances currently set to publish from - the workfile overlap one another for the folder + product they are publishing - to. + the workfile overlap one another for the folder + product they are + publishing to. This does not perform any check against existing publishes in the database since it is allowed to publish into existing products resulting in @@ -72,8 +72,10 @@ def process(self, context): # All is ok return - msg = ("Instance product names {} are not unique. ".format(non_unique) + - "Please remove or rename duplicates.") + msg = ( + f"Instance product names {non_unique} are not unique." + " Please remove or rename duplicates." + ) formatting_data = { "non_unique": ",".join(non_unique) } diff --git a/client/ayon_core/scripts/otio_burnin.py b/client/ayon_core/scripts/otio_burnin.py index 6b132b9a6a..cb72606222 100644 --- a/client/ayon_core/scripts/otio_burnin.py +++ b/client/ayon_core/scripts/otio_burnin.py @@ -79,7 +79,8 @@ class ModifiedBurnins(ffmpeg_burnins.Burnins): - Datatypes explanation: string format must be supported by FFmpeg. Examples: "#000000", "0x000000", "black" - must be accesible by ffmpeg = name of registered Font in system or path to font file. + must be accesible by ffmpeg = name of registered Font in system + or path to font file. Examples: "Arial", "C:/Windows/Fonts/arial.ttf" - Possible keys: @@ -87,17 +88,21 @@ class ModifiedBurnins(ffmpeg_burnins.Burnins): "bg_opacity" - Opacity of background (box around text) - "bg_color" - Background color - "bg_padding" - Background padding in pixels - - "x_offset" - offsets burnin vertically by entered pixels from border - - "y_offset" - offsets burnin horizontally by entered pixels from border - + "x_offset" - offsets burnin vertically by entered pixels + from border - + "y_offset" - offsets burnin horizontally by entered pixels + from border - - x_offset & y_offset should be set at least to same value as bg_padding!! "font" - Font Family for text - "font_size" - Font size in pixels - "font_color" - Color of text - "frame_offset" - Default start frame - - - required IF start frame is not set when using frames or timecode burnins + - required IF start frame is not set when using frames + or timecode burnins - On initializing class can be set General options through "options_init" arg. - General can be overridden when adding burnin + On initializing class can be set General options through + "options_init" arg. + General options can be overridden when adding burnin. ''' TOP_CENTERED = ffmpeg_burnins.TOP_CENTERED diff --git a/client/ayon_core/settings/lib.py b/client/ayon_core/settings/lib.py index 3126bafd57..aa56fa8326 100644 --- a/client/ayon_core/settings/lib.py +++ b/client/ayon_core/settings/lib.py @@ -190,6 +190,7 @@ def get_current_project_settings(): project_name = os.environ.get("AYON_PROJECT_NAME") if not project_name: raise ValueError( - "Missing context project in environemt variable `AYON_PROJECT_NAME`." + "Missing context project in environment" + " variable `AYON_PROJECT_NAME`." ) return get_project_settings(project_name) diff --git a/client/ayon_core/tools/creator/widgets.py b/client/ayon_core/tools/creator/widgets.py index 96ce899881..bbc6848e6c 100644 --- a/client/ayon_core/tools/creator/widgets.py +++ b/client/ayon_core/tools/creator/widgets.py @@ -217,7 +217,9 @@ def __init__(self, parent=None): product_type_label = QtWidgets.QLabel(self) product_type_label.setObjectName("CreatorProductTypeLabel") - product_type_label.setAlignment(QtCore.Qt.AlignBottom | QtCore.Qt.AlignLeft) + product_type_label.setAlignment( + QtCore.Qt.AlignBottom | QtCore.Qt.AlignLeft + ) help_label = QtWidgets.QLabel(self) help_label.setAlignment(QtCore.Qt.AlignTop | QtCore.Qt.AlignLeft) diff --git a/client/ayon_core/tools/launcher/models/actions.py b/client/ayon_core/tools/launcher/models/actions.py index 7158c05431..8bd30daffa 100644 --- a/client/ayon_core/tools/launcher/models/actions.py +++ b/client/ayon_core/tools/launcher/models/actions.py @@ -21,9 +21,9 @@ class ApplicationAction(LauncherAction): Application action based on 'ApplicationManager' system. - Handling of applications in launcher is not ideal and should be completely - redone from scratch. This is just a temporary solution to keep backwards - compatibility with AYON launcher. + Handling of applications in launcher is not ideal and should be + completely redone from scratch. This is just a temporary solution + to keep backwards compatibility with AYON launcher. Todos: Move handling of errors to frontend. diff --git a/client/ayon_core/tools/loader/ui/_multicombobox.py b/client/ayon_core/tools/loader/ui/_multicombobox.py index c026952418..9efe57ef0f 100644 --- a/client/ayon_core/tools/loader/ui/_multicombobox.py +++ b/client/ayon_core/tools/loader/ui/_multicombobox.py @@ -517,7 +517,11 @@ def _paint_items(self, painter, indexes, content_rect): def setItemCheckState(self, index, state): self.setItemData(index, state, QtCore.Qt.CheckStateRole) - def set_value(self, values: Optional[Iterable[Any]], role: Optional[int] = None): + def set_value( + self, + values: Optional[Iterable[Any]], + role: Optional[int] = None, + ): if role is None: role = self._value_role diff --git a/client/ayon_core/tools/loader/ui/products_model.py b/client/ayon_core/tools/loader/ui/products_model.py index bc24d4d7f7..3571788134 100644 --- a/client/ayon_core/tools/loader/ui/products_model.py +++ b/client/ayon_core/tools/loader/ui/products_model.py @@ -499,8 +499,10 @@ def refresh(self, project_name, folder_ids): version_item.version_id for version_item in last_version_by_product_id.values() } - repre_count_by_version_id = self._controller.get_versions_representation_count( - project_name, version_ids + repre_count_by_version_id = ( + self._controller.get_versions_representation_count( + project_name, version_ids + ) ) sync_availability_by_version_id = ( self._controller.get_version_sync_availability( diff --git a/client/ayon_core/tools/publisher/widgets/overview_widget.py b/client/ayon_core/tools/publisher/widgets/overview_widget.py index a09ee80ed5..c6c3b774f0 100644 --- a/client/ayon_core/tools/publisher/widgets/overview_widget.py +++ b/client/ayon_core/tools/publisher/widgets/overview_widget.py @@ -339,7 +339,9 @@ def _on_change_anim_finished(self): self._change_visibility_for_state() self._product_content_layout.addWidget(self._create_widget, 7) self._product_content_layout.addWidget(self._product_views_widget, 3) - self._product_content_layout.addWidget(self._product_attributes_wrap, 7) + self._product_content_layout.addWidget( + self._product_attributes_wrap, 7 + ) def _change_visibility_for_state(self): self._create_widget.setVisible( diff --git a/client/ayon_core/tools/publisher/widgets/product_context.py b/client/ayon_core/tools/publisher/widgets/product_context.py index 04c9ca7e56..30b318982b 100644 --- a/client/ayon_core/tools/publisher/widgets/product_context.py +++ b/client/ayon_core/tools/publisher/widgets/product_context.py @@ -214,8 +214,8 @@ class TasksCombobox(QtWidgets.QComboBox): Combobox gives ability to select only from intersection of task names for folder paths in selected instances. - If folder paths in selected instances does not have same tasks then combobox - will be empty. + If folder paths in selected instances does not have same tasks + then combobox will be empty. """ value_changed = QtCore.Signal() @@ -604,7 +604,7 @@ def set_value(self, variants=None): class GlobalAttrsWidget(QtWidgets.QWidget): - """Global attributes mainly to define context and product name of instances. + """Global attributes to define context and product name of instances. product name is or may be affected on context. Gives abiity to modify context and product name of instance. This change is not autopromoted but diff --git a/client/ayon_core/tools/publisher/widgets/tasks_model.py b/client/ayon_core/tools/publisher/widgets/tasks_model.py index 16a4111f59..8bfa81116a 100644 --- a/client/ayon_core/tools/publisher/widgets/tasks_model.py +++ b/client/ayon_core/tools/publisher/widgets/tasks_model.py @@ -22,8 +22,8 @@ class TasksModel(QtGui.QStandardItemModel): tasks with same names then model is empty too. Args: - controller (AbstractPublisherFrontend): Controller which handles creation and - publishing. + controller (AbstractPublisherFrontend): Controller which handles + creation and publishing. """ def __init__( diff --git a/client/ayon_core/tools/publisher/window.py b/client/ayon_core/tools/publisher/window.py index a912495d4e..ed5b909a55 100644 --- a/client/ayon_core/tools/publisher/window.py +++ b/client/ayon_core/tools/publisher/window.py @@ -998,7 +998,11 @@ def _on_creator_error(self, event): new_item["label"] = new_item.pop("creator_label") new_item["identifier"] = new_item.pop("creator_identifier") new_failed_info.append(new_item) - self.add_error_message_dialog(event["title"], new_failed_info, "Creator:") + self.add_error_message_dialog( + event["title"], + new_failed_info, + "Creator:" + ) def _on_convertor_error(self, event): new_failed_info = [] diff --git a/client/ayon_core/tools/sceneinventory/models/containers.py b/client/ayon_core/tools/sceneinventory/models/containers.py index 4f3ddf1ded..4280445b60 100644 --- a/client/ayon_core/tools/sceneinventory/models/containers.py +++ b/client/ayon_core/tools/sceneinventory/models/containers.py @@ -366,8 +366,8 @@ def _update_cache(self): try: uuid.UUID(repre_id) except (ValueError, TypeError, AttributeError): - # Fake not existing representation id so container is shown in UI - # but as invalid + # Fake not existing representation id so container + # is shown in UI but as invalid item.representation_id = invalid_ids_mapping.setdefault( repre_id, uuid.uuid4().hex ) diff --git a/client/ayon_core/tools/utils/lib.py b/client/ayon_core/tools/utils/lib.py index 200e281664..4b303c0143 100644 --- a/client/ayon_core/tools/utils/lib.py +++ b/client/ayon_core/tools/utils/lib.py @@ -556,9 +556,10 @@ def get_qta_icon_by_name_and_color(cls, icon_name, icon_color): log.info("Didn't find icon \"{}\"".format(icon_name)) elif used_variant != icon_name: - log.debug("Icon \"{}\" was not found \"{}\" is used instead".format( - icon_name, used_variant - )) + log.debug( + f"Icon \"{icon_name}\" was not found" + f" \"{used_variant}\" is used instead" + ) cls._qtawesome_cache[full_icon_name] = icon return icon diff --git a/server/settings/publish_plugins.py b/server/settings/publish_plugins.py index 16b1f37187..8893b00e23 100644 --- a/server/settings/publish_plugins.py +++ b/server/settings/publish_plugins.py @@ -358,7 +358,10 @@ class ExtractOIIOTranscodeOutputModel(BaseSettingsModel): custom_tags: list[str] = SettingsField( default_factory=list, title="Custom Tags", - description="Additional custom tags that will be added to the created representation." + description=( + "Additional custom tags that will be added" + " to the created representation." + ) ) @@ -892,9 +895,11 @@ class PublishPuginsModel(BaseSettingsModel): default_factory=CollectFramesFixDefModel, title="Collect Frames to Fix", ) - CollectUSDLayerContributions: CollectUSDLayerContributionsModel = SettingsField( - default_factory=CollectUSDLayerContributionsModel, - title="Collect USD Layer Contributions", + CollectUSDLayerContributions: CollectUSDLayerContributionsModel = ( + SettingsField( + default_factory=CollectUSDLayerContributionsModel, + title="Collect USD Layer Contributions", + ) ) ValidateEditorialAssetName: ValidateBaseModel = SettingsField( default_factory=ValidateBaseModel, @@ -1214,7 +1219,9 @@ class PublishPuginsModel(BaseSettingsModel): "TOP_RIGHT": "{anatomy[version]}", "BOTTOM_LEFT": "{username}", "BOTTOM_CENTERED": "{folder[name]}", - "BOTTOM_RIGHT": "{frame_start}-{current_frame}-{frame_end}", + "BOTTOM_RIGHT": ( + "{frame_start}-{current_frame}-{frame_end}" + ), "filter": { "families": [], "tags": [] @@ -1240,7 +1247,9 @@ class PublishPuginsModel(BaseSettingsModel): "TOP_RIGHT": "{anatomy[version]}", "BOTTOM_LEFT": "{username}", "BOTTOM_CENTERED": "{folder[name]}", - "BOTTOM_RIGHT": "{frame_start}-{current_frame}-{frame_end}", + "BOTTOM_RIGHT": ( + "{frame_start}-{current_frame}-{frame_end}" + ), "filter": { "families": [], "tags": [] diff --git a/server/settings/tools.py b/server/settings/tools.py index a2785c1edf..96851be1da 100644 --- a/server/settings/tools.py +++ b/server/settings/tools.py @@ -83,8 +83,8 @@ class CreatorToolModel(BaseSettingsModel): filter_creator_profiles: list[FilterCreatorProfile] = SettingsField( default_factory=list, title="Filter creator profiles", - description="Allowed list of creator labels that will be only shown if " - "profile matches context." + description="Allowed list of creator labels that will be only shown" + " if profile matches context." ) @validator("product_types_smart_select") @@ -426,7 +426,9 @@ class GlobalToolsModel(BaseSettingsModel): ], "task_types": [], "tasks": [], - "template": "{product[type]}{Task[name]}_{Renderlayer}_{Renderpass}" + "template": ( + "{product[type]}{Task[name]}_{Renderlayer}_{Renderpass}" + ) }, { "product_types": [ diff --git a/tests/client/ayon_core/pipeline/editorial/test_extract_otio_review.py b/tests/client/ayon_core/pipeline/editorial/test_extract_otio_review.py index ea31e1a260..8b1c9da30e 100644 --- a/tests/client/ayon_core/pipeline/editorial/test_extract_otio_review.py +++ b/tests/client/ayon_core/pipeline/editorial/test_extract_otio_review.py @@ -130,19 +130,20 @@ def test_image_sequence_and_handles_out_of_range(): expected = [ # 5 head black frames generated from gap (991-995) - "/path/to/ffmpeg -t 0.2 -r 25.0 -f lavfi -i color=c=black:s=1280x720 -tune " - "stillimage -start_number 991 C:/result/output.%03d.jpg", + "/path/to/ffmpeg -t 0.2 -r 25.0 -f lavfi -i color=c=black:s=1280x720" + " -tune stillimage -start_number 991 C:/result/output.%03d.jpg", # 9 tail back frames generated from gap (1097-1105) - "/path/to/ffmpeg -t 0.36 -r 25.0 -f lavfi -i color=c=black:s=1280x720 -tune " - "stillimage -start_number 1097 C:/result/output.%03d.jpg", + "/path/to/ffmpeg -t 0.36 -r 25.0 -f lavfi -i color=c=black:s=1280x720" + " -tune stillimage -start_number 1097 C:/result/output.%03d.jpg", # Report from source tiff (996-1096) # 996-1000 = additional 5 head frames # 1001-1095 = source range conformed to 25fps # 1096-1096 = additional 1 tail frames "/path/to/ffmpeg -start_number 1000 -framerate 25.0 -i " - f"C:\\tif_seq{os.sep}output.%04d.tif -start_number 996 C:/result/output.%03d.jpg" + f"C:\\tif_seq{os.sep}output.%04d.tif -start_number 996" + f" C:/result/output.%03d.jpg" ] assert calls == expected @@ -179,13 +180,13 @@ def test_short_movie_head_gap_handles(): expected = [ # 10 head black frames generated from gap (991-1000) - "/path/to/ffmpeg -t 0.4 -r 25.0 -f lavfi -i color=c=black:s=1280x720 -tune " - "stillimage -start_number 991 C:/result/output.%03d.jpg", + "/path/to/ffmpeg -t 0.4 -r 25.0 -f lavfi -i color=c=black:s=1280x720" + " -tune stillimage -start_number 991 C:/result/output.%03d.jpg", # source range + 10 tail frames # duration = 50fr (source) + 10fr (tail handle) = 60 fr = 2.4s - "/path/to/ffmpeg -ss 0.0 -t 2.4 -i C:\\data\\movie.mp4 -start_number 1001 " - "C:/result/output.%03d.jpg" + "/path/to/ffmpeg -ss 0.0 -t 2.4 -i C:\\data\\movie.mp4" + " -start_number 1001 C:/result/output.%03d.jpg" ] assert calls == expected @@ -208,7 +209,8 @@ def test_short_movie_tail_gap_handles(): # 10 head frames + source range # duration = 10fr (head handle) + 66fr (source) = 76fr = 3.16s "/path/to/ffmpeg -ss 1.0416666666666667 -t 3.1666666666666665 -i " - "C:\\data\\qt_no_tc_24fps.mov -start_number 991 C:/result/output.%03d.jpg" + "C:\\data\\qt_no_tc_24fps.mov -start_number 991" + " C:/result/output.%03d.jpg" ] assert calls == expected @@ -234,10 +236,12 @@ def test_multiple_review_clips_no_gap(): expected = [ # 10 head black frames generated from gap (991-1000) - '/path/to/ffmpeg -t 0.4 -r 25.0 -f lavfi -i color=c=black:s=1280x720 -tune ' + '/path/to/ffmpeg -t 0.4 -r 25.0 -f lavfi' + ' -i color=c=black:s=1280x720 -tune ' 'stillimage -start_number 991 C:/result/output.%03d.jpg', - # Alternance 25fps tiff sequence and 24fps exr sequence for 100 frames each + # Alternance 25fps tiff sequence and 24fps exr sequence + # for 100 frames each '/path/to/ffmpeg -start_number 1000 -framerate 25.0 -i ' f'C:\\no_tc{os.sep}output.%04d.tif ' '-start_number 1001 C:/result/output.%03d.jpg', @@ -315,7 +319,8 @@ def test_multiple_review_clips_with_gap(): expected = [ # Gap on review track (12 frames) - '/path/to/ffmpeg -t 0.5 -r 24.0 -f lavfi -i color=c=black:s=1280x720 -tune ' + '/path/to/ffmpeg -t 0.5 -r 24.0 -f lavfi' + ' -i color=c=black:s=1280x720 -tune ' 'stillimage -start_number 991 C:/result/output.%03d.jpg', '/path/to/ffmpeg -start_number 1000 -framerate 24.0 -i ' From 3de2755de52567694e4dd1a248cbbfa69499e1b6 Mon Sep 17 00:00:00 2001 From: Jakub Trllo <43494761+iLLiCiTiT@users.noreply.github.com> Date: Mon, 25 Nov 2024 10:37:18 +0100 Subject: [PATCH 31/34] remove unrelated information from docstring --- client/ayon_core/lib/local_settings.py | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) diff --git a/client/ayon_core/lib/local_settings.py b/client/ayon_core/lib/local_settings.py index 690781151c..08030ae87e 100644 --- a/client/ayon_core/lib/local_settings.py +++ b/client/ayon_core/lib/local_settings.py @@ -276,12 +276,7 @@ def delete_item(self, name): @abstractmethod def _delete_item(self, name): # type: (str) -> None - """Delete item from settings. - - Note: - see :meth:`ayon_core.lib.user_settings.ARegistrySettings.delete_item` - - """ + """Delete item from settings.""" pass def __delitem__(self, name): @@ -433,12 +428,7 @@ def delete_item_from_section(self, section, name): config.write(cfg) def _delete_item(self, name): - """Delete item from default section. - - Note: - See :meth:`~ayon_core.lib.IniSettingsRegistry.delete_item_from_section` - - """ + """Delete item from default section.""" self.delete_item_from_section("MAIN", name) From ef6d7b5a6ce863c0a0231fb8da5ea939b6d29717 Mon Sep 17 00:00:00 2001 From: Jakub Trllo <43494761+iLLiCiTiT@users.noreply.github.com> Date: Mon, 25 Nov 2024 10:37:27 +0100 Subject: [PATCH 32/34] put noqa at correct place --- client/ayon_core/pipeline/entity_uri.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/client/ayon_core/pipeline/entity_uri.py b/client/ayon_core/pipeline/entity_uri.py index 1dee9a1423..1362389ee9 100644 --- a/client/ayon_core/pipeline/entity_uri.py +++ b/client/ayon_core/pipeline/entity_uri.py @@ -18,13 +18,13 @@ def parse_ayon_entity_uri(uri: str) -> Optional[dict]: Example: >>> parse_ayon_entity_uri( - >>> "ayon://test/char/villain?product=modelMain&version=2&representation=usd" # noqa: E501 + >>> "ayon://test/char/villain?product=modelMain&version=2&representation=usd" >>> ) {'project': 'test', 'folderPath': '/char/villain', 'product': 'modelMain', 'version': 1, 'representation': 'usd'} >>> parse_ayon_entity_uri( - >>> "ayon+entity://project/folder?product=renderMain&version=3&representation=exr" # noqa: E501 + >>> "ayon+entity://project/folder?product=renderMain&version=3&representation=exr" >>> ) {'project': 'project', 'folderPath': '/folder', 'product': 'renderMain', 'version': 3, @@ -34,7 +34,7 @@ def parse_ayon_entity_uri(uri: str) -> Optional[dict]: dict[str, Union[str, int]]: The individual key with their values as found in the ayon entity URI. - """ + """ # noqa: E501 if not (uri.startswith("ayon+entity://") or uri.startswith("ayon://")): return {} From 07c246ba74ceb628a05ccd11bfea5e20bf393cfe Mon Sep 17 00:00:00 2001 From: ynbot Date: Mon, 25 Nov 2024 13:57:32 +0000 Subject: [PATCH 33/34] [Automated] Update assign_pr_to_project caller workflow --- .github/workflows/assign_pr_to_project.yml | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 .github/workflows/assign_pr_to_project.yml diff --git a/.github/workflows/assign_pr_to_project.yml b/.github/workflows/assign_pr_to_project.yml new file mode 100644 index 0000000000..86707fc9da --- /dev/null +++ b/.github/workflows/assign_pr_to_project.yml @@ -0,0 +1,15 @@ +name: 🔸Auto assign pr +on: + pull_request: + types: + - opened + +jobs: + auto-assign-pr: + uses: ynput/ops-repo-automation/.github/workflows/pr_to_project.yml@develop + with: + repo: "${{ github.repository }}" + project_id: 16 + pull_request_number: ${{ github.event.pull_request.number }} + secrets: + token: ${{ secrets.YNPUT_BOT_TOKEN }} From 333363f024119022437e5b520b2faa7bcf82e392 Mon Sep 17 00:00:00 2001 From: ynbot Date: Mon, 25 Nov 2024 14:07:54 +0000 Subject: [PATCH 34/34] [Automated] Update validate_pr_labels caller workflow --- .github/workflows/validate_pr_labels.yml | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 .github/workflows/validate_pr_labels.yml diff --git a/.github/workflows/validate_pr_labels.yml b/.github/workflows/validate_pr_labels.yml new file mode 100644 index 0000000000..00e5742afe --- /dev/null +++ b/.github/workflows/validate_pr_labels.yml @@ -0,0 +1,18 @@ +name: 🔎 Validate PR Labels +on: + pull_request: + types: + - opened + - edited + - labeled + - unlabeled + +jobs: + validate-type-label: + uses: ynput/ops-repo-automation/.github/workflows/validate_pr_labels.yml@develop + with: + repo: "${{ github.repository }}" + pull_request_number: ${{ github.event.pull_request.number }} + query_prefix: "type: " + secrets: + token: ${{ secrets.YNPUT_BOT_TOKEN }}