diff --git a/client/ayon_core/cli.py b/client/ayon_core/cli.py index 0ad4364bcd..2759b4fccf 100644 --- a/client/ayon_core/cli.py +++ b/client/ayon_core/cli.py @@ -103,19 +103,18 @@ def extractenvironments(output_json_path, project, asset, task, app, envgroup): @main_cli.command() -@click.argument("paths", nargs=-1) -@click.option("-t", "--targets", help="Targets module", default=None, +@click.argument("path", required=True) +@click.option("-t", "--targets", help="Targets", default=None, multiple=True) @click.option("-g", "--gui", is_flag=True, help="Show Publish UI", default=False) -def publish(paths, targets, gui): +def publish(path, targets, gui): """Start CLI publishing. - Publish collects json from paths provided as an argument. - More than one path is allowed. + Publish collects json from path provided as an argument. +S """ - - Commands.publish(list(paths), targets, gui) + Commands.publish(path, targets, gui) @main_cli.command(context_settings={"ignore_unknown_options": True}) diff --git a/client/ayon_core/cli_commands.py b/client/ayon_core/cli_commands.py index 156196c401..4335a3f2d9 100644 --- a/client/ayon_core/cli_commands.py +++ b/client/ayon_core/cli_commands.py @@ -3,6 +3,7 @@ import os import sys import json +import warnings class Commands: @@ -41,21 +42,21 @@ class Commands: return click_func @staticmethod - def publish(paths, targets=None, gui=False): + def publish(path: str, targets: list=None, gui:bool=False) -> None: """Start headless publishing. - Publish use json from passed paths argument. + Publish use json from passed path argument. Args: - paths (list): Paths to jsons. - targets (string): What module should be targeted - (to choose validator for example) + path (str): Path to JSON. + targets (list of str): List of pyblish targets. gui (bool): Show publish UI. Raises: RuntimeError: When there is no path to process. - """ + RuntimeError: When executed with list of JSON paths. + """ from ayon_core.lib import Logger from ayon_core.lib.applications import ( get_app_environments_for_context, @@ -73,6 +74,9 @@ class Commands: import pyblish.api import pyblish.util + if not isinstance(path, str): + raise RuntimeError("Path to JSON must be a string.") + # Fix older jobs for src_key, dst_key in ( ("AVALON_PROJECT", "AYON_PROJECT_NAME"), @@ -95,11 +99,8 @@ class Commands: publish_paths = manager.collect_plugin_paths()["publish"] - for path in publish_paths: - pyblish.api.register_plugin_path(path) - - if not any(paths): - raise RuntimeError("No publish paths specified") + for plugin_path in publish_paths: + pyblish.api.register_plugin_path(plugin_path) app_full_name = os.getenv("AYON_APP_NAME") if app_full_name: @@ -122,7 +123,7 @@ class Commands: else: pyblish.api.register_target("farm") - os.environ["AYON_PUBLISH_DATA"] = os.pathsep.join(paths) + os.environ["AYON_PUBLISH_DATA"] = path os.environ["HEADLESS_PUBLISH"] = 'true' # to use in app lib log.info("Running publish ...") diff --git a/client/ayon_core/hosts/aftereffects/plugins/load/load_background.py b/client/ayon_core/hosts/aftereffects/plugins/load/load_background.py index e45de5524e..7c9bd2fcfd 100644 --- a/client/ayon_core/hosts/aftereffects/plugins/load/load_background.py +++ b/client/ayon_core/hosts/aftereffects/plugins/load/load_background.py @@ -20,7 +20,7 @@ class BackgroundLoader(api.AfterEffectsLoader): metadata """ label = "Load JSON Background" - families = ["background"] + product_types = {"background"} representations = ["json"] def load(self, context, name=None, namespace=None, data=None): diff --git a/client/ayon_core/hosts/aftereffects/plugins/load/load_file.py b/client/ayon_core/hosts/aftereffects/plugins/load/load_file.py index 29536945dd..79e791af7b 100644 --- a/client/ayon_core/hosts/aftereffects/plugins/load/load_file.py +++ b/client/ayon_core/hosts/aftereffects/plugins/load/load_file.py @@ -12,12 +12,14 @@ class FileLoader(api.AfterEffectsLoader): """ label = "Load file" - families = ["image", - "plate", - "render", - "prerender", - "review", - "audio"] + product_types = { + "image", + "plate", + "render", + "prerender", + "review", + "audio", + } representations = ["*"] def load(self, context, name=None, namespace=None, data=None): diff --git a/client/ayon_core/hosts/blender/plugins/load/import_workfile.py b/client/ayon_core/hosts/blender/plugins/load/import_workfile.py index 7144c132e8..3aa73a5143 100644 --- a/client/ayon_core/hosts/blender/plugins/load/import_workfile.py +++ b/client/ayon_core/hosts/blender/plugins/load/import_workfile.py @@ -44,7 +44,7 @@ class AppendBlendLoader(plugin.AssetLoader): """ representations = ["blend"] - families = ["workfile"] + product_types = {"workfile"} label = "Append Workfile" order = 9 @@ -69,7 +69,7 @@ class ImportBlendLoader(plugin.AssetLoader): """ representations = ["blend"] - families = ["workfile"] + product_types = {"workfile"} label = "Import Workfile" order = 9 diff --git a/client/ayon_core/hosts/blender/plugins/load/load_abc.py b/client/ayon_core/hosts/blender/plugins/load/load_abc.py index 7ae9936ed5..938ae6106b 100644 --- a/client/ayon_core/hosts/blender/plugins/load/load_abc.py +++ b/client/ayon_core/hosts/blender/plugins/load/load_abc.py @@ -26,7 +26,7 @@ class CacheModelLoader(plugin.AssetLoader): Note: At least for now it only supports Alembic files. """ - families = ["model", "pointcache", "animation"] + product_types = {"model", "pointcache", "animation"} representations = ["abc"] label = "Load Alembic" diff --git a/client/ayon_core/hosts/blender/plugins/load/load_action.py b/client/ayon_core/hosts/blender/plugins/load/load_action.py index a079387b9f..4161f8bff3 100644 --- a/client/ayon_core/hosts/blender/plugins/load/load_action.py +++ b/client/ayon_core/hosts/blender/plugins/load/load_action.py @@ -24,7 +24,7 @@ class BlendActionLoader(plugin.AssetLoader): moment. """ - families = ["action"] + product_types = {"action"} representations = ["blend"] label = "Link Action" diff --git a/client/ayon_core/hosts/blender/plugins/load/load_animation.py b/client/ayon_core/hosts/blender/plugins/load/load_animation.py index b805790c28..effb91c48c 100644 --- a/client/ayon_core/hosts/blender/plugins/load/load_animation.py +++ b/client/ayon_core/hosts/blender/plugins/load/load_animation.py @@ -16,7 +16,7 @@ class BlendAnimationLoader(plugin.AssetLoader): moment. """ - families = ["animation"] + product_types = {"animation"} representations = ["blend"] label = "Link Animation" diff --git a/client/ayon_core/hosts/blender/plugins/load/load_audio.py b/client/ayon_core/hosts/blender/plugins/load/load_audio.py index de74bf95d3..db83c4bca2 100644 --- a/client/ayon_core/hosts/blender/plugins/load/load_audio.py +++ b/client/ayon_core/hosts/blender/plugins/load/load_audio.py @@ -20,7 +20,7 @@ from ayon_core.hosts.blender.api.pipeline import ( class AudioLoader(plugin.AssetLoader): """Load audio in Blender.""" - families = ["audio"] + product_types = {"audio"} representations = ["wav"] label = "Load Audio" diff --git a/client/ayon_core/hosts/blender/plugins/load/load_blend.py b/client/ayon_core/hosts/blender/plugins/load/load_blend.py index 465485ba86..e84dddc88f 100644 --- a/client/ayon_core/hosts/blender/plugins/load/load_blend.py +++ b/client/ayon_core/hosts/blender/plugins/load/load_blend.py @@ -20,7 +20,7 @@ from ayon_core.hosts.blender.api.pipeline import ( class BlendLoader(plugin.AssetLoader): """Load assets from a .blend file.""" - families = ["model", "rig", "layout", "camera"] + product_types = {"model", "rig", "layout", "camera"} representations = ["blend"] label = "Append Blend" diff --git a/client/ayon_core/hosts/blender/plugins/load/load_blendscene.py b/client/ayon_core/hosts/blender/plugins/load/load_blendscene.py index 2c93b739f8..627941752f 100644 --- a/client/ayon_core/hosts/blender/plugins/load/load_blendscene.py +++ b/client/ayon_core/hosts/blender/plugins/load/load_blendscene.py @@ -18,7 +18,7 @@ from ayon_core.hosts.blender.api.pipeline import ( class BlendSceneLoader(plugin.AssetLoader): """Load assets from a .blend file.""" - families = ["blendScene"] + product_types = {"blendScene"} representations = ["blend"] label = "Append Blend" diff --git a/client/ayon_core/hosts/blender/plugins/load/load_camera_abc.py b/client/ayon_core/hosts/blender/plugins/load/load_camera_abc.py index 98a4e2c2ec..e677fc3e58 100644 --- a/client/ayon_core/hosts/blender/plugins/load/load_camera_abc.py +++ b/client/ayon_core/hosts/blender/plugins/load/load_camera_abc.py @@ -23,7 +23,7 @@ class AbcCameraLoader(plugin.AssetLoader): Stores the imported asset in an empty named after the asset. """ - families = ["camera"] + product_types = {"camera"} representations = ["abc"] label = "Load Camera (ABC)" diff --git a/client/ayon_core/hosts/blender/plugins/load/load_camera_fbx.py b/client/ayon_core/hosts/blender/plugins/load/load_camera_fbx.py index f31e53270e..14d61a6395 100644 --- a/client/ayon_core/hosts/blender/plugins/load/load_camera_fbx.py +++ b/client/ayon_core/hosts/blender/plugins/load/load_camera_fbx.py @@ -23,7 +23,7 @@ class FbxCameraLoader(plugin.AssetLoader): Stores the imported asset in an empty named after the asset. """ - families = ["camera"] + product_types = {"camera"} representations = ["fbx"] label = "Load Camera (FBX)" diff --git a/client/ayon_core/hosts/blender/plugins/load/load_fbx.py b/client/ayon_core/hosts/blender/plugins/load/load_fbx.py index 1eaab4e7b7..0042482284 100644 --- a/client/ayon_core/hosts/blender/plugins/load/load_fbx.py +++ b/client/ayon_core/hosts/blender/plugins/load/load_fbx.py @@ -23,7 +23,7 @@ class FbxModelLoader(plugin.AssetLoader): Stores the imported asset in an empty named after the asset. """ - families = ["model", "rig"] + product_types = {"model", "rig"} representations = ["fbx"] label = "Load FBX" diff --git a/client/ayon_core/hosts/blender/plugins/load/load_layout_json.py b/client/ayon_core/hosts/blender/plugins/load/load_layout_json.py index f3d14ac018..7a3da1882e 100644 --- a/client/ayon_core/hosts/blender/plugins/load/load_layout_json.py +++ b/client/ayon_core/hosts/blender/plugins/load/load_layout_json.py @@ -26,7 +26,7 @@ from ayon_core.hosts.blender.api import plugin class JsonLayoutLoader(plugin.AssetLoader): """Load layout published from Unreal.""" - families = ["layout"] + product_types = {"layout"} representations = ["json"] label = "Load Layout" diff --git a/client/ayon_core/hosts/blender/plugins/load/load_look.py b/client/ayon_core/hosts/blender/plugins/load/load_look.py index 7cefbd5148..ce677a8471 100644 --- a/client/ayon_core/hosts/blender/plugins/load/load_look.py +++ b/client/ayon_core/hosts/blender/plugins/load/load_look.py @@ -23,7 +23,7 @@ class BlendLookLoader(plugin.AssetLoader): contains the model. There is no further need to 'containerise' it. """ - families = ["look"] + product_types = {"look"} representations = ["json"] label = "Load Look" diff --git a/client/ayon_core/hosts/flame/plugins/load/load_clip.py b/client/ayon_core/hosts/flame/plugins/load/load_clip.py index faa2b7145d..f528caeb29 100644 --- a/client/ayon_core/hosts/flame/plugins/load/load_clip.py +++ b/client/ayon_core/hosts/flame/plugins/load/load_clip.py @@ -17,7 +17,7 @@ class LoadClip(opfapi.ClipLoader): during conforming to project """ - families = ["render2d", "source", "plate", "render", "review"] + product_types = {"render2d", "source", "plate", "render", "review"} representations = ["*"] extensions = set( ext.lstrip(".") for ext in IMAGE_EXTENSIONS.union(VIDEO_EXTENSIONS) diff --git a/client/ayon_core/hosts/flame/plugins/load/load_clip_batch.py b/client/ayon_core/hosts/flame/plugins/load/load_clip_batch.py index 7eaaa308df..9bdd467d63 100644 --- a/client/ayon_core/hosts/flame/plugins/load/load_clip_batch.py +++ b/client/ayon_core/hosts/flame/plugins/load/load_clip_batch.py @@ -16,7 +16,7 @@ class LoadClipBatch(opfapi.ClipLoader): during conforming to project """ - families = ["render2d", "source", "plate", "render", "review"] + product_types = {"render2d", "source", "plate", "render", "review"} representations = ["*"] extensions = set( ext.lstrip(".") for ext in IMAGE_EXTENSIONS.union(VIDEO_EXTENSIONS) diff --git a/client/ayon_core/hosts/fusion/plugins/load/actions.py b/client/ayon_core/hosts/fusion/plugins/load/actions.py index 2fac884b2e..9600479680 100644 --- a/client/ayon_core/hosts/fusion/plugins/load/actions.py +++ b/client/ayon_core/hosts/fusion/plugins/load/actions.py @@ -8,13 +8,15 @@ from ayon_core.pipeline import load class FusionSetFrameRangeLoader(load.LoaderPlugin): """Set frame range excluding pre- and post-handles""" - families = ["animation", - "camera", - "imagesequence", - "render", - "yeticache", - "pointcache", - "render"] + product_types = { + "animation", + "camera", + "imagesequence", + "render", + "yeticache", + "pointcache", + "render", + } representations = ["*"] extensions = {"*"} @@ -43,13 +45,15 @@ class FusionSetFrameRangeLoader(load.LoaderPlugin): class FusionSetFrameRangeWithHandlesLoader(load.LoaderPlugin): """Set frame range including pre- and post-handles""" - families = ["animation", - "camera", - "imagesequence", - "render", - "yeticache", - "pointcache", - "render"] + product_types = { + "animation", + "camera", + "imagesequence", + "render", + "yeticache", + "pointcache", + "render", + } representations = ["*"] label = "Set frame range (with handles)" diff --git a/client/ayon_core/hosts/fusion/plugins/load/load_alembic.py b/client/ayon_core/hosts/fusion/plugins/load/load_alembic.py index d78a8b0ba0..ae2175964d 100644 --- a/client/ayon_core/hosts/fusion/plugins/load/load_alembic.py +++ b/client/ayon_core/hosts/fusion/plugins/load/load_alembic.py @@ -12,7 +12,7 @@ from ayon_core.hosts.fusion.api import ( class FusionLoadAlembicMesh(load.LoaderPlugin): """Load Alembic mesh into Fusion""" - families = ["pointcache", "model"] + product_types = {"pointcache", "model"} representations = ["*"] extensions = {"abc"} diff --git a/client/ayon_core/hosts/fusion/plugins/load/load_fbx.py b/client/ayon_core/hosts/fusion/plugins/load/load_fbx.py index d2e1885b0c..68b7cdacd1 100644 --- a/client/ayon_core/hosts/fusion/plugins/load/load_fbx.py +++ b/client/ayon_core/hosts/fusion/plugins/load/load_fbx.py @@ -12,7 +12,7 @@ from ayon_core.hosts.fusion.api import ( class FusionLoadFBXMesh(load.LoaderPlugin): """Load FBX mesh into Fusion""" - families = ["*"] + product_types = {"*"} representations = ["*"] extensions = { "3ds", diff --git a/client/ayon_core/hosts/fusion/plugins/load/load_sequence.py b/client/ayon_core/hosts/fusion/plugins/load/load_sequence.py index dfd7e4231b..f0a8233377 100644 --- a/client/ayon_core/hosts/fusion/plugins/load/load_sequence.py +++ b/client/ayon_core/hosts/fusion/plugins/load/load_sequence.py @@ -129,14 +129,14 @@ def loader_shift(loader, frame, relative=True): class FusionLoadSequence(load.LoaderPlugin): """Load image sequence into Fusion""" - families = [ + product_types = { "imagesequence", "review", "render", "plate", "image", "online", - ] + } representations = ["*"] extensions = set( ext.lstrip(".") for ext in IMAGE_EXTENSIONS.union(VIDEO_EXTENSIONS) diff --git a/client/ayon_core/hosts/fusion/plugins/load/load_usd.py b/client/ayon_core/hosts/fusion/plugins/load/load_usd.py index a609af6197..2f8eeb4c66 100644 --- a/client/ayon_core/hosts/fusion/plugins/load/load_usd.py +++ b/client/ayon_core/hosts/fusion/plugins/load/load_usd.py @@ -16,7 +16,7 @@ class FusionLoadUSD(load.LoaderPlugin): Support for USD was added since Fusion 18.5 """ - families = ["*"] + product_types = {"*"} representations = ["*"] extensions = {"usd", "usda", "usdz"} diff --git a/client/ayon_core/hosts/fusion/plugins/load/load_workfile.py b/client/ayon_core/hosts/fusion/plugins/load/load_workfile.py index d50fded502..fd2fa7c08b 100644 --- a/client/ayon_core/hosts/fusion/plugins/load/load_workfile.py +++ b/client/ayon_core/hosts/fusion/plugins/load/load_workfile.py @@ -14,7 +14,7 @@ from ayon_core.hosts.fusion.api import ( class FusionLoadWorkfile(load.LoaderPlugin): """Load the content of a workfile into Fusion""" - families = ["workfile"] + product_types = {"workfile"} representations = ["*"] extensions = {"comp"} diff --git a/client/ayon_core/hosts/harmony/api/README.md b/client/ayon_core/hosts/harmony/api/README.md index b9c21e1882..6d1e400476 100644 --- a/client/ayon_core/hosts/harmony/api/README.md +++ b/client/ayon_core/hosts/harmony/api/README.md @@ -582,7 +582,7 @@ class ImageSequenceLoader(load.LoaderPlugin): """Load images Stores the imported asset in a container named after the asset. """ - families = ["mindbender.imagesequence"] + product_types = {"mindbender.imagesequence"} representations = ["*"] def load(self, context, name=None, namespace=None, data=None): diff --git a/client/ayon_core/hosts/harmony/plugins/load/load_audio.py b/client/ayon_core/hosts/harmony/plugins/load/load_audio.py index 0f8aab6d57..00f3ac77ec 100644 --- a/client/ayon_core/hosts/harmony/plugins/load/load_audio.py +++ b/client/ayon_core/hosts/harmony/plugins/load/load_audio.py @@ -35,7 +35,7 @@ function %s(args) class ImportAudioLoader(load.LoaderPlugin): """Import audio.""" - families = ["shot", "audio"] + product_types = {"shot", "audio"} representations = ["wav"] label = "Import Audio" diff --git a/client/ayon_core/hosts/harmony/plugins/load/load_background.py b/client/ayon_core/hosts/harmony/plugins/load/load_background.py index 72b26c826a..74bc5a4fd8 100644 --- a/client/ayon_core/hosts/harmony/plugins/load/load_background.py +++ b/client/ayon_core/hosts/harmony/plugins/load/load_background.py @@ -233,7 +233,7 @@ class BackgroundLoader(load.LoaderPlugin): """Load images Stores the imported asset in a container named after the asset. """ - families = ["background"] + product_types = {"background"} representations = ["json"] def load(self, context, name=None, namespace=None, data=None): diff --git a/client/ayon_core/hosts/harmony/plugins/load/load_imagesequence.py b/client/ayon_core/hosts/harmony/plugins/load/load_imagesequence.py index 0fbcd03c92..bf4b87a03e 100644 --- a/client/ayon_core/hosts/harmony/plugins/load/load_imagesequence.py +++ b/client/ayon_core/hosts/harmony/plugins/load/load_imagesequence.py @@ -20,7 +20,14 @@ class ImageSequenceLoader(load.LoaderPlugin): Stores the imported asset in a container named after the asset. """ - families = ["shot", "render", "image", "plate", "reference", "review"] + product_types = { + "shot", + "render", + "image", + "plate", + "reference", + "review", + } representations = ["*"] extensions = {"jpeg", "png", "jpg"} diff --git a/client/ayon_core/hosts/harmony/plugins/load/load_palette.py b/client/ayon_core/hosts/harmony/plugins/load/load_palette.py index 79ae2fb154..d5fbeb323b 100644 --- a/client/ayon_core/hosts/harmony/plugins/load/load_palette.py +++ b/client/ayon_core/hosts/harmony/plugins/load/load_palette.py @@ -11,7 +11,7 @@ import ayon_core.hosts.harmony.api as harmony class ImportPaletteLoader(load.LoaderPlugin): """Import palettes.""" - families = ["palette", "harmony.palette"] + product_types = {"palette", "harmony.palette"} representations = ["plt"] label = "Import Palette" diff --git a/client/ayon_core/hosts/harmony/plugins/load/load_template.py b/client/ayon_core/hosts/harmony/plugins/load/load_template.py index 2d9af362eb..48064f2b75 100644 --- a/client/ayon_core/hosts/harmony/plugins/load/load_template.py +++ b/client/ayon_core/hosts/harmony/plugins/load/load_template.py @@ -23,7 +23,7 @@ class TemplateLoader(load.LoaderPlugin): """ - families = ["template", "workfile"] + product_types = {"template", "workfile"} representations = ["*"] label = "Load Template" icon = "gift" diff --git a/client/ayon_core/hosts/harmony/plugins/load/load_template_workfile.py b/client/ayon_core/hosts/harmony/plugins/load/load_template_workfile.py index 59d66b7cfc..7bf634f00c 100644 --- a/client/ayon_core/hosts/harmony/plugins/load/load_template_workfile.py +++ b/client/ayon_core/hosts/harmony/plugins/load/load_template_workfile.py @@ -13,7 +13,7 @@ import ayon_core.hosts.harmony.api as harmony class ImportTemplateLoader(load.LoaderPlugin): """Import templates.""" - families = ["harmony.template", "workfile"] + product_types = {"harmony.template", "workfile"} representations = ["*"] label = "Import Template" @@ -60,6 +60,6 @@ class ImportTemplateLoader(load.LoaderPlugin): class ImportWorkfileLoader(ImportTemplateLoader): """Import workfiles.""" - families = ["workfile"] + product_types = {"workfile"} representations = ["zip"] label = "Import Workfile" diff --git a/client/ayon_core/hosts/hiero/plugins/load/load_clip.py b/client/ayon_core/hosts/hiero/plugins/load/load_clip.py index c2ff907650..72d7e03a9a 100644 --- a/client/ayon_core/hosts/hiero/plugins/load/load_clip.py +++ b/client/ayon_core/hosts/hiero/plugins/load/load_clip.py @@ -15,7 +15,7 @@ class LoadClip(phiero.SequenceLoader): during conforming to project """ - families = ["render2d", "source", "plate", "render", "review"] + product_types = {"render2d", "source", "plate", "render", "review"} representations = ["*"] extensions = set( ext.lstrip(".") for ext in IMAGE_EXTENSIONS.union(VIDEO_EXTENSIONS) @@ -59,13 +59,7 @@ class LoadClip(phiero.SequenceLoader): if option == "representations": continue - if option == "product_types": - # TODO remove the key conversion when loaders can filter by - # product types - # convert 'product_types' to 'families' - option = "families" - - elif option == "clip_name_template": + if option == "clip_name_template": # TODO remove the formatting replacement value = ( value diff --git a/client/ayon_core/hosts/hiero/plugins/load/load_effects.py b/client/ayon_core/hosts/hiero/plugins/load/load_effects.py index 521a7c4494..fd6b8ed694 100644 --- a/client/ayon_core/hosts/hiero/plugins/load/load_effects.py +++ b/client/ayon_core/hosts/hiero/plugins/load/load_effects.py @@ -14,7 +14,7 @@ from ayon_core.lib import Logger class LoadEffects(load.LoaderPlugin): """Loading colorspace soft effect exported from nukestudio""" - families = ["effect"] + product_types = {"effect"} representations = ["*"] extension = {"json"} diff --git a/client/ayon_core/hosts/houdini/api/usd.py b/client/ayon_core/hosts/houdini/api/usd.py index 443a52bc37..ed33fbf590 100644 --- a/client/ayon_core/hosts/houdini/api/usd.py +++ b/client/ayon_core/hosts/houdini/api/usd.py @@ -8,8 +8,11 @@ from qtpy import QtWidgets, QtCore, QtGui from ayon_core import style from ayon_core.pipeline import get_current_project_name -from ayon_core.tools.utils import PlaceholderLineEdit, RefreshButton -from ayon_core.tools.ayon_utils.widgets import SimpleFoldersWidget +from ayon_core.tools.utils import ( + PlaceholderLineEdit, + RefreshButton, + SimpleFoldersWidget, +) from pxr import Sdf diff --git a/client/ayon_core/hosts/houdini/plugins/load/actions.py b/client/ayon_core/hosts/houdini/plugins/load/actions.py index 049869be25..c277005919 100644 --- a/client/ayon_core/hosts/houdini/plugins/load/actions.py +++ b/client/ayon_core/hosts/houdini/plugins/load/actions.py @@ -8,13 +8,13 @@ from ayon_core.pipeline import load class SetFrameRangeLoader(load.LoaderPlugin): """Set frame range excluding pre- and post-handles""" - families = [ + product_types = { "animation", "camera", "pointcache", "vdbcache", "usd", - ] + } representations = ["abc", "vdb", "usd"] label = "Set frame range" @@ -45,13 +45,13 @@ class SetFrameRangeLoader(load.LoaderPlugin): class SetFrameRangeWithHandlesLoader(load.LoaderPlugin): """Set frame range including pre- and post-handles""" - families = [ + product_types = { "animation", "camera", "pointcache", "vdbcache", "usd", - ] + } representations = ["abc", "vdb", "usd"] label = "Set frame range (with handles)" diff --git a/client/ayon_core/hosts/houdini/plugins/load/load_alembic.py b/client/ayon_core/hosts/houdini/plugins/load/load_alembic.py index 5235923b4c..3398920e87 100644 --- a/client/ayon_core/hosts/houdini/plugins/load/load_alembic.py +++ b/client/ayon_core/hosts/houdini/plugins/load/load_alembic.py @@ -9,7 +9,7 @@ from ayon_core.hosts.houdini.api import pipeline class AbcLoader(load.LoaderPlugin): """Load Alembic""" - families = ["model", "animation", "pointcache", "gpuCache"] + product_types = {"model", "animation", "pointcache", "gpuCache"} label = "Load Alembic" representations = ["abc"] order = -10 diff --git a/client/ayon_core/hosts/houdini/plugins/load/load_alembic_archive.py b/client/ayon_core/hosts/houdini/plugins/load/load_alembic_archive.py index 6585df3f17..8d3becb973 100644 --- a/client/ayon_core/hosts/houdini/plugins/load/load_alembic_archive.py +++ b/client/ayon_core/hosts/houdini/plugins/load/load_alembic_archive.py @@ -9,7 +9,7 @@ from ayon_core.hosts.houdini.api import pipeline class AbcArchiveLoader(load.LoaderPlugin): """Load Alembic as full geometry network hierarchy """ - families = ["model", "animation", "pointcache", "gpuCache"] + product_types = {"model", "animation", "pointcache", "gpuCache"} label = "Load Alembic as Archive" representations = ["abc"] order = -5 diff --git a/client/ayon_core/hosts/houdini/plugins/load/load_ass.py b/client/ayon_core/hosts/houdini/plugins/load/load_ass.py index 628b5b2f34..fd0e8f4604 100644 --- a/client/ayon_core/hosts/houdini/plugins/load/load_ass.py +++ b/client/ayon_core/hosts/houdini/plugins/load/load_ass.py @@ -11,7 +11,7 @@ from ayon_core.hosts.houdini.api import pipeline class AssLoader(load.LoaderPlugin): """Load .ass with Arnold Procedural""" - families = ["ass"] + product_types = {"ass"} label = "Load Arnold Procedural" representations = ["ass"] order = -10 diff --git a/client/ayon_core/hosts/houdini/plugins/load/load_bgeo.py b/client/ayon_core/hosts/houdini/plugins/load/load_bgeo.py index f02067db75..fd8071c0de 100644 --- a/client/ayon_core/hosts/houdini/plugins/load/load_bgeo.py +++ b/client/ayon_core/hosts/houdini/plugins/load/load_bgeo.py @@ -13,7 +13,7 @@ class BgeoLoader(load.LoaderPlugin): """Load bgeo files to Houdini.""" label = "Load bgeo" - families = ["model", "pointcache", "bgeo"] + product_types = {"model", "pointcache", "bgeo"} representations = [ "bgeo", "bgeosc", "bgeogz", "bgeo.sc", "bgeo.gz", "bgeo.lzma", "bgeo.bz2"] diff --git a/client/ayon_core/hosts/houdini/plugins/load/load_camera.py b/client/ayon_core/hosts/houdini/plugins/load/load_camera.py index 50fc7f4eb6..605e5724e6 100644 --- a/client/ayon_core/hosts/houdini/plugins/load/load_camera.py +++ b/client/ayon_core/hosts/houdini/plugins/load/load_camera.py @@ -87,7 +87,7 @@ def transfer_non_default_values(src, dest, ignore=None): class CameraLoader(load.LoaderPlugin): """Load camera from an Alembic file""" - families = ["camera"] + product_types = {"camera"} label = "Load Camera (abc)" representations = ["abc"] order = -10 diff --git a/client/ayon_core/hosts/houdini/plugins/load/load_fbx.py b/client/ayon_core/hosts/houdini/plugins/load/load_fbx.py index 2ebbed5e12..a0c5e0c934 100644 --- a/client/ayon_core/hosts/houdini/plugins/load/load_fbx.py +++ b/client/ayon_core/hosts/houdini/plugins/load/load_fbx.py @@ -16,7 +16,7 @@ class FbxLoader(load.LoaderPlugin): order = -10 - families = ["*"] + product_types = {"*"} representations = ["*"] extensions = {"fbx"} diff --git a/client/ayon_core/hosts/houdini/plugins/load/load_hda.py b/client/ayon_core/hosts/houdini/plugins/load/load_hda.py index 07949fd177..df77783a34 100644 --- a/client/ayon_core/hosts/houdini/plugins/load/load_hda.py +++ b/client/ayon_core/hosts/houdini/plugins/load/load_hda.py @@ -10,7 +10,7 @@ from ayon_core.hosts.houdini.api import pipeline class HdaLoader(load.LoaderPlugin): """Load Houdini Digital Asset file.""" - families = ["hda"] + product_types = {"hda"} label = "Load Hda" representations = ["hda"] order = -10 diff --git a/client/ayon_core/hosts/houdini/plugins/load/load_image.py b/client/ayon_core/hosts/houdini/plugins/load/load_image.py index cc9dcc30c8..b77e4f662a 100644 --- a/client/ayon_core/hosts/houdini/plugins/load/load_image.py +++ b/client/ayon_core/hosts/houdini/plugins/load/load_image.py @@ -44,7 +44,7 @@ def get_image_avalon_container(): class ImageLoader(load.LoaderPlugin): """Load images into COP2""" - families = ["imagesequence"] + product_types = {"imagesequence"} label = "Load Image (COP2)" representations = ["*"] order = -10 diff --git a/client/ayon_core/hosts/houdini/plugins/load/load_redshift_proxy.py b/client/ayon_core/hosts/houdini/plugins/load/load_redshift_proxy.py index 86c7ae0272..a6556619fc 100644 --- a/client/ayon_core/hosts/houdini/plugins/load/load_redshift_proxy.py +++ b/client/ayon_core/hosts/houdini/plugins/load/load_redshift_proxy.py @@ -13,7 +13,7 @@ import hou class RedshiftProxyLoader(load.LoaderPlugin): """Load Redshift Proxy""" - families = ["redshiftproxy"] + product_types = {"redshiftproxy"} label = "Load Redshift Proxy" representations = ["rs"] order = -10 diff --git a/client/ayon_core/hosts/houdini/plugins/load/load_usd_layer.py b/client/ayon_core/hosts/houdini/plugins/load/load_usd_layer.py index 6ee21f87ec..19950e2c98 100644 --- a/client/ayon_core/hosts/houdini/plugins/load/load_usd_layer.py +++ b/client/ayon_core/hosts/houdini/plugins/load/load_usd_layer.py @@ -9,10 +9,10 @@ from ayon_core.hosts.houdini.api import lib class USDSublayerLoader(load.LoaderPlugin): """Sublayer USD file in Solaris""" - families = [ + product_types = { "usd", "usdCamera", - ] + } label = "Sublayer USD" representations = ["usd", "usda", "usdlc", "usdnc", "abc"] order = 1 diff --git a/client/ayon_core/hosts/houdini/plugins/load/load_usd_reference.py b/client/ayon_core/hosts/houdini/plugins/load/load_usd_reference.py index d0421083c6..25f98c7c7c 100644 --- a/client/ayon_core/hosts/houdini/plugins/load/load_usd_reference.py +++ b/client/ayon_core/hosts/houdini/plugins/load/load_usd_reference.py @@ -9,10 +9,10 @@ from ayon_core.hosts.houdini.api import lib class USDReferenceLoader(load.LoaderPlugin): """Reference USD file in Solaris""" - families = [ + product_types = { "usd", "usdCamera", - ] + } label = "Reference USD" representations = ["usd", "usda", "usdlc", "usdnc", "abc"] order = -8 diff --git a/client/ayon_core/hosts/houdini/plugins/load/load_vdb.py b/client/ayon_core/hosts/houdini/plugins/load/load_vdb.py index 7b2803ab5d..d9808020d7 100644 --- a/client/ayon_core/hosts/houdini/plugins/load/load_vdb.py +++ b/client/ayon_core/hosts/houdini/plugins/load/load_vdb.py @@ -11,7 +11,7 @@ from ayon_core.hosts.houdini.api import pipeline class VdbLoader(load.LoaderPlugin): """Load VDB""" - families = ["vdbcache"] + product_types = {"vdbcache"} label = "Load VDB" representations = ["vdb"] order = -10 diff --git a/client/ayon_core/hosts/houdini/plugins/load/show_usdview.py b/client/ayon_core/hosts/houdini/plugins/load/show_usdview.py index 2f86f23b68..9506d9dd0c 100644 --- a/client/ayon_core/hosts/houdini/plugins/load/show_usdview.py +++ b/client/ayon_core/hosts/houdini/plugins/load/show_usdview.py @@ -11,7 +11,7 @@ class ShowInUsdview(load.LoaderPlugin): label = "Show in usdview" representations = ["*"] - families = ["*"] + product_types = {"*"} extensions = {"usd", "usda", "usdlc", "usdnc", "abc"} order = 15 diff --git a/client/ayon_core/hosts/max/plugins/load/load_camera_fbx.py b/client/ayon_core/hosts/max/plugins/load/load_camera_fbx.py index 664904eb4e..e1de6b98f9 100644 --- a/client/ayon_core/hosts/max/plugins/load/load_camera_fbx.py +++ b/client/ayon_core/hosts/max/plugins/load/load_camera_fbx.py @@ -18,7 +18,7 @@ from ayon_core.pipeline import get_representation_path, load class FbxLoader(load.LoaderPlugin): """Fbx Loader.""" - families = ["camera"] + product_types = {"camera"} representations = ["fbx"] order = -9 icon = "code-fork" diff --git a/client/ayon_core/hosts/max/plugins/load/load_max_scene.py b/client/ayon_core/hosts/max/plugins/load/load_max_scene.py index 0090b2256a..1c2c5317cc 100644 --- a/client/ayon_core/hosts/max/plugins/load/load_max_scene.py +++ b/client/ayon_core/hosts/max/plugins/load/load_max_scene.py @@ -72,9 +72,11 @@ class MaterialDupOptionsWindow(QtWidgets.QDialog): class MaxSceneLoader(load.LoaderPlugin): """Max Scene Loader.""" - families = ["camera", - "maxScene", - "model"] + product_types = { + "camera", + "maxScene", + "model", + } representations = ["max"] order = -8 diff --git a/client/ayon_core/hosts/max/plugins/load/load_model.py b/client/ayon_core/hosts/max/plugins/load/load_model.py index 0c39c1ba0d..00e675d69c 100644 --- a/client/ayon_core/hosts/max/plugins/load/load_model.py +++ b/client/ayon_core/hosts/max/plugins/load/load_model.py @@ -14,7 +14,7 @@ from ayon_core.hosts.max.api.lib import ( class ModelAbcLoader(load.LoaderPlugin): """Loading model with the Alembic loader.""" - families = ["model"] + product_types = {"model"} label = "Load Model with Alembic" representations = ["abc"] order = -10 diff --git a/client/ayon_core/hosts/max/plugins/load/load_model_fbx.py b/client/ayon_core/hosts/max/plugins/load/load_model_fbx.py index 7f5f1255ec..4b87c60de0 100644 --- a/client/ayon_core/hosts/max/plugins/load/load_model_fbx.py +++ b/client/ayon_core/hosts/max/plugins/load/load_model_fbx.py @@ -17,7 +17,7 @@ from ayon_core.hosts.max.api.lib import maintained_selection class FbxModelLoader(load.LoaderPlugin): """Fbx Model Loader.""" - families = ["model"] + product_types = {"model"} representations = ["fbx"] order = -9 icon = "code-fork" diff --git a/client/ayon_core/hosts/max/plugins/load/load_model_obj.py b/client/ayon_core/hosts/max/plugins/load/load_model_obj.py index 4b8d260921..4f8a22af07 100644 --- a/client/ayon_core/hosts/max/plugins/load/load_model_obj.py +++ b/client/ayon_core/hosts/max/plugins/load/load_model_obj.py @@ -20,7 +20,7 @@ from ayon_core.pipeline import get_representation_path, load class ObjLoader(load.LoaderPlugin): """Obj Loader.""" - families = ["model"] + product_types = {"model"} representations = ["obj"] order = -9 icon = "code-fork" diff --git a/client/ayon_core/hosts/max/plugins/load/load_model_usd.py b/client/ayon_core/hosts/max/plugins/load/load_model_usd.py index 6bcff2b6a5..bde23e119e 100644 --- a/client/ayon_core/hosts/max/plugins/load/load_model_usd.py +++ b/client/ayon_core/hosts/max/plugins/load/load_model_usd.py @@ -22,7 +22,7 @@ from ayon_core.pipeline import get_representation_path, load class ModelUSDLoader(load.LoaderPlugin): """Loading model with the USD loader.""" - families = ["model"] + product_types = {"model"} label = "Load Model(USD)" representations = ["usda"] order = -10 diff --git a/client/ayon_core/hosts/max/plugins/load/load_pointcache.py b/client/ayon_core/hosts/max/plugins/load/load_pointcache.py index 613d240447..7f515ac6a5 100644 --- a/client/ayon_core/hosts/max/plugins/load/load_pointcache.py +++ b/client/ayon_core/hosts/max/plugins/load/load_pointcache.py @@ -18,7 +18,7 @@ from ayon_core.hosts.max.api.pipeline import ( class AbcLoader(load.LoaderPlugin): """Alembic loader.""" - families = ["camera", "animation", "pointcache"] + product_types = {"camera", "animation", "pointcache"} label = "Load Alembic" representations = ["abc"] order = -10 diff --git a/client/ayon_core/hosts/max/plugins/load/load_pointcache_ornatrix.py b/client/ayon_core/hosts/max/plugins/load/load_pointcache_ornatrix.py index 7cf7d162c1..31d3f02ec0 100644 --- a/client/ayon_core/hosts/max/plugins/load/load_pointcache_ornatrix.py +++ b/client/ayon_core/hosts/max/plugins/load/load_pointcache_ornatrix.py @@ -21,7 +21,7 @@ from pymxs import runtime as rt class OxAbcLoader(load.LoaderPlugin): """Ornatrix Alembic loader.""" - families = ["camera", "animation", "pointcache"] + product_types = {"camera", "animation", "pointcache"} label = "Load Alembic with Ornatrix" representations = ["abc"] order = -10 diff --git a/client/ayon_core/hosts/max/plugins/load/load_pointcloud.py b/client/ayon_core/hosts/max/plugins/load/load_pointcloud.py index 6b9e5d6fb1..c0000c7a79 100644 --- a/client/ayon_core/hosts/max/plugins/load/load_pointcloud.py +++ b/client/ayon_core/hosts/max/plugins/load/load_pointcloud.py @@ -17,7 +17,7 @@ from ayon_core.pipeline import get_representation_path, load class PointCloudLoader(load.LoaderPlugin): """Point Cloud Loader.""" - families = ["pointcloud"] + product_types = {"pointcloud"} representations = ["prt"] order = -8 icon = "code-fork" diff --git a/client/ayon_core/hosts/max/plugins/load/load_redshift_proxy.py b/client/ayon_core/hosts/max/plugins/load/load_redshift_proxy.py index 40c7701797..ff6811bd1b 100644 --- a/client/ayon_core/hosts/max/plugins/load/load_redshift_proxy.py +++ b/client/ayon_core/hosts/max/plugins/load/load_redshift_proxy.py @@ -23,7 +23,7 @@ class RedshiftProxyLoader(load.LoaderPlugin): """Load rs files with Redshift Proxy""" label = "Load Redshift Proxy" - families = ["redshiftproxy"] + product_types = {"redshiftproxy"} representations = ["rs"] order = -9 icon = "code-fork" diff --git a/client/ayon_core/hosts/max/plugins/load/load_tycache.py b/client/ayon_core/hosts/max/plugins/load/load_tycache.py index 24cb762b2d..0244e4e6fc 100644 --- a/client/ayon_core/hosts/max/plugins/load/load_tycache.py +++ b/client/ayon_core/hosts/max/plugins/load/load_tycache.py @@ -16,7 +16,7 @@ from ayon_core.pipeline import get_representation_path, load class TyCacheLoader(load.LoaderPlugin): """TyCache Loader.""" - families = ["tycache"] + product_types = {"tycache"} representations = ["tyc"] order = -8 icon = "code-fork" diff --git a/client/ayon_core/hosts/maya/api/plugin.py b/client/ayon_core/hosts/maya/api/plugin.py index eaf93725f4..bdb0cb1c99 100644 --- a/client/ayon_core/hosts/maya/api/plugin.py +++ b/client/ayon_core/hosts/maya/api/plugin.py @@ -608,7 +608,7 @@ class RenderlayerCreator(NewCreator, MayaCreatorBase): return get_product_name( project_name, task_name, - task_type + task_type, host_name, self.layer_instance_prefix or self.product_type, variant, diff --git a/client/ayon_core/hosts/maya/plugins/load/_load_animation.py b/client/ayon_core/hosts/maya/plugins/load/_load_animation.py index e6dc1e520a..884bdd7538 100644 --- a/client/ayon_core/hosts/maya/plugins/load/_load_animation.py +++ b/client/ayon_core/hosts/maya/plugins/load/_load_animation.py @@ -46,9 +46,11 @@ def _process_reference(file_url, name, namespace, options): class AbcLoader(ayon_core.hosts.maya.api.plugin.ReferenceLoader): """Loader to reference an Alembic file""" - families = ["animation", - "camera", - "pointcache"] + product_types = { + "animation", + "camera", + "pointcache", + } representations = ["abc"] label = "Reference animation" @@ -75,8 +77,10 @@ class AbcLoader(ayon_core.hosts.maya.api.plugin.ReferenceLoader): class FbxLoader(ayon_core.hosts.maya.api.plugin.ReferenceLoader): """Loader to reference an Fbx files""" - families = ["animation", - "camera"] + product_types = { + "animation", + "camera", + } representations = ["fbx"] label = "Reference animation" diff --git a/client/ayon_core/hosts/maya/plugins/load/actions.py b/client/ayon_core/hosts/maya/plugins/load/actions.py index 5f4095eeec..a98fe97692 100644 --- a/client/ayon_core/hosts/maya/plugins/load/actions.py +++ b/client/ayon_core/hosts/maya/plugins/load/actions.py @@ -13,10 +13,12 @@ import ayon_core.hosts.maya.api.plugin class SetFrameRangeLoader(load.LoaderPlugin): """Set frame range excluding pre- and post-handles""" - families = ["animation", - "camera", - "proxyAbc", - "pointcache"] + product_types = { + "animation", + "camera", + "proxyAbc", + "pointcache", + } representations = ["abc"] label = "Set frame range" @@ -46,10 +48,12 @@ class SetFrameRangeLoader(load.LoaderPlugin): class SetFrameRangeWithHandlesLoader(load.LoaderPlugin): """Set frame range including pre- and post-handles""" - families = ["animation", - "camera", - "proxyAbc", - "pointcache"] + product_types = { + "animation", + "camera", + "proxyAbc", + "pointcache", + } representations = ["abc"] label = "Set frame range (with handles)" @@ -91,7 +95,7 @@ class ImportMayaLoader(ayon_core.hosts.maya.api.plugin.Loader): """ representations = ["ma", "mb", "obj"] - families = [ + product_types = { "model", "pointcache", "proxyAbc", @@ -104,8 +108,8 @@ class ImportMayaLoader(ayon_core.hosts.maya.api.plugin.Loader): "rig", "camerarig", "staticMesh", - "workfile" - ] + "workfile", + } label = "Import" order = 10 diff --git a/client/ayon_core/hosts/maya/plugins/load/load_arnold_standin.py b/client/ayon_core/hosts/maya/plugins/load/load_arnold_standin.py index 0219a72515..920ad762b3 100644 --- a/client/ayon_core/hosts/maya/plugins/load/load_arnold_standin.py +++ b/client/ayon_core/hosts/maya/plugins/load/load_arnold_standin.py @@ -29,7 +29,9 @@ def is_sequence(files): class ArnoldStandinLoader(load.LoaderPlugin): """Load as Arnold standin""" - families = ["ass", "animation", "model", "proxyAbc", "pointcache", "usd"] + product_types = { + "ass", "animation", "model", "proxyAbc", "pointcache", "usd" + } representations = ["ass", "abc", "usda", "usdc", "usd"] label = "Load as Arnold standin" diff --git a/client/ayon_core/hosts/maya/plugins/load/load_assembly.py b/client/ayon_core/hosts/maya/plugins/load/load_assembly.py index 7ab7fc4207..a0cbf91905 100644 --- a/client/ayon_core/hosts/maya/plugins/load/load_assembly.py +++ b/client/ayon_core/hosts/maya/plugins/load/load_assembly.py @@ -12,7 +12,7 @@ from ayon_core.hosts.maya.api import setdress class AssemblyLoader(load.LoaderPlugin): - families = ["assembly"] + product_types = {"assembly"} representations = ["json"] label = "Load Set Dress" diff --git a/client/ayon_core/hosts/maya/plugins/load/load_audio.py b/client/ayon_core/hosts/maya/plugins/load/load_audio.py index ee37a7ad8c..0a40993fcd 100644 --- a/client/ayon_core/hosts/maya/plugins/load/load_audio.py +++ b/client/ayon_core/hosts/maya/plugins/load/load_audio.py @@ -11,7 +11,7 @@ from ayon_core.hosts.maya.api.lib import unique_namespace, get_container_members class AudioLoader(load.LoaderPlugin): """Specific loader of audio.""" - families = ["audio"] + product_types = {"audio"} label = "Load audio" representations = ["wav"] icon = "volume-up" diff --git a/client/ayon_core/hosts/maya/plugins/load/load_gpucache.py b/client/ayon_core/hosts/maya/plugins/load/load_gpucache.py index 080d20b0a6..494bc7cfc6 100644 --- a/client/ayon_core/hosts/maya/plugins/load/load_gpucache.py +++ b/client/ayon_core/hosts/maya/plugins/load/load_gpucache.py @@ -15,7 +15,7 @@ from ayon_core.hosts.maya.api.plugin import get_load_color_for_product_type class GpuCacheLoader(load.LoaderPlugin): """Load Alembic as gpuCache""" - families = ["model", "animation", "proxyAbc", "pointcache"] + product_types = {"model", "animation", "proxyAbc", "pointcache"} representations = ["abc", "gpu_cache"] label = "Load Gpu Cache" diff --git a/client/ayon_core/hosts/maya/plugins/load/load_image.py b/client/ayon_core/hosts/maya/plugins/load/load_image.py index d595aa2987..4976c46d7f 100644 --- a/client/ayon_core/hosts/maya/plugins/load/load_image.py +++ b/client/ayon_core/hosts/maya/plugins/load/load_image.py @@ -93,7 +93,7 @@ def create_stencil(): class FileNodeLoader(load.LoaderPlugin): """File node loader.""" - families = ["image", "plate", "render"] + product_types = {"image", "plate", "render"} label = "Load file node" representations = ["exr", "tif", "png", "jpg"] icon = "image" diff --git a/client/ayon_core/hosts/maya/plugins/load/load_image_plane.py b/client/ayon_core/hosts/maya/plugins/load/load_image_plane.py index 71ae892150..7d6f7e26cf 100644 --- a/client/ayon_core/hosts/maya/plugins/load/load_image_plane.py +++ b/client/ayon_core/hosts/maya/plugins/load/load_image_plane.py @@ -87,7 +87,7 @@ class CameraWindow(QtWidgets.QDialog): class ImagePlaneLoader(load.LoaderPlugin): """Specific loader of plate for image planes on selected camera.""" - families = ["image", "plate", "render"] + product_types = {"image", "plate", "render"} label = "Load imagePlane" representations = ["mov", "exr", "preview", "png", "jpg"] icon = "image" diff --git a/client/ayon_core/hosts/maya/plugins/load/load_look.py b/client/ayon_core/hosts/maya/plugins/load/load_look.py index 9226c7b16f..f126a1df26 100644 --- a/client/ayon_core/hosts/maya/plugins/load/load_look.py +++ b/client/ayon_core/hosts/maya/plugins/load/load_look.py @@ -17,7 +17,7 @@ from ayon_core.tools.utils import ScrollMessageBox class LookLoader(ayon_core.hosts.maya.api.plugin.ReferenceLoader): """Specific loader for lookdev""" - families = ["look"] + product_types = {"look"} representations = ["ma"] label = "Reference look" diff --git a/client/ayon_core/hosts/maya/plugins/load/load_matchmove.py b/client/ayon_core/hosts/maya/plugins/load/load_matchmove.py index 885d2dbae1..05da173bb7 100644 --- a/client/ayon_core/hosts/maya/plugins/load/load_matchmove.py +++ b/client/ayon_core/hosts/maya/plugins/load/load_matchmove.py @@ -8,7 +8,7 @@ class MatchmoveLoader(load.LoaderPlugin): Supported script types are .py and .mel """ - families = ["matchmove"] + product_types = {"matchmove"} representations = ["py", "mel"] defaults = ["Camera", "Object", "Mocap"] diff --git a/client/ayon_core/hosts/maya/plugins/load/load_maya_usd.py b/client/ayon_core/hosts/maya/plugins/load/load_maya_usd.py index 0a8adaf87f..cd73c26de1 100644 --- a/client/ayon_core/hosts/maya/plugins/load/load_maya_usd.py +++ b/client/ayon_core/hosts/maya/plugins/load/load_maya_usd.py @@ -16,7 +16,7 @@ from ayon_core.hosts.maya.api.pipeline import containerise class MayaUsdLoader(load.LoaderPlugin): """Read USD data in a Maya USD Proxy""" - families = ["model", "usd", "pointcache", "animation"] + product_types = {"model", "usd", "pointcache", "animation"} representations = ["usd", "usda", "usdc", "usdz", "abc"] label = "Load USD to Maya Proxy" diff --git a/client/ayon_core/hosts/maya/plugins/load/load_multiverse_usd.py b/client/ayon_core/hosts/maya/plugins/load/load_multiverse_usd.py index aab87fc546..984d14dff3 100644 --- a/client/ayon_core/hosts/maya/plugins/load/load_multiverse_usd.py +++ b/client/ayon_core/hosts/maya/plugins/load/load_multiverse_usd.py @@ -20,8 +20,14 @@ from ayon_core.hosts.maya.api.pipeline import containerise class MultiverseUsdLoader(load.LoaderPlugin): """Read USD data in a Multiverse Compound""" - families = ["model", "usd", "mvUsdComposition", "mvUsdOverride", - "pointcache", "animation"] + product_types = { + "model", + "usd", + "mvUsdComposition", + "mvUsdOverride", + "pointcache", + "animation", + } representations = ["usd", "usda", "usdc", "usdz", "abc"] label = "Load USD to Multiverse" diff --git a/client/ayon_core/hosts/maya/plugins/load/load_multiverse_usd_over.py b/client/ayon_core/hosts/maya/plugins/load/load_multiverse_usd_over.py index 70069d3ae6..dc5bc6ec1c 100644 --- a/client/ayon_core/hosts/maya/plugins/load/load_multiverse_usd_over.py +++ b/client/ayon_core/hosts/maya/plugins/load/load_multiverse_usd_over.py @@ -19,7 +19,7 @@ from ayon_core.hosts.maya.api.pipeline import containerise class MultiverseUsdOverLoader(load.LoaderPlugin): """Reference file""" - families = ["mvUsdOverride"] + product_types = {"mvUsdOverride"} representations = ["usda", "usd", "udsz"] label = "Load Usd Override into Compound" diff --git a/client/ayon_core/hosts/maya/plugins/load/load_redshift_proxy.py b/client/ayon_core/hosts/maya/plugins/load/load_redshift_proxy.py index a0ed7cd6e7..63dae87243 100644 --- a/client/ayon_core/hosts/maya/plugins/load/load_redshift_proxy.py +++ b/client/ayon_core/hosts/maya/plugins/load/load_redshift_proxy.py @@ -22,7 +22,7 @@ from ayon_core.hosts.maya.api.plugin import get_load_color_for_product_type class RedshiftProxyLoader(load.LoaderPlugin): """Load Redshift proxy""" - families = ["redshiftproxy"] + product_types = {"redshiftproxy"} representations = ["rs"] label = "Import Redshift Proxy" diff --git a/client/ayon_core/hosts/maya/plugins/load/load_reference.py b/client/ayon_core/hosts/maya/plugins/load/load_reference.py index 75f5cee5a5..fdd85eda43 100644 --- a/client/ayon_core/hosts/maya/plugins/load/load_reference.py +++ b/client/ayon_core/hosts/maya/plugins/load/load_reference.py @@ -89,21 +89,23 @@ def preserve_modelpanel_cameras(container, log=None): class ReferenceLoader(plugin.ReferenceLoader): """Reference file""" - families = ["model", - "pointcache", - "proxyAbc", - "animation", - "mayaAscii", - "mayaScene", - "setdress", - "layout", - "camera", - "rig", - "camerarig", - "staticMesh", - "skeletalMesh", - "mvLook", - "matchmove"] + product_types = { + "model", + "pointcache", + "proxyAbc", + "animation", + "mayaAscii", + "mayaScene", + "setdress", + "layout", + "camera", + "rig", + "camerarig", + "staticMesh", + "skeletalMesh", + "mvLook", + "matchmove", + } representations = ["ma", "abc", "fbx", "mb"] @@ -270,7 +272,7 @@ class MayaUSDReferenceLoader(ReferenceLoader): """Reference USD file to native Maya nodes using MayaUSDImport reference""" label = "Reference Maya USD" - families = ["usd"] + product_types = {"usd"} representations = ["usd"] extensions = {"usd", "usda", "usdc"} diff --git a/client/ayon_core/hosts/maya/plugins/load/load_rendersetup.py b/client/ayon_core/hosts/maya/plugins/load/load_rendersetup.py index 0f01a65539..6f20e677f0 100644 --- a/client/ayon_core/hosts/maya/plugins/load/load_rendersetup.py +++ b/client/ayon_core/hosts/maya/plugins/load/load_rendersetup.py @@ -24,7 +24,7 @@ import maya.app.renderSetup.model.renderSetup as renderSetup class RenderSetupLoader(load.LoaderPlugin): """Load json preset for RenderSetup overwriting current one.""" - families = ["rendersetup"] + product_types = {"rendersetup"} representations = ["json"] defaults = ['Main'] diff --git a/client/ayon_core/hosts/maya/plugins/load/load_vdb_to_arnold.py b/client/ayon_core/hosts/maya/plugins/load/load_vdb_to_arnold.py index 05dac0e260..eaa7ff1ae3 100644 --- a/client/ayon_core/hosts/maya/plugins/load/load_vdb_to_arnold.py +++ b/client/ayon_core/hosts/maya/plugins/load/load_vdb_to_arnold.py @@ -12,7 +12,7 @@ from ayon_core.hosts.maya.api.plugin import get_load_color_for_product_type class LoadVDBtoArnold(load.LoaderPlugin): """Load OpenVDB for Arnold in aiVolume""" - families = ["vdbcache"] + product_types = {"vdbcache"} representations = ["vdb"] label = "Load VDB to Arnold" diff --git a/client/ayon_core/hosts/maya/plugins/load/load_vdb_to_redshift.py b/client/ayon_core/hosts/maya/plugins/load/load_vdb_to_redshift.py index b6cd513d9e..1707008b67 100644 --- a/client/ayon_core/hosts/maya/plugins/load/load_vdb_to_redshift.py +++ b/client/ayon_core/hosts/maya/plugins/load/load_vdb_to_redshift.py @@ -18,7 +18,7 @@ class LoadVDBtoRedShift(load.LoaderPlugin): """ - families = ["vdbcache"] + product_types = {"vdbcache"} representations = ["vdb"] label = "Load VDB to RedShift" diff --git a/client/ayon_core/hosts/maya/plugins/load/load_vdb_to_vray.py b/client/ayon_core/hosts/maya/plugins/load/load_vdb_to_vray.py index 8b5923bdbb..42d4583d76 100644 --- a/client/ayon_core/hosts/maya/plugins/load/load_vdb_to_vray.py +++ b/client/ayon_core/hosts/maya/plugins/load/load_vdb_to_vray.py @@ -77,7 +77,7 @@ def _fix_duplicate_vvg_callbacks(): class LoadVDBtoVRay(load.LoaderPlugin): """Load OpenVDB in a V-Ray Volume Grid""" - families = ["vdbcache"] + product_types = {"vdbcache"} representations = ["vdb"] label = "Load VDB to VRay" diff --git a/client/ayon_core/hosts/maya/plugins/load/load_vrayproxy.py b/client/ayon_core/hosts/maya/plugins/load/load_vrayproxy.py index fe1f8425d8..651197627e 100644 --- a/client/ayon_core/hosts/maya/plugins/load/load_vrayproxy.py +++ b/client/ayon_core/hosts/maya/plugins/load/load_vrayproxy.py @@ -27,7 +27,7 @@ from ayon_core.hosts.maya.api.plugin import get_load_color_for_product_type class VRayProxyLoader(load.LoaderPlugin): """Load VRay Proxy with Alembic or VrayMesh.""" - families = ["vrayproxy", "model", "pointcache", "animation"] + product_types = {"vrayproxy", "model", "pointcache", "animation"} representations = ["vrmesh", "abc"] label = "Import VRay Proxy" diff --git a/client/ayon_core/hosts/maya/plugins/load/load_vrayscene.py b/client/ayon_core/hosts/maya/plugins/load/load_vrayscene.py index 3d21464edc..2f4ab1d080 100644 --- a/client/ayon_core/hosts/maya/plugins/load/load_vrayscene.py +++ b/client/ayon_core/hosts/maya/plugins/load/load_vrayscene.py @@ -17,7 +17,7 @@ from ayon_core.hosts.maya.api.plugin import get_load_color_for_product_type class VRaySceneLoader(load.LoaderPlugin): """Load Vray scene""" - families = ["vrayscene_layer"] + product_types = {"vrayscene_layer"} representations = ["vrscene"] label = "Import VRay Scene" diff --git a/client/ayon_core/hosts/maya/plugins/load/load_xgen.py b/client/ayon_core/hosts/maya/plugins/load/load_xgen.py index 58a6d86292..880efd82e1 100644 --- a/client/ayon_core/hosts/maya/plugins/load/load_xgen.py +++ b/client/ayon_core/hosts/maya/plugins/load/load_xgen.py @@ -20,7 +20,7 @@ from ayon_core.pipeline import get_representation_path class XgenLoader(ayon_core.hosts.maya.api.plugin.ReferenceLoader): """Load Xgen as reference""" - families = ["xgen"] + product_types = {"xgen"} representations = ["ma", "mb"] label = "Reference Xgen" diff --git a/client/ayon_core/hosts/maya/plugins/load/load_yeti_cache.py b/client/ayon_core/hosts/maya/plugins/load/load_yeti_cache.py index 18a094c29d..8933c4d8a6 100644 --- a/client/ayon_core/hosts/maya/plugins/load/load_yeti_cache.py +++ b/client/ayon_core/hosts/maya/plugins/load/load_yeti_cache.py @@ -36,7 +36,7 @@ def set_attribute(node, attr, value): class YetiCacheLoader(load.LoaderPlugin): """Load Yeti Cache with one or more Yeti nodes""" - families = ["yeticache", "yetiRig"] + product_types = {"yeticache", "yetiRig"} representations = ["fur"] label = "Load Yeti Cache" diff --git a/client/ayon_core/hosts/maya/plugins/load/load_yeti_rig.py b/client/ayon_core/hosts/maya/plugins/load/load_yeti_rig.py index 310c943198..74e33c5866 100644 --- a/client/ayon_core/hosts/maya/plugins/load/load_yeti_rig.py +++ b/client/ayon_core/hosts/maya/plugins/load/load_yeti_rig.py @@ -7,7 +7,7 @@ from ayon_core.hosts.maya.api import lib class YetiRigLoader(plugin.ReferenceLoader): """This loader will load Yeti rig.""" - families = ["yetiRig"] + product_types = {"yetiRig"} representations = ["ma"] label = "Load Yeti Rig" diff --git a/client/ayon_core/hosts/maya/plugins/publish/collect_render.py b/client/ayon_core/hosts/maya/plugins/publish/collect_render.py index 19e0c133c4..13eb8fd49e 100644 --- a/client/ayon_core/hosts/maya/plugins/publish/collect_render.py +++ b/client/ayon_core/hosts/maya/plugins/publish/collect_render.py @@ -290,8 +290,8 @@ class CollectMayaRender(pyblish.api.InstancePlugin): "colorspaceView": colorspace_data["view"], } - rr_settings = context.data["project_settings"]["royalrender"] - if rr_settings["enabled"]: + manager = context.data["ayonAddonsManager"] + if manager.get_enabled_addon("royalrender") is not None: data["rrPathName"] = instance.data.get("rrPathName") self.log.debug(data["rrPathName"]) diff --git a/client/ayon_core/hosts/nuke/plugins/load/actions.py b/client/ayon_core/hosts/nuke/plugins/load/actions.py index 707a8a3c4d..a1b3697ef1 100644 --- a/client/ayon_core/hosts/nuke/plugins/load/actions.py +++ b/client/ayon_core/hosts/nuke/plugins/load/actions.py @@ -12,11 +12,13 @@ log = Logger.get_logger(__name__) class SetFrameRangeLoader(load.LoaderPlugin): """Set frame range excluding pre- and post-handles""" - families = ["animation", - "camera", - "write", - "yeticache", - "pointcache"] + product_types = { + "animation", + "camera", + "write", + "yeticache", + "pointcache", + } representations = ["*"] extensions = {"*"} @@ -44,11 +46,13 @@ class SetFrameRangeLoader(load.LoaderPlugin): class SetFrameRangeWithHandlesLoader(load.LoaderPlugin): """Set frame range including pre- and post-handles""" - families = ["animation", - "camera", - "write", - "yeticache", - "pointcache"] + product_types = { + "animation", + "camera", + "write", + "yeticache", + "pointcache", + } representations = ["*"] label = "Set frame range (with handles)" diff --git a/client/ayon_core/hosts/nuke/plugins/load/load_backdrop.py b/client/ayon_core/hosts/nuke/plugins/load/load_backdrop.py index 51fe7dac34..e48dbf5e2f 100644 --- a/client/ayon_core/hosts/nuke/plugins/load/load_backdrop.py +++ b/client/ayon_core/hosts/nuke/plugins/load/load_backdrop.py @@ -21,7 +21,7 @@ from ayon_core.hosts.nuke.api import containerise, update_container class LoadBackdropNodes(load.LoaderPlugin): """Loading Published Backdrop nodes (workfile, nukenodes)""" - families = ["workfile", "nukenodes"] + product_types = {"workfile", "nukenodes"} representations = ["*"] extensions = {"nk"} diff --git a/client/ayon_core/hosts/nuke/plugins/load/load_camera_abc.py b/client/ayon_core/hosts/nuke/plugins/load/load_camera_abc.py index bb7c8ea7c8..70b736b1c8 100644 --- a/client/ayon_core/hosts/nuke/plugins/load/load_camera_abc.py +++ b/client/ayon_core/hosts/nuke/plugins/load/load_camera_abc.py @@ -20,7 +20,7 @@ class AlembicCameraLoader(load.LoaderPlugin): This will load alembic camera into script. """ - families = ["camera"] + product_types = {"camera"} representations = ["*"] extensions = {"abc"} diff --git a/client/ayon_core/hosts/nuke/plugins/load/load_clip.py b/client/ayon_core/hosts/nuke/plugins/load/load_clip.py index e972b99b85..8a41d854d9 100644 --- a/client/ayon_core/hosts/nuke/plugins/load/load_clip.py +++ b/client/ayon_core/hosts/nuke/plugins/load/load_clip.py @@ -35,13 +35,13 @@ class LoadClip(plugin.NukeLoader): """ log = Logger.get_logger(__name__) - families = [ + product_types = { "source", "plate", "render", "prerender", - "review" - ] + "review", + } representations = ["*"] extensions = set( ext.lstrip(".") for ext in IMAGE_EXTENSIONS.union(VIDEO_EXTENSIONS) diff --git a/client/ayon_core/hosts/nuke/plugins/load/load_effects.py b/client/ayon_core/hosts/nuke/plugins/load/load_effects.py index 50ce0d1ad7..f17b179d1b 100644 --- a/client/ayon_core/hosts/nuke/plugins/load/load_effects.py +++ b/client/ayon_core/hosts/nuke/plugins/load/load_effects.py @@ -18,7 +18,7 @@ from ayon_core.hosts.nuke.api import ( class LoadEffects(load.LoaderPlugin): """Loading colorspace soft effect exported from nukestudio""" - families = ["effect"] + product_types = {"effect"} representations = ["*"] extensions = {"json"} diff --git a/client/ayon_core/hosts/nuke/plugins/load/load_effects_ip.py b/client/ayon_core/hosts/nuke/plugins/load/load_effects_ip.py index 8c58241316..6b58977a95 100644 --- a/client/ayon_core/hosts/nuke/plugins/load/load_effects_ip.py +++ b/client/ayon_core/hosts/nuke/plugins/load/load_effects_ip.py @@ -19,7 +19,7 @@ from ayon_core.hosts.nuke.api import ( class LoadEffectsInputProcess(load.LoaderPlugin): """Loading colorspace soft effect exported from nukestudio""" - families = ["effect"] + product_types = {"effect"} representations = ["*"] extensions = {"json"} diff --git a/client/ayon_core/hosts/nuke/plugins/load/load_gizmo.py b/client/ayon_core/hosts/nuke/plugins/load/load_gizmo.py index 5130b825c4..6709648ffb 100644 --- a/client/ayon_core/hosts/nuke/plugins/load/load_gizmo.py +++ b/client/ayon_core/hosts/nuke/plugins/load/load_gizmo.py @@ -21,7 +21,7 @@ from ayon_core.hosts.nuke.api import ( class LoadGizmo(load.LoaderPlugin): """Loading nuke Gizmo""" - families = ["gizmo"] + product_types = {"gizmo"} representations = ["*"] extensions = {"nk"} diff --git a/client/ayon_core/hosts/nuke/plugins/load/load_gizmo_ip.py b/client/ayon_core/hosts/nuke/plugins/load/load_gizmo_ip.py index 8aa73ca0e4..3017fa5fc9 100644 --- a/client/ayon_core/hosts/nuke/plugins/load/load_gizmo_ip.py +++ b/client/ayon_core/hosts/nuke/plugins/load/load_gizmo_ip.py @@ -23,7 +23,7 @@ from ayon_core.hosts.nuke.api import ( class LoadGizmoInputProcess(load.LoaderPlugin): """Loading colorspace soft effect exported from nukestudio""" - families = ["gizmo"] + product_types = {"gizmo"} representations = ["*"] extensions = {"nk"} diff --git a/client/ayon_core/hosts/nuke/plugins/load/load_image.py b/client/ayon_core/hosts/nuke/plugins/load/load_image.py index 002592758f..9d3f9ceea0 100644 --- a/client/ayon_core/hosts/nuke/plugins/load/load_image.py +++ b/client/ayon_core/hosts/nuke/plugins/load/load_image.py @@ -23,15 +23,15 @@ from ayon_core.lib.transcoding import ( class LoadImage(load.LoaderPlugin): """Load still image into Nuke""" - families = [ + product_types = { "render2d", "source", "plate", "render", "prerender", "review", - "image" - ] + "image", + } representations = ["*"] extensions = set( ext.lstrip(".") for ext in IMAGE_EXTENSIONS diff --git a/client/ayon_core/hosts/nuke/plugins/load/load_matchmove.py b/client/ayon_core/hosts/nuke/plugins/load/load_matchmove.py index 412181f3d9..73c21376b4 100644 --- a/client/ayon_core/hosts/nuke/plugins/load/load_matchmove.py +++ b/client/ayon_core/hosts/nuke/plugins/load/load_matchmove.py @@ -7,7 +7,7 @@ class MatchmoveLoader(load.LoaderPlugin): This will run matchmove script to create track in script. """ - families = ["matchmove"] + product_types = {"matchmove"} representations = ["*"] extensions = {"py"} diff --git a/client/ayon_core/hosts/nuke/plugins/load/load_model.py b/client/ayon_core/hosts/nuke/plugins/load/load_model.py index fcf1c2eda9..971c36b6cf 100644 --- a/client/ayon_core/hosts/nuke/plugins/load/load_model.py +++ b/client/ayon_core/hosts/nuke/plugins/load/load_model.py @@ -18,7 +18,7 @@ class AlembicModelLoader(load.LoaderPlugin): This will load alembic model or anim into script. """ - families = ["model", "pointcache", "animation"] + product_types = {"model", "pointcache", "animation"} representations = ["*"] extensions = {"abc"} diff --git a/client/ayon_core/hosts/nuke/plugins/load/load_ociolook.py b/client/ayon_core/hosts/nuke/plugins/load/load_ociolook.py index 94af7c40e2..82addcdfc0 100644 --- a/client/ayon_core/hosts/nuke/plugins/load/load_ociolook.py +++ b/client/ayon_core/hosts/nuke/plugins/load/load_ociolook.py @@ -20,7 +20,7 @@ from ayon_core.hosts.nuke.api import ( class LoadOcioLookNodes(load.LoaderPlugin): """Loading Ocio look to the nuke.Node graph""" - families = ["ociolook"] + product_types = {"ociolook"} representations = ["*"] extensions = {"json"} diff --git a/client/ayon_core/hosts/nuke/plugins/load/load_script_precomp.py b/client/ayon_core/hosts/nuke/plugins/load/load_script_precomp.py index 9fb168f322..ccc4164355 100644 --- a/client/ayon_core/hosts/nuke/plugins/load/load_script_precomp.py +++ b/client/ayon_core/hosts/nuke/plugins/load/load_script_precomp.py @@ -16,7 +16,7 @@ from ayon_core.hosts.nuke.api import ( class LinkAsGroup(load.LoaderPlugin): """Copy the published file to be pasted at the desired location""" - families = ["workfile", "nukenodes"] + product_types = {"workfile", "nukenodes"} representations = ["*"] extensions = {"nk"} diff --git a/client/ayon_core/hosts/photoshop/plugins/load/load_image.py b/client/ayon_core/hosts/photoshop/plugins/load/load_image.py index 42cc2dbcbf..72df2706b5 100644 --- a/client/ayon_core/hosts/photoshop/plugins/load/load_image.py +++ b/client/ayon_core/hosts/photoshop/plugins/load/load_image.py @@ -11,7 +11,7 @@ class ImageLoader(photoshop.PhotoshopLoader): Stores the imported asset in a container named after the asset. """ - families = ["image", "render"] + product_types = {"image", "render"} representations = ["*"] def load(self, context, name=None, namespace=None, data=None): diff --git a/client/ayon_core/hosts/photoshop/plugins/load/load_image_from_sequence.py b/client/ayon_core/hosts/photoshop/plugins/load/load_image_from_sequence.py index e20c9a5138..25b22f53a4 100644 --- a/client/ayon_core/hosts/photoshop/plugins/load/load_image_from_sequence.py +++ b/client/ayon_core/hosts/photoshop/plugins/load/load_image_from_sequence.py @@ -24,7 +24,7 @@ class ImageFromSequenceLoader(photoshop.PhotoshopLoader): difficult. """ - families = ["render"] + product_types = {"render"} representations = ["*"] options = [] diff --git a/client/ayon_core/hosts/photoshop/plugins/load/load_reference.py b/client/ayon_core/hosts/photoshop/plugins/load/load_reference.py index f1897ad18a..7cd34690f7 100644 --- a/client/ayon_core/hosts/photoshop/plugins/load/load_reference.py +++ b/client/ayon_core/hosts/photoshop/plugins/load/load_reference.py @@ -14,7 +14,7 @@ class ReferenceLoader(photoshop.PhotoshopLoader): "Cannot write to closing transport", possible refactor. """ - families = ["image", "render"] + product_types = {"image", "render"} representations = ["*"] def load(self, context, name=None, namespace=None, data=None): diff --git a/client/ayon_core/hosts/resolve/api/lib.py b/client/ayon_core/hosts/resolve/api/lib.py index 6e4e17811f..a60f3cd4ec 100644 --- a/client/ayon_core/hosts/resolve/api/lib.py +++ b/client/ayon_core/hosts/resolve/api/lib.py @@ -330,19 +330,25 @@ def get_timeline_item(media_pool_item: object, Returns: object: resolve.TimelineItem """ - _clip_property = media_pool_item.GetClipProperty - clip_name = _clip_property("File Name") + clip_name = media_pool_item.GetClipProperty("File Name") output_timeline_item = None timeline = timeline or get_current_timeline() with maintain_current_timeline(timeline): # search the timeline for the added clip - for _ti_data in get_current_timeline_items(): - _ti_clip = _ti_data["clip"]["item"] - _ti_clip_property = _ti_clip.GetMediaPoolItem().GetClipProperty - if clip_name in _ti_clip_property("File Name"): - output_timeline_item = _ti_clip + for ti_data in get_current_timeline_items(): + ti_clip_item = ti_data["clip"]["item"] + ti_media_pool_item = ti_clip_item.GetMediaPoolItem() + + # Skip items that do not have a media pool item, like for example + # an "Adjustment Clip" or a "Fusion Composition" from the effects + # toolbox + if not ti_media_pool_item: + continue + + if clip_name in ti_media_pool_item.GetClipProperty("File Name"): + output_timeline_item = ti_clip_item return output_timeline_item @@ -713,6 +719,11 @@ def swap_clips(from_clip, to_clip, to_in_frame, to_out_frame): bool: True if successfully replaced """ + # copy ACES input transform from timeline clip to new media item + mediapool_item_from_timeline = from_clip.GetMediaPoolItem() + _idt = mediapool_item_from_timeline.GetClipProperty('IDT') + to_clip.SetClipProperty('IDT', _idt) + _clip_prop = to_clip.GetClipProperty to_clip_name = _clip_prop("File Name") # add clip item as take to timeline diff --git a/client/ayon_core/hosts/resolve/api/plugin.py b/client/ayon_core/hosts/resolve/api/plugin.py index 8c97df98b8..d4c2d919a2 100644 --- a/client/ayon_core/hosts/resolve/api/plugin.py +++ b/client/ayon_core/hosts/resolve/api/plugin.py @@ -481,14 +481,16 @@ class ClipLoader: ) _clip_property = media_pool_item.GetClipProperty - source_in = int(_clip_property("Start")) - source_out = int(_clip_property("End")) + # Read trimming from timeline item + timeline_item_in = timeline_item.GetLeftOffset() + timeline_item_len = timeline_item.GetDuration() + timeline_item_out = timeline_item_in + timeline_item_len lib.swap_clips( timeline_item, media_pool_item, - source_in, - source_out + timeline_item_in, + timeline_item_out ) print("Loading clips: `{}`".format(self.data["clip_name"])) diff --git a/client/ayon_core/hosts/resolve/plugins/load/load_clip.py b/client/ayon_core/hosts/resolve/plugins/load/load_clip.py index 26ee35a90d..c7bced5e8e 100644 --- a/client/ayon_core/hosts/resolve/plugins/load/load_clip.py +++ b/client/ayon_core/hosts/resolve/plugins/load/load_clip.py @@ -18,7 +18,7 @@ class LoadClip(plugin.TimelineItemLoader): during conforming to project """ - families = ["render2d", "source", "plate", "render", "review"] + product_types = {"render2d", "source", "plate", "render", "review"} representations = ["*"] extensions = set( diff --git a/client/ayon_core/hosts/substancepainter/plugins/load/load_mesh.py b/client/ayon_core/hosts/substancepainter/plugins/load/load_mesh.py index fb2f1db726..f2254c0907 100644 --- a/client/ayon_core/hosts/substancepainter/plugins/load/load_mesh.py +++ b/client/ayon_core/hosts/substancepainter/plugins/load/load_mesh.py @@ -17,7 +17,7 @@ import qargparse class SubstanceLoadProjectMesh(load.LoaderPlugin): """Load mesh for project""" - families = ["*"] + product_types = {"*"} representations = ["abc", "fbx", "obj", "gltf"] label = "Load mesh" diff --git a/client/ayon_core/hosts/tvpaint/plugins/load/load_image.py b/client/ayon_core/hosts/tvpaint/plugins/load/load_image.py index 21bbe56a54..e954b72f12 100644 --- a/client/ayon_core/hosts/tvpaint/plugins/load/load_image.py +++ b/client/ayon_core/hosts/tvpaint/plugins/load/load_image.py @@ -6,7 +6,7 @@ from ayon_core.hosts.tvpaint.api.lib import execute_george_through_file class ImportImage(plugin.Loader): """Load image or image sequence to TVPaint as new layer.""" - families = ["render", "image", "background", "plate", "review"] + product_types = {"render", "image", "background", "plate", "review"} representations = ["*"] label = "Import Image" diff --git a/client/ayon_core/hosts/tvpaint/plugins/load/load_reference_image.py b/client/ayon_core/hosts/tvpaint/plugins/load/load_reference_image.py index 2820b883ed..a3bcf4c144 100644 --- a/client/ayon_core/hosts/tvpaint/plugins/load/load_reference_image.py +++ b/client/ayon_core/hosts/tvpaint/plugins/load/load_reference_image.py @@ -20,7 +20,7 @@ from ayon_core.hosts.tvpaint.api.pipeline import ( class LoadImage(plugin.Loader): """Load image or image sequence to TVPaint as new layer.""" - families = ["render", "image", "background", "plate", "review"] + product_types = {"render", "image", "background", "plate", "review"} representations = ["*"] label = "Load Image" diff --git a/client/ayon_core/hosts/tvpaint/plugins/load/load_sound.py b/client/ayon_core/hosts/tvpaint/plugins/load/load_sound.py index 86f3e6857f..182d95d6db 100644 --- a/client/ayon_core/hosts/tvpaint/plugins/load/load_sound.py +++ b/client/ayon_core/hosts/tvpaint/plugins/load/load_sound.py @@ -22,7 +22,7 @@ class ImportSound(plugin.Loader): file contain any audio. """ - families = ["audio", "review", "plate"] + product_types = {"audio", "review", "plate"} representations = ["*"] label = "Import Sound" diff --git a/client/ayon_core/hosts/tvpaint/plugins/load/load_workfile.py b/client/ayon_core/hosts/tvpaint/plugins/load/load_workfile.py index 4bb34089bd..56aa67708d 100644 --- a/client/ayon_core/hosts/tvpaint/plugins/load/load_workfile.py +++ b/client/ayon_core/hosts/tvpaint/plugins/load/load_workfile.py @@ -24,7 +24,7 @@ from ayon_core.pipeline.version_start import get_versioning_start class LoadWorkfile(plugin.Loader): """Load workfile.""" - families = ["workfile"] + product_types = {"workfile"} representations = ["tvpp"] label = "Load Workfile" diff --git a/client/ayon_core/hosts/unreal/plugins/load/load_alembic_animation.py b/client/ayon_core/hosts/unreal/plugins/load/load_alembic_animation.py index 9b8d22fb5e..02259b706c 100644 --- a/client/ayon_core/hosts/unreal/plugins/load/load_alembic_animation.py +++ b/client/ayon_core/hosts/unreal/plugins/load/load_alembic_animation.py @@ -14,7 +14,7 @@ import unreal # noqa class AnimationAlembicLoader(plugin.Loader): """Load Unreal SkeletalMesh from Alembic""" - families = ["animation"] + product_types = {"animation"} label = "Import Alembic Animation" representations = ["abc"] icon = "cube" diff --git a/client/ayon_core/hosts/unreal/plugins/load/load_animation.py b/client/ayon_core/hosts/unreal/plugins/load/load_animation.py index b2c066c871..0f51ac39e0 100644 --- a/client/ayon_core/hosts/unreal/plugins/load/load_animation.py +++ b/client/ayon_core/hosts/unreal/plugins/load/load_animation.py @@ -20,7 +20,7 @@ from ayon_core.hosts.unreal.api import pipeline as unreal_pipeline class AnimationFBXLoader(plugin.Loader): """Load Unreal SkeletalMesh from FBX.""" - families = ["animation"] + product_types = {"animation"} label = "Import FBX Animation" representations = ["fbx"] icon = "cube" diff --git a/client/ayon_core/hosts/unreal/plugins/load/load_camera.py b/client/ayon_core/hosts/unreal/plugins/load/load_camera.py index ed159d31bd..285834c911 100644 --- a/client/ayon_core/hosts/unreal/plugins/load/load_camera.py +++ b/client/ayon_core/hosts/unreal/plugins/load/load_camera.py @@ -28,7 +28,7 @@ from ayon_core.hosts.unreal.api.pipeline import ( class CameraLoader(plugin.Loader): """Load Unreal StaticMesh from FBX""" - families = ["camera"] + product_types = {"camera"} label = "Load Camera" representations = ["fbx"] icon = "cube" diff --git a/client/ayon_core/hosts/unreal/plugins/load/load_geometrycache_abc.py b/client/ayon_core/hosts/unreal/plugins/load/load_geometrycache_abc.py index d0c936ed06..44c308069b 100644 --- a/client/ayon_core/hosts/unreal/plugins/load/load_geometrycache_abc.py +++ b/client/ayon_core/hosts/unreal/plugins/load/load_geometrycache_abc.py @@ -19,7 +19,7 @@ import unreal # noqa class PointCacheAlembicLoader(plugin.Loader): """Load Point Cache from Alembic""" - families = ["model", "pointcache"] + product_types = {"model", "pointcache"} label = "Import Alembic Point Cache" representations = ["abc"] icon = "cube" diff --git a/client/ayon_core/hosts/unreal/plugins/load/load_layout.py b/client/ayon_core/hosts/unreal/plugins/load/load_layout.py index beb94ada7b..6c667d3d2f 100644 --- a/client/ayon_core/hosts/unreal/plugins/load/load_layout.py +++ b/client/ayon_core/hosts/unreal/plugins/load/load_layout.py @@ -40,7 +40,7 @@ from ayon_core.hosts.unreal.api.pipeline import ( class LayoutLoader(plugin.Loader): """Load Layout from a JSON file""" - families = ["layout"] + product_types = {"layout"} representations = ["json"] label = "Load Layout" diff --git a/client/ayon_core/hosts/unreal/plugins/load/load_layout_existing.py b/client/ayon_core/hosts/unreal/plugins/load/load_layout_existing.py index 144df10fe0..700b6957a2 100644 --- a/client/ayon_core/hosts/unreal/plugins/load/load_layout_existing.py +++ b/client/ayon_core/hosts/unreal/plugins/load/load_layout_existing.py @@ -21,7 +21,7 @@ class ExistingLayoutLoader(plugin.Loader): Load Layout for an existing scene, and match the existing assets. """ - families = ["layout"] + product_types = {"layout"} representations = ["json"] label = "Load Layout on Existing Scene" diff --git a/client/ayon_core/hosts/unreal/plugins/load/load_skeletalmesh_abc.py b/client/ayon_core/hosts/unreal/plugins/load/load_skeletalmesh_abc.py index 4d9c0554d8..64b1810080 100644 --- a/client/ayon_core/hosts/unreal/plugins/load/load_skeletalmesh_abc.py +++ b/client/ayon_core/hosts/unreal/plugins/load/load_skeletalmesh_abc.py @@ -18,7 +18,7 @@ import unreal # noqa class SkeletalMeshAlembicLoader(plugin.Loader): """Load Unreal SkeletalMesh from Alembic""" - families = ["pointcache", "skeletalMesh"] + product_types = {"pointcache", "skeletalMesh"} label = "Import Alembic Skeletal Mesh" representations = ["abc"] icon = "cube" diff --git a/client/ayon_core/hosts/unreal/plugins/load/load_skeletalmesh_fbx.py b/client/ayon_core/hosts/unreal/plugins/load/load_skeletalmesh_fbx.py index 990ad4b977..f61f0dbc3f 100644 --- a/client/ayon_core/hosts/unreal/plugins/load/load_skeletalmesh_fbx.py +++ b/client/ayon_core/hosts/unreal/plugins/load/load_skeletalmesh_fbx.py @@ -18,7 +18,7 @@ import unreal # noqa class SkeletalMeshFBXLoader(plugin.Loader): """Load Unreal SkeletalMesh from FBX.""" - families = ["rig", "skeletalMesh"] + product_types = {"rig", "skeletalMesh"} label = "Import FBX Skeletal Mesh" representations = ["fbx"] icon = "cube" diff --git a/client/ayon_core/hosts/unreal/plugins/load/load_staticmesh_abc.py b/client/ayon_core/hosts/unreal/plugins/load/load_staticmesh_abc.py index 5e4a28a031..256cb9e8bc 100644 --- a/client/ayon_core/hosts/unreal/plugins/load/load_staticmesh_abc.py +++ b/client/ayon_core/hosts/unreal/plugins/load/load_staticmesh_abc.py @@ -18,7 +18,7 @@ import unreal # noqa class StaticMeshAlembicLoader(plugin.Loader): """Load Unreal StaticMesh from Alembic""" - families = ["model", "staticMesh"] + product_types = {"model", "staticMesh"} label = "Import Alembic Static Mesh" representations = ["abc"] icon = "cube" diff --git a/client/ayon_core/hosts/unreal/plugins/load/load_staticmesh_fbx.py b/client/ayon_core/hosts/unreal/plugins/load/load_staticmesh_fbx.py index 1db2dcf676..0ec4b1b4f8 100644 --- a/client/ayon_core/hosts/unreal/plugins/load/load_staticmesh_fbx.py +++ b/client/ayon_core/hosts/unreal/plugins/load/load_staticmesh_fbx.py @@ -18,7 +18,7 @@ import unreal # noqa class StaticMeshFBXLoader(plugin.Loader): """Load Unreal StaticMesh from FBX.""" - families = ["model", "staticMesh"] + product_types = {"model", "staticMesh"} label = "Import FBX Static Mesh" representations = ["fbx"] icon = "cube" diff --git a/client/ayon_core/hosts/unreal/plugins/load/load_uasset.py b/client/ayon_core/hosts/unreal/plugins/load/load_uasset.py index e0b1a69aac..89ef357c89 100644 --- a/client/ayon_core/hosts/unreal/plugins/load/load_uasset.py +++ b/client/ayon_core/hosts/unreal/plugins/load/load_uasset.py @@ -15,7 +15,7 @@ import unreal # noqa class UAssetLoader(plugin.Loader): """Load UAsset.""" - families = ["uasset"] + product_types = {"uasset"} label = "Load UAsset" representations = ["uasset"] icon = "cube" @@ -164,7 +164,7 @@ class UAssetLoader(plugin.Loader): class UMapLoader(UAssetLoader): """Load Level.""" - families = ["uasset"] + product_types = {"uasset"} label = "Load Level" representations = ["umap"] diff --git a/client/ayon_core/hosts/unreal/plugins/load/load_yeticache.py b/client/ayon_core/hosts/unreal/plugins/load/load_yeticache.py index 7a1767e52a..21715a24c6 100644 --- a/client/ayon_core/hosts/unreal/plugins/load/load_yeticache.py +++ b/client/ayon_core/hosts/unreal/plugins/load/load_yeticache.py @@ -15,7 +15,7 @@ import unreal # noqa class YetiLoader(plugin.Loader): """Load Yeti Cache""" - families = ["yeticacheUE"] + product_types = {"yeticacheUE"} label = "Import Yeti" representations = ["abc"] icon = "pagelines" diff --git a/client/ayon_core/pipeline/load/plugins.py b/client/ayon_core/pipeline/load/plugins.py index b5d228380a..91f839ebf3 100644 --- a/client/ayon_core/pipeline/load/plugins.py +++ b/client/ayon_core/pipeline/load/plugins.py @@ -24,7 +24,7 @@ class LoaderPlugin(list): """ - families = [] + product_types = set() representations = [] extensions = {"*"} order = 0 @@ -118,7 +118,7 @@ class LoaderPlugin(list): On override make sure it is overriden as class or static method. - This checks the version's families and the representation for the given + This checks the product type and the representation for the given loader plugin. Args: @@ -130,7 +130,7 @@ class LoaderPlugin(list): """ plugin_repre_names = cls.get_representations() - plugin_product_types = cls.families + plugin_product_types = cls.product_types if ( not plugin_repre_names or not plugin_product_types diff --git a/client/ayon_core/pipeline/load/utils.py b/client/ayon_core/pipeline/load/utils.py index 8fdaf52e27..f3d39800cd 100644 --- a/client/ayon_core/pipeline/load/utils.py +++ b/client/ayon_core/pipeline/load/utils.py @@ -735,7 +735,7 @@ def get_representation_path(representation, root=None): def is_compatible_loader(Loader, context): """Return whether a loader is compatible with a context. - This checks the version's families and the representation for the given + This checks the product type and the representation for the given Loader. Returns: diff --git a/client/ayon_core/pipeline/workfile/build_workfile.py b/client/ayon_core/pipeline/workfile/build_workfile.py index 6d7ea2c7ad..5ff8b21259 100644 --- a/client/ayon_core/pipeline/workfile/build_workfile.py +++ b/client/ayon_core/pipeline/workfile/build_workfile.py @@ -315,9 +315,9 @@ class BuildWorkfile: ).format(json.dumps(profile, indent=4))) continue - # Check families - profile_families = profile.get("product_types") - if not profile_families: + # Check product types + profile_product_types = profile.get("product_types") + if not profile_product_types: self.log.warning(( "Build profile is missing families configuration: {0}" ).format(json.dumps(profile, indent=4))) @@ -334,7 +334,8 @@ class BuildWorkfile: # Prepare lowered families and representation names profile["product_types_lowered"] = [ - fam.lower() for fam in profile_families + product_type.lower() + for product_type in profile_product_types ] profile["repre_names_lowered"] = [ name.lower() for name in profile_repre_names diff --git a/client/ayon_core/pipeline/workfile/workfile_template_builder.py b/client/ayon_core/pipeline/workfile/workfile_template_builder.py index e8b5268a6d..124952b2c0 100644 --- a/client/ayon_core/pipeline/workfile/workfile_template_builder.py +++ b/client/ayon_core/pipeline/workfile/workfile_template_builder.py @@ -1286,14 +1286,14 @@ class PlaceholderLoadMixin(object): loader_items = list(sorted(loader_items, key=lambda i: i["label"])) options = options or {} - # Get families from all loaders excluding "*" - families = set() + # Get product types from all loaders excluding "*" + product_types = set() for loader in loaders_by_name.values(): - families.update(loader.families) - families.discard("*") + product_types.update(loader.product_types) + product_types.discard("*") # Sort for readability - families = list(sorted(families)) + product_types = list(sorted(product_types)) builder_type_enum_items = [ {"label": "Current folder", "value": "context_folder"}, @@ -1333,7 +1333,7 @@ class PlaceholderLoadMixin(object): "product_type", label="Product type", default=product_type, - items=families + items=product_types ), attribute_definitions.TextDef( "representation", diff --git a/client/ayon_core/plugins/load/copy_file.py b/client/ayon_core/plugins/load/copy_file.py index 0da22826f0..5e6daa866b 100644 --- a/client/ayon_core/plugins/load/copy_file.py +++ b/client/ayon_core/plugins/load/copy_file.py @@ -6,7 +6,7 @@ class CopyFile(load.LoaderPlugin): """Copy the published file to be pasted at the desired location""" representations = ["*"] - families = ["*"] + product_types = {"*"} label = "Copy File" order = 10 diff --git a/client/ayon_core/plugins/load/copy_file_path.py b/client/ayon_core/plugins/load/copy_file_path.py index c3478c32f3..ecde3bc55f 100644 --- a/client/ayon_core/plugins/load/copy_file_path.py +++ b/client/ayon_core/plugins/load/copy_file_path.py @@ -6,7 +6,7 @@ from ayon_core.pipeline import load class CopyFilePath(load.LoaderPlugin): """Copy published file path to clipboard""" representations = ["*"] - families = ["*"] + product_types = {"*"} label = "Copy File Path" order = 20 diff --git a/client/ayon_core/plugins/load/delete_old_versions.py b/client/ayon_core/plugins/load/delete_old_versions.py index 8fa0c2edb6..04873d8b5c 100644 --- a/client/ayon_core/plugins/load/delete_old_versions.py +++ b/client/ayon_core/plugins/load/delete_old_versions.py @@ -27,7 +27,7 @@ # sequence_splitter = "__sequence_splitter__" # # representations = ["*"] -# families = ["*"] +# product_types = {"*"} # tool_names = ["library_loader"] # # label = "Delete Old Versions" diff --git a/client/ayon_core/plugins/load/delivery.py b/client/ayon_core/plugins/load/delivery.py index 453bdfb87a..cfa245d0d2 100644 --- a/client/ayon_core/plugins/load/delivery.py +++ b/client/ayon_core/plugins/load/delivery.py @@ -29,7 +29,7 @@ class Delivery(load.ProductLoaderPlugin): sequence_splitter = "__sequence_splitter__" representations = ["*"] - families = ["*"] + product_types = {"*"} tool_names = ["library_loader"] label = "Deliver Versions" diff --git a/client/ayon_core/plugins/load/open_djv.py b/client/ayon_core/plugins/load/open_djv.py index 70352c2435..30023ac1f5 100644 --- a/client/ayon_core/plugins/load/open_djv.py +++ b/client/ayon_core/plugins/load/open_djv.py @@ -18,7 +18,7 @@ class OpenInDJV(load.LoaderPlugin): """Open Image Sequence with system default""" djv_list = existing_djv_path() - families = ["*"] if djv_list else [] + product_types = {"*"} if djv_list else [] representations = ["*"] extensions = { "cin", "dpx", "avi", "dv", "gif", "flv", "mkv", "mov", "mpg", "mpeg", diff --git a/client/ayon_core/plugins/load/open_file.py b/client/ayon_core/plugins/load/open_file.py index 5ae5959102..fc57708cd6 100644 --- a/client/ayon_core/plugins/load/open_file.py +++ b/client/ayon_core/plugins/load/open_file.py @@ -18,7 +18,7 @@ def open(filepath): class OpenFile(load.LoaderPlugin): """Open Image Sequence or Video with system default""" - families = ["render2d"] + product_types = {"render2d"} representations = ["*"] label = "Open" diff --git a/client/ayon_core/plugins/load/push_to_library.py b/client/ayon_core/plugins/load/push_to_library.py index a191ee88f0..02d834bc95 100644 --- a/client/ayon_core/plugins/load/push_to_library.py +++ b/client/ayon_core/plugins/load/push_to_library.py @@ -12,7 +12,7 @@ class PushToLibraryProject(load.ProductLoaderPlugin): is_multiple_contexts_compatible = True representations = ["*"] - families = ["*"] + product_types = {"*"} label = "Push to Library project" order = 35 diff --git a/client/ayon_core/plugins/publish/collect_rendered_files.py b/client/ayon_core/plugins/publish/collect_rendered_files.py index ca88a7aa82..8a60e7619d 100644 --- a/client/ayon_core/plugins/publish/collect_rendered_files.py +++ b/client/ayon_core/plugins/publish/collect_rendered_files.py @@ -36,18 +36,18 @@ class CollectRenderedFiles(pyblish.api.ContextPlugin): def _load_json(self, path): path = path.strip('\"') - assert os.path.isfile(path), ( - "Path to json file doesn't exist. \"{}\"".format(path) - ) + + if not os.path.isfile(path): + raise FileNotFoundError( + f"Path to json file doesn't exist. \"{path}\"") + data = None with open(path, "r") as json_file: try: data = json.load(json_file) except Exception as exc: self.log.error( - "Error loading json: " - "{} - Exception: {}".format(path, exc) - ) + "Error loading json: %s - Exception: %s", path, exc) return data def _fill_staging_dir(self, data_object, anatomy): @@ -73,30 +73,23 @@ class CollectRenderedFiles(pyblish.api.ContextPlugin): data_err = "invalid json file - missing data" required = ["user", "comment", "job", "instances", "version"] - assert all(elem in data.keys() for elem in required), data_err + + if any(elem not in data for elem in required): + raise ValueError(data_err) + if "folderPath" not in data and "asset" not in data: - raise AssertionError(data_err) + raise ValueError(data_err) if "folderPath" not in data: data["folderPath"] = data.pop("asset") - # set context by first json file - ctx = self._context.data - - ctx["folderPath"] = ctx.get("folderPath") or data.get("folderPath") - ctx["intent"] = ctx.get("intent") or data.get("intent") - ctx["comment"] = ctx.get("comment") or data.get("comment") - ctx["user"] = ctx.get("user") or data.get("user") - ctx["version"] = ctx.get("version") or data.get("version") - - # basic sanity check to see if we are working in same context - # if some other json file has different context, bail out. - ctx_err = "inconsistent contexts in json files - %s" - assert ctx.get("folderPath") == data.get("folderPath"), ctx_err % "folderPath" - assert ctx.get("intent") == data.get("intent"), ctx_err % "intent" - assert ctx.get("comment") == data.get("comment"), ctx_err % "comment" - assert ctx.get("user") == data.get("user"), ctx_err % "user" - assert ctx.get("version") == data.get("version"), ctx_err % "version" + # ftrack credentials are passed as environment variables by Deadline + # to publish job, but Muster doesn't pass them. + if data.get("ftrack") and not os.environ.get("FTRACK_API_USER"): + ftrack = data.get("ftrack") + os.environ["FTRACK_API_USER"] = ftrack["FTRACK_API_USER"] + os.environ["FTRACK_API_KEY"] = ftrack["FTRACK_API_KEY"] + os.environ["FTRACK_SERVER"] = ftrack["FTRACK_SERVER"] # now we can just add instances from json file and we are done any_staging_dir_persistent = False diff --git a/client/ayon_core/tools/ayon_utils/widgets/__init__.py b/client/ayon_core/tools/ayon_utils/widgets/__init__.py deleted file mode 100644 index a62bab6751..0000000000 --- a/client/ayon_core/tools/ayon_utils/widgets/__init__.py +++ /dev/null @@ -1,51 +0,0 @@ -from .projects_widget import ( - # ProjectsWidget, - ProjectsCombobox, - ProjectsQtModel, - ProjectSortFilterProxy, - PROJECT_NAME_ROLE, - PROJECT_IS_CURRENT_ROLE, - PROJECT_IS_ACTIVE_ROLE, - PROJECT_IS_LIBRARY_ROLE, -) - -from .folders_widget import ( - FoldersWidget, - FoldersQtModel, - FOLDERS_MODEL_SENDER_NAME, - SimpleFoldersWidget, -) - -from .tasks_widget import ( - TasksWidget, - TasksQtModel, - TASKS_MODEL_SENDER_NAME, -) -from .utils import ( - get_qt_icon, - RefreshThread, -) - - -__all__ = ( - # "ProjectsWidget", - "ProjectsCombobox", - "ProjectsQtModel", - "ProjectSortFilterProxy", - "PROJECT_NAME_ROLE", - "PROJECT_IS_CURRENT_ROLE", - "PROJECT_IS_ACTIVE_ROLE", - "PROJECT_IS_LIBRARY_ROLE", - - "FoldersWidget", - "FoldersQtModel", - "FOLDERS_MODEL_SENDER_NAME", - "SimpleFoldersWidget", - - "TasksWidget", - "TasksQtModel", - "TASKS_MODEL_SENDER_NAME", - - "get_qt_icon", - "RefreshThread", -) diff --git a/client/ayon_core/tools/ayon_utils/widgets/utils.py b/client/ayon_core/tools/ayon_utils/widgets/utils.py deleted file mode 100644 index ead8f4edb2..0000000000 --- a/client/ayon_core/tools/ayon_utils/widgets/utils.py +++ /dev/null @@ -1,109 +0,0 @@ -import os -from functools import partial - -from qtpy import QtCore, QtGui - -from ayon_core.tools.utils.lib import get_qta_icon_by_name_and_color - - -class RefreshThread(QtCore.QThread): - refresh_finished = QtCore.Signal(str) - - def __init__(self, thread_id, func, *args, **kwargs): - super(RefreshThread, self).__init__() - self._id = thread_id - self._callback = partial(func, *args, **kwargs) - self._exception = None - self._result = None - self.finished.connect(self._on_finish_callback) - - @property - def id(self): - return self._id - - @property - def failed(self): - return self._exception is not None - - def run(self): - try: - self._result = self._callback() - except Exception as exc: - self._exception = exc - - def get_result(self): - return self._result - - def _on_finish_callback(self): - """Trigger custom signal with thread id. - - Listening for 'finished' signal we make sure that execution of thread - finished and QThread object can be safely deleted. - """ - - self.refresh_finished.emit(self.id) - - -class _IconsCache: - """Cache for icons.""" - - _cache = {} - _default = None - - @classmethod - def _get_cache_key(cls, icon_def): - parts = [] - icon_type = icon_def["type"] - if icon_type == "path": - parts = [icon_type, icon_def["path"]] - - elif icon_type == "awesome-font": - parts = [icon_type, icon_def["name"], icon_def["color"]] - return "|".join(parts) - - @classmethod - def get_icon(cls, icon_def): - if not icon_def: - return None - icon_type = icon_def["type"] - cache_key = cls._get_cache_key(icon_def) - cache = cls._cache.get(cache_key) - if cache is not None: - return cache - - icon = None - if icon_type == "path": - path = icon_def["path"] - if os.path.exists(path): - icon = QtGui.QIcon(path) - - elif icon_type == "awesome-font": - icon_name = icon_def["name"] - icon_color = icon_def["color"] - icon = get_qta_icon_by_name_and_color(icon_name, icon_color) - if icon is None: - icon = get_qta_icon_by_name_and_color( - "fa.{}".format(icon_name), icon_color) - if icon is None: - icon = cls.get_default() - cls._cache[cache_key] = icon - return icon - - @classmethod - def get_default(cls): - pix = QtGui.QPixmap(1, 1) - pix.fill(QtCore.Qt.transparent) - return QtGui.QIcon(pix) - - -def get_qt_icon(icon_def): - """Returns icon from cache or creates new one. - - Args: - icon_def (dict[str, Any]): Icon definition. - - Returns: - QtGui.QIcon: Icon. - """ - - return _IconsCache.get_icon(icon_def) diff --git a/client/ayon_core/tools/ayon_utils/models/__init__.py b/client/ayon_core/tools/common_models/__init__.py similarity index 100% rename from client/ayon_core/tools/ayon_utils/models/__init__.py rename to client/ayon_core/tools/common_models/__init__.py diff --git a/client/ayon_core/tools/ayon_utils/models/cache.py b/client/ayon_core/tools/common_models/cache.py similarity index 100% rename from client/ayon_core/tools/ayon_utils/models/cache.py rename to client/ayon_core/tools/common_models/cache.py diff --git a/client/ayon_core/tools/ayon_utils/models/hierarchy.py b/client/ayon_core/tools/common_models/hierarchy.py similarity index 100% rename from client/ayon_core/tools/ayon_utils/models/hierarchy.py rename to client/ayon_core/tools/common_models/hierarchy.py diff --git a/client/ayon_core/tools/ayon_utils/models/projects.py b/client/ayon_core/tools/common_models/projects.py similarity index 100% rename from client/ayon_core/tools/ayon_utils/models/projects.py rename to client/ayon_core/tools/common_models/projects.py diff --git a/client/ayon_core/tools/ayon_utils/models/selection.py b/client/ayon_core/tools/common_models/selection.py similarity index 100% rename from client/ayon_core/tools/ayon_utils/models/selection.py rename to client/ayon_core/tools/common_models/selection.py diff --git a/client/ayon_core/tools/ayon_utils/models/thumbnails.py b/client/ayon_core/tools/common_models/thumbnails.py similarity index 100% rename from client/ayon_core/tools/ayon_utils/models/thumbnails.py rename to client/ayon_core/tools/common_models/thumbnails.py diff --git a/client/ayon_core/tools/context_dialog/window.py b/client/ayon_core/tools/context_dialog/window.py index b145e77515..828d771142 100644 --- a/client/ayon_core/tools/context_dialog/window.py +++ b/client/ayon_core/tools/context_dialog/window.py @@ -6,19 +6,17 @@ from qtpy import QtWidgets, QtCore, QtGui from ayon_core import style from ayon_core.lib.events import QueuedEventSystem -from ayon_core.tools.ayon_utils.models import ( +from ayon_core.tools.common_models import ( ProjectsModel, HierarchyModel, ) -from ayon_core.tools.ayon_utils.widgets import ( +from ayon_core.tools.utils import ( ProjectsCombobox, FoldersWidget, TasksWidget, -) -from ayon_core.tools.utils.lib import ( - center_window, get_ayon_qt_app, ) +from ayon_core.tools.utils.lib import center_window class SelectionModel(object): diff --git a/client/ayon_core/tools/launcher/control.py b/client/ayon_core/tools/launcher/control.py index 8780b211f1..abd0cd78d8 100644 --- a/client/ayon_core/tools/launcher/control.py +++ b/client/ayon_core/tools/launcher/control.py @@ -1,7 +1,7 @@ from ayon_core.lib import Logger from ayon_core.lib.events import QueuedEventSystem from ayon_core.settings import get_project_settings -from ayon_core.tools.ayon_utils.models import ProjectsModel, HierarchyModel +from ayon_core.tools.common_models import ProjectsModel, HierarchyModel from .abstract import AbstractLauncherFrontEnd, AbstractLauncherBackend from .models import LauncherSelectionModel, ActionsModel diff --git a/client/ayon_core/tools/launcher/ui/actions_widget.py b/client/ayon_core/tools/launcher/ui/actions_widget.py index 617f3b0c91..a225827418 100644 --- a/client/ayon_core/tools/launcher/ui/actions_widget.py +++ b/client/ayon_core/tools/launcher/ui/actions_widget.py @@ -4,7 +4,7 @@ import collections from qtpy import QtWidgets, QtCore, QtGui from ayon_core.tools.flickcharm import FlickCharm -from ayon_core.tools.ayon_utils.widgets import get_qt_icon +from ayon_core.tools.utils import get_qt_icon from .resources import get_options_image_path diff --git a/client/ayon_core/tools/launcher/ui/hierarchy_page.py b/client/ayon_core/tools/launcher/ui/hierarchy_page.py index 5b5f88a802..226a57930b 100644 --- a/client/ayon_core/tools/launcher/ui/hierarchy_page.py +++ b/client/ayon_core/tools/launcher/ui/hierarchy_page.py @@ -6,7 +6,7 @@ from ayon_core.tools.utils import ( SquareButton, RefreshButton, ) -from ayon_core.tools.ayon_utils.widgets import ( +from ayon_core.tools.utils import ( ProjectsCombobox, FoldersWidget, TasksWidget, diff --git a/client/ayon_core/tools/launcher/ui/projects_widget.py b/client/ayon_core/tools/launcher/ui/projects_widget.py index 729caf3232..e2af54b55d 100644 --- a/client/ayon_core/tools/launcher/ui/projects_widget.py +++ b/client/ayon_core/tools/launcher/ui/projects_widget.py @@ -1,12 +1,13 @@ from qtpy import QtWidgets, QtCore from ayon_core.tools.flickcharm import FlickCharm -from ayon_core.tools.utils import PlaceholderLineEdit, RefreshButton -from ayon_core.tools.ayon_utils.widgets import ( +from ayon_core.tools.utils import ( + PlaceholderLineEdit, + RefreshButton, ProjectsQtModel, ProjectSortFilterProxy, ) -from ayon_core.tools.ayon_utils.models import PROJECTS_MODEL_SENDER +from ayon_core.tools.common_models import PROJECTS_MODEL_SENDER class ProjectIconView(QtWidgets.QListView): diff --git a/client/ayon_core/tools/loader/control.py b/client/ayon_core/tools/loader/control.py index 5995bd2cae..d8562f50ca 100644 --- a/client/ayon_core/tools/loader/control.py +++ b/client/ayon_core/tools/loader/control.py @@ -6,7 +6,7 @@ import ayon_api from ayon_core.lib.events import QueuedEventSystem from ayon_core.pipeline import Anatomy, get_current_context from ayon_core.host import ILoadHost -from ayon_core.tools.ayon_utils.models import ( +from ayon_core.tools.common_models import ( ProjectsModel, HierarchyModel, NestedCacheItem, diff --git a/client/ayon_core/tools/loader/models/actions.py b/client/ayon_core/tools/loader/models/actions.py index aab5ba49d1..ad2993af50 100644 --- a/client/ayon_core/tools/loader/models/actions.py +++ b/client/ayon_core/tools/loader/models/actions.py @@ -17,7 +17,7 @@ from ayon_core.pipeline.load import ( LoadError, IncompatibleLoaderError, ) -from ayon_core.tools.ayon_utils.models import NestedCacheItem +from ayon_core.tools.common_models import NestedCacheItem from ayon_core.tools.loader.abstract import ActionItem ACTIONS_MODEL_SENDER = "actions.model" diff --git a/client/ayon_core/tools/loader/models/products.py b/client/ayon_core/tools/loader/models/products.py index 63547bef8b..812446a012 100644 --- a/client/ayon_core/tools/loader/models/products.py +++ b/client/ayon_core/tools/loader/models/products.py @@ -6,7 +6,7 @@ import ayon_api from ayon_api.operations import OperationsSession from ayon_core.style import get_default_entity_icon_color -from ayon_core.tools.ayon_utils.models import NestedCacheItem +from ayon_core.tools.common_models import NestedCacheItem from ayon_core.tools.loader.abstract import ( ProductTypeItem, ProductItem, diff --git a/client/ayon_core/tools/loader/models/site_sync.py b/client/ayon_core/tools/loader/models/site_sync.py index daa9f7ba50..a589cf7fbe 100644 --- a/client/ayon_core/tools/loader/models/site_sync.py +++ b/client/ayon_core/tools/loader/models/site_sync.py @@ -4,7 +4,7 @@ from ayon_api import get_representations, get_versions_links from ayon_core.lib import Logger from ayon_core.addon import AddonsManager -from ayon_core.tools.ayon_utils.models import NestedCacheItem +from ayon_core.tools.common_models import NestedCacheItem from ayon_core.tools.loader.abstract import ActionItem DOWNLOAD_IDENTIFIER = "sitesync.download" diff --git a/client/ayon_core/tools/loader/ui/actions_utils.py b/client/ayon_core/tools/loader/ui/actions_utils.py index bf6ab6eeb5..5a988ef4c2 100644 --- a/client/ayon_core/tools/loader/ui/actions_utils.py +++ b/client/ayon_core/tools/loader/ui/actions_utils.py @@ -10,7 +10,7 @@ from ayon_core.tools.utils.widgets import ( OptionalAction, OptionDialog, ) -from ayon_core.tools.ayon_utils.widgets import get_qt_icon +from ayon_core.tools.utils import get_qt_icon def show_actions_menu(action_items, global_point, one_item_selected, parent): diff --git a/client/ayon_core/tools/loader/ui/folders_widget.py b/client/ayon_core/tools/loader/ui/folders_widget.py index 34881ab49d..7b146456da 100644 --- a/client/ayon_core/tools/loader/ui/folders_widget.py +++ b/client/ayon_core/tools/loader/ui/folders_widget.py @@ -7,11 +7,11 @@ from ayon_core.tools.utils import ( ) from ayon_core.style import get_objected_colors -from ayon_core.tools.ayon_utils.widgets import ( +from ayon_core.tools.utils import ( FoldersQtModel, FOLDERS_MODEL_SENDER_NAME, ) -from ayon_core.tools.ayon_utils.widgets.folders_widget import FOLDER_ID_ROLE +from ayon_core.tools.utils.folders_widget import FOLDER_ID_ROLE if qtpy.API == "pyside": from PySide.QtGui import QStyleOptionViewItemV4 diff --git a/client/ayon_core/tools/loader/ui/product_types_widget.py b/client/ayon_core/tools/loader/ui/product_types_widget.py index 26244517ec..180994fd7f 100644 --- a/client/ayon_core/tools/loader/ui/product_types_widget.py +++ b/client/ayon_core/tools/loader/ui/product_types_widget.py @@ -1,6 +1,6 @@ from qtpy import QtWidgets, QtGui, QtCore -from ayon_core.tools.ayon_utils.widgets import get_qt_icon +from ayon_core.tools.utils import get_qt_icon PRODUCT_TYPE_ROLE = QtCore.Qt.UserRole + 1 diff --git a/client/ayon_core/tools/loader/ui/products_model.py b/client/ayon_core/tools/loader/ui/products_model.py index 331efad68a..c51172849a 100644 --- a/client/ayon_core/tools/loader/ui/products_model.py +++ b/client/ayon_core/tools/loader/ui/products_model.py @@ -4,7 +4,7 @@ import qtawesome from qtpy import QtGui, QtCore from ayon_core.style import get_default_entity_icon_color -from ayon_core.tools.ayon_utils.widgets import get_qt_icon +from ayon_core.tools.utils import get_qt_icon PRODUCTS_MODEL_SENDER_NAME = "qt_products_model" diff --git a/client/ayon_core/tools/loader/ui/repres_widget.py b/client/ayon_core/tools/loader/ui/repres_widget.py index 27db8dda40..3b6b8f94bf 100644 --- a/client/ayon_core/tools/loader/ui/repres_widget.py +++ b/client/ayon_core/tools/loader/ui/repres_widget.py @@ -4,7 +4,7 @@ from qtpy import QtWidgets, QtGui, QtCore import qtawesome from ayon_core.style import get_default_entity_icon_color -from ayon_core.tools.ayon_utils.widgets import get_qt_icon +from ayon_core.tools.utils import get_qt_icon from ayon_core.tools.utils import DeselectableTreeView from .actions_utils import show_actions_menu diff --git a/client/ayon_core/tools/loader/ui/window.py b/client/ayon_core/tools/loader/ui/window.py index 104b64d81c..3a6f4679fa 100644 --- a/client/ayon_core/tools/loader/ui/window.py +++ b/client/ayon_core/tools/loader/ui/window.py @@ -10,7 +10,7 @@ from ayon_core.tools.utils import ( GoToCurrentButton, ) from ayon_core.tools.utils.lib import center_window -from ayon_core.tools.ayon_utils.widgets import ProjectsCombobox +from ayon_core.tools.utils import ProjectsCombobox from ayon_core.tools.loader.control import LoaderController from .folders_widget import LoaderFoldersWidget diff --git a/client/ayon_core/tools/publisher/control.py b/client/ayon_core/tools/publisher/control.py index aaca0fea10..ede772b917 100644 --- a/client/ayon_core/tools/publisher/control.py +++ b/client/ayon_core/tools/publisher/control.py @@ -38,7 +38,7 @@ from ayon_core.pipeline.create.context import ( ConvertorsOperationFailed, ) from ayon_core.pipeline.publish import get_publish_instance_label -from ayon_core.tools.ayon_utils.models import HierarchyModel +from ayon_core.tools.common_models import HierarchyModel # Define constant for plugin orders offset PLUGIN_ORDER_OFFSET = 0.5 diff --git a/client/ayon_core/tools/publisher/widgets/create_context_widgets.py b/client/ayon_core/tools/publisher/widgets/create_context_widgets.py index d65a2ace8d..61223bbe75 100644 --- a/client/ayon_core/tools/publisher/widgets/create_context_widgets.py +++ b/client/ayon_core/tools/publisher/widgets/create_context_widgets.py @@ -3,8 +3,8 @@ from qtpy import QtWidgets, QtCore, QtGui from ayon_core.lib.events import QueuedEventSystem from ayon_core.tools.utils import PlaceholderLineEdit, GoToCurrentButton -from ayon_core.tools.ayon_utils.models import HierarchyExpectedSelection -from ayon_core.tools.ayon_utils.widgets import FoldersWidget, TasksWidget +from ayon_core.tools.common_models import HierarchyExpectedSelection +from ayon_core.tools.utils import FoldersWidget, TasksWidget class CreateSelectionModel(object): diff --git a/client/ayon_core/tools/publisher/widgets/folders_dialog.py b/client/ayon_core/tools/publisher/widgets/folders_dialog.py index 8f93264b2e..03336e10a6 100644 --- a/client/ayon_core/tools/publisher/widgets/folders_dialog.py +++ b/client/ayon_core/tools/publisher/widgets/folders_dialog.py @@ -1,8 +1,7 @@ from qtpy import QtWidgets, QtCore, QtGui from ayon_core.lib.events import QueuedEventSystem -from ayon_core.tools.ayon_utils.widgets import FoldersWidget -from ayon_core.tools.utils import PlaceholderLineEdit +from ayon_core.tools.utils import PlaceholderLineEdit, FoldersWidget class FoldersDialogController: diff --git a/client/ayon_core/tools/publisher/widgets/tasks_model.py b/client/ayon_core/tools/publisher/widgets/tasks_model.py index 8f00dc37a2..e36de80fcf 100644 --- a/client/ayon_core/tools/publisher/widgets/tasks_model.py +++ b/client/ayon_core/tools/publisher/widgets/tasks_model.py @@ -1,6 +1,7 @@ from qtpy import QtWidgets, QtCore, QtGui -from ayon_core.tools.utils.lib import get_default_task_icon +from ayon_core.style import get_default_entity_icon_color +from ayon_core.tools.utils import get_qt_icon TASK_NAME_ROLE = QtCore.Qt.UserRole + 1 TASK_TYPE_ROLE = QtCore.Qt.UserRole + 2 @@ -121,6 +122,11 @@ class TasksModel(QtGui.QStandardItemModel): item = self._items_by_name.pop(task_name) root_item.removeRow(item.row()) + icon = get_qt_icon({ + "type": "awesome-font", + "name": "fa.male", + "color": get_default_entity_icon_color(), + }) new_items = [] for task_name in new_task_names: if task_name in self._items_by_name: @@ -129,7 +135,7 @@ class TasksModel(QtGui.QStandardItemModel): item = QtGui.QStandardItem(task_name) item.setData(task_name, TASK_NAME_ROLE) if task_name: - item.setData(get_default_task_icon(), QtCore.Qt.DecorationRole) + item.setData(icon, QtCore.Qt.DecorationRole) self._items_by_name[task_name] = item new_items.append(item) diff --git a/client/ayon_core/tools/push_to_project/control.py b/client/ayon_core/tools/push_to_project/control.py index d5acaadc2a..58447a8389 100644 --- a/client/ayon_core/tools/push_to_project/control.py +++ b/client/ayon_core/tools/push_to_project/control.py @@ -6,7 +6,7 @@ from ayon_core.settings import get_project_settings from ayon_core.lib import prepare_template_data from ayon_core.lib.events import QueuedEventSystem from ayon_core.pipeline.create import get_product_name_template -from ayon_core.tools.ayon_utils.models import ProjectsModel, HierarchyModel +from ayon_core.tools.common_models import ProjectsModel, HierarchyModel from .models import ( PushToProjectSelectionModel, diff --git a/client/ayon_core/tools/push_to_project/ui/window.py b/client/ayon_core/tools/push_to_project/ui/window.py index bc2fc6bf96..4d64509afd 100644 --- a/client/ayon_core/tools/push_to_project/ui/window.py +++ b/client/ayon_core/tools/push_to_project/ui/window.py @@ -5,8 +5,6 @@ from ayon_core.tools.utils import ( PlaceholderLineEdit, SeparatorWidget, set_style_property, -) -from ayon_core.tools.ayon_utils.widgets import ( ProjectsCombobox, FoldersWidget, TasksWidget, diff --git a/client/ayon_core/tools/sceneinventory/control.py b/client/ayon_core/tools/sceneinventory/control.py index 16b889e855..77f4d60b22 100644 --- a/client/ayon_core/tools/sceneinventory/control.py +++ b/client/ayon_core/tools/sceneinventory/control.py @@ -6,7 +6,7 @@ from ayon_core.pipeline import ( registered_host, get_current_context, ) -from ayon_core.tools.ayon_utils.models import HierarchyModel +from ayon_core.tools.common_models import HierarchyModel from .models import SiteSyncModel diff --git a/client/ayon_core/tools/sceneinventory/model.py b/client/ayon_core/tools/sceneinventory/model.py index e53b6aa4c3..df0dea7a3d 100644 --- a/client/ayon_core/tools/sceneinventory/model.py +++ b/client/ayon_core/tools/sceneinventory/model.py @@ -13,8 +13,8 @@ from ayon_core.pipeline import ( HeroVersionType, ) from ayon_core.style import get_default_entity_icon_color +from ayon_core.tools.utils import get_qt_icon from ayon_core.tools.utils.models import TreeModel, Item -from ayon_core.tools.ayon_utils.widgets import get_qt_icon def walk_hierarchy(node): diff --git a/client/ayon_core/tools/sceneinventory/switch_dialog/folders_input.py b/client/ayon_core/tools/sceneinventory/switch_dialog/folders_input.py index e46c28474f..3137e70214 100644 --- a/client/ayon_core/tools/sceneinventory/switch_dialog/folders_input.py +++ b/client/ayon_core/tools/sceneinventory/switch_dialog/folders_input.py @@ -5,8 +5,8 @@ from ayon_core.tools.utils import ( PlaceholderLineEdit, BaseClickableFrame, set_style_property, + FoldersWidget, ) -from ayon_core.tools.ayon_utils.widgets import FoldersWidget NOT_SET = object() diff --git a/client/ayon_core/tools/traypublisher/window.py b/client/ayon_core/tools/traypublisher/window.py index 988c22819a..4700e20531 100644 --- a/client/ayon_core/tools/traypublisher/window.py +++ b/client/ayon_core/tools/traypublisher/window.py @@ -16,9 +16,10 @@ from ayon_core.pipeline import install_host from ayon_core.hosts.traypublisher.api import TrayPublisherHost from ayon_core.tools.publisher.control_qt import QtPublisherController from ayon_core.tools.publisher.window import PublisherWindow -from ayon_core.tools.utils import PlaceholderLineEdit, get_ayon_qt_app -from ayon_core.tools.ayon_utils.models import ProjectsModel -from ayon_core.tools.ayon_utils.widgets import ( +from ayon_core.tools.common_models import ProjectsModel +from ayon_core.tools.utils import ( + PlaceholderLineEdit, + get_ayon_qt_app, ProjectsQtModel, ProjectSortFilterProxy, PROJECT_NAME_ROLE, diff --git a/client/ayon_core/tools/utils/__init__.py b/client/ayon_core/tools/utils/__init__.py index 445b4d9b97..4b5fbeaf67 100644 --- a/client/ayon_core/tools/utils/__init__.py +++ b/client/ayon_core/tools/utils/__init__.py @@ -37,6 +37,7 @@ from .lib import ( get_qt_app, get_ayon_qt_app, get_openpype_qt_app, + get_qt_icon, ) from .models import ( @@ -55,6 +56,28 @@ from .dialogs import ( SimplePopup, PopupUpdateKeys, ) +from .projects_widget import ( + ProjectsCombobox, + ProjectsQtModel, + ProjectSortFilterProxy, + PROJECT_NAME_ROLE, + PROJECT_IS_CURRENT_ROLE, + PROJECT_IS_ACTIVE_ROLE, + PROJECT_IS_LIBRARY_ROLE, +) + +from .folders_widget import ( + FoldersWidget, + FoldersQtModel, + FOLDERS_MODEL_SENDER_NAME, + SimpleFoldersWidget, +) + +from .tasks_widget import ( + TasksWidget, + TasksQtModel, + TASKS_MODEL_SENDER_NAME, +) __all__ = ( @@ -96,6 +119,7 @@ __all__ = ( "get_qt_app", "get_ayon_qt_app", "get_openpype_qt_app", + "get_qt_icon", "RecursiveSortFilterProxyModel", @@ -113,4 +137,21 @@ __all__ = ( "ScrollMessageBox", "SimplePopup", "PopupUpdateKeys", + + "ProjectsCombobox", + "ProjectsQtModel", + "ProjectSortFilterProxy", + "PROJECT_NAME_ROLE", + "PROJECT_IS_CURRENT_ROLE", + "PROJECT_IS_ACTIVE_ROLE", + "PROJECT_IS_LIBRARY_ROLE", + + "FoldersWidget", + "FoldersQtModel", + "FOLDERS_MODEL_SENDER_NAME", + "SimpleFoldersWidget", + + "TasksWidget", + "TasksQtModel", + "TASKS_MODEL_SENDER_NAME", ) diff --git a/client/ayon_core/tools/ayon_utils/widgets/folders_widget.py b/client/ayon_core/tools/utils/folders_widget.py similarity index 99% rename from client/ayon_core/tools/ayon_utils/widgets/folders_widget.py rename to client/ayon_core/tools/utils/folders_widget.py index e42a5b635c..2ad640de37 100644 --- a/client/ayon_core/tools/ayon_utils/widgets/folders_widget.py +++ b/client/ayon_core/tools/utils/folders_widget.py @@ -3,16 +3,15 @@ import collections from qtpy import QtWidgets, QtGui, QtCore from ayon_core.lib.events import QueuedEventSystem -from ayon_core.tools.ayon_utils.models import ( +from ayon_core.tools.common_models import ( HierarchyModel, HierarchyExpectedSelection, ) -from ayon_core.tools.utils import ( - RecursiveSortFilterProxyModel, - TreeView, -) -from .utils import RefreshThread, get_qt_icon +from .models import RecursiveSortFilterProxyModel +from .views import TreeView +from .lib import RefreshThread, get_qt_icon + FOLDERS_MODEL_SENDER_NAME = "qt_folders_model" FOLDER_ID_ROLE = QtCore.Qt.UserRole + 1 diff --git a/client/ayon_core/tools/utils/lib.py b/client/ayon_core/tools/utils/lib.py index 741fc1f335..8bcfe8b985 100644 --- a/client/ayon_core/tools/utils/lib.py +++ b/client/ayon_core/tools/utils/lib.py @@ -1,6 +1,7 @@ import os import sys import contextlib +from functools import partial from qtpy import QtWidgets, QtCore, QtGui import qtawesome @@ -195,51 +196,6 @@ def get_openpype_qt_app(): return get_ayon_qt_app() -class _Cache: - icons = {} - - -def get_qta_icon_by_name_and_color(icon_name, icon_color): - if not icon_name or not icon_color: - return None - - full_icon_name = "{0}-{1}".format(icon_name, icon_color) - if full_icon_name in _Cache.icons: - return _Cache.icons[full_icon_name] - - variants = [icon_name] - qta_instance = qtawesome._instance() - for key in qta_instance.charmap.keys(): - variants.append("{0}.{1}".format(key, icon_name)) - - icon = None - used_variant = None - for variant in variants: - try: - icon = qtawesome.icon(variant, color=icon_color) - used_variant = variant - break - except Exception: - pass - - if used_variant is None: - 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 - )) - - _Cache.icons[full_icon_name] = icon - return icon - - -def get_default_task_icon(color=None): - if color is None: - color = get_default_entity_icon_color() - return get_qta_icon_by_name_and_color("fa.male", color) - - def iter_model_rows(model, column, include_root=False): """Iterate over all row indices in a model""" indices = [QtCore.QModelIndex()] # start iteration at root @@ -457,3 +413,156 @@ def get_warning_pixmap(color=None): color = get_objected_colors("delete-btn-bg").get_qcolor() return paint_image_with_color(src_image, color) + + +class RefreshThread(QtCore.QThread): + refresh_finished = QtCore.Signal(str) + + def __init__(self, thread_id, func, *args, **kwargs): + super(RefreshThread, self).__init__() + self._id = thread_id + self._callback = partial(func, *args, **kwargs) + self._exception = None + self._result = None + self.finished.connect(self._on_finish_callback) + + @property + def id(self): + return self._id + + @property + def failed(self): + return self._exception is not None + + def run(self): + try: + self._result = self._callback() + except Exception as exc: + self._exception = exc + + def get_result(self): + return self._result + + def _on_finish_callback(self): + """Trigger custom signal with thread id. + + Listening for 'finished' signal we make sure that execution of thread + finished and QThread object can be safely deleted. + """ + + self.refresh_finished.emit(self.id) + + +class _IconsCache: + """Cache for icons.""" + + _cache = {} + _default = None + _qtawesome_cache = {} + + @classmethod + def _get_cache_key(cls, icon_def): + parts = [] + icon_type = icon_def["type"] + if icon_type == "path": + parts = [icon_type, icon_def["path"]] + + elif icon_type == "awesome-font": + parts = [icon_type, icon_def["name"], icon_def["color"]] + return "|".join(parts) + + @classmethod + def get_icon(cls, icon_def): + if not icon_def: + return None + icon_type = icon_def["type"] + cache_key = cls._get_cache_key(icon_def) + cache = cls._cache.get(cache_key) + if cache is not None: + return cache + + icon = None + if icon_type == "path": + path = icon_def["path"] + if os.path.exists(path): + icon = QtGui.QIcon(path) + + elif icon_type == "awesome-font": + icon_name = icon_def["name"] + icon_color = icon_def["color"] + icon = cls.get_qta_icon_by_name_and_color(icon_name, icon_color) + if icon is None: + icon = cls.get_qta_icon_by_name_and_color( + "fa.{}".format(icon_name), icon_color) + if icon is None: + icon = cls.get_default() + cls._cache[cache_key] = icon + return icon + + @classmethod + def get_default(cls): + pix = QtGui.QPixmap(1, 1) + pix.fill(QtCore.Qt.transparent) + return QtGui.QIcon(pix) + + @classmethod + def get_qta_icon_by_name_and_color(cls, icon_name, icon_color): + if not icon_name or not icon_color: + return None + + full_icon_name = "{0}-{1}".format(icon_name, icon_color) + if full_icon_name in cls._qtawesome_cache: + return cls._qtawesome_cache[full_icon_name] + + variants = [icon_name] + qta_instance = qtawesome._instance() + for key in qta_instance.charmap.keys(): + variants.append("{0}.{1}".format(key, icon_name)) + + icon = None + used_variant = None + for variant in variants: + try: + icon = qtawesome.icon(variant, color=icon_color) + used_variant = variant + break + except Exception: + pass + + if used_variant is None: + 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 + )) + + cls._qtawesome_cache[full_icon_name] = icon + return icon + + +def get_qt_icon(icon_def): + """Returns icon from cache or creates new one. + + Args: + icon_def (dict[str, Any]): Icon definition. + + Returns: + QtGui.QIcon: Icon. + + """ + return _IconsCache.get_icon(icon_def) + + +def get_qta_icon_by_name_and_color(icon_name, icon_color): + """Returns icon from cache or creates new one. + + Args: + icon_name (str): Icon name. + icon_color (str): Icon color. + + Returns: + QtGui.QIcon: Icon. + + """ + return _IconsCache.get_qta_icon_by_name_and_color(icon_name, icon_color) diff --git a/client/ayon_core/tools/ayon_utils/widgets/projects_widget.py b/client/ayon_core/tools/utils/projects_widget.py similarity index 99% rename from client/ayon_core/tools/ayon_utils/widgets/projects_widget.py rename to client/ayon_core/tools/utils/projects_widget.py index 79ffc77640..fd361493ab 100644 --- a/client/ayon_core/tools/ayon_utils/widgets/projects_widget.py +++ b/client/ayon_core/tools/utils/projects_widget.py @@ -1,7 +1,8 @@ from qtpy import QtWidgets, QtCore, QtGui -from ayon_core.tools.ayon_utils.models import PROJECTS_MODEL_SENDER -from .utils import RefreshThread, get_qt_icon +from ayon_core.tools.common_models import PROJECTS_MODEL_SENDER + +from .lib import RefreshThread, get_qt_icon PROJECT_NAME_ROLE = QtCore.Qt.UserRole + 1 PROJECT_IS_ACTIVE_ROLE = QtCore.Qt.UserRole + 2 diff --git a/client/ayon_core/tools/ayon_utils/widgets/tasks_widget.py b/client/ayon_core/tools/utils/tasks_widget.py similarity index 99% rename from client/ayon_core/tools/ayon_utils/widgets/tasks_widget.py rename to client/ayon_core/tools/utils/tasks_widget.py index cfe901c492..0ff8e8a5c1 100644 --- a/client/ayon_core/tools/ayon_utils/widgets/tasks_widget.py +++ b/client/ayon_core/tools/utils/tasks_widget.py @@ -1,9 +1,9 @@ from qtpy import QtWidgets, QtGui, QtCore from ayon_core.style import get_disabled_entity_icon_color -from ayon_core.tools.utils import DeselectableTreeView -from .utils import RefreshThread, get_qt_icon +from .views import DeselectableTreeView +from .lib import RefreshThread, get_qt_icon TASKS_MODEL_SENDER_NAME = "qt_tasks_model" ITEM_ID_ROLE = QtCore.Qt.UserRole + 1 diff --git a/client/ayon_core/tools/workfiles/control.py b/client/ayon_core/tools/workfiles/control.py index 3111c4d443..7fa7af1662 100644 --- a/client/ayon_core/tools/workfiles/control.py +++ b/client/ayon_core/tools/workfiles/control.py @@ -15,7 +15,7 @@ from ayon_core.pipeline.context_tools import ( ) from ayon_core.pipeline.workfile import create_workdir_extra_folders -from ayon_core.tools.ayon_utils.models import ( +from ayon_core.tools.common_models import ( HierarchyModel, HierarchyExpectedSelection, ProjectsModel, diff --git a/client/ayon_core/tools/workfiles/widgets/window.py b/client/ayon_core/tools/workfiles/widgets/window.py index 86a84b6195..8a2617d270 100644 --- a/client/ayon_core/tools/workfiles/widgets/window.py +++ b/client/ayon_core/tools/workfiles/widgets/window.py @@ -6,9 +6,13 @@ from ayon_core.tools.utils import ( MessageOverlayObject, ) -from ayon_core.tools.ayon_utils.widgets import FoldersWidget, TasksWidget from ayon_core.tools.workfiles.control import BaseWorkfileController -from ayon_core.tools.utils import GoToCurrentButton, RefreshButton +from ayon_core.tools.utils import ( + GoToCurrentButton, + RefreshButton, + FoldersWidget, + TasksWidget, +) from .side_panel import SidePanelWidget from .files_widget import FilesWidget