From d5473aee74c1e816a2ae2f381cd1e59dab0b132e Mon Sep 17 00:00:00 2001 From: Milan Kolar Date: Thu, 3 Dec 2020 00:02:43 +0100 Subject: [PATCH 01/54] refactor maya loaders config to settings --- pype/plugins/maya/load/load_ass.py | 10 +++++----- pype/plugins/maya/load/load_gpucache.py | 6 +++--- pype/plugins/maya/load/load_reference.py | 6 +++--- pype/plugins/maya/load/load_vdb_to_redshift.py | 6 +++--- pype/plugins/maya/load/load_vdb_to_vray.py | 6 +++--- pype/plugins/maya/load/load_vrayproxy.py | 6 +++--- pype/plugins/maya/load/load_yeti_cache.py | 6 +++--- pype/plugins/maya/load/load_yeti_rig.py | 6 +++--- 8 files changed, 26 insertions(+), 26 deletions(-) diff --git a/pype/plugins/maya/load/load_ass.py b/pype/plugins/maya/load/load_ass.py index ffe70c39e8..dc3e0043ee 100644 --- a/pype/plugins/maya/load/load_ass.py +++ b/pype/plugins/maya/load/load_ass.py @@ -1,7 +1,7 @@ from avalon import api import pype.hosts.maya.plugin import os -from pype.api import config +from pype.api import project_settings import clique @@ -74,8 +74,8 @@ class AssProxyLoader(pype.hosts.maya.plugin.ReferenceLoader): proxyShape.dso.set(path) proxyShape.aiOverrideShaders.set(0) - presets = config.get_presets(project=os.environ['AVALON_PROJECT']) - colors = presets['plugins']['maya']['load']['colors'] + settings = project_settings(os.environ['AVALON_PROJECT']) + colors = settings['maya']['load']['colors'] c = colors.get(family) if c is not None: @@ -196,8 +196,8 @@ class AssStandinLoader(api.Loader): label = "{}:{}".format(namespace, name) root = pm.group(name=label, empty=True) - presets = config.get_presets(project=os.environ['AVALON_PROJECT']) - colors = presets['plugins']['maya']['load']['colors'] + settings = project_settings(os.environ['AVALON_PROJECT']) + colors = settings['maya']['load']['colors'] c = colors.get('ass') if c is not None: diff --git a/pype/plugins/maya/load/load_gpucache.py b/pype/plugins/maya/load/load_gpucache.py index 9930dbaac6..6520be0a07 100644 --- a/pype/plugins/maya/load/load_gpucache.py +++ b/pype/plugins/maya/load/load_gpucache.py @@ -1,7 +1,7 @@ from avalon import api import pype.hosts.maya.plugin import os -from pype.api import config +from pype.api import project_settings reload(config) @@ -35,8 +35,8 @@ class GpuCacheLoader(api.Loader): label = "{}:{}".format(namespace, name) root = cmds.group(name=label, empty=True) - presets = config.get_presets(project=os.environ['AVALON_PROJECT']) - colors = presets['plugins']['maya']['load']['colors'] + settings = project_settings(os.environ['AVALON_PROJECT']) + colors = settings['maya']['load']['colors'] c = colors.get('model') if c is not None: cmds.setAttr(root + ".useOutlinerColor", 1) diff --git a/pype/plugins/maya/load/load_reference.py b/pype/plugins/maya/load/load_reference.py index dbb3cc98b2..90a3015894 100644 --- a/pype/plugins/maya/load/load_reference.py +++ b/pype/plugins/maya/load/load_reference.py @@ -2,7 +2,7 @@ import pype.hosts.maya.plugin from avalon import api, maya from maya import cmds import os -from pype.api import config +from pype.api import project_settings class ReferenceLoader(pype.hosts.maya.plugin.ReferenceLoader): @@ -77,8 +77,8 @@ class ReferenceLoader(pype.hosts.maya.plugin.ReferenceLoader): cmds.setAttr(groupName + ".displayHandle", 1) - presets = config.get_presets(project=os.environ['AVALON_PROJECT']) - colors = presets['plugins']['maya']['load']['colors'] + settings = project_settings(os.environ['AVALON_PROJECT']) + colors = settings['maya']['load']['colors'] c = colors.get(family) if c is not None: groupNode.useOutlinerColor.set(1) diff --git a/pype/plugins/maya/load/load_vdb_to_redshift.py b/pype/plugins/maya/load/load_vdb_to_redshift.py index 4893640b27..885f0f23c8 100644 --- a/pype/plugins/maya/load/load_vdb_to_redshift.py +++ b/pype/plugins/maya/load/load_vdb_to_redshift.py @@ -1,6 +1,6 @@ from avalon import api import os -from pype.api import config +from pype.api import project_settings class LoadVDBtoRedShift(api.Loader): """Load OpenVDB in a Redshift Volume Shape""" @@ -55,8 +55,8 @@ class LoadVDBtoRedShift(api.Loader): label = "{}:{}".format(namespace, name) root = cmds.group(name=label, empty=True) - presets = config.get_presets(project=os.environ['AVALON_PROJECT']) - colors = presets['plugins']['maya']['load']['colors'] + settings = project_settings(os.environ['AVALON_PROJECT']) + colors = settings['maya']['load']['colors'] c = colors.get(family) if c is not None: diff --git a/pype/plugins/maya/load/load_vdb_to_vray.py b/pype/plugins/maya/load/load_vdb_to_vray.py index aee0ee026d..9bfdda0308 100644 --- a/pype/plugins/maya/load/load_vdb_to_vray.py +++ b/pype/plugins/maya/load/load_vdb_to_vray.py @@ -1,5 +1,5 @@ from avalon import api -from pype.api import config +from pype.api import project_settings import os @@ -48,8 +48,8 @@ class LoadVDBtoVRay(api.Loader): label = "{}:{}".format(namespace, name) root = cmds.group(name=label, empty=True) - presets = config.get_presets(project=os.environ['AVALON_PROJECT']) - colors = presets['plugins']['maya']['load']['colors'] + settings = project_settings(os.environ['AVALON_PROJECT']) + colors = settings['maya']['load']['colors'] c = colors.get(family) if c is not None: diff --git a/pype/plugins/maya/load/load_vrayproxy.py b/pype/plugins/maya/load/load_vrayproxy.py index 894ec75c32..1294df2fc7 100644 --- a/pype/plugins/maya/load/load_vrayproxy.py +++ b/pype/plugins/maya/load/load_vrayproxy.py @@ -1,6 +1,6 @@ from avalon.maya import lib from avalon import api -from pype.api import config +from pype.api import project_settings import os import maya.cmds as cmds @@ -47,8 +47,8 @@ class VRayProxyLoader(api.Loader): return # colour the group node - presets = config.get_presets(project=os.environ['AVALON_PROJECT']) - colors = presets['plugins']['maya']['load']['colors'] + settings = project_settings(os.environ['AVALON_PROJECT']) + colors = settings['maya']['load']['colors'] c = colors.get(family) if c is not None: cmds.setAttr("{0}.useOutlinerColor".format(group_node), 1) diff --git a/pype/plugins/maya/load/load_yeti_cache.py b/pype/plugins/maya/load/load_yeti_cache.py index ef0b5d5efa..8ee1602202 100644 --- a/pype/plugins/maya/load/load_yeti_cache.py +++ b/pype/plugins/maya/load/load_yeti_cache.py @@ -9,7 +9,7 @@ from maya import cmds from avalon import api, io from avalon.maya import lib as avalon_lib, pipeline from pype.hosts.maya import lib -from pype.api import config +from pype.api import project_settings from pprint import pprint @@ -59,8 +59,8 @@ class YetiCacheLoader(api.Loader): group_name = "{}:{}".format(namespace, name) group_node = cmds.group(nodes, name=group_name) - presets = config.get_presets(project=os.environ['AVALON_PROJECT']) - colors = presets['plugins']['maya']['load']['colors'] + settings = project_settings(os.environ['AVALON_PROJECT']) + colors = settings['maya']['load']['colors'] c = colors.get(family) if c is not None: diff --git a/pype/plugins/maya/load/load_yeti_rig.py b/pype/plugins/maya/load/load_yeti_rig.py index 0604953198..bd74fcbc43 100644 --- a/pype/plugins/maya/load/load_yeti_rig.py +++ b/pype/plugins/maya/load/load_yeti_rig.py @@ -1,7 +1,7 @@ import os from collections import defaultdict -from pype.api import config +from pype.api import project_settings import pype.hosts.maya.plugin from pype.hosts.maya import lib @@ -77,8 +77,8 @@ class YetiRigLoader(pype.hosts.maya.plugin.ReferenceLoader): groupName = "{}:{}".format(namespace, name) - presets = config.get_presets(project=os.environ['AVALON_PROJECT']) - colors = presets['plugins']['maya']['load']['colors'] + settings = project_settings(os.environ['AVALON_PROJECT']) + colors = settings['maya']['load']['colors'] c = colors.get('yetiRig') if c is not None: From 8798bec8f0c2dda76cb33687ef092a4914fd31fd Mon Sep 17 00:00:00 2001 From: Milan Kolar Date: Thu, 3 Dec 2020 00:03:11 +0100 Subject: [PATCH 02/54] refactor maya muster submit config to settings --- pype/plugins/maya/publish/submit_maya_muster.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/pype/plugins/maya/publish/submit_maya_muster.py b/pype/plugins/maya/publish/submit_maya_muster.py index ffe434048a..df75fce1a4 100644 --- a/pype/plugins/maya/publish/submit_maya_muster.py +++ b/pype/plugins/maya/publish/submit_maya_muster.py @@ -11,7 +11,7 @@ from avalon.vendor import requests import pyblish.api from pype.hosts.maya import lib -from pype.api import config +from pype.api import system_settings # mapping between Maya renderer names and Muster template ids @@ -25,10 +25,9 @@ def _get_template_id(renderer): :rtype: int """ - templates = config.get_presets()["muster"]["templates_mapping"] + templates = system_settings()["modules"]["Muster"]["templates_mapping"] if not templates: - raise RuntimeError(("Muster template mapping missing in pype-config " - "`presets/muster/templates_mapping.json`")) + raise RuntimeError(("Muster template mapping missing in pype-settings")) try: template_id = templates[renderer] except KeyError: From ad6b4bf895058e6bb5645e5fd543dd28cb5dda9b Mon Sep 17 00:00:00 2001 From: Milan Kolar Date: Thu, 3 Dec 2020 00:03:30 +0100 Subject: [PATCH 03/54] refactor rendersetup example to settings --- pype/plugins/maya/create/create_rendersetup.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pype/plugins/maya/create/create_rendersetup.py b/pype/plugins/maya/create/create_rendersetup.py index 98f54f2d70..406d90223f 100644 --- a/pype/plugins/maya/create/create_rendersetup.py +++ b/pype/plugins/maya/create/create_rendersetup.py @@ -26,10 +26,10 @@ class CreateRenderSetup(avalon.maya.Creator): # \__| | # \_____/ - # from pype.api import config + # from pype.api import project_settings # import maya.app.renderSetup.model.renderSetup as renderSetup - # presets = config.get_presets(project=os.environ['AVALON_PROJECT']) - # layer = presets['plugins']['maya']['create']['renderSetup']["layer"] + # settings = project_settings(os.environ['AVALON_PROJECT']) + # layer = settings['maya']['create']['renderSetup']["layer"] # rs = renderSetup.instance() # rs.createRenderLayer(layer) From f7655dbb442bf91967c9f596c0f5f30cf5ecaaea Mon Sep 17 00:00:00 2001 From: Milan Kolar Date: Thu, 3 Dec 2020 11:09:57 +0100 Subject: [PATCH 04/54] change automatic plugin config loading to settings --- pype/__init__.py | 9 +++++---- pype/lib/plugin_tools.py | 6 +++--- pype/plugin.py | 8 +++++--- 3 files changed, 13 insertions(+), 10 deletions(-) diff --git a/pype/__init__.py b/pype/__init__.py index 2a922547e8..928bff6e9d 100644 --- a/pype/__init__.py +++ b/pype/__init__.py @@ -2,7 +2,7 @@ import os from pyblish import api as pyblish from avalon import api as avalon -from .api import config, Anatomy +from .api import project_settings, Anatomy from .lib import filter_pyblish_plugins @@ -50,14 +50,14 @@ def patched_discover(superclass): print(">>> trying to find presets for {}:{} ...".format(host, plugin_type)) try: - config_data = config.get_presets()['plugins'][host][plugin_type] + settings = project_settings(os.environ['AVALON_PROJECT'])[host][plugin_type] except KeyError: print("*** no presets found.") else: for plugin in plugins: - if plugin.__name__ in config_data: + if plugin.__name__ in settings: print(">>> We have preset for {}".format(plugin.__name__)) - for option, value in config_data[plugin.__name__].items(): + for option, value in settings[plugin.__name__].items(): if option == "enabled" and value is False: setattr(plugin, "active", False) print(" - is disabled by preset") @@ -104,6 +104,7 @@ def install(): anatomy.set_root_environments() avalon.register_root(anatomy.roots) # apply monkey patched discover to original one + log.info("Patching discovery") avalon.discover = patched_discover diff --git a/pype/lib/plugin_tools.py b/pype/lib/plugin_tools.py index 0b6ace807e..185ebce10f 100644 --- a/pype/lib/plugin_tools.py +++ b/pype/lib/plugin_tools.py @@ -4,7 +4,7 @@ import os import inspect import logging -from ..api import config +from ..api import config, project_settings log = logging.getLogger(__name__) @@ -25,7 +25,7 @@ def filter_pyblish_plugins(plugins): host = api.current_host() - presets = config.get_presets().get('plugins', {}) + presets = project_settings(os.environ['AVALON_PROJECT']) or {} # iterate over plugins for plugin in plugins[:]: @@ -53,7 +53,7 @@ def filter_pyblish_plugins(plugins): log.info('removing plugin {}'.format(plugin.__name__)) plugins.remove(plugin) else: - log.info('setting {}:{} on plugin {}'.format( + log.info('setting XXX {}:{} on plugin {}'.format( option, value, plugin.__name__)) setattr(plugin, option, value) diff --git a/pype/plugin.py b/pype/plugin.py index a169e82beb..8d53e9c4be 100644 --- a/pype/plugin.py +++ b/pype/plugin.py @@ -2,7 +2,7 @@ import tempfile import os import pyblish.api -from pype.api import config +from pype.api import project_settings import inspect ValidatePipelineOrder = pyblish.api.ValidatorOrder + 0.05 @@ -24,12 +24,14 @@ def imprint_attributes(plugin): plugin_host = file.split(os.path.sep)[-3:-2][0] plugin_name = type(plugin).__name__ try: - config_data = config.get_presets()['plugins'][plugin_host][plugin_kind][plugin_name] # noqa: E501 + settings = project_settings(os.environ['AVALON_PROJECT']) + settings_data = settings[plugin_host][plugin_kind][plugin_name] # noqa: E501 + print(settings_data) except KeyError: print("preset not found") return - for option, value in config_data.items(): + for option, value in settings_data.items(): if option == "enabled" and value is False: setattr(plugin, "active", False) else: From 09c846023e218b6c7108b25513910d8355f51d27 Mon Sep 17 00:00:00 2001 From: Milan Kolar Date: Thu, 3 Dec 2020 11:49:41 +0100 Subject: [PATCH 05/54] workfiles build from settings --- pype/lib/avalon_context.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/pype/lib/avalon_context.py b/pype/lib/avalon_context.py index 6cecdb93e3..c984e47b91 100644 --- a/pype/lib/avalon_context.py +++ b/pype/lib/avalon_context.py @@ -5,7 +5,7 @@ import logging import collections from avalon import io, pipeline -from ..api import config +from ..api import project_settings import avalon.api log = logging.getLogger("AvalonContext") @@ -410,12 +410,12 @@ class BuildWorkfile: (dict): preset per entered task name """ host_name = avalon.api.registered_host().__name__.rsplit(".", 1)[-1] - presets = config.get_presets(io.Session["AVALON_PROJECT"]) + presets = project_settings(io.Session["AVALON_PROJECT"]) # Get presets for host build_presets = ( - presets["plugins"] - .get(host_name, {}) + presets.get(host_name, {}) .get("workfile_build") + .get("profiles") ) if not build_presets: return From 81c56a45d625b1919ecbdab62db38dce6321ba6b Mon Sep 17 00:00:00 2001 From: Milan Kolar Date: Thu, 3 Dec 2020 11:50:27 +0100 Subject: [PATCH 06/54] publish filters from settings --- pype/tools/pyblish_pype/control.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/pype/tools/pyblish_pype/control.py b/pype/tools/pyblish_pype/control.py index fecfffd821..0994e25d4a 100644 --- a/pype/tools/pyblish_pype/control.py +++ b/pype/tools/pyblish_pype/control.py @@ -22,7 +22,7 @@ import pyblish.version from . import util from .constants import InstanceStates -from pype.api import config +from pype.api import project_settings class IterationBreak(Exception): @@ -121,14 +121,14 @@ class Controller(QtCore.QObject): def presets_by_hosts(self): # Get global filters as base - presets = config.get_presets().get("plugins", {}) + presets = project_settings(os.environ['AVALON_PROJECT']) or {} if not presets: return {} - result = presets.get("global", {}).get("filter", {}) + result = presets.get("global", {}).get("filters", {}) hosts = pyblish.api.registered_hosts() for host in hosts: - host_presets = presets.get(host, {}).get("filter") + host_presets = presets.get(host, {}).get("filters") if not host_presets: continue From f577480745639585f1d1caf70b52dfb0ff0e5368 Mon Sep 17 00:00:00 2001 From: Milan Kolar Date: Thu, 3 Dec 2020 11:50:47 +0100 Subject: [PATCH 07/54] publish intents from settings --- pype/tools/pyblish_pype/model.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/pype/tools/pyblish_pype/model.py b/pype/tools/pyblish_pype/model.py index ec9689381e..8c9bc07d7e 100644 --- a/pype/tools/pyblish_pype/model.py +++ b/pype/tools/pyblish_pype/model.py @@ -35,7 +35,7 @@ from six import text_type from .vendor import qtawesome from .constants import PluginStates, InstanceStates, GroupStates, Roles -from pype.api import config +from pype.api import system_settings # ItemTypes @@ -104,8 +104,9 @@ class IntentModel(QtGui.QStandardItemModel): self.default_index = 0 intents_preset = ( - config.get_presets() - .get("global", {}) + system_settings() + .get("modules", {}) + .get("Ftrack", {}) .get("intent", {}) ) From 650d63081314730b32a95adf1ee5b55ca6ce7127 Mon Sep 17 00:00:00 2001 From: Milan Kolar Date: Thu, 3 Dec 2020 11:51:03 +0100 Subject: [PATCH 08/54] change intent settings to group --- .../gui_schemas/system_schema/module_settings/schema_ftrack.json | 1 + 1 file changed, 1 insertion(+) diff --git a/pype/tools/settings/settings/gui_schemas/system_schema/module_settings/schema_ftrack.json b/pype/tools/settings/settings/gui_schemas/system_schema/module_settings/schema_ftrack.json index fa4cd3eea8..58cd81f544 100644 --- a/pype/tools/settings/settings/gui_schemas/system_schema/module_settings/schema_ftrack.json +++ b/pype/tools/settings/settings/gui_schemas/system_schema/module_settings/schema_ftrack.json @@ -59,6 +59,7 @@ "type": "dict", "label": "Intent", "collapsable_key": true, + "is_group": true, "children": [ { "type": "label", From 68002362e4f8233cf4806111634e0d1808fd7d43 Mon Sep 17 00:00:00 2001 From: Milan Kolar Date: Thu, 3 Dec 2020 11:53:39 +0100 Subject: [PATCH 09/54] nuke load mov outputs from settings --- pype/plugins/nuke/load/load_mov.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/pype/plugins/nuke/load/load_mov.py b/pype/plugins/nuke/load/load_mov.py index d252aaa09d..078127ee42 100644 --- a/pype/plugins/nuke/load/load_mov.py +++ b/pype/plugins/nuke/load/load_mov.py @@ -4,7 +4,7 @@ import contextlib from avalon import api, io from pype.hosts.nuke import presets -from pype.api import config +from pype.api import project_settings @contextlib.contextmanager @@ -73,7 +73,8 @@ def add_review_presets_config(): "families": list(), "representations": list() } - review_presets = config.get_presets()["plugins"]["global"]["publish"].get( + settings = project_settings(io.Session["AVALON_PROJECT"]) + review_presets = settings["global"]["publish"].get( "ExtractReview", {}) outputs = review_presets.get("outputs", {}) From 15daa17544fe7b38a2e63eb4ef4c07902677a3cb Mon Sep 17 00:00:00 2001 From: Milan Kolar Date: Thu, 3 Dec 2020 12:00:55 +0100 Subject: [PATCH 10/54] standalone publish families from settings --- .../tools/standalonepublish/widgets/widget_family.py | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/pype/tools/standalonepublish/widgets/widget_family.py b/pype/tools/standalonepublish/widgets/widget_family.py index 1c8f2238fc..be68e411fd 100644 --- a/pype/tools/standalonepublish/widgets/widget_family.py +++ b/pype/tools/standalonepublish/widgets/widget_family.py @@ -1,10 +1,11 @@ +import os from collections import namedtuple from Qt import QtWidgets, QtCore from . import HelpRole, FamilyRole, ExistsRole, PluginRole, PluginKeyRole from . import FamilyDescriptionWidget -from pype.api import config +from pype.api import project_settings class FamilyWidget(QtWidgets.QWidget): @@ -309,9 +310,14 @@ class FamilyWidget(QtWidgets.QWidget): def refresh(self): has_families = False - presets = config.get_presets().get('standalone_publish', {}) + settings = project_settings(os.environ['AVALON_PROJECT']) + sp_settings = settings.get('standalonepublisher', {}) + print(sp_settings) + + for key, creator in sp_settings.get("create", {}).items(): + if key == "__dynamic_keys_labels__": + continue - for key, creator in presets.get('families', {}).items(): creator = namedtuple("Creator", creator.keys())(*creator.values()) label = creator.label or creator.family From 8e6abe759af6626078dae5f46b9bf72b6873a7c2 Mon Sep 17 00:00:00 2001 From: Milan Kolar Date: Thu, 3 Dec 2020 12:01:10 +0100 Subject: [PATCH 11/54] mark legacy review for removal --- pype/scripts/otio_burnin.py | 1 + 1 file changed, 1 insertion(+) diff --git a/pype/scripts/otio_burnin.py b/pype/scripts/otio_burnin.py index 8da1dd8616..0bd636c6c5 100644 --- a/pype/scripts/otio_burnin.py +++ b/pype/scripts/otio_burnin.py @@ -429,6 +429,7 @@ def burnins_from_data( """ # Use legacy processing when options are not set + # TODO: remove legacy review if options is None or burnin_values is None: presets = config.get_presets().get("tools", {}).get("burnins", {}) options = presets.get("options") From 6c128049370bed0e6f695f5232874a126d3f7999 Mon Sep 17 00:00:00 2001 From: Milan Kolar Date: Thu, 3 Dec 2020 12:06:26 +0100 Subject: [PATCH 12/54] maya project shelves from settings --- setup/maya/userSetup.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/setup/maya/userSetup.py b/setup/maya/userSetup.py index bbf66846da..3cf2718796 100644 --- a/setup/maya/userSetup.py +++ b/setup/maya/userSetup.py @@ -1,5 +1,5 @@ import os -from pype.api import config +from pype.api import project_settings import pype.hosts.maya.lib as mlib from maya import cmds @@ -7,14 +7,14 @@ from maya import cmds print("starting PYPE usersetup") # build a shelf -presets = config.get_presets() -shelf_preset = presets['maya'].get('project_shelf') +settings = project_settings(os.environ['AVALON_PROJECT']) +shelf_preset = settings['maya'].get('project_shelf') if shelf_preset: project = os.environ["AVALON_PROJECT"] - icon_path = os.path.join(os.environ['PYPE_PROJECT_SCRIPTS'], project,"icons") + icon_path = os.path.join(os.environ['PYPE_PROJECT_SCRIPTS'], project, "icons") icon_path = os.path.abspath(icon_path) for i in shelf_preset['imports']: From 26a60111a6664ab9bd19f33af7bf8916933f3cde Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Thu, 3 Dec 2020 12:40:51 +0100 Subject: [PATCH 13/54] remove status setting from application actionas was moved to prelaunch hook --- .../ftrack/actions/action_applications.py | 50 ------------------- 1 file changed, 50 deletions(-) diff --git a/pype/modules/ftrack/actions/action_applications.py b/pype/modules/ftrack/actions/action_applications.py index a75b581ce3..d488bd20a2 100644 --- a/pype/modules/ftrack/actions/action_applications.py +++ b/pype/modules/ftrack/actions/action_applications.py @@ -1,7 +1,6 @@ import os from uuid import uuid4 -from pype.api import config from pype.modules.ftrack.lib import BaseAction from pype.lib import ( ApplicationManager, @@ -205,55 +204,6 @@ class AppplicationsAction(BaseAction): "message": msg } - # TODO Move to prelaunch/afterlaunch hooks - # TODO change to settings - # Change status of task to In progress - presets = config.get_presets()["ftrack"]["ftrack_config"] - - if "status_update" in presets: - statuses = presets["status_update"] - - actual_status = entity["status"]["name"].lower() - already_tested = [] - ent_path = "/".join( - [ent["name"] for ent in entity["link"]] - ) - while True: - next_status_name = None - for key, value in statuses.items(): - if key in already_tested: - continue - if actual_status in value or "_any_" in value: - if key != "_ignore_": - next_status_name = key - already_tested.append(key) - break - already_tested.append(key) - - if next_status_name is None: - break - - try: - query = "Status where name is \"{}\"".format( - next_status_name - ) - status = session.query(query).one() - - entity["status"] = status - session.commit() - self.log.debug("Changing status to \"{}\" <{}>".format( - next_status_name, ent_path - )) - break - - except Exception: - session.rollback() - msg = ( - "Status \"{}\" in presets wasn't found" - " on Ftrack entity type \"{}\"" - ).format(next_status_name, entity.entity_type) - self.log.warning(msg) - return { "success": True, "message": "Launching {0}".format(self.label) From 6f3fe954051eb448a3691bc0f1279d50d421aaed Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Thu, 3 Dec 2020 12:58:20 +0100 Subject: [PATCH 14/54] application is used everywhere so removed a lot of code --- pype/lib/applications.py | 388 +----------------- .../actions/action_application_loader.py | 104 ----- .../ftrack/actions/action_applications.py | 6 +- .../actions/action_create_cust_attrs.py | 71 +--- pype/modules/ftrack/lib/avalon_sync.py | 44 +- pype/modules/ftrack/lib/ftrack_app_handler.py | 223 ---------- pype/tools/launcher/lib.py | 47 --- pype/tools/launcher/models.py | 12 +- 8 files changed, 18 insertions(+), 877 deletions(-) delete mode 100644 pype/modules/ftrack/actions/action_application_loader.py delete mode 100644 pype/modules/ftrack/lib/ftrack_app_handler.py diff --git a/pype/lib/applications.py b/pype/lib/applications.py index ddff9ddcd2..0f2ea42175 100644 --- a/pype/lib/applications.py +++ b/pype/lib/applications.py @@ -1,6 +1,4 @@ import os -import sys -import getpass import copy import platform import inspect @@ -10,25 +8,14 @@ import distutils.spawn from abc import ABCMeta, abstractmethod import six -import acre -import avalon.lib -import avalon.api +from pype.settings import system_settings, environemtns +from ..api import Logger -from ..api import ( - Anatomy, - Logger, - config, - system_settings, - environments -) from .python_module_tools import ( modules_from_path, classes_from_module ) -from .hooks import execute_hook -from .deprecated import get_avalon_database - log = logging.getLogger(__name__) @@ -79,377 +66,6 @@ class ApplicationLaunchFailed(Exception): pass -def launch_application(project_name, asset_name, task_name, app_name): - """Launch host application with filling required environments. - - TODO(iLLiCiT): This should be split into more parts. - """ - # `get_avalon_database` is in Pype 3 replaced with using `AvalonMongoDB` - database = get_avalon_database() - project_document = database[project_name].find_one({"type": "project"}) - asset_document = database[project_name].find_one({ - "type": "asset", - "name": asset_name - }) - - asset_doc_parents = asset_document["data"].get("parents") - hierarchy = "/".join(asset_doc_parents) - - app_def = avalon.lib.get_application(app_name) - app_label = app_def.get("ftrack_label", app_def.get("label", app_name)) - - host_name = app_def["application_dir"] - # Workfile data collection may be special function? - data = { - "project": { - "name": project_document["name"], - "code": project_document["data"].get("code") - }, - "task": task_name, - "asset": asset_name, - "app": host_name, - "hierarchy": hierarchy - } - - try: - anatomy = Anatomy(project_name) - anatomy_filled = anatomy.format(data) - workdir = os.path.normpath(anatomy_filled["work"]["folder"]) - - except Exception as exc: - raise ApplicationLaunchFailed( - "Error in anatomy.format: {}".format(str(exc)) - ) - - try: - os.makedirs(workdir) - except FileExistsError: - pass - - last_workfile_path = None - extensions = avalon.api.HOST_WORKFILE_EXTENSIONS.get(host_name) - if extensions: - # Find last workfile - file_template = anatomy.templates["work"]["file"] - data.update({ - "version": 1, - "user": os.environ.get("PYPE_USERNAME") or getpass.getuser(), - "ext": extensions[0] - }) - - last_workfile_path = avalon.api.last_workfile( - workdir, file_template, data, extensions, True - ) - - # set environments for Avalon - prep_env = copy.deepcopy(os.environ) - prep_env.update({ - "AVALON_PROJECT": project_name, - "AVALON_ASSET": asset_name, - "AVALON_TASK": task_name, - "AVALON_APP": host_name, - "AVALON_APP_NAME": app_name, - "AVALON_HIERARCHY": hierarchy, - "AVALON_WORKDIR": workdir - }) - - start_last_workfile = avalon.api.should_start_last_workfile( - project_name, host_name, task_name - ) - # Store boolean as "0"(False) or "1"(True) - prep_env["AVALON_OPEN_LAST_WORKFILE"] = ( - str(int(bool(start_last_workfile))) - ) - - if ( - start_last_workfile - and last_workfile_path - and os.path.exists(last_workfile_path) - ): - prep_env["AVALON_LAST_WORKFILE"] = last_workfile_path - - prep_env.update(anatomy.roots_obj.root_environments()) - - # collect all the 'environment' attributes from parents - tools_attr = [prep_env["AVALON_APP"], prep_env["AVALON_APP_NAME"]] - tools_env = asset_document["data"].get("tools_env") or [] - tools_attr.extend(tools_env) - - tools_env = acre.get_tools(tools_attr) - env = acre.compute(tools_env) - env = acre.merge(env, current_env=dict(prep_env)) - - # Get path to execute - st_temp_path = os.environ["PYPE_CONFIG"] - os_plat = platform.system().lower() - - # Path to folder with launchers - path = os.path.join(st_temp_path, "launchers", os_plat) - - # Full path to executable launcher - execfile = None - - launch_hook = app_def.get("launch_hook") - if launch_hook: - log.info("launching hook: {}".format(launch_hook)) - ret_val = execute_hook(launch_hook, env=env) - if not ret_val: - raise ApplicationLaunchFailed( - "Hook didn't finish successfully {}".format(app_label) - ) - - if sys.platform == "win32": - for ext in os.environ["PATHEXT"].split(os.pathsep): - fpath = os.path.join(path.strip('"'), app_def["executable"] + ext) - if os.path.isfile(fpath) and os.access(fpath, os.X_OK): - execfile = fpath - break - - # Run SW if was found executable - if execfile is None: - raise ApplicationLaunchFailed( - "We didn't find launcher for {}".format(app_label) - ) - - popen = avalon.lib.launch( - executable=execfile, args=[], environment=env - ) - - elif ( - sys.platform.startswith("linux") - or sys.platform.startswith("darwin") - ): - execfile = os.path.join(path.strip('"'), app_def["executable"]) - # Run SW if was found executable - if execfile is None: - raise ApplicationLaunchFailed( - "We didn't find launcher for {}".format(app_label) - ) - - if not os.path.isfile(execfile): - raise ApplicationLaunchFailed( - "Launcher doesn't exist - {}".format(execfile) - ) - - try: - fp = open(execfile) - except PermissionError as perm_exc: - raise ApplicationLaunchFailed( - "Access denied on launcher {} - {}".format(execfile, perm_exc) - ) - - fp.close() - # check executable permission - if not os.access(execfile, os.X_OK): - raise ApplicationLaunchFailed( - "No executable permission - {}".format(execfile) - ) - - popen = avalon.lib.launch( # noqa: F841 - "/usr/bin/env", args=["bash", execfile], environment=env - ) - return popen - - -class ApplicationAction: - """Default application launcher - - This is a convenience application Action that when "config" refers to a - parsed application `.toml` this can launch the application. - - """ - _log = None - config = None - group = None - variant = None - required_session_keys = ( - "AVALON_PROJECT", - "AVALON_ASSET", - "AVALON_TASK" - ) - - @property - def log(self): - if self._log is None: - self._log = Logger().get_logger(self.__class__.__name__) - return self._log - - def is_compatible(self, session): - for key in self.required_session_keys: - if key not in session: - return False - return True - - def process(self, session, **kwargs): - """Process the full Application action""" - - project_name = session["AVALON_PROJECT"] - asset_name = session["AVALON_ASSET"] - task_name = session["AVALON_TASK"] - launch_application( - project_name, asset_name, task_name, self.name - ) - - self._ftrack_after_launch_procedure( - project_name, asset_name, task_name - ) - - def _ftrack_after_launch_procedure( - self, project_name, asset_name, task_name - ): - # TODO move to launch hook - required_keys = ("FTRACK_SERVER", "FTRACK_API_USER", "FTRACK_API_KEY") - for key in required_keys: - if not os.environ.get(key): - self.log.debug(( - "Missing required environment \"{}\"" - " for Ftrack after launch procedure." - ).format(key)) - return - - try: - import ftrack_api - session = ftrack_api.Session(auto_connect_event_hub=True) - self.log.debug("Ftrack session created") - except Exception: - self.log.warning("Couldn't create Ftrack session") - return - - try: - entity = self._find_ftrack_task_entity( - session, project_name, asset_name, task_name - ) - self._ftrack_status_change(session, entity, project_name) - self._start_timer(session, entity, ftrack_api) - except Exception: - self.log.warning( - "Couldn't finish Ftrack procedure.", exc_info=True - ) - return - - finally: - session.close() - - def _find_ftrack_task_entity( - self, session, project_name, asset_name, task_name - ): - project_entity = session.query( - "Project where full_name is \"{}\"".format(project_name) - ).first() - if not project_entity: - self.log.warning( - "Couldn't find project \"{}\" in Ftrack.".format(project_name) - ) - return - - potential_task_entities = session.query(( - "TypedContext where parent.name is \"{}\" and project_id is \"{}\"" - ).format(asset_name, project_entity["id"])).all() - filtered_entities = [] - for _entity in potential_task_entities: - if ( - _entity.entity_type.lower() == "task" - and _entity["name"] == task_name - ): - filtered_entities.append(_entity) - - if not filtered_entities: - self.log.warning(( - "Couldn't find task \"{}\" under parent \"{}\" in Ftrack." - ).format(task_name, asset_name)) - return - - if len(filtered_entities) > 1: - self.log.warning(( - "Found more than one task \"{}\"" - " under parent \"{}\" in Ftrack." - ).format(task_name, asset_name)) - return - - return filtered_entities[0] - - def _ftrack_status_change(self, session, entity, project_name): - presets = config.get_presets(project_name)["ftrack"]["ftrack_config"] - statuses = presets.get("status_update") - if not statuses: - return - - actual_status = entity["status"]["name"].lower() - already_tested = set() - ent_path = "/".join( - [ent["name"] for ent in entity["link"]] - ) - while True: - next_status_name = None - for key, value in statuses.items(): - if key in already_tested: - continue - if actual_status in value or "_any_" in value: - if key != "_ignore_": - next_status_name = key - already_tested.add(key) - break - already_tested.add(key) - - if next_status_name is None: - break - - try: - query = "Status where name is \"{}\"".format( - next_status_name - ) - status = session.query(query).one() - - entity["status"] = status - session.commit() - self.log.debug("Changing status to \"{}\" <{}>".format( - next_status_name, ent_path - )) - break - - except Exception: - session.rollback() - msg = ( - "Status \"{}\" in presets wasn't found" - " on Ftrack entity type \"{}\"" - ).format(next_status_name, entity.entity_type) - self.log.warning(msg) - - def _start_timer(self, session, entity, _ftrack_api): - self.log.debug("Triggering timer start.") - - user_entity = session.query("User where username is \"{}\"".format( - os.environ["FTRACK_API_USER"] - )).first() - if not user_entity: - self.log.warning( - "Couldn't find user with username \"{}\" in Ftrack".format( - os.environ["FTRACK_API_USER"] - ) - ) - return - - source = { - "user": { - "id": user_entity["id"], - "username": user_entity["username"] - } - } - event_data = { - "actionIdentifier": "start.timer", - "selection": [{"entityId": entity["id"], "entityType": "task"}] - } - session.event_hub.publish( - _ftrack_api.event.base.Event( - topic="ftrack.action.launch", - data=event_data, - source=source - ), - on_error="ignore" - ) - self.log.debug("Timer start triggered successfully.") - - # Special naming case for subprocess since its a built-in method. def _subprocess(*args, **kwargs): """Convenience method for getting output errors for subprocess. diff --git a/pype/modules/ftrack/actions/action_application_loader.py b/pype/modules/ftrack/actions/action_application_loader.py deleted file mode 100644 index 8749f89555..0000000000 --- a/pype/modules/ftrack/actions/action_application_loader.py +++ /dev/null @@ -1,104 +0,0 @@ -import os -import toml -import time -from pype.modules.ftrack.lib import AppAction -from avalon import lib -from pype.api import Logger, config - -log = Logger().get_logger(__name__) - - -def registerApp(app, session, plugins_presets): - name = app['name'] - variant = "" - try: - variant = app['name'].split("_")[1] - except Exception: - pass - - abspath = lib.which_app(app['name']) - if abspath is None: - log.error( - "'{0}' - App don't have config toml file".format(app['name']) - ) - return - - apptoml = toml.load(abspath) - - ''' REQUIRED ''' - executable = apptoml['executable'] - - ''' OPTIONAL ''' - label = apptoml.get('ftrack_label', app.get('label', name)) - icon = apptoml.get('ftrack_icon', None) - description = apptoml.get('description', None) - preactions = apptoml.get('preactions', []) - - if icon: - icon = icon.format(os.environ.get('PYPE_STATICS_SERVER', '')) - - # register action - AppAction( - session, label, name, executable, variant, - icon, description, preactions, plugins_presets - ).register() - - if not variant: - log.info('- Variant is not set') - - -def register(session, plugins_presets={}): - from pype.lib import env_value_to_bool - if env_value_to_bool("PYPE_USE_APP_MANAGER", default=False): - return - - app_usages = ( - config.get_presets() - .get("global", {}) - .get("applications") - ) or {} - - apps = [] - missing_app_names = [] - launchers_path = os.path.join(os.environ["PYPE_CONFIG"], "launchers") - for file in os.listdir(launchers_path): - filename, ext = os.path.splitext(file) - if ext.lower() != ".toml": - continue - - app_usage = app_usages.get(filename) - if not app_usage: - if app_usage is None: - missing_app_names.append(filename) - continue - - loaded_data = toml.load(os.path.join(launchers_path, file)) - app_data = { - "name": filename, - "label": loaded_data.get("label", filename) - } - apps.append(app_data) - - if missing_app_names: - log.debug( - "Apps not defined in applications usage. ({})".format( - ", ".join(( - "\"{}\"".format(app_name) - for app_name in missing_app_names - )) - ) - ) - - apps = sorted(apps, key=lambda app: app["name"]) - app_counter = 0 - for app in apps: - try: - registerApp(app, session, plugins_presets) - if app_counter % 5 == 0: - time.sleep(0.1) - app_counter += 1 - except Exception as exc: - log.warning( - "\"{}\" - not a proper App ({})".format(app['name'], str(exc)), - exc_info=True - ) diff --git a/pype/modules/ftrack/actions/action_applications.py b/pype/modules/ftrack/actions/action_applications.py index d488bd20a2..cf047a658d 100644 --- a/pype/modules/ftrack/actions/action_applications.py +++ b/pype/modules/ftrack/actions/action_applications.py @@ -211,7 +211,5 @@ class AppplicationsAction(BaseAction): def register(session, plugins_presets=None): - '''Register action. Called when used as an event plugin.''' - from pype.lib import env_value_to_bool - if env_value_to_bool("PYPE_USE_APP_MANAGER", default=False): - AppplicationsAction(session, plugins_presets).register() + """Register action. Called when used as an event plugin.""" + AppplicationsAction(session, plugins_presets).register() diff --git a/pype/modules/ftrack/actions/action_create_cust_attrs.py b/pype/modules/ftrack/actions/action_create_cust_attrs.py index 11931a5b30..d2d60df43e 100644 --- a/pype/modules/ftrack/actions/action_create_cust_attrs.py +++ b/pype/modules/ftrack/actions/action_create_cust_attrs.py @@ -146,9 +146,6 @@ class CustomAttributes(BaseAction): "text", "boolean", "date", "enumerator", "dynamic enumerator", "number" ) - # Pype 3 features - use_app_manager = env_value_to_bool("PYPE_USE_APP_MANAGER", default=False) - app_manager = None def discover(self, session, entities, event): ''' @@ -171,8 +168,7 @@ class CustomAttributes(BaseAction): }) session.commit() - if self.use_app_manager: - self.app_manager = ApplicationManager() + self.app_manager = ApplicationManager() try: self.prepare_global_data(session) @@ -391,54 +387,8 @@ class CustomAttributes(BaseAction): app_definitions.append({"empty": "< Empty >"}) return app_definitions - def application_definitions(self): - app_usages = self.presets.get("global", {}).get("applications") or {} - - app_definitions = [] - launchers_path = os.path.join(os.environ["PYPE_CONFIG"], "launchers") - - missing_app_names = [] - for file in os.listdir(launchers_path): - app_name, ext = os.path.splitext(file) - if ext.lower() != ".toml": - continue - - if not app_usages.get(app_name): - missing_app_names.append(app_name) - continue - - loaded_data = toml.load(os.path.join(launchers_path, file)) - - ftrack_label = loaded_data.get("ftrack_label") - if ftrack_label: - parts = app_name.split("_") - if len(parts) > 1: - ftrack_label = " ".join((ftrack_label, parts[-1])) - else: - ftrack_label = loaded_data.get("label", app_name) - - app_definitions.append({app_name: ftrack_label}) - - if missing_app_names: - self.log.warning( - "Apps not defined in applications usage. ({})".format( - ", ".join(( - "\"{}\"".format(app_name) - for app_name in missing_app_names - )) - ) - ) - - # Make sure there is at least one item - if not app_definitions: - app_definitions.append({"empty": "< Empty >"}) - return app_definitions - def applications_attribute(self, event): - if self.use_app_manager: - apps_data = self.app_defs_from_app_manager() - else: - apps_data = self.application_definitions() + apps_data = self.app_defs_from_app_manager() applications_custom_attr_data = { "label": "Applications", @@ -453,28 +403,13 @@ class CustomAttributes(BaseAction): } self.process_attr_data(applications_custom_attr_data, event) - def tools_from_app_manager(self): + def tools_attribute(self, event): tools_data = [] for tool_name, tool in self.app_manager.tools.items(): if tool.enabled: tools_data.append({ tool_name: tool_name }) - return tools_data - - def tools_data(self): - tool_usages = self.presets.get("global", {}).get("tools") or {} - tools_data = [] - for tool_name, usage in tool_usages.items(): - if usage: - tools_data.append({tool_name: tool_name}) - return tools_data - - def tools_attribute(self, event): - if self.use_app_manager: - tools_data = self.tools_from_app_manager() - else: - tools_data = self.tools_data() # Make sure there is at least one item if not tools_data: diff --git a/pype/modules/ftrack/lib/avalon_sync.py b/pype/modules/ftrack/lib/avalon_sync.py index 97116317af..c2bc6d2b29 100644 --- a/pype/modules/ftrack/lib/avalon_sync.py +++ b/pype/modules/ftrack/lib/avalon_sync.py @@ -191,43 +191,17 @@ def get_project_apps(in_app_list): apps = [] warnings = collections.defaultdict(list) - if env_value_to_bool("PYPE_USE_APP_MANAGER", default=False): - missing_app_msg = "Missing definition of application" - application_manager = ApplicationManager() - for app_name in in_app_list: - app = application_manager.applications.get(app_name) - if app: - apps.append({ - "name": app_name, - "label": app.full_label - }) - else: - warnings[missing_app_msg].append(app_name) - return apps, warnings - - # TODO report - missing_toml_msg = "Missing config file for application" - error_msg = ( - "Unexpected error happend during preparation of application" - ) - - for app in in_app_list: - try: - toml_path = avalon.lib.which_app(app) - if not toml_path: - log.warning(missing_toml_msg + ' "{}"'.format(app)) - warnings[missing_toml_msg].append(app) - continue - + missing_app_msg = "Missing definition of application" + application_manager = ApplicationManager() + for app_name in in_app_list: + app = application_manager.applications.get(app_name) + if app: apps.append({ - "name": app, - "label": toml.load(toml_path)["label"] + "name": app_name, + "label": app.full_label }) - except Exception: - warnings[error_msg].append(app) - log.warning(( - "Error has happened during preparing application \"{}\"" - ).format(app), exc_info=True) + else: + warnings[missing_app_msg].append(app_name) return apps, warnings diff --git a/pype/modules/ftrack/lib/ftrack_app_handler.py b/pype/modules/ftrack/lib/ftrack_app_handler.py deleted file mode 100644 index 23776aced7..0000000000 --- a/pype/modules/ftrack/lib/ftrack_app_handler.py +++ /dev/null @@ -1,223 +0,0 @@ -from pype import lib as pypelib -from pype.api import config -from .ftrack_action_handler import BaseAction - - -class AppAction(BaseAction): - """Application Action class. - - Args: - session (ftrack_api.Session): Session where action will be registered. - label (str): A descriptive string identifing your action. - varaint (str, optional): To group actions together, give them the same - label and specify a unique variant per action. - identifier (str): An unique identifier for app. - description (str): A verbose descriptive text for you action. - icon (str): Url path to icon which will be shown in Ftrack web. - """ - - type = "Application" - preactions = ["start.timer"] - - def __init__( - self, session, label, name, executable, variant=None, - icon=None, description=None, preactions=[], plugins_presets={} - ): - self.label = label - self.identifier = name - self.executable = executable - self.variant = variant - self.icon = icon - self.description = description - self.preactions.extend(preactions) - - super().__init__(session, plugins_presets) - if label is None: - raise ValueError("Action missing label.") - if name is None: - raise ValueError("Action missing identifier.") - if executable is None: - raise ValueError("Action missing executable.") - - def register(self): - """Registers the action, subscribing the discover and launch topics.""" - - discovery_subscription = ( - "topic=ftrack.action.discover and source.user.username={0}" - ).format(self.session.api_user) - - self.session.event_hub.subscribe( - discovery_subscription, - self._discover, - priority=self.priority - ) - - launch_subscription = ( - "topic=ftrack.action.launch" - " and data.actionIdentifier={0}" - " and source.user.username={1}" - ).format( - self.identifier, - self.session.api_user - ) - self.session.event_hub.subscribe( - launch_subscription, - self._launch - ) - - def discover(self, session, entities, event): - """Return true if we can handle the selected entities. - - Args: - session (ftrack_api.Session): Helps to query necessary data. - entities (list): Object of selected entities. - event (ftrack_api.Event): Ftrack event causing discover callback. - """ - - if ( - len(entities) != 1 - or entities[0].entity_type.lower() != "task" - ): - return False - - entity = entities[0] - if entity["parent"].entity_type.lower() == "project": - return False - - avalon_project_apps = event["data"].get("avalon_project_apps", None) - avalon_project_doc = event["data"].get("avalon_project_doc", None) - if avalon_project_apps is None: - if avalon_project_doc is None: - ft_project = self.get_project_from_entity(entity) - database = pypelib.get_avalon_database() - project_name = ft_project["full_name"] - avalon_project_doc = database[project_name].find_one({ - "type": "project" - }) or False - event["data"]["avalon_project_doc"] = avalon_project_doc - - if not avalon_project_doc: - return False - - project_apps_config = avalon_project_doc["config"].get("apps", []) - avalon_project_apps = [ - app["name"] for app in project_apps_config - ] or False - event["data"]["avalon_project_apps"] = avalon_project_apps - - if not avalon_project_apps: - return False - - return self.identifier in avalon_project_apps - - def _launch(self, event): - entities = self._translate_event(event) - - preactions_launched = self._handle_preactions( - self.session, event - ) - if preactions_launched is False: - return - - response = self.launch(self.session, entities, event) - - return self._handle_result(response) - - def launch(self, session, entities, event): - """Callback method for the custom action. - - return either a bool (True if successful or False if the action failed) - or a dictionary with they keys `message` and `success`, the message - should be a string and will be displayed as feedback to the user, - success should be a bool, True if successful or False if the action - failed. - - *session* is a `ftrack_api.Session` instance - - *entities* is a list of tuples each containing the entity type and - the entity id. If the entity is a hierarchical you will always get - the entity type TypedContext, once retrieved through a get operation - you will have the "real" entity type ie. example Shot, Sequence - or Asset Build. - - *event* the unmodified original event - """ - - entity = entities[0] - - task_name = entity["name"] - asset_name = entity["parent"]["name"] - project_name = entity["project"]["full_name"] - try: - pypelib.launch_application( - project_name, asset_name, task_name, self.identifier - ) - - except pypelib.ApplicationLaunchFailed as exc: - self.log.error(str(exc)) - return { - "success": False, - "message": str(exc) - } - - except Exception: - msg = "Unexpected failure of application launch {}".format( - self.label - ) - self.log.error(msg, exc_info=True) - return { - "success": False, - "message": msg - } - - # Change status of task to In progress - presets = config.get_presets()["ftrack"]["ftrack_config"] - - if "status_update" in presets: - statuses = presets["status_update"] - - actual_status = entity["status"]["name"].lower() - already_tested = [] - ent_path = "/".join( - [ent["name"] for ent in entity["link"]] - ) - while True: - next_status_name = None - for key, value in statuses.items(): - if key in already_tested: - continue - if actual_status in value or "_any_" in value: - if key != "_ignore_": - next_status_name = key - already_tested.append(key) - break - already_tested.append(key) - - if next_status_name is None: - break - - try: - query = "Status where name is \"{}\"".format( - next_status_name - ) - status = session.query(query).one() - - entity["status"] = status - session.commit() - self.log.debug("Changing status to \"{}\" <{}>".format( - next_status_name, ent_path - )) - break - - except Exception: - session.rollback() - msg = ( - "Status \"{}\" in presets wasn't found" - " on Ftrack entity type \"{}\"" - ).format(next_status_name, entity.entity_type) - self.log.warning(msg) - - return { - "success": True, - "message": "Launching {0}".format(self.label) - } diff --git a/pype/tools/launcher/lib.py b/pype/tools/launcher/lib.py index f70929fc2e..7d2a49db9d 100644 --- a/pype/tools/launcher/lib.py +++ b/pype/tools/launcher/lib.py @@ -16,60 +16,13 @@ provides a bridge between the file-based project inventory and configuration. import os from Qt import QtGui -from avalon import lib from avalon.vendor import qtawesome from pype.api import resources -from pype.lib import ApplicationAction ICON_CACHE = {} NOT_FOUND = type("NotFound", (object, ), {}) -def get_application_actions(project): - """Define dynamic Application classes for project using `.toml` files - - Args: - project (dict): project document from the database - - Returns: - list: list of dictionaries - """ - - apps = [] - for app in project["config"]["apps"]: - try: - app_name = app["name"] - app_definition = lib.get_application(app_name) - except Exception as exc: - print("Unable to load application: %s - %s" % (app['name'], exc)) - continue - - # Get from app definition, if not there from app in project - icon = app_definition.get("icon", app.get("icon", "folder-o")) - color = app_definition.get("color", app.get("color", None)) - order = app_definition.get("order", app.get("order", 0)) - label = app_definition.get("label") or app.get("label") or app_name - label_variant = app_definition.get("label_variant") - group = app_definition.get("group") or app.get("group") - action = type( - "app_{}".format(app_name), - (ApplicationAction,), - { - "name": app_name, - "label": label, - "label_variant": label_variant, - "group": group, - "icon": icon, - "color": color, - "order": order, - "config": app_definition.copy() - } - ) - - apps.append(action) - return apps - - def get_action_icon(action): icon_name = action.icon if not icon_name: diff --git a/pype/tools/launcher/models.py b/pype/tools/launcher/models.py index 07db36fa9a..81d6a455d5 100644 --- a/pype/tools/launcher/models.py +++ b/pype/tools/launcher/models.py @@ -117,11 +117,7 @@ class ActionModel(QtGui.QStandardItemModel): super(ActionModel, self).__init__(parent=parent) self.dbcon = dbcon - self.use_manager = env_value_to_bool( - "PYPE_USE_APP_MANAGER", default=False - ) - if self.use_manager: - self.application_manager = ApplicationManager() + self.application_manager = ApplicationManager() self._session = {} self._groups = {} @@ -141,11 +137,7 @@ class ActionModel(QtGui.QStandardItemModel): actions = api.discover(api.Action) # Get available project actions and the application actions - if self.use_manager: - app_actions = self.get_application_actions() - else: - project_doc = self.dbcon.find_one({"type": "project"}) - app_actions = lib.get_application_actions(project_doc) + app_actions = self.get_application_actions() actions.extend(app_actions) self._registered_actions = actions From d24ac5597aa5353402b6d7408c0a153131564243 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Thu, 3 Dec 2020 12:59:18 +0100 Subject: [PATCH 15/54] removed deprecated from lib --- pype/lib/__init__.py | 5 ----- pype/lib/deprecated.py | 26 ---------------------- pype/tests/test_lib_restructuralization.py | 2 -- 3 files changed, 33 deletions(-) delete mode 100644 pype/lib/deprecated.py diff --git a/pype/lib/__init__.py b/pype/lib/__init__.py index ecdd155c99..5fec2b8069 100644 --- a/pype/lib/__init__.py +++ b/pype/lib/__init__.py @@ -1,11 +1,6 @@ # -*- coding: utf-8 -*- """Pype lib module.""" -from .deprecated import ( - get_avalon_database, - set_io_database -) - from .env_tools import ( env_value_to_bool, get_paths_from_environ diff --git a/pype/lib/deprecated.py b/pype/lib/deprecated.py deleted file mode 100644 index e7296f67ef..0000000000 --- a/pype/lib/deprecated.py +++ /dev/null @@ -1,26 +0,0 @@ -import os - -from avalon import io - - -def get_avalon_database(): - """Mongo database used in avalon's io. - - * Function is not used in pype 3.0 where was replaced with usage of - AvalonMongoDB. - """ - if io._database is None: - set_io_database() - return io._database - - -def set_io_database(): - """Set avalon's io context with environemnts. - - * Function is not used in pype 3.0 where was replaced with usage of - AvalonMongoDB. - """ - required_keys = ["AVALON_PROJECT", "AVALON_ASSET", "AVALON_SILO"] - for key in required_keys: - os.environ[key] = os.environ.get(key, "") - io.install() diff --git a/pype/tests/test_lib_restructuralization.py b/pype/tests/test_lib_restructuralization.py index 152be8d1eb..48370f5438 100644 --- a/pype/tests/test_lib_restructuralization.py +++ b/pype/tests/test_lib_restructuralization.py @@ -13,8 +13,6 @@ def test_backward_compatibility(printer): from pype.lib import ApplicationLaunchFailed from pype.lib import launch_application from pype.lib import ApplicationAction - from pype.lib import get_avalon_database - from pype.lib import set_io_database from pype.lib import get_ffmpeg_tool_path from pype.lib import get_last_version_from_path From db1c5b4a8db44badbf0f1ec43aefe8ec577d2a27 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Thu, 3 Dec 2020 13:03:45 +0100 Subject: [PATCH 16/54] removed unused imports --- pype/modules/ftrack/actions/action_create_cust_attrs.py | 2 +- pype/modules/ftrack/lib/avalon_sync.py | 5 +---- pype/tools/launcher/models.py | 2 +- 3 files changed, 3 insertions(+), 6 deletions(-) diff --git a/pype/modules/ftrack/actions/action_create_cust_attrs.py b/pype/modules/ftrack/actions/action_create_cust_attrs.py index d2d60df43e..f76d794d6f 100644 --- a/pype/modules/ftrack/actions/action_create_cust_attrs.py +++ b/pype/modules/ftrack/actions/action_create_cust_attrs.py @@ -9,7 +9,7 @@ from pype.modules.ftrack.lib.avalon_sync import ( CUST_ATTR_ID_KEY, CUST_ATTR_GROUP, default_custom_attributes_definition ) from pype.api import config -from pype.lib import ApplicationManager, env_value_to_bool +from pype.lib import ApplicationManager """ This action creates/updates custom attributes. diff --git a/pype/modules/ftrack/lib/avalon_sync.py b/pype/modules/ftrack/lib/avalon_sync.py index c2bc6d2b29..671899a028 100644 --- a/pype/modules/ftrack/lib/avalon_sync.py +++ b/pype/modules/ftrack/lib/avalon_sync.py @@ -17,10 +17,7 @@ from bson.errors import InvalidId from pymongo import UpdateOne import ftrack_api from pype.api import config -from pype.lib import ( - ApplicationManager, - env_value_to_bool -) +from pype.lib import ApplicationManager log = Logger().get_logger(__name__) diff --git a/pype/tools/launcher/models.py b/pype/tools/launcher/models.py index 81d6a455d5..3e869f3e4a 100644 --- a/pype/tools/launcher/models.py +++ b/pype/tools/launcher/models.py @@ -7,7 +7,7 @@ from .actions import ApplicationAction from Qt import QtCore, QtGui from avalon.vendor import qtawesome from avalon import style, api -from pype.lib import ApplicationManager, env_value_to_bool +from pype.lib import ApplicationManager log = logging.getLogger(__name__) From ce8c200de1e806af4c8458f09c78559800b9e954 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Thu, 3 Dec 2020 13:11:19 +0100 Subject: [PATCH 17/54] fixed imports --- pype/lib/__init__.py | 7 ------- pype/lib/applications.py | 2 +- pype/tests/test_lib_restructuralization.py | 2 -- 3 files changed, 1 insertion(+), 10 deletions(-) diff --git a/pype/lib/__init__.py b/pype/lib/__init__.py index 5fec2b8069..d02d20ad4d 100644 --- a/pype/lib/__init__.py +++ b/pype/lib/__init__.py @@ -31,8 +31,6 @@ from .applications import ( ApplicationManager, PreLaunchHook, PostLaunchHook, - launch_application, - ApplicationAction, _subprocess ) @@ -50,9 +48,6 @@ from .ffmpeg_utils import ( ) __all__ = [ - "get_avalon_database", - "set_io_database", - "env_value_to_bool", "get_paths_from_environ", @@ -77,8 +72,6 @@ __all__ = [ "ApplicationManager", "PreLaunchHook", "PostLaunchHook", - "launch_application", - "ApplicationAction", "filter_pyblish_plugins", diff --git a/pype/lib/applications.py b/pype/lib/applications.py index 0f2ea42175..ea95fefea1 100644 --- a/pype/lib/applications.py +++ b/pype/lib/applications.py @@ -9,7 +9,7 @@ from abc import ABCMeta, abstractmethod import six -from pype.settings import system_settings, environemtns +from pype.settings import system_settings, environments from ..api import Logger from .python_module_tools import ( diff --git a/pype/tests/test_lib_restructuralization.py b/pype/tests/test_lib_restructuralization.py index 48370f5438..957167a8bf 100644 --- a/pype/tests/test_lib_restructuralization.py +++ b/pype/tests/test_lib_restructuralization.py @@ -11,8 +11,6 @@ def test_backward_compatibility(printer): from pype.lib import get_latest_version from pype.lib import ApplicationLaunchFailed - from pype.lib import launch_application - from pype.lib import ApplicationAction from pype.lib import get_ffmpeg_tool_path from pype.lib import get_last_version_from_path From 59ee5827517d57ba173043d22897c3f178a6ad6e Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Thu, 3 Dec 2020 13:18:49 +0100 Subject: [PATCH 18/54] removed unused logger --- pype/lib/applications.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/pype/lib/applications.py b/pype/lib/applications.py index ea95fefea1..abc6ca5017 100644 --- a/pype/lib/applications.py +++ b/pype/lib/applications.py @@ -2,7 +2,6 @@ import os import copy import platform import inspect -import logging import subprocess import distutils.spawn from abc import ABCMeta, abstractmethod @@ -17,8 +16,6 @@ from .python_module_tools import ( classes_from_module ) -log = logging.getLogger(__name__) - class ApplicationNotFound(Exception): """Application was not found in ApplicationManager by name.""" From f890fb74c5a386c5695e1e1d915774c78f8c1e53 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Thu, 3 Dec 2020 13:32:52 +0100 Subject: [PATCH 19/54] removed unsused imports and modified docstring --- pype/modules/ftrack/lib/avalon_sync.py | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/pype/modules/ftrack/lib/avalon_sync.py b/pype/modules/ftrack/lib/avalon_sync.py index 671899a028..a379aa9900 100644 --- a/pype/modules/ftrack/lib/avalon_sync.py +++ b/pype/modules/ftrack/lib/avalon_sync.py @@ -8,8 +8,6 @@ import copy from avalon.api import AvalonMongoDB import avalon -import avalon.api -from avalon.vendor import toml from pype.api import Logger, Anatomy from bson.objectid import ObjectId @@ -175,15 +173,14 @@ def get_avalon_project_template(project_name): def get_project_apps(in_app_list): - """ - Returns metadata information about apps in 'in_app_list' enhanced - from toml files. + """ Application definitions for app name. + Args: in_app_list: (list) - names of applications Returns: - tuple (list, dictionary) - list of dictionaries about apps - dictionary of warnings + tuple (list, dictionary) - list of dictionaries with apps definitions + dictionary of warnings """ apps = [] warnings = collections.defaultdict(list) From 9575a721843e7198a4acdc2cccefa58248efeebc Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Thu, 3 Dec 2020 13:41:12 +0100 Subject: [PATCH 20/54] remov ftrack json to lower filename --- .../defaults/project_settings/Ftrack.json | 98 ------------------- 1 file changed, 98 deletions(-) delete mode 100644 pype/settings/defaults/project_settings/Ftrack.json diff --git a/pype/settings/defaults/project_settings/Ftrack.json b/pype/settings/defaults/project_settings/Ftrack.json deleted file mode 100644 index 023b85cb3b..0000000000 --- a/pype/settings/defaults/project_settings/Ftrack.json +++ /dev/null @@ -1,98 +0,0 @@ -{ - "ftrack_actions_path": [], - "ftrack_events_path": [], - "events": { - "sync_to_avalon": { - "enabled": true, - "statuses_name_change": [ - "ready", - "not ready" - ] - }, - "push_frame_values_to_task": { - "enabled": true, - "interest_entity_types": [ - "shot", - "asset build" - ], - "interest_attributess": [ - "frameStart", - "frameEnd" - ] - }, - "thumbnail_updates": { - "enabled": true, - "levels": 2 - }, - "user_assignment": { - "enabled": true - }, - "status_update": { - "enabled": true, - "mapping": { - "In Progress": [ - "__any__" - ], - "Ready": [ - "Not Ready" - ], - "__ignore__": [ - "in prgoress", - "omitted", - "on hold" - ] - } - }, - "status_task_to_parent": { - "enabled": true, - "parent_status_match_all_task_statuses": { - "Completed": [ - "Approved", - "Omitted" - ] - }, - "parent_status_by_task_status": { - "In Progress": [ - "in progress", - "change requested", - "retake", - "pending review" - ] - } - }, - "status_task_to_version": { - "enabled": true, - "mapping": { - "Approved": [ - "Complete" - ] - } - }, - "status_version_to_task": { - "enabled": true, - "mapping": { - "Complete": [ - "Approved", - "Complete" - ] - } - }, - "first_version_status": { - "enabled": true, - "status": "" - }, - "next_task_update": { - "enabled": true, - "mapping": { - "Ready": "Not Ready" - } - } - }, - "publish": { - "IntegrateFtrackNote": { - "enabled": true, - "note_with_intent_template": "", - "note_labels": [] - } - } -} \ No newline at end of file From b97fbc2285ce1cf52e295f22e32d1d08557a633e Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Thu, 3 Dec 2020 13:43:34 +0100 Subject: [PATCH 21/54] moved back ftrack json file with lowered name and lowered key in schema --- .../defaults/project_settings/ftrack.json | 98 +++++++++++++++++++ .../schema_project_ftrack.json | 2 +- 2 files changed, 99 insertions(+), 1 deletion(-) create mode 100644 pype/settings/defaults/project_settings/ftrack.json diff --git a/pype/settings/defaults/project_settings/ftrack.json b/pype/settings/defaults/project_settings/ftrack.json new file mode 100644 index 0000000000..4eabb52dc1 --- /dev/null +++ b/pype/settings/defaults/project_settings/ftrack.json @@ -0,0 +1,98 @@ +{ + "ftrack_actions_path": [], + "ftrack_events_path": [], + "events": { + "sync_to_avalon": { + "enabled": true, + "statuses_name_change": [ + "ready", + "not ready" + ] + }, + "push_frame_values_to_task": { + "enabled": true, + "interest_entity_types": [ + "shot", + "asset build" + ], + "interest_attributess": [ + "frameStart", + "frameEnd" + ] + }, + "thumbnail_updates": { + "enabled": true, + "levels": 2 + }, + "user_assignment": { + "enabled": true + }, + "status_update": { + "enabled": true, + "mapping": { + "In Progress": [ + "__any__" + ], + "Ready": [ + "Not Ready" + ], + "__ignore__": [ + "in prgoress", + "omitted", + "on hold" + ] + } + }, + "status_task_to_parent": { + "enabled": true, + "parent_status_match_all_task_statuses": { + "Completed": [ + "Approved", + "Omitted" + ] + }, + "parent_status_by_task_status": { + "In Progress": [ + "in progress", + "change requested", + "retake", + "pending review" + ] + } + }, + "status_task_to_version": { + "enabled": true, + "mapping": { + "Approved": [ + "Complete" + ] + } + }, + "status_version_to_task": { + "enabled": true, + "mapping": { + "Complete": [ + "Approved", + "Complete" + ] + } + }, + "first_version_status": { + "enabled": true, + "status": "" + }, + "next_task_update": { + "enabled": true, + "mapping": { + "Ready": "Not Ready" + } + } + }, + "publish": { + "IntegrateFtrackNote": { + "enabled": true, + "note_with_intent_template": "", + "note_labels": [] + } + } +} diff --git a/pype/tools/settings/settings/gui_schemas/projects_schema/schema_project_ftrack.json b/pype/tools/settings/settings/gui_schemas/projects_schema/schema_project_ftrack.json index 3b784accc1..f54c1232a6 100644 --- a/pype/tools/settings/settings/gui_schemas/projects_schema/schema_project_ftrack.json +++ b/pype/tools/settings/settings/gui_schemas/projects_schema/schema_project_ftrack.json @@ -1,6 +1,6 @@ { "type": "dict", - "key": "Ftrack", + "key": "ftrack", "label": "Ftrack", "collapsable": true, "checkbox_key": "enabled", From 9515bcae3eb1b22f3fd19928119b0602a16ea6bb Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Thu, 3 Dec 2020 14:26:24 +0100 Subject: [PATCH 22/54] modified user assignment to use settings --- .../ftrack/events/event_user_assigment.py | 71 +++++++++++++------ 1 file changed, 49 insertions(+), 22 deletions(-) diff --git a/pype/modules/ftrack/events/event_user_assigment.py b/pype/modules/ftrack/events/event_user_assigment.py index 19a67b745f..bc05faa192 100644 --- a/pype/modules/ftrack/events/event_user_assigment.py +++ b/pype/modules/ftrack/events/event_user_assigment.py @@ -8,7 +8,7 @@ from avalon.api import AvalonMongoDB from bson.objectid import ObjectId -from pype.api import config, Anatomy +from pype.api import Anatomy, project_settings as get_project_settings class UserAssigmentEvent(BaseEvent): @@ -173,26 +173,50 @@ class UserAssigmentEvent(BaseEvent): return t_data def launch(self, session, event): - # load shell scripts presets - presets = config.get_presets()['ftrack'].get("user_assigment_event") - if not presets: + if not event.get("data"): return - for entity in event.get('data', {}).get('entities', []): - if entity.get('entity_type') != 'Appointment': + + entities_info = event["data"].get("entities") + if not entities_info: + return + + # load shell scripts presets + tmp_by_project_name = {} + for entity_info in entities_info: + if entity_info.get('entity_type') != 'Appointment': continue - task, user = self._get_task_and_user(session, - entity.get('action'), - entity.get('changes')) + task_entity, user_entity = self._get_task_and_user( + session, + entity_info.get('action'), + entity_info.get('changes') + ) - if not task or not user: - self.log.error( - 'Task or User was not found.') + if not task_entity or not user_entity: + self.log.error("Task or User was not found.") continue - data = self._get_template_data(task) # format directories to pass to shell script - anatomy = Anatomy(data["project"]["name"]) + project_name = task_entity["project"]["full_name"] + project_data = tmp_by_project_name.get(project_name) or {} + if "scripts_by_action" not in project_data: + project_settings = get_project_settings(project_name) + _settings = ( + project_settings["ftrack"]["events"]["user_assignment"] + ) + project_data["scripts_by_action"] = _settings.get("scripts") + tmp_by_project_name[project_name] = project_data + + scripts_by_action = project_data["scripts_by_action"] + if not scripts_by_action: + continue + + if "anatomy" not in project_data: + project_data["anatomy"] = Anatomy(project_name) + tmp_by_project_name[project_name] = project_data + + anatomy = project_data["anatomy"] + data = self._get_template_data(task_entity) anatomy_filled = anatomy.format(data) # formatting work dir is easiest part as we can use whole path work_dir = anatomy_filled["work"]["folder"] @@ -201,8 +225,10 @@ class UserAssigmentEvent(BaseEvent): publish = anatomy_filled["publish"]["folder"] # now find path to {asset} - m = re.search("(^.+?{})".format(data['asset']), - publish) + m = re.search( + "(^.+?{})".format(data["asset"]), + publish + ) if not m: msg = 'Cannot get part of publish path {}'.format(publish) @@ -213,12 +239,13 @@ class UserAssigmentEvent(BaseEvent): } publish_dir = m.group(1) - for script in presets.get(entity.get('action')): - self.log.info( - '[{}] : running script for user {}'.format( - entity.get('action'), user["username"])) - self._run_script(script, [user["username"], - work_dir, publish_dir]) + username = user_entity["username"] + event_entity_action = entity_info["action"] + for script in scripts_by_action.get(event_entity_action): + self.log.info(( + "[{}] : running script for user {}" + ).format(event_entity_action, username)) + self._run_script(script, [username, work_dir, publish_dir]) return True From e9892ce77ef68d4f8616cabb2124829ba149b6cb Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Thu, 3 Dec 2020 14:48:03 +0100 Subject: [PATCH 23/54] create project structure is using settings --- .../action_create_project_structure.py | 29 ++++++++++--------- .../ftrack/ftrack_server/ftrack_server.py | 4 ++- pype/modules/ftrack/lib/__init__.py | 4 +-- 3 files changed, 19 insertions(+), 18 deletions(-) diff --git a/pype/modules/ftrack/actions/action_create_project_structure.py b/pype/modules/ftrack/actions/action_create_project_structure.py index 22190c16db..d5cb381a63 100644 --- a/pype/modules/ftrack/actions/action_create_project_structure.py +++ b/pype/modules/ftrack/actions/action_create_project_structure.py @@ -2,7 +2,7 @@ import os import re from pype.modules.ftrack.lib import BaseAction, statics_icon -from pype.api import config, Anatomy +from pype.api import Anatomy, project_settings as get_project_settings class CreateProjectFolders(BaseAction): @@ -69,25 +69,26 @@ class CreateProjectFolders(BaseAction): return True def launch(self, session, entities, event): - entity = entities[0] - project = self.get_project_from_entity(entity) - project_folder_presets = ( - config.get_presets() - .get("tools", {}) - .get("project_folder_structure") + # Get project entity + project_entity = self.get_project_from_entity(entities[0]) + # Load settings for project + project_name = project_entity["full_name"] + project_settings = get_project_settings(project_name) + project_folder_structure = ( + project_settings["global"]["project_folder_structure"] ) - if not project_folder_presets: + if not project_folder_structure: return { "success": False, - "message": "Project structure presets are not set." + "message": "Project structure is not set." } try: # Get paths based on presets - basic_paths = self.get_path_items(project_folder_presets) - anatomy = Anatomy(project["full_name"]) - self.create_folders(basic_paths, entity, project, anatomy) - self.create_ftrack_entities(basic_paths, project) + basic_paths = self.get_path_items(project_folder_structure) + anatomy = Anatomy(project_entity["full_name"]) + self.create_folders(basic_paths, project_entity, anatomy) + self.create_ftrack_entities(basic_paths, project_entity) except Exception as exc: session.rollback() @@ -219,7 +220,7 @@ class CreateProjectFolders(BaseAction): output.append(os.path.normpath(os.path.sep.join(clean_items))) return output - def create_folders(self, basic_paths, entity, project, anatomy): + def create_folders(self, basic_paths, project, anatomy): roots_paths = [] if isinstance(anatomy.roots, dict): for root in anatomy.roots: diff --git a/pype/modules/ftrack/ftrack_server/ftrack_server.py b/pype/modules/ftrack/ftrack_server/ftrack_server.py index 92f3c0b3a0..9940ab236e 100644 --- a/pype/modules/ftrack/ftrack_server/ftrack_server.py +++ b/pype/modules/ftrack/ftrack_server/ftrack_server.py @@ -2,10 +2,12 @@ import os import sys import types import importlib -import ftrack_api import time import logging import inspect + +import ftrack_api + from pype.api import Logger, config diff --git a/pype/modules/ftrack/lib/__init__.py b/pype/modules/ftrack/lib/__init__.py index a52e73d10f..3890eacf90 100644 --- a/pype/modules/ftrack/lib/__init__.py +++ b/pype/modules/ftrack/lib/__init__.py @@ -3,7 +3,6 @@ from . import credentials from .ftrack_base_handler import BaseHandler from .ftrack_event_handler import BaseEvent from .ftrack_action_handler import BaseAction, ServerAction, statics_icon -from .ftrack_app_handler import AppAction __all__ = ( "avalon_sync", @@ -12,6 +11,5 @@ __all__ = ( "BaseEvent", "BaseAction", "ServerAction", - "statics_icon", - "AppAction" + "statics_icon" ) From 72d3cc6e8b23ae3b9bf467e072aad4b933bd17c8 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Thu, 3 Dec 2020 15:21:28 +0100 Subject: [PATCH 24/54] event handler VersionToTaskStatus is using settings --- .../events/event_version_to_task_statuses.py | 32 ++++++++----------- 1 file changed, 14 insertions(+), 18 deletions(-) diff --git a/pype/modules/ftrack/events/event_version_to_task_statuses.py b/pype/modules/ftrack/events/event_version_to_task_statuses.py index fdb48cbc37..6c4ebf2d10 100644 --- a/pype/modules/ftrack/events/event_version_to_task_statuses.py +++ b/pype/modules/ftrack/events/event_version_to_task_statuses.py @@ -1,12 +1,8 @@ from pype.modules.ftrack import BaseEvent -from pype.api import config +from pype.api import project_settings as get_project_settings class VersionToTaskStatus(BaseEvent): - - # Presets usage - default_status_mapping = {} - def launch(self, session, event): '''Propagates status from version to task when changed''' @@ -48,14 +44,20 @@ class VersionToTaskStatus(BaseEvent): version_status_orig = version_status["name"] + # Get entities necessary for processing + version = session.get("AssetVersion", entity["entityId"]) + task = version.get("task") + if not task: + continue + + project_entity = self.get_project_from_entity(task) + project_name = project_entity["full_name"] + project_settings = get_project_settings(project_name) + # Load status mapping from presets status_mapping = ( - config.get_presets() - .get("ftrack", {}) - .get("ftrack_config", {}) - .get("status_version_to_task") - ) or self.default_status_mapping - + project_settings["ftrack"]["event"]["status_version_to_task"] + ) # Skip if mapping is empty if not status_mapping: continue @@ -78,16 +80,10 @@ class VersionToTaskStatus(BaseEvent): # Lower all names from presets new_status_names = [name.lower() for name in new_status_names] - # Get entities necessary for processing - version = session.get("AssetVersion", entity["entityId"]) - task = version.get("task") - if not task: - continue - if version["asset"]["type"]["short"].lower() == "scene": continue - project_schema = task["project"]["project_schema"] + project_schema = project_entity["project_schema"] # Get all available statuses for Task statuses = project_schema.get_statuses("Task", task["type_id"]) # map lowered status name with it's object From 92d751d94dfc6f4dfd7115fb2e358df380eecfa0 Mon Sep 17 00:00:00 2001 From: Milan Kolar Date: Thu, 3 Dec 2020 16:04:52 +0100 Subject: [PATCH 25/54] replace project_settings with get_project_settings --- .ropeproject/config.py | 114 ++++++++++++++++++ pype/__init__.py | 4 +- pype/lib/avalon_context.py | 4 +- pype/lib/plugin_tools.py | 4 +- .../action_create_project_structure.py | 6 +- .../ftrack/events/event_user_assigment.py | 6 +- .../events/event_version_to_task_statuses.py | 6 +- pype/plugin.py | 4 +- .../plugins/maya/create/create_rendersetup.py | 4 +- pype/plugins/maya/load/load_ass.py | 6 +- pype/plugins/maya/load/load_gpucache.py | 4 +- pype/plugins/maya/load/load_reference.py | 4 +- .../plugins/maya/load/load_vdb_to_redshift.py | 4 +- pype/plugins/maya/load/load_vdb_to_vray.py | 4 +- pype/plugins/maya/load/load_vrayproxy.py | 4 +- pype/plugins/maya/load/load_yeti_cache.py | 4 +- pype/plugins/maya/load/load_yeti_rig.py | 4 +- pype/plugins/nuke/load/load_mov.py | 4 +- pype/tools/pyblish_pype/control.py | 4 +- .../widgets/widget_family.py | 4 +- setup/maya/userSetup.py | 4 +- 21 files changed, 158 insertions(+), 44 deletions(-) create mode 100644 .ropeproject/config.py diff --git a/.ropeproject/config.py b/.ropeproject/config.py new file mode 100644 index 0000000000..dee2d1ae9a --- /dev/null +++ b/.ropeproject/config.py @@ -0,0 +1,114 @@ +# The default ``config.py`` +# flake8: noqa + + +def set_prefs(prefs): + """This function is called before opening the project""" + + # Specify which files and folders to ignore in the project. + # Changes to ignored resources are not added to the history and + # VCSs. Also they are not returned in `Project.get_files()`. + # Note that ``?`` and ``*`` match all characters but slashes. + # '*.pyc': matches 'test.pyc' and 'pkg/test.pyc' + # 'mod*.pyc': matches 'test/mod1.pyc' but not 'mod/1.pyc' + # '.svn': matches 'pkg/.svn' and all of its children + # 'build/*.o': matches 'build/lib.o' but not 'build/sub/lib.o' + # 'build//*.o': matches 'build/lib.o' and 'build/sub/lib.o' + prefs['ignored_resources'] = ['*.pyc', '*~', '.ropeproject', + '.hg', '.svn', '_svn', '.git', '.tox'] + + # Specifies which files should be considered python files. It is + # useful when you have scripts inside your project. Only files + # ending with ``.py`` are considered to be python files by + # default. + # prefs['python_files'] = ['*.py'] + + # Custom source folders: By default rope searches the project + # for finding source folders (folders that should be searched + # for finding modules). You can add paths to that list. Note + # that rope guesses project source folders correctly most of the + # time; use this if you have any problems. + # The folders should be relative to project root and use '/' for + # separating folders regardless of the platform rope is running on. + # 'src/my_source_folder' for instance. + # prefs.add('source_folders', 'src') + + # You can extend python path for looking up modules + # prefs.add('python_path', '~/python/') + + # Should rope save object information or not. + prefs['save_objectdb'] = True + prefs['compress_objectdb'] = False + + # If `True`, rope analyzes each module when it is being saved. + prefs['automatic_soa'] = True + # The depth of calls to follow in static object analysis + prefs['soa_followed_calls'] = 0 + + # If `False` when running modules or unit tests "dynamic object + # analysis" is turned off. This makes them much faster. + prefs['perform_doa'] = True + + # Rope can check the validity of its object DB when running. + prefs['validate_objectdb'] = True + + # How many undos to hold? + prefs['max_history_items'] = 32 + + # Shows whether to save history across sessions. + prefs['save_history'] = True + prefs['compress_history'] = False + + # Set the number spaces used for indenting. According to + # :PEP:`8`, it is best to use 4 spaces. Since most of rope's + # unit-tests use 4 spaces it is more reliable, too. + prefs['indent_size'] = 4 + + # Builtin and c-extension modules that are allowed to be imported + # and inspected by rope. + prefs['extension_modules'] = [] + + # Add all standard c-extensions to extension_modules list. + prefs['import_dynload_stdmods'] = True + + # If `True` modules with syntax errors are considered to be empty. + # The default value is `False`; When `False` syntax errors raise + # `rope.base.exceptions.ModuleSyntaxError` exception. + prefs['ignore_syntax_errors'] = False + + # If `True`, rope ignores unresolvable imports. Otherwise, they + # appear in the importing namespace. + prefs['ignore_bad_imports'] = False + + # If `True`, rope will insert new module imports as + # `from import ` by default. + prefs['prefer_module_from_imports'] = False + + # If `True`, rope will transform a comma list of imports into + # multiple separate import statements when organizing + # imports. + prefs['split_imports'] = False + + # If `True`, rope will remove all top-level import statements and + # reinsert them at the top of the module when making changes. + prefs['pull_imports_to_top'] = True + + # If `True`, rope will sort imports alphabetically by module name instead + # of alphabetically by import statement, with from imports after normal + # imports. + prefs['sort_imports_alphabetically'] = False + + # Location of implementation of + # rope.base.oi.type_hinting.interfaces.ITypeHintingFactory In general + # case, you don't have to change this value, unless you're an rope expert. + # Change this value to inject you own implementations of interfaces + # listed in module rope.base.oi.type_hinting.providers.interfaces + # For example, you can add you own providers for Django Models, or disable + # the search type-hinting in a class hierarchy, etc. + prefs['type_hinting_factory'] = ( + 'rope.base.oi.type_hinting.factory.default_type_hinting_factory') + + +def project_opened(project): + """This function is called after opening the project""" + # Do whatever you like here! diff --git a/pype/__init__.py b/pype/__init__.py index 928bff6e9d..8481fa2d48 100644 --- a/pype/__init__.py +++ b/pype/__init__.py @@ -2,7 +2,7 @@ import os from pyblish import api as pyblish from avalon import api as avalon -from .api import project_settings, Anatomy +from .api import get_project_settings, Anatomy from .lib import filter_pyblish_plugins @@ -50,7 +50,7 @@ def patched_discover(superclass): print(">>> trying to find presets for {}:{} ...".format(host, plugin_type)) try: - settings = project_settings(os.environ['AVALON_PROJECT'])[host][plugin_type] + settings = get_project_settings(os.environ['AVALON_PROJECT'])[host][plugin_type] except KeyError: print("*** no presets found.") else: diff --git a/pype/lib/avalon_context.py b/pype/lib/avalon_context.py index c984e47b91..25966d550e 100644 --- a/pype/lib/avalon_context.py +++ b/pype/lib/avalon_context.py @@ -5,7 +5,7 @@ import logging import collections from avalon import io, pipeline -from ..api import project_settings +from ..api import get_project_settings import avalon.api log = logging.getLogger("AvalonContext") @@ -410,7 +410,7 @@ class BuildWorkfile: (dict): preset per entered task name """ host_name = avalon.api.registered_host().__name__.rsplit(".", 1)[-1] - presets = project_settings(io.Session["AVALON_PROJECT"]) + presets = get_project_settings(io.Session["AVALON_PROJECT"]) # Get presets for host build_presets = ( presets.get(host_name, {}) diff --git a/pype/lib/plugin_tools.py b/pype/lib/plugin_tools.py index 185ebce10f..726726bb4c 100644 --- a/pype/lib/plugin_tools.py +++ b/pype/lib/plugin_tools.py @@ -4,7 +4,7 @@ import os import inspect import logging -from ..api import config, project_settings +from ..api import config, get_project_settings log = logging.getLogger(__name__) @@ -25,7 +25,7 @@ def filter_pyblish_plugins(plugins): host = api.current_host() - presets = project_settings(os.environ['AVALON_PROJECT']) or {} + presets = get_project_settings(os.environ['AVALON_PROJECT']) or {} # iterate over plugins for plugin in plugins[:]: diff --git a/pype/modules/ftrack/actions/action_create_project_structure.py b/pype/modules/ftrack/actions/action_create_project_structure.py index d5cb381a63..4fc59da89e 100644 --- a/pype/modules/ftrack/actions/action_create_project_structure.py +++ b/pype/modules/ftrack/actions/action_create_project_structure.py @@ -2,7 +2,7 @@ import os import re from pype.modules.ftrack.lib import BaseAction, statics_icon -from pype.api import Anatomy, project_settings as get_project_settings +from pype.api import Anatomy, get_project_settings as get_project_settings class CreateProjectFolders(BaseAction): @@ -73,9 +73,9 @@ class CreateProjectFolders(BaseAction): project_entity = self.get_project_from_entity(entities[0]) # Load settings for project project_name = project_entity["full_name"] - project_settings = get_project_settings(project_name) + get_project_settings = get_project_settings(project_name) project_folder_structure = ( - project_settings["global"]["project_folder_structure"] + get_project_settings["global"]["project_folder_structure"] ) if not project_folder_structure: return { diff --git a/pype/modules/ftrack/events/event_user_assigment.py b/pype/modules/ftrack/events/event_user_assigment.py index bc05faa192..6a230f6ff9 100644 --- a/pype/modules/ftrack/events/event_user_assigment.py +++ b/pype/modules/ftrack/events/event_user_assigment.py @@ -8,7 +8,7 @@ from avalon.api import AvalonMongoDB from bson.objectid import ObjectId -from pype.api import Anatomy, project_settings as get_project_settings +from pype.api import Anatomy, get_project_settings as get_project_settings class UserAssigmentEvent(BaseEvent): @@ -200,9 +200,9 @@ class UserAssigmentEvent(BaseEvent): project_name = task_entity["project"]["full_name"] project_data = tmp_by_project_name.get(project_name) or {} if "scripts_by_action" not in project_data: - project_settings = get_project_settings(project_name) + get_project_settings = get_project_settings(project_name) _settings = ( - project_settings["ftrack"]["events"]["user_assignment"] + get_project_settings["ftrack"]["events"]["user_assignment"] ) project_data["scripts_by_action"] = _settings.get("scripts") tmp_by_project_name[project_name] = project_data diff --git a/pype/modules/ftrack/events/event_version_to_task_statuses.py b/pype/modules/ftrack/events/event_version_to_task_statuses.py index 6c4ebf2d10..ca55f24f32 100644 --- a/pype/modules/ftrack/events/event_version_to_task_statuses.py +++ b/pype/modules/ftrack/events/event_version_to_task_statuses.py @@ -1,5 +1,5 @@ from pype.modules.ftrack import BaseEvent -from pype.api import project_settings as get_project_settings +from pype.api import get_project_settings as get_project_settings class VersionToTaskStatus(BaseEvent): @@ -52,11 +52,11 @@ class VersionToTaskStatus(BaseEvent): project_entity = self.get_project_from_entity(task) project_name = project_entity["full_name"] - project_settings = get_project_settings(project_name) + get_project_settings = get_project_settings(project_name) # Load status mapping from presets status_mapping = ( - project_settings["ftrack"]["event"]["status_version_to_task"] + get_project_settings["ftrack"]["event"]["status_version_to_task"] ) # Skip if mapping is empty if not status_mapping: diff --git a/pype/plugin.py b/pype/plugin.py index 8d53e9c4be..1b769cd1f1 100644 --- a/pype/plugin.py +++ b/pype/plugin.py @@ -2,7 +2,7 @@ import tempfile import os import pyblish.api -from pype.api import project_settings +from pype.api import get_project_settings import inspect ValidatePipelineOrder = pyblish.api.ValidatorOrder + 0.05 @@ -24,7 +24,7 @@ def imprint_attributes(plugin): plugin_host = file.split(os.path.sep)[-3:-2][0] plugin_name = type(plugin).__name__ try: - settings = project_settings(os.environ['AVALON_PROJECT']) + settings = get_project_settings(os.environ['AVALON_PROJECT']) settings_data = settings[plugin_host][plugin_kind][plugin_name] # noqa: E501 print(settings_data) except KeyError: diff --git a/pype/plugins/maya/create/create_rendersetup.py b/pype/plugins/maya/create/create_rendersetup.py index 406d90223f..969c085ea6 100644 --- a/pype/plugins/maya/create/create_rendersetup.py +++ b/pype/plugins/maya/create/create_rendersetup.py @@ -26,9 +26,9 @@ class CreateRenderSetup(avalon.maya.Creator): # \__| | # \_____/ - # from pype.api import project_settings + # from pype.api import get_project_settings # import maya.app.renderSetup.model.renderSetup as renderSetup - # settings = project_settings(os.environ['AVALON_PROJECT']) + # settings = get_project_settings(os.environ['AVALON_PROJECT']) # layer = settings['maya']['create']['renderSetup']["layer"] # rs = renderSetup.instance() diff --git a/pype/plugins/maya/load/load_ass.py b/pype/plugins/maya/load/load_ass.py index dc3e0043ee..9b851a3757 100644 --- a/pype/plugins/maya/load/load_ass.py +++ b/pype/plugins/maya/load/load_ass.py @@ -1,7 +1,7 @@ from avalon import api import pype.hosts.maya.plugin import os -from pype.api import project_settings +from pype.api import get_project_settings import clique @@ -74,7 +74,7 @@ class AssProxyLoader(pype.hosts.maya.plugin.ReferenceLoader): proxyShape.dso.set(path) proxyShape.aiOverrideShaders.set(0) - settings = project_settings(os.environ['AVALON_PROJECT']) + settings = get_project_settings(os.environ['AVALON_PROJECT']) colors = settings['maya']['load']['colors'] c = colors.get(family) @@ -196,7 +196,7 @@ class AssStandinLoader(api.Loader): label = "{}:{}".format(namespace, name) root = pm.group(name=label, empty=True) - settings = project_settings(os.environ['AVALON_PROJECT']) + settings = get_project_settings(os.environ['AVALON_PROJECT']) colors = settings['maya']['load']['colors'] c = colors.get('ass') diff --git a/pype/plugins/maya/load/load_gpucache.py b/pype/plugins/maya/load/load_gpucache.py index 6520be0a07..0b3daae710 100644 --- a/pype/plugins/maya/load/load_gpucache.py +++ b/pype/plugins/maya/load/load_gpucache.py @@ -1,7 +1,7 @@ from avalon import api import pype.hosts.maya.plugin import os -from pype.api import project_settings +from pype.api import get_project_settings reload(config) @@ -35,7 +35,7 @@ class GpuCacheLoader(api.Loader): label = "{}:{}".format(namespace, name) root = cmds.group(name=label, empty=True) - settings = project_settings(os.environ['AVALON_PROJECT']) + settings = get_project_settings(os.environ['AVALON_PROJECT']) colors = settings['maya']['load']['colors'] c = colors.get('model') if c is not None: diff --git a/pype/plugins/maya/load/load_reference.py b/pype/plugins/maya/load/load_reference.py index 90a3015894..23b3cedb55 100644 --- a/pype/plugins/maya/load/load_reference.py +++ b/pype/plugins/maya/load/load_reference.py @@ -2,7 +2,7 @@ import pype.hosts.maya.plugin from avalon import api, maya from maya import cmds import os -from pype.api import project_settings +from pype.api import get_project_settings class ReferenceLoader(pype.hosts.maya.plugin.ReferenceLoader): @@ -77,7 +77,7 @@ class ReferenceLoader(pype.hosts.maya.plugin.ReferenceLoader): cmds.setAttr(groupName + ".displayHandle", 1) - settings = project_settings(os.environ['AVALON_PROJECT']) + settings = get_project_settings(os.environ['AVALON_PROJECT']) colors = settings['maya']['load']['colors'] c = colors.get(family) if c is not None: diff --git a/pype/plugins/maya/load/load_vdb_to_redshift.py b/pype/plugins/maya/load/load_vdb_to_redshift.py index 885f0f23c8..17c78d7165 100644 --- a/pype/plugins/maya/load/load_vdb_to_redshift.py +++ b/pype/plugins/maya/load/load_vdb_to_redshift.py @@ -1,6 +1,6 @@ from avalon import api import os -from pype.api import project_settings +from pype.api import get_project_settings class LoadVDBtoRedShift(api.Loader): """Load OpenVDB in a Redshift Volume Shape""" @@ -55,7 +55,7 @@ class LoadVDBtoRedShift(api.Loader): label = "{}:{}".format(namespace, name) root = cmds.group(name=label, empty=True) - settings = project_settings(os.environ['AVALON_PROJECT']) + settings = get_project_settings(os.environ['AVALON_PROJECT']) colors = settings['maya']['load']['colors'] c = colors.get(family) diff --git a/pype/plugins/maya/load/load_vdb_to_vray.py b/pype/plugins/maya/load/load_vdb_to_vray.py index 9bfdda0308..2959ef42ec 100644 --- a/pype/plugins/maya/load/load_vdb_to_vray.py +++ b/pype/plugins/maya/load/load_vdb_to_vray.py @@ -1,5 +1,5 @@ from avalon import api -from pype.api import project_settings +from pype.api import get_project_settings import os @@ -48,7 +48,7 @@ class LoadVDBtoVRay(api.Loader): label = "{}:{}".format(namespace, name) root = cmds.group(name=label, empty=True) - settings = project_settings(os.environ['AVALON_PROJECT']) + settings = get_project_settings(os.environ['AVALON_PROJECT']) colors = settings['maya']['load']['colors'] c = colors.get(family) diff --git a/pype/plugins/maya/load/load_vrayproxy.py b/pype/plugins/maya/load/load_vrayproxy.py index 1294df2fc7..73f02b81e4 100644 --- a/pype/plugins/maya/load/load_vrayproxy.py +++ b/pype/plugins/maya/load/load_vrayproxy.py @@ -1,6 +1,6 @@ from avalon.maya import lib from avalon import api -from pype.api import project_settings +from pype.api import get_project_settings import os import maya.cmds as cmds @@ -47,7 +47,7 @@ class VRayProxyLoader(api.Loader): return # colour the group node - settings = project_settings(os.environ['AVALON_PROJECT']) + settings = get_project_settings(os.environ['AVALON_PROJECT']) colors = settings['maya']['load']['colors'] c = colors.get(family) if c is not None: diff --git a/pype/plugins/maya/load/load_yeti_cache.py b/pype/plugins/maya/load/load_yeti_cache.py index 8ee1602202..19cf3920fe 100644 --- a/pype/plugins/maya/load/load_yeti_cache.py +++ b/pype/plugins/maya/load/load_yeti_cache.py @@ -9,7 +9,7 @@ from maya import cmds from avalon import api, io from avalon.maya import lib as avalon_lib, pipeline from pype.hosts.maya import lib -from pype.api import project_settings +from pype.api import get_project_settings from pprint import pprint @@ -59,7 +59,7 @@ class YetiCacheLoader(api.Loader): group_name = "{}:{}".format(namespace, name) group_node = cmds.group(nodes, name=group_name) - settings = project_settings(os.environ['AVALON_PROJECT']) + settings = get_project_settings(os.environ['AVALON_PROJECT']) colors = settings['maya']['load']['colors'] c = colors.get(family) diff --git a/pype/plugins/maya/load/load_yeti_rig.py b/pype/plugins/maya/load/load_yeti_rig.py index bd74fcbc43..3a9339c707 100644 --- a/pype/plugins/maya/load/load_yeti_rig.py +++ b/pype/plugins/maya/load/load_yeti_rig.py @@ -1,7 +1,7 @@ import os from collections import defaultdict -from pype.api import project_settings +from pype.api import get_project_settings import pype.hosts.maya.plugin from pype.hosts.maya import lib @@ -77,7 +77,7 @@ class YetiRigLoader(pype.hosts.maya.plugin.ReferenceLoader): groupName = "{}:{}".format(namespace, name) - settings = project_settings(os.environ['AVALON_PROJECT']) + settings = get_project_settings(os.environ['AVALON_PROJECT']) colors = settings['maya']['load']['colors'] c = colors.get('yetiRig') diff --git a/pype/plugins/nuke/load/load_mov.py b/pype/plugins/nuke/load/load_mov.py index 078127ee42..104f59d5be 100644 --- a/pype/plugins/nuke/load/load_mov.py +++ b/pype/plugins/nuke/load/load_mov.py @@ -4,7 +4,7 @@ import contextlib from avalon import api, io from pype.hosts.nuke import presets -from pype.api import project_settings +from pype.api import get_project_settings @contextlib.contextmanager @@ -73,7 +73,7 @@ def add_review_presets_config(): "families": list(), "representations": list() } - settings = project_settings(io.Session["AVALON_PROJECT"]) + settings = get_project_settings(io.Session["AVALON_PROJECT"]) review_presets = settings["global"]["publish"].get( "ExtractReview", {}) diff --git a/pype/tools/pyblish_pype/control.py b/pype/tools/pyblish_pype/control.py index 0994e25d4a..4f7a43d6d1 100644 --- a/pype/tools/pyblish_pype/control.py +++ b/pype/tools/pyblish_pype/control.py @@ -22,7 +22,7 @@ import pyblish.version from . import util from .constants import InstanceStates -from pype.api import project_settings +from pype.api import get_project_settings class IterationBreak(Exception): @@ -121,7 +121,7 @@ class Controller(QtCore.QObject): def presets_by_hosts(self): # Get global filters as base - presets = project_settings(os.environ['AVALON_PROJECT']) or {} + presets = get_project_settings(os.environ['AVALON_PROJECT']) or {} if not presets: return {} diff --git a/pype/tools/standalonepublish/widgets/widget_family.py b/pype/tools/standalonepublish/widgets/widget_family.py index be68e411fd..5c0c8ccd38 100644 --- a/pype/tools/standalonepublish/widgets/widget_family.py +++ b/pype/tools/standalonepublish/widgets/widget_family.py @@ -5,7 +5,7 @@ from Qt import QtWidgets, QtCore from . import HelpRole, FamilyRole, ExistsRole, PluginRole, PluginKeyRole from . import FamilyDescriptionWidget -from pype.api import project_settings +from pype.api import get_project_settings class FamilyWidget(QtWidgets.QWidget): @@ -310,7 +310,7 @@ class FamilyWidget(QtWidgets.QWidget): def refresh(self): has_families = False - settings = project_settings(os.environ['AVALON_PROJECT']) + settings = get_project_settings(os.environ['AVALON_PROJECT']) sp_settings = settings.get('standalonepublisher', {}) print(sp_settings) diff --git a/setup/maya/userSetup.py b/setup/maya/userSetup.py index 3cf2718796..e401580bd8 100644 --- a/setup/maya/userSetup.py +++ b/setup/maya/userSetup.py @@ -1,5 +1,5 @@ import os -from pype.api import project_settings +from pype.api import get_project_settings import pype.hosts.maya.lib as mlib from maya import cmds @@ -7,7 +7,7 @@ from maya import cmds print("starting PYPE usersetup") # build a shelf -settings = project_settings(os.environ['AVALON_PROJECT']) +settings = get_project_settings(os.environ['AVALON_PROJECT']) shelf_preset = settings['maya'].get('project_shelf') From fccdd586be866cc27a2ca6a6abcbee4870dce6b1 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Thu, 3 Dec 2020 16:08:20 +0100 Subject: [PATCH 26/54] remove .ropeproject --- .gitignore | 2 + .ropeproject/config.py | 114 ----------------------------------------- 2 files changed, 2 insertions(+), 114 deletions(-) delete mode 100644 .ropeproject/config.py diff --git a/.gitignore b/.gitignore index 101c1e6224..044efb4617 100644 --- a/.gitignore +++ b/.gitignore @@ -15,6 +15,8 @@ __pycache__/ Icon # Thumbnails ._* +# rope project dir +.ropeproject # Files that might appear in the root of a volume .DocumentRevisions-V100 .fseventsd diff --git a/.ropeproject/config.py b/.ropeproject/config.py deleted file mode 100644 index dee2d1ae9a..0000000000 --- a/.ropeproject/config.py +++ /dev/null @@ -1,114 +0,0 @@ -# The default ``config.py`` -# flake8: noqa - - -def set_prefs(prefs): - """This function is called before opening the project""" - - # Specify which files and folders to ignore in the project. - # Changes to ignored resources are not added to the history and - # VCSs. Also they are not returned in `Project.get_files()`. - # Note that ``?`` and ``*`` match all characters but slashes. - # '*.pyc': matches 'test.pyc' and 'pkg/test.pyc' - # 'mod*.pyc': matches 'test/mod1.pyc' but not 'mod/1.pyc' - # '.svn': matches 'pkg/.svn' and all of its children - # 'build/*.o': matches 'build/lib.o' but not 'build/sub/lib.o' - # 'build//*.o': matches 'build/lib.o' and 'build/sub/lib.o' - prefs['ignored_resources'] = ['*.pyc', '*~', '.ropeproject', - '.hg', '.svn', '_svn', '.git', '.tox'] - - # Specifies which files should be considered python files. It is - # useful when you have scripts inside your project. Only files - # ending with ``.py`` are considered to be python files by - # default. - # prefs['python_files'] = ['*.py'] - - # Custom source folders: By default rope searches the project - # for finding source folders (folders that should be searched - # for finding modules). You can add paths to that list. Note - # that rope guesses project source folders correctly most of the - # time; use this if you have any problems. - # The folders should be relative to project root and use '/' for - # separating folders regardless of the platform rope is running on. - # 'src/my_source_folder' for instance. - # prefs.add('source_folders', 'src') - - # You can extend python path for looking up modules - # prefs.add('python_path', '~/python/') - - # Should rope save object information or not. - prefs['save_objectdb'] = True - prefs['compress_objectdb'] = False - - # If `True`, rope analyzes each module when it is being saved. - prefs['automatic_soa'] = True - # The depth of calls to follow in static object analysis - prefs['soa_followed_calls'] = 0 - - # If `False` when running modules or unit tests "dynamic object - # analysis" is turned off. This makes them much faster. - prefs['perform_doa'] = True - - # Rope can check the validity of its object DB when running. - prefs['validate_objectdb'] = True - - # How many undos to hold? - prefs['max_history_items'] = 32 - - # Shows whether to save history across sessions. - prefs['save_history'] = True - prefs['compress_history'] = False - - # Set the number spaces used for indenting. According to - # :PEP:`8`, it is best to use 4 spaces. Since most of rope's - # unit-tests use 4 spaces it is more reliable, too. - prefs['indent_size'] = 4 - - # Builtin and c-extension modules that are allowed to be imported - # and inspected by rope. - prefs['extension_modules'] = [] - - # Add all standard c-extensions to extension_modules list. - prefs['import_dynload_stdmods'] = True - - # If `True` modules with syntax errors are considered to be empty. - # The default value is `False`; When `False` syntax errors raise - # `rope.base.exceptions.ModuleSyntaxError` exception. - prefs['ignore_syntax_errors'] = False - - # If `True`, rope ignores unresolvable imports. Otherwise, they - # appear in the importing namespace. - prefs['ignore_bad_imports'] = False - - # If `True`, rope will insert new module imports as - # `from import ` by default. - prefs['prefer_module_from_imports'] = False - - # If `True`, rope will transform a comma list of imports into - # multiple separate import statements when organizing - # imports. - prefs['split_imports'] = False - - # If `True`, rope will remove all top-level import statements and - # reinsert them at the top of the module when making changes. - prefs['pull_imports_to_top'] = True - - # If `True`, rope will sort imports alphabetically by module name instead - # of alphabetically by import statement, with from imports after normal - # imports. - prefs['sort_imports_alphabetically'] = False - - # Location of implementation of - # rope.base.oi.type_hinting.interfaces.ITypeHintingFactory In general - # case, you don't have to change this value, unless you're an rope expert. - # Change this value to inject you own implementations of interfaces - # listed in module rope.base.oi.type_hinting.providers.interfaces - # For example, you can add you own providers for Django Models, or disable - # the search type-hinting in a class hierarchy, etc. - prefs['type_hinting_factory'] = ( - 'rope.base.oi.type_hinting.factory.default_type_hinting_factory') - - -def project_opened(project): - """This function is called after opening the project""" - # Do whatever you like here! From c64fdd19ddb17f6c9a7b778df65f25357c25522c Mon Sep 17 00:00:00 2001 From: Milan Kolar Date: Thu, 3 Dec 2020 16:08:50 +0100 Subject: [PATCH 27/54] system_settings to get_system_settings --- pype/lib/applications.py | 2 +- pype/plugins/maya/publish/submit_maya_muster.py | 4 ++-- pype/tools/pyblish_pype/model.py | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/pype/lib/applications.py b/pype/lib/applications.py index 9b6e364a4c..bee51d0570 100644 --- a/pype/lib/applications.py +++ b/pype/lib/applications.py @@ -8,7 +8,7 @@ from abc import ABCMeta, abstractmethod import six -from pype.settings import system_settings, environments +from pype.settings import get_system_settings, get_environments from ..api import Logger from .python_module_tools import ( diff --git a/pype/plugins/maya/publish/submit_maya_muster.py b/pype/plugins/maya/publish/submit_maya_muster.py index df75fce1a4..65889bf068 100644 --- a/pype/plugins/maya/publish/submit_maya_muster.py +++ b/pype/plugins/maya/publish/submit_maya_muster.py @@ -11,7 +11,7 @@ from avalon.vendor import requests import pyblish.api from pype.hosts.maya import lib -from pype.api import system_settings +from pype.api import get_system_settings # mapping between Maya renderer names and Muster template ids @@ -25,7 +25,7 @@ def _get_template_id(renderer): :rtype: int """ - templates = system_settings()["modules"]["Muster"]["templates_mapping"] + templates = get_system_settings()["modules"]["Muster"]["templates_mapping"] if not templates: raise RuntimeError(("Muster template mapping missing in pype-settings")) try: diff --git a/pype/tools/pyblish_pype/model.py b/pype/tools/pyblish_pype/model.py index 8c9bc07d7e..88dce679f7 100644 --- a/pype/tools/pyblish_pype/model.py +++ b/pype/tools/pyblish_pype/model.py @@ -35,7 +35,7 @@ from six import text_type from .vendor import qtawesome from .constants import PluginStates, InstanceStates, GroupStates, Roles -from pype.api import system_settings +from pype.api import get_system_settings # ItemTypes @@ -104,7 +104,7 @@ class IntentModel(QtGui.QStandardItemModel): self.default_index = 0 intents_preset = ( - system_settings() + get_system_settings() .get("modules", {}) .get("Ftrack", {}) .get("intent", {}) From 9e407af9d3bb442a5af40537a5094464211a681b Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Thu, 3 Dec 2020 16:27:07 +0100 Subject: [PATCH 28/54] empty dictionary is passed to ftrack events and actions instead of presets --- pype/modules/ftrack/ftrack_server/ftrack_server.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/pype/modules/ftrack/ftrack_server/ftrack_server.py b/pype/modules/ftrack/ftrack_server/ftrack_server.py index 9940ab236e..ec39bdc50f 100644 --- a/pype/modules/ftrack/ftrack_server/ftrack_server.py +++ b/pype/modules/ftrack/ftrack_server/ftrack_server.py @@ -8,7 +8,7 @@ import inspect import ftrack_api -from pype.api import Logger, config +from pype.api import Logger log = Logger().get_logger(__name__) @@ -111,9 +111,8 @@ class FtrackServer: key = "user" if self.server_type.lower() == "event": key = "server" - plugins_presets = config.get_presets().get( - "ftrack", {} - ).get("plugins", {}).get(key, {}) + # TODO replace with settings or get rid of passing the dictionary + plugins_presets = {} function_counter = 0 for function_dict in register_functions_dict: From d7af09160cbffdf742874dfb2d30f90c24310c5c Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Thu, 3 Dec 2020 16:28:23 +0100 Subject: [PATCH 29/54] rv action is just checking for rv path and do not use presets --- pype/modules/ftrack/actions/action_rv.py | 30 ++++++++++-------------- 1 file changed, 12 insertions(+), 18 deletions(-) diff --git a/pype/modules/ftrack/actions/action_rv.py b/pype/modules/ftrack/actions/action_rv.py index f9aeb87f71..eeb5672047 100644 --- a/pype/modules/ftrack/actions/action_rv.py +++ b/pype/modules/ftrack/actions/action_rv.py @@ -3,7 +3,6 @@ import subprocess import traceback import json -from pype.api import config from pype.modules.ftrack.lib import BaseAction, statics_icon import ftrack_api from avalon import io, api @@ -11,7 +10,6 @@ from avalon import io, api class RVAction(BaseAction): """ Launch RV action """ - ignore_me = "rv" not in config.get_presets() identifier = "rv.launch.action" label = "rv" description = "rv Launcher" @@ -19,6 +17,8 @@ class RVAction(BaseAction): type = 'Application' + allowed_types = ["img", "mov", "exr", "mp4"] + def __init__(self, session, plugins_presets): """ Constructor @@ -26,36 +26,30 @@ class RVAction(BaseAction): :type session: :class:`ftrack_api.Session` """ super().__init__(session, plugins_presets) - self.rv_path = None - self.config_data = None + + # QUESTION load RV application data from AppplicationManager? + rv_path = None # RV_HOME should be set if properly installed if os.environ.get('RV_HOME'): - self.rv_path = os.path.join( + rv_path = os.path.join( os.environ.get('RV_HOME'), 'bin', 'rv' ) - else: - # if not, fallback to config file location - if "rv" in config.get_presets(): - self.config_data = config.get_presets()['rv']['config'] - self.set_rv_path() + if not os.path.exists(rv_path): + rv_path = None - if self.rv_path is None: - return + if not rv_path: + self.log.info("RV path was not found.") + self.ignore_me = True - self.allowed_types = self.config_data.get( - 'file_ext', ["img", "mov", "exr", "mp4"] - ) + self.rv_path = rv_path def discover(self, session, entities, event): """Return available actions based on *event*. """ return True - def set_rv_path(self): - self.rv_path = self.config_data.get("rv_path") - def preregister(self): if self.rv_path is None: return ( From a633307b2d72e634f924e0f98e971454d397c06a Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Thu, 3 Dec 2020 16:33:42 +0100 Subject: [PATCH 30/54] added default roles for project cusstom attributes --- .../defaults/system_settings/modules.json | 22 ++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/pype/settings/defaults/system_settings/modules.json b/pype/settings/defaults/system_settings/modules.json index 8c228e91ef..4a91d2dddf 100644 --- a/pype/settings/defaults/system_settings/modules.json +++ b/pype/settings/defaults/system_settings/modules.json @@ -58,13 +58,25 @@ "show": { "avalon_auto_sync": { "default": "", - "write_security_role": [], - "read_security_role": [] + "write_security_role": [ + "API", + "Administrator" + ], + "read_security_role": [ + "API", + "Administrator" + ] }, "library_project": { "default": "", - "write_security_role": [], - "read_security_role": [] + "write_security_role": [ + "API", + "Administrator" + ], + "read_security_role": [ + "API", + "Administrator" + ] } }, "is_hierarchical": { @@ -190,4 +202,4 @@ "Idle Manager": { "enabled": true } -} \ No newline at end of file +} From d5b10b085ea782d3179b2e9e7c40c340563a63e6 Mon Sep 17 00:00:00 2001 From: Milan Kolar Date: Thu, 3 Dec 2020 16:51:39 +0100 Subject: [PATCH 31/54] load nuke creator from settings --- pype/hosts/nuke/plugin.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pype/hosts/nuke/plugin.py b/pype/hosts/nuke/plugin.py index 652c0396a8..5d00b19ec5 100644 --- a/pype/hosts/nuke/plugin.py +++ b/pype/hosts/nuke/plugin.py @@ -1,13 +1,13 @@ import re import avalon.api import avalon.nuke -from pype.api import config +from pype.api import get_current_project_settings class PypeCreator(avalon.nuke.pipeline.Creator): """Pype Nuke Creator class wrapper """ def __init__(self, *args, **kwargs): super(PypeCreator, self).__init__(*args, **kwargs) - self.presets = config.get_presets()['plugins']["nuke"]["create"].get( + self.presets = get_current_project_settings()["nuke"]["create"].get( self.__class__.__name__, {} ) From 06d9f9ab5250c0f2e2e151cfab98185c37307222 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Thu, 3 Dec 2020 16:56:47 +0100 Subject: [PATCH 32/54] create update custom attributes use settings --- .../actions/action_create_cust_attrs.py | 21 +++++++------------ 1 file changed, 7 insertions(+), 14 deletions(-) diff --git a/pype/modules/ftrack/actions/action_create_cust_attrs.py b/pype/modules/ftrack/actions/action_create_cust_attrs.py index f76d794d6f..68fae16382 100644 --- a/pype/modules/ftrack/actions/action_create_cust_attrs.py +++ b/pype/modules/ftrack/actions/action_create_cust_attrs.py @@ -1,6 +1,4 @@ -import os import collections -import toml import json import arrow import ftrack_api @@ -8,7 +6,7 @@ from pype.modules.ftrack.lib import BaseAction, statics_icon from pype.modules.ftrack.lib.avalon_sync import ( CUST_ATTR_ID_KEY, CUST_ATTR_GROUP, default_custom_attributes_definition ) -from pype.api import config +from pype.api import get_system_settings from pype.lib import ApplicationManager """ @@ -213,15 +211,12 @@ class CustomAttributes(BaseAction): self.groups = {} - self.presets = config.get_presets() + self.ftrack_settings = get_system_settings()["modules"]["Ftrack"] self.attrs_presets = self.prepare_attribute_pressets() def prepare_attribute_pressets(self): output = {} - - attr_presets = ( - self.presets.get("ftrack", {}).get("ftrack_custom_attributes") - ) or {} + attr_presets = self.ftrack_settings["custom_attributes"] for entity_type, preset in attr_presets.items(): # Lower entity type entity_type = entity_type.lower() @@ -429,12 +424,7 @@ class CustomAttributes(BaseAction): self.process_attr_data(tools_custom_attr_data, event) def intent_attribute(self, event): - intent_key_values = ( - self.presets - .get("global", {}) - .get("intent", {}) - .get("items", {}) - ) or {} + intent_key_values = self.ftrack_settings["intent"]["items"] intent_values = [] for key, label in intent_key_values.items(): @@ -740,6 +730,9 @@ class CustomAttributes(BaseAction): return default err_msg = 'Default value is not' if type == 'number': + if isinstance(default, (str)) and default.isnumeric(): + default = float(default) + if not isinstance(default, (float, int)): raise CustAttrException('{} integer'.format(err_msg)) elif type == 'text': From 1838f70ae090259e6b7be85a709de84ea6598e04 Mon Sep 17 00:00:00 2001 From: Milan Kolar Date: Thu, 3 Dec 2020 17:03:49 +0100 Subject: [PATCH 33/54] harmony read from settings --- pype/hosts/harmony/__init__.py | 6 ++-- .../defaults/project_settings/harmony.json | 7 ++++ .../schema_project_harmony.json | 34 +++++++++++++++++++ 3 files changed, 44 insertions(+), 3 deletions(-) create mode 100644 pype/settings/defaults/project_settings/harmony.json create mode 100644 pype/tools/settings/settings/gui_schemas/projects_schema/schema_project_harmony.json diff --git a/pype/hosts/harmony/__init__.py b/pype/hosts/harmony/__init__.py index 7ea261292e..bc91b4db2f 100644 --- a/pype/hosts/harmony/__init__.py +++ b/pype/hosts/harmony/__init__.py @@ -9,7 +9,7 @@ import avalon.tools.sceneinventory import pyblish.api from pype import lib -from pype.api import config +from pype.api import get_current_project_settings def set_scene_settings(settings): @@ -51,9 +51,9 @@ def get_asset_settings(): try: skip_resolution_check = \ - config.get_presets()["harmony"]["general"]["skip_resolution_check"] + get_current_project_settings()["harmony"]["general"]["skip_resolution_check"] skip_timelines_check = \ - config.get_presets()["harmony"]["general"]["skip_timelines_check"] + get_current_project_settings()["harmony"]["general"]["skip_timelines_check"] except KeyError: skip_resolution_check = [] skip_timelines_check = [] diff --git a/pype/settings/defaults/project_settings/harmony.json b/pype/settings/defaults/project_settings/harmony.json new file mode 100644 index 0000000000..5eca4f60eb --- /dev/null +++ b/pype/settings/defaults/project_settings/harmony.json @@ -0,0 +1,7 @@ +{ + "publish": {}, + "general": { + "skip_resolution_check": false, + "skip_timelines_check": false + } +} \ No newline at end of file diff --git a/pype/tools/settings/settings/gui_schemas/projects_schema/schema_project_harmony.json b/pype/tools/settings/settings/gui_schemas/projects_schema/schema_project_harmony.json new file mode 100644 index 0000000000..282a4350b6 --- /dev/null +++ b/pype/tools/settings/settings/gui_schemas/projects_schema/schema_project_harmony.json @@ -0,0 +1,34 @@ +{ + "type": "dict", + "collapsable": true, + "key": "harmony", + "label": "Harmony", + "is_file": true, + "children": [ + { + "type": "dict", + "collapsable": true, + "key": "publish", + "label": "Publish plugins", + "children": [] + }, + { + "type": "dict", + "collapsable": true, + "key": "general", + "label": "General", + "children": [ + + { + "type": "boolean", + "key": "skip_resolution_check", + "label": "Skip Resolution Check" + }, + { + "type": "boolean", + "key": "skip_timelines_check", + "label": "Skip Timeliene Check" + } + ] + }] +} From be5eaa6701ab00dc4908d5723db2b040a6336b32 Mon Sep 17 00:00:00 2001 From: Milan Kolar Date: Thu, 3 Dec 2020 17:05:02 +0100 Subject: [PATCH 34/54] add harmony and minor cosmetics --- .../defaults/project_settings/ftrack.json | 2 +- .../defaults/project_settings/maya.json | 91 +++++++++++++++---- .../project_settings/standalonepublisher.json | 6 +- .../projects_schema/schema_main.json | 6 +- 4 files changed, 82 insertions(+), 23 deletions(-) diff --git a/pype/settings/defaults/project_settings/ftrack.json b/pype/settings/defaults/project_settings/ftrack.json index 4eabb52dc1..023b85cb3b 100644 --- a/pype/settings/defaults/project_settings/ftrack.json +++ b/pype/settings/defaults/project_settings/ftrack.json @@ -95,4 +95,4 @@ "note_labels": [] } } -} +} \ No newline at end of file diff --git a/pype/settings/defaults/project_settings/maya.json b/pype/settings/defaults/project_settings/maya.json index 0c640a63e4..9193ea2b52 100644 --- a/pype/settings/defaults/project_settings/maya.json +++ b/pype/settings/defaults/project_settings/maya.json @@ -132,7 +132,7 @@ "regex": "" }, "ValidateMeshHasOverlappingUVs": { - "enabled": true + "enabled": false }, "ExtractCameraAlembic": { "enabled": true, @@ -145,23 +145,78 @@ } }, "load": { - "colors": { - "model": [0.821, 0.518, 0.117], - "rig": [0.144, 0.443, 0.463], - "pointcache": [0.368, 0.821, 0.117], - "animation": [0.368, 0.821, 0.117], - "ass": [1.0, 0.332, 0.312], - "camera": [0.447, 0.312, 1.0], - "camerarig": [0.447, 0.312, 1.0], - "fbx": [1.0, 0.931, 0.312], - "mayaAscii": [0.312, 1.0, 0.747], - "setdress": [0.312, 1.0, 0.747], - "layout": [0.312, 1.0, 0.747], - "vdbcache": [0.312, 1.0, 0.428], - "vrayproxy": [0.258, 0.95, 0.541], - "yeticache": [0.2, 0.8, 0.3], - "yetiRig": [0, 0.8, 0.5] - } + "colors": { + "model": [ + 0.821, + 0.518, + 0.117 + ], + "rig": [ + 0.144, + 0.443, + 0.463 + ], + "pointcache": [ + 0.368, + 0.821, + 0.117 + ], + "animation": [ + 0.368, + 0.821, + 0.117 + ], + "ass": [ + 1.0, + 0.332, + 0.312 + ], + "camera": [ + 0.447, + 0.312, + 1.0 + ], + "fbx": [ + 1.0, + 0.931, + 0.312 + ], + "mayaAscii": [ + 0.312, + 1.0, + 0.747 + ], + "setdress": [ + 0.312, + 1.0, + 0.747 + ], + "layout": [ + 0.312, + 1.0, + 0.747 + ], + "vdbcache": [ + 0.312, + 1.0, + 0.428 + ], + "vrayproxy": [ + 0.258, + 0.95, + 0.541 + ], + "yeticache": [ + 0.2, + 0.8, + 0.3 + ], + "yetiRig": [ + 0.0, + 0.8, + 0.5 + ] + } }, "workfile_build": { "profiles": [ diff --git a/pype/settings/defaults/project_settings/standalonepublisher.json b/pype/settings/defaults/project_settings/standalonepublisher.json index 877055ceef..b8015f2832 100644 --- a/pype/settings/defaults/project_settings/standalonepublisher.json +++ b/pype/settings/defaults/project_settings/standalonepublisher.json @@ -19,7 +19,7 @@ "create_camera": "Camera", "create_editorial": "Editorial", "create_image": "Image", - "create_matchmove": "matchmove", + "create_matchmove": "Matchmove", "": "" }, "create_workfile": { @@ -112,7 +112,7 @@ }, "create_matchmove": { "name": "matchmove", - "label": "Matchmove script", + "label": "Matchmove Scripts", "family": "matchmove", "icon": "empire", "defaults": [ @@ -123,4 +123,4 @@ "help": "Script exported from matchmoving application" } } -} \ No newline at end of file +} diff --git a/pype/tools/settings/settings/gui_schemas/projects_schema/schema_main.json b/pype/tools/settings/settings/gui_schemas/projects_schema/schema_main.json index f0226446ea..5b3c399666 100644 --- a/pype/tools/settings/settings/gui_schemas/projects_schema/schema_main.json +++ b/pype/tools/settings/settings/gui_schemas/projects_schema/schema_main.json @@ -10,7 +10,7 @@ "type": "anatomy_roots", "key": "roots", "is_file": true - }, + }, { "type": "schema", "name": "schema_anatomy_templates" @@ -48,6 +48,10 @@ "type": "schema", "name": "schema_project_hiero" }, + { + "type": "schema", + "name": "schema_project_harmony" + }, { "type": "schema", "name": "schema_project_celaction" From a81923aeee8e65359739ab70061bfbd752c5a492 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Thu, 3 Dec 2020 17:23:27 +0100 Subject: [PATCH 35/54] action create folders use settings --- .../ftrack/actions/action_create_folders.py | 40 ++++++++++++------- 1 file changed, 25 insertions(+), 15 deletions(-) diff --git a/pype/modules/ftrack/actions/action_create_folders.py b/pype/modules/ftrack/actions/action_create_folders.py index e689e0260c..a131a0e35b 100644 --- a/pype/modules/ftrack/actions/action_create_folders.py +++ b/pype/modules/ftrack/actions/action_create_folders.py @@ -1,7 +1,11 @@ import os from pype.modules.ftrack.lib import BaseAction, statics_icon from avalon import lib as avalonlib -from pype.api import config, Anatomy +from pype.api import ( + Anatomy, + get_project_settings +) +from pype.lib import ApplicationManager class CreateFolders(BaseAction): @@ -93,6 +97,7 @@ class CreateFolders(BaseAction): all_entities = self.get_notask_children(entity) anatomy = Anatomy(project_name) + project_settings = get_project_settings(project_name) work_keys = ["work", "folder"] work_template = anatomy.templates @@ -106,10 +111,13 @@ class CreateFolders(BaseAction): publish_template = publish_template[key] publish_has_apps = "{app" in publish_template - presets = config.get_presets() - app_presets = presets.get("tools", {}).get("sw_folders") - cached_apps = {} + tools_settings = project_settings["global"]["tools"] + app_presets = tools_settings["Workfiles"]["sw_folders"] + app_manager_apps = None + if app_presets and (work_has_apps or publish_has_apps): + app_manager_apps = ApplicationManager().applications + cached_apps = {} collected_paths = [] for entity in all_entities: if entity.entity_type.lower() == "project": @@ -140,18 +148,20 @@ class CreateFolders(BaseAction): task_data["task"] = child["name"] apps = [] - if app_presets and (work_has_apps or publish_has_apps): - possible_apps = app_presets.get(task_type_name, []) - for app in possible_apps: - if app in cached_apps: - app_dir = cached_apps[app] + if app_manager_apps: + possible_apps = app_presets.get(task_type_name) or [] + for app_name in possible_apps: + + if app_name in cached_apps: + apps.append(cached_apps[app_name]) + continue + + app_def = app_manager_apps.get(app_name) + if app_def and app_def.is_host: + app_dir = app_def.host_name else: - try: - app_data = avalonlib.get_application(app) - app_dir = app_data["application_dir"] - except ValueError: - app_dir = app - cached_apps[app] = app_dir + app_dir = app_name + cached_apps[app_name] = app_dir apps.append(app_dir) # Template wok From 467aa65aa74ed97c56d01bd5a14d7d628bc9d26f Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Thu, 3 Dec 2020 17:38:43 +0100 Subject: [PATCH 36/54] remove loading clockify presets in ftrack event subprocess --- .../ftrack_server/sub_event_processor.py | 18 +----------------- 1 file changed, 1 insertion(+), 17 deletions(-) diff --git a/pype/modules/ftrack/ftrack_server/sub_event_processor.py b/pype/modules/ftrack/ftrack_server/sub_event_processor.py index 4a3241dd4f..c719c8fd08 100644 --- a/pype/modules/ftrack/ftrack_server/sub_event_processor.py +++ b/pype/modules/ftrack/ftrack_server/sub_event_processor.py @@ -9,7 +9,7 @@ from pype.modules.ftrack.ftrack_server.lib import ( SocketSession, ProcessEventHub, TOPIC_STATUS_SERVER ) import ftrack_api -from pype.api import Logger, config +from pype.api import Logger log = Logger().get_logger("Event processor") @@ -56,32 +56,16 @@ def register(session): def clockify_module_registration(): - module_name = "Clockify" - - menu_items = config.get_presets()["tray"]["menu_items"] - if not menu_items["item_usage"][module_name]: - return - api_key = os.environ.get("CLOCKIFY_API_KEY") if not api_key: log.warning("Clockify API key is not set.") return workspace_name = os.environ.get("CLOCKIFY_WORKSPACE") - if not workspace_name: - workspace_name = ( - menu_items - .get("attributes", {}) - .get(module_name, {}) - .get("workspace_name", {}) - ) - if not workspace_name: log.warning("Clockify Workspace is not set.") return - os.environ["CLOCKIFY_WORKSPACE"] = workspace_name - from pype.modules.clockify.constants import CLOCKIFY_FTRACK_SERVER_PATH current = os.environ.get("FTRACK_EVENTS_PATH") or "" From 38c9b093b5e3b96c1342f67a1bc4d4b49ccbc5d4 Mon Sep 17 00:00:00 2001 From: Milan Kolar Date: Thu, 3 Dec 2020 17:51:26 +0100 Subject: [PATCH 37/54] fix review settings --- .../defaults/project_settings/global.json | 46 +++++++++---------- 1 file changed, 21 insertions(+), 25 deletions(-) diff --git a/pype/settings/defaults/project_settings/global.json b/pype/settings/defaults/project_settings/global.json index 7cedd7cf88..5f76f2d0f6 100644 --- a/pype/settings/defaults/project_settings/global.json +++ b/pype/settings/defaults/project_settings/global.json @@ -27,12 +27,12 @@ "video_filters": [], "audio_filters": [], "input": [ - "gamma 2.2" + "-gamma 2.2" ], "output": [ - "pix_fmt yuv420p", - "crf 18", - "intra" + "-pix_fmt yuv420p", + "-crf 18", + "-intra" ] }, "filter": { @@ -76,18 +76,16 @@ }, "IntegrateAssetNew": { "template_name_profiles": { - "template_name_profiles": { - "publish": { - "families": [], - "tasks": [] - }, - "render": { - "families": [ - "review", - "render", - "prerender" - ] - } + "publish": { + "families": [], + "tasks": [] + }, + "render": { + "families": [ + "review", + "render", + "prerender" + ] } } }, @@ -135,15 +133,13 @@ } }, "Workfiles": { - "last_workfile_on_startup": { - "profiles": [ - { - "hosts": [], - "tasks": [], - "enabled": true - } - ] - }, + "last_workfile_on_startup": [ + { + "hosts": [], + "tasks": [], + "enabled": true + } + ], "sw_folders": { "compositing": [ "nuke", From 0fcfde7c0527da57a7c4c9112038edbadb0b8014 Mon Sep 17 00:00:00 2001 From: Milan Kolar Date: Thu, 3 Dec 2020 17:51:53 +0100 Subject: [PATCH 38/54] last workfile on statup from settings --- pype/hooks/global/pre_global_host_data.py | 19 ++--- .../schemas/schema_global_tools.json | 70 +++++++++---------- 2 files changed, 37 insertions(+), 52 deletions(-) diff --git a/pype/hooks/global/pre_global_host_data.py b/pype/hooks/global/pre_global_host_data.py index 3f403b43f5..09fc707e4e 100644 --- a/pype/hooks/global/pre_global_host_data.py +++ b/pype/hooks/global/pre_global_host_data.py @@ -6,7 +6,7 @@ import copy from pype.api import ( Anatomy, - config + get_project_settings ) from pype.lib import ( env_value_to_bool, @@ -284,20 +284,9 @@ class GlobalHostDataHook(PreLaunchHook): bool: True if host should start workfile. """ - default_output = env_value_to_bool( - "AVALON_OPEN_LAST_WORKFILE", default=False - ) - # TODO convert to settings - try: - startup_presets = ( - config.get_presets(project_name) - .get("tools", {}) - .get("workfiles", {}) - .get("last_workfile_on_startup") - ) - except Exception: - startup_presets = None - self.log.warning("Couldn't load pype's presets", exc_info=True) + + project_settings = get_project_settings(project_name)['global']['tools'] + startup_presets = project_settings['Workfiles']['last_workfile_on_startup'] if not startup_presets: return default_output diff --git a/pype/tools/settings/settings/gui_schemas/projects_schema/schemas/schema_global_tools.json b/pype/tools/settings/settings/gui_schemas/projects_schema/schemas/schema_global_tools.json index 5a19e4827d..529794fd28 100644 --- a/pype/tools/settings/settings/gui_schemas/projects_schema/schemas/schema_global_tools.json +++ b/pype/tools/settings/settings/gui_schemas/projects_schema/schemas/schema_global_tools.json @@ -28,45 +28,41 @@ "label": "Workfiles", "children": [ { - "type": "dict", - "collapsable": true, - "key": "last_workfile_on_startup", + "type": "collapsible-wrap", "label": "Open last workfiles on launch", - "checkbox_key": "enabled", - "is_group": true, "children": [ - { - "type": "list", - "key": "profiles", - "label": "Profiles", - "object_type": - { - "type": "dict", - "children": [ - { - "key": "hosts", - "label": "Hosts", - "type": "list", - "object_type": "text" - }, - { - "key": "tasks", - "label": "Tasks", - "type": "list", - "object_type": "text" - }, - { - "type": "splitter" - }, - { - "type": "boolean", - "key": "enabled", - "label": "Enabled" - } - ] - } - } - ] + { + "type": "list", + "key": "last_workfile_on_startup", + "label": "", + "is_group": true, + "object_type": + { + "type": "dict", + "children": [ + { + "key": "hosts", + "label": "Hosts", + "type": "list", + "object_type": "text" + }, + { + "key": "tasks", + "label": "Tasks", + "type": "list", + "object_type": "text" + }, + { + "type": "splitter" + }, + { + "type": "boolean", + "key": "enabled", + "label": "Enabled" + } + ] + } + }] }, { "type": "dict-modifiable", From 49cfd19a160c104623652fe42c751076aacaec3f Mon Sep 17 00:00:00 2001 From: Milan Kolar Date: Thu, 3 Dec 2020 17:54:40 +0100 Subject: [PATCH 39/54] convert unreal to settings --- pype/hosts/unreal/lib.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pype/hosts/unreal/lib.py b/pype/hosts/unreal/lib.py index d6bfba436e..c356193ea0 100644 --- a/pype/hosts/unreal/lib.py +++ b/pype/hosts/unreal/lib.py @@ -4,7 +4,7 @@ import platform import json from distutils import dir_util import subprocess -from pype.api import config +from pype.api import get_current_project_settings def get_engine_versions(): @@ -150,7 +150,7 @@ def create_unreal_project(project_name: str, :type dev_mode: bool :returns: None """ - preset = config.get_presets()["unreal"]["project_setup"] + preset = get_current_project_settings()["unreal"]["project_setup"] if os.path.isdir(os.environ.get("AVALON_UNREAL_PLUGIN", "")): # copy plugin to correct path under project From 379560a224ddad521ed5e3091963faa515322a3e Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Thu, 3 Dec 2020 18:04:54 +0100 Subject: [PATCH 40/54] post ftrack change is using settings --- pype/hooks/global/post_ftrack_changes.py | 29 +++++++++++++++++------- 1 file changed, 21 insertions(+), 8 deletions(-) diff --git a/pype/hooks/global/post_ftrack_changes.py b/pype/hooks/global/post_ftrack_changes.py index 144f618620..4dc45f5419 100644 --- a/pype/hooks/global/post_ftrack_changes.py +++ b/pype/hooks/global/post_ftrack_changes.py @@ -1,7 +1,7 @@ import os import ftrack_api -from pype.api import config +from pype.api import get_project_settings from pype.lib import PostLaunchHook @@ -101,10 +101,23 @@ class PostFtrackHook(PostLaunchHook): return filtered_entities[0] def ftrack_status_change(self, session, entity, project_name): - # TODO use settings - presets = config.get_presets(project_name)["ftrack"]["ftrack_config"] - statuses = presets.get("status_update") - if not statuses: + project_settings = get_project_settings(project_name) + status_update = project_settings["ftrack"]["events"]["status_update"] + if not status_update["enabled"]: + self.log.debug( + "Status changes are disabled for project \"{}\"".format( + project_name + ) + ) + return + + status_mapping = status_update["mapping"] + if not status_mapping: + self.log.warning( + "Project \"{}\" does not have set status changes.".format( + project_name + ) + ) return actual_status = entity["status"]["name"].lower() @@ -114,11 +127,11 @@ class PostFtrackHook(PostLaunchHook): ) while True: next_status_name = None - for key, value in statuses.items(): + for key, value in status_mapping.items(): if key in already_tested: continue - if actual_status in value or "_any_" in value: - if key != "_ignore_": + if actual_status in value or "__any__" in value: + if key != "__ignore__": next_status_name = key already_tested.add(key) break From 27fbe814f506de965aa1f817921deb3031f3ac29 Mon Sep 17 00:00:00 2001 From: Milan Kolar Date: Thu, 3 Dec 2020 18:12:13 +0100 Subject: [PATCH 41/54] change preset collecting to settings --- .../plugins/global/publish/collect_presets.py | 22 +++---------------- 1 file changed, 3 insertions(+), 19 deletions(-) diff --git a/pype/plugins/global/publish/collect_presets.py b/pype/plugins/global/publish/collect_presets.py index 4ffb2fc0b3..95fb4dbfad 100644 --- a/pype/plugins/global/publish/collect_presets.py +++ b/pype/plugins/global/publish/collect_presets.py @@ -8,7 +8,7 @@ Provides: """ from pyblish import api -from pype.api import config +from pype.api import get_current_project_settings class CollectPresets(api.ContextPlugin): @@ -18,23 +18,7 @@ class CollectPresets(api.ContextPlugin): label = "Collect Presets" def process(self, context): - presets = config.get_presets() - try: - # try if it is not in projects custom directory - # `{PYPE_PROJECT_CONFIGS}/[PROJECT_NAME]/init.json` - # init.json define preset names to be used - p_init = presets["init"] - presets["colorspace"] = presets["colorspace"][p_init["colorspace"]] - presets["dataflow"] = presets["dataflow"][p_init["dataflow"]] - except KeyError: - self.log.warning("No projects custom preset available...") - presets["colorspace"] = presets["colorspace"]["default"] - presets["dataflow"] = presets["dataflow"]["default"] - self.log.info( - "Presets `colorspace` and `dataflow` loaded from `default`..." - ) + project_settings = get_current_project_settings() + context.data["presets"] = project_settings - context.data["presets"] = presets - - # self.log.info(context.data["presets"]) return From c8c6902ae8f7a43cbc7d684b6d6e22064a49aa8f Mon Sep 17 00:00:00 2001 From: Milan Kolar Date: Thu, 3 Dec 2020 18:18:55 +0100 Subject: [PATCH 42/54] remove legacy preset loading --- pype/plugins/maya/publish/extract_camera_mayaScene.py | 1 + pype/scripts/otio_burnin.py | 7 ------- 2 files changed, 1 insertion(+), 7 deletions(-) diff --git a/pype/plugins/maya/publish/extract_camera_mayaScene.py b/pype/plugins/maya/publish/extract_camera_mayaScene.py index 8fce48badf..a01c5885b0 100644 --- a/pype/plugins/maya/publish/extract_camera_mayaScene.py +++ b/pype/plugins/maya/publish/extract_camera_mayaScene.py @@ -102,6 +102,7 @@ class ExtractCameraMayaScene(pype.api.Extractor): def process(self, instance): """Plugin entry point.""" # get settings + # TODO: load all settings directly, rather than passing them through context ext_mapping = instance.context.data["presets"]["maya"].get("ext_mapping") # noqa: E501 if ext_mapping: self.log.info("Looking in presets for scene type ...") diff --git a/pype/scripts/otio_burnin.py b/pype/scripts/otio_burnin.py index 0bd636c6c5..dfa94adf1f 100644 --- a/pype/scripts/otio_burnin.py +++ b/pype/scripts/otio_burnin.py @@ -428,13 +428,6 @@ def burnins_from_data( } """ - # Use legacy processing when options are not set - # TODO: remove legacy review - if options is None or burnin_values is None: - presets = config.get_presets().get("tools", {}).get("burnins", {}) - options = presets.get("options") - burnin_values = presets.get("burnins") or {} - burnin = ModifiedBurnins(input_path, options_init=options) frame_start = data.get("frame_start") From d513d47695fb53947c5c8d3d741661cc412197be Mon Sep 17 00:00:00 2001 From: Milan Kolar Date: Thu, 3 Dec 2020 18:27:58 +0100 Subject: [PATCH 43/54] remove slate presets --- pype/scripts/slates/slate_base/lib.py | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/pype/scripts/slates/slate_base/lib.py b/pype/scripts/slates/slate_base/lib.py index 6b0c01883c..ec283e0e22 100644 --- a/pype/scripts/slates/slate_base/lib.py +++ b/pype/scripts/slates/slate_base/lib.py @@ -12,11 +12,6 @@ from .items import ( ItemTable, ItemImage, ItemRectangle, ItemPlaceHolder ) -try: - from pype.api.config import get_presets -except Exception: - get_presets = dict - log = logging.getLogger(__name__) @@ -41,11 +36,7 @@ def create_slates( ) elif slate_data is None: - slate_presets = ( - get_presets() - .get("tools", {}) - .get("slates") - ) or {} + slate_presets = {} slate_data = slate_presets.get(slate_name) if slate_data is None: raise ValueError( From 44df16bf681d21efcb6ad2081eaac7a9045e8a9b Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Thu, 3 Dec 2020 18:30:10 +0100 Subject: [PATCH 44/54] add short task names to anatomy attributes --- .../defaults/project_anatomy/attributes.json | 18 +++++++++++++++++- .../schemas/schema_anatomy_attributes.json | 6 ++++++ 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/pype/settings/defaults/project_anatomy/attributes.json b/pype/settings/defaults/project_anatomy/attributes.json index fbf0218999..8f35e41533 100644 --- a/pype/settings/defaults/project_anatomy/attributes.json +++ b/pype/settings/defaults/project_anatomy/attributes.json @@ -9,5 +9,21 @@ "resolutionWidth": 1920, "resolutionHeight": 1080, "pixelAspect": 1, - "applications": [] + "applications": [], + "task_short_names": { + "Generic": "gener", + "Art": "art", + "Modeling": "mdl", + "Texture": "tex", + "Lookdev": "look", + "Rigging": "rig", + "Edit": "edit", + "Layout": "lay", + "Setdress": "dress", + "Animation": "anim", + "FX": "fx", + "Lighting": "lgt", + "Paint": "paint", + "Compositing": "comp" + } } \ No newline at end of file diff --git a/pype/tools/settings/settings/gui_schemas/projects_schema/schemas/schema_anatomy_attributes.json b/pype/tools/settings/settings/gui_schemas/projects_schema/schemas/schema_anatomy_attributes.json index 1ede46903c..a64b99ce9d 100644 --- a/pype/tools/settings/settings/gui_schemas/projects_schema/schemas/schema_anatomy_attributes.json +++ b/pype/tools/settings/settings/gui_schemas/projects_schema/schemas/schema_anatomy_attributes.json @@ -68,6 +68,12 @@ {"blender_2.91": "Blender 2.91"}, {"aftereffects_2021": "After Effects 2021"} ] + }, + { + "type": "dict-modifiable", + "key": "task_short_names", + "label": "Task short names (by Task type)", + "object_type": "text" } ] } From f25ba30bffa4da3a65138119d395d6085ff363de Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Thu, 3 Dec 2020 18:30:18 +0100 Subject: [PATCH 45/54] fix unreal settings --- pype/hosts/unreal/lib.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pype/hosts/unreal/lib.py b/pype/hosts/unreal/lib.py index c356193ea0..02b1ae5bf5 100644 --- a/pype/hosts/unreal/lib.py +++ b/pype/hosts/unreal/lib.py @@ -4,7 +4,7 @@ import platform import json from distutils import dir_util import subprocess -from pype.api import get_current_project_settings +from pype.api import get_project_settings def get_engine_versions(): @@ -150,7 +150,7 @@ def create_unreal_project(project_name: str, :type dev_mode: bool :returns: None """ - preset = get_current_project_settings()["unreal"]["project_setup"] + preset = get_project_settings(project_name)["unreal"]["project_setup"] if os.path.isdir(os.environ.get("AVALON_UNREAL_PLUGIN", "")): # copy plugin to correct path under project From 7889b2a360116be4218366395219bee39ea41fe5 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Thu, 3 Dec 2020 18:46:09 +0100 Subject: [PATCH 46/54] don't use get_presets in avalon_sync --- pype/modules/ftrack/lib/avalon_sync.py | 42 +++++++++----------------- 1 file changed, 14 insertions(+), 28 deletions(-) diff --git a/pype/modules/ftrack/lib/avalon_sync.py b/pype/modules/ftrack/lib/avalon_sync.py index a379aa9900..0716a5975f 100644 --- a/pype/modules/ftrack/lib/avalon_sync.py +++ b/pype/modules/ftrack/lib/avalon_sync.py @@ -8,13 +8,12 @@ import copy from avalon.api import AvalonMongoDB import avalon -from pype.api import Logger, Anatomy +from pype.api import Logger, Anatomy, get_anatomy_data from bson.objectid import ObjectId from bson.errors import InvalidId from pymongo import UpdateOne import ftrack_api -from pype.api import config from pype.lib import ApplicationManager log = Logger().get_logger(__name__) @@ -276,28 +275,6 @@ def get_hierarchical_attributes(session, entity, attr_names, attr_defaults={}): return hier_values -def get_task_short_name(task_type): - """ - Returns short name (code) for 'task_type'. Short name stored in - metadata dictionary in project.config per each 'task_type'. - Could be used in anatomy, paths etc. - If no appropriate short name is found in mapping, 'task_type' is - returned back unchanged. - - Currently stores data in: - 'pype-config/presets/ftrack/project_defaults.json' - Args: - task_type: (string) - Animation | Modeling ... - - Returns: - (string) - anim | model ... - """ - presets = config.get_presets()['ftrack']['project_defaults']\ - .get("task_short_names") - - return presets.get(task_type, task_type) - - class SyncEntitiesFactory: dbcon = AvalonMongoDB() @@ -1118,6 +1095,13 @@ class SyncEntitiesFactory: ) def prepare_ftrack_ent_data(self): + project_name = self.entities_dict[self.ft_project_id]["name"] + project_anatomy_data = get_anatomy_data(project_name) + + task_type_mapping = ( + project_anatomy_data["attributes"]["task_short_names"] + ) + not_set_ids = [] for id, entity_dict in self.entities_dict.items(): entity = entity_dict["entity"] @@ -1154,10 +1138,12 @@ class SyncEntitiesFactory: continue self.report_items["warning"][msg] = items tasks = {} - for tt in task_types: - tasks[tt["name"]] = { - "short_name": get_task_short_name(tt["name"]) - } + for task_type in task_types: + task_type_name = task_type["name"] + short_name = task_type_mapping.get(task_type_name) + tasks[task_type_name] = { + "short_name": short_name or task_type_name + } self.entities_dict[id]["final_entity"]["config"] = { "tasks": tasks, "apps": proj_apps From cdf7b820e92756ecd050051338424802e4e1b46e Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Thu, 3 Dec 2020 18:58:40 +0100 Subject: [PATCH 47/54] pype tray modified to use settings --- pype/tools/tray/pype_tray.py | 38 +++++++++++++----------------------- 1 file changed, 14 insertions(+), 24 deletions(-) diff --git a/pype/tools/tray/pype_tray.py b/pype/tools/tray/pype_tray.py index a4cf4eabfe..81a628fdb5 100644 --- a/pype/tools/tray/pype_tray.py +++ b/pype/tools/tray/pype_tray.py @@ -3,7 +3,8 @@ import sys import platform from avalon import style from Qt import QtCore, QtGui, QtWidgets, QtSvg -from pype.api import config, Logger, resources +from pype.api import Logger, resources +from pype.settings.lib import get_system_settings, load_json_file import pype.version try: import configparser @@ -31,18 +32,11 @@ class TrayManager: self.errors = [] CURRENT_DIR = os.path.dirname(__file__) - self.modules_imports = config.load_json( + self.modules_imports = load_json_file( os.path.join(CURRENT_DIR, "modules_imports.json") ) - presets = config.get_presets(first_run=True) - menu_items = presets["tray"]["menu_items"] - try: - self.modules_usage = menu_items["item_usage"] - except Exception: - self.modules_usage = {} - self.log.critical("Couldn't find modules usage data.") - - self.module_attributes = menu_items.get("attributes") or {} + module_settings = get_system_settings()["modules"] + self.module_settings = module_settings self.icon_run = QtGui.QIcon( resources.get_resource("icons", "circle_green.png") @@ -75,23 +69,19 @@ class TrayManager: import_path = item.get("import_path") title = item.get("title") - item_usage = self.modules_usage.get(title) - if item_usage is None: - item_usage = self.modules_usage.get(import_path, True) - - if not item_usage: + module_data = self.module_settings.get(title) + if not module_data: if not title: title = import_path - self.log.info("{} - Module ignored".format(title)) + self.log.warning("{} - Module data not found".format(title)) continue - _attributes = self.module_attributes.get(title) - if _attributes is None: - _attributes = self.module_attributes.get(import_path) - - if _attributes: - item["attributes"] = _attributes + enabled = module_data.pop("enabled", True) + if not enabled: + self.log.debug("{} - Module is disabled".format(title)) + continue + item["attributes"] = module_data items.append(item) if items: @@ -207,7 +197,7 @@ class TrayManager: ) klass = getattr(module, "CLASS_DEFINIION", None) if not klass and attributes: - self.log.error(( + self.log.debug(( "There are defined attributes for module \"{}\" but" "module does not have defined \"CLASS_DEFINIION\"." ).format(import_path)) From 57b1cc7cd171c2f57c9c7bd9769e36857db727f1 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Thu, 3 Dec 2020 19:00:33 +0100 Subject: [PATCH 48/54] turn of clockify by default --- pype/settings/defaults/system_settings/modules.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pype/settings/defaults/system_settings/modules.json b/pype/settings/defaults/system_settings/modules.json index 4a91d2dddf..a36a3b75cf 100644 --- a/pype/settings/defaults/system_settings/modules.json +++ b/pype/settings/defaults/system_settings/modules.json @@ -166,7 +166,7 @@ "message_time": 0.5 }, "Clockify": { - "enabled": true, + "enabled": false, "workspace_name": "studio name" }, "Deadline": { From 31a2c70b26c7cce67806334c35352e3bb2ccf0d4 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Thu, 3 Dec 2020 19:29:13 +0100 Subject: [PATCH 49/54] implemented `clear_metadata_from_settings` to remove metadata from loaded settings --- pype/settings/lib.py | 61 ++++++++++++++++++++++++++++++++++---------- 1 file changed, 47 insertions(+), 14 deletions(-) diff --git a/pype/settings/lib.py b/pype/settings/lib.py index 33a427c3a6..1189b1ab2a 100644 --- a/pype/settings/lib.py +++ b/pype/settings/lib.py @@ -17,6 +17,13 @@ M_DYNAMIC_KEY_LABEL = "__dynamic_keys_labels__" # NOTE key popping not implemented yet M_POP_KEY = "__pop_key__" +METADATA_KEYS = ( + M_OVERRIDEN_KEY, + M_ENVIRONMENT_KEY, + M_DYNAMIC_KEY_LABEL, + M_POP_KEY +) + # Folder where studio overrides are stored STUDIO_OVERRIDES_PATH = os.getenv("PYPE_PROJECT_CONFIGS") or "" @@ -413,30 +420,37 @@ def apply_overrides(source_data, override_data): return merge_overrides(_source_data, override_data) -def get_system_settings(): +def get_system_settings(clear_metadata=True): """System settings with applied studio overrides.""" default_values = get_default_settings()[SYSTEM_SETTINGS_KEY] studio_values = get_studio_system_settings_overrides() - return apply_overrides(default_values, studio_values) + result = apply_overrides(default_values, studio_values) + if clear_metadata: + clear_metadata_from_settings(result) + return result -def get_default_project_settings(): +def get_default_project_settings(clear_metadata=True): """Project settings with applied studio's default project overrides.""" default_values = get_default_settings()[PROJECT_SETTINGS_KEY] studio_values = get_studio_project_settings_overrides() - - return apply_overrides(default_values, studio_values) + result = apply_overrides(default_values, studio_values) + if clear_metadata: + clear_metadata_from_settings(result) + return result -def get_default_project_anatomy_data(): +def get_default_project_anatomy_data(clear_metadata=True): """Project anatomy data with applied studio's default project overrides.""" default_values = get_default_settings()[PROJECT_ANATOMY_KEY] studio_values = get_studio_project_anatomy_overrides() - - return apply_overrides(default_values, studio_values) + result = apply_overrides(default_values, studio_values) + if clear_metadata: + clear_metadata_from_settings(result) + return result -def get_anatomy_data(project_name): +def get_anatomy_data(project_name, clear_metadata=True): """Project anatomy data with applied studio and project overrides.""" if not project_name: raise ValueError( @@ -444,13 +458,16 @@ def get_anatomy_data(project_name): " Call `get_default_project_anatomy_data` to get project defaults." ) - studio_overrides = get_default_project_anatomy_data() + studio_overrides = get_default_project_anatomy_data(False) project_overrides = get_project_anatomy_overrides(project_name) - return apply_overrides(studio_overrides, project_overrides) + result = apply_overrides(studio_overrides, project_overrides) + if clear_metadata: + clear_metadata_from_settings(result) + return result -def get_project_settings(project_name): +def get_project_settings(project_name, clear_metadata=True): """Project settings with applied studio and project overrides.""" if not project_name: raise ValueError( @@ -458,10 +475,13 @@ def get_project_settings(project_name): " Call `get_default_project_settings` to get project defaults." ) - studio_overrides = get_default_project_settings() + studio_overrides = get_default_project_settings(False) project_overrides = get_project_settings_overrides(project_name) - return apply_overrides(studio_overrides, project_overrides) + result = apply_overrides(studio_overrides, project_overrides) + if clear_metadata: + clear_metadata_from_settings(result) + return result def get_current_project_settings(): @@ -491,3 +511,16 @@ def get_environments(): """ return find_environments(get_system_settings()) + + +def clear_metadata_from_settings(values): + """Remove all metadata keys from loaded settings.""" + if isinstance(values, dict): + for key in tuple(values.keys()): + if key in METADATA_KEYS: + values.pop(key) + else: + clear_metadata_from_settings(values[key]) + elif isinstance(values, list): + for item in values: + clear_metadata_from_settings(item) From c8e0a2e414b013ab9940ff6e033ce6aa61609be2 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Thu, 3 Dec 2020 19:30:58 +0100 Subject: [PATCH 50/54] removed as syntax --- pype/modules/ftrack/actions/action_create_project_structure.py | 2 +- pype/modules/ftrack/events/event_user_assigment.py | 2 +- pype/modules/ftrack/events/event_version_to_task_statuses.py | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/pype/modules/ftrack/actions/action_create_project_structure.py b/pype/modules/ftrack/actions/action_create_project_structure.py index 4fc59da89e..1f7dfcec0b 100644 --- a/pype/modules/ftrack/actions/action_create_project_structure.py +++ b/pype/modules/ftrack/actions/action_create_project_structure.py @@ -2,7 +2,7 @@ import os import re from pype.modules.ftrack.lib import BaseAction, statics_icon -from pype.api import Anatomy, get_project_settings as get_project_settings +from pype.api import Anatomy, get_project_settings class CreateProjectFolders(BaseAction): diff --git a/pype/modules/ftrack/events/event_user_assigment.py b/pype/modules/ftrack/events/event_user_assigment.py index 6a230f6ff9..f65c2334b0 100644 --- a/pype/modules/ftrack/events/event_user_assigment.py +++ b/pype/modules/ftrack/events/event_user_assigment.py @@ -8,7 +8,7 @@ from avalon.api import AvalonMongoDB from bson.objectid import ObjectId -from pype.api import Anatomy, get_project_settings as get_project_settings +from pype.api import Anatomy, get_project_settings class UserAssigmentEvent(BaseEvent): diff --git a/pype/modules/ftrack/events/event_version_to_task_statuses.py b/pype/modules/ftrack/events/event_version_to_task_statuses.py index ca55f24f32..39384e996e 100644 --- a/pype/modules/ftrack/events/event_version_to_task_statuses.py +++ b/pype/modules/ftrack/events/event_version_to_task_statuses.py @@ -1,5 +1,5 @@ from pype.modules.ftrack import BaseEvent -from pype.api import get_project_settings as get_project_settings +from pype.api import get_project_settings class VersionToTaskStatus(BaseEvent): From d8b94cca5cd4c15f9aa8b297858835a63bf53f6b Mon Sep 17 00:00:00 2001 From: Milan Kolar Date: Thu, 3 Dec 2020 20:45:32 +0100 Subject: [PATCH 51/54] remove unused config imports --- pype/lib/plugin_tools.py | 2 +- pype/scripts/otio_burnin.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pype/lib/plugin_tools.py b/pype/lib/plugin_tools.py index 726726bb4c..a78c9e525e 100644 --- a/pype/lib/plugin_tools.py +++ b/pype/lib/plugin_tools.py @@ -4,7 +4,7 @@ import os import inspect import logging -from ..api import config, get_project_settings +from ..api import get_project_settings log = logging.getLogger(__name__) diff --git a/pype/scripts/otio_burnin.py b/pype/scripts/otio_burnin.py index dfa94adf1f..4f5c290e9d 100644 --- a/pype/scripts/otio_burnin.py +++ b/pype/scripts/otio_burnin.py @@ -5,7 +5,7 @@ import subprocess import platform import json import opentimelineio_contrib.adapters.ffmpeg_burnins as ffmpeg_burnins -from pype.api import config, resources +from pype.api import resources import pype.lib From 01c1ae89117f91fbea86bb29b537855b69bc65db Mon Sep 17 00:00:00 2001 From: Milan Kolar Date: Thu, 3 Dec 2020 20:45:58 +0100 Subject: [PATCH 52/54] asset creator tool uses settings (hidden for now) --- .../ftrack/project_schemas/default.json | 39 +++++++++++++++++++ pype/tools/assetcreator/app.py | 4 +- 2 files changed, 41 insertions(+), 2 deletions(-) create mode 100644 pype/settings/defaults/project_settings/ftrack/project_schemas/default.json diff --git a/pype/settings/defaults/project_settings/ftrack/project_schemas/default.json b/pype/settings/defaults/project_settings/ftrack/project_schemas/default.json new file mode 100644 index 0000000000..a90a0b3a8b --- /dev/null +++ b/pype/settings/defaults/project_settings/ftrack/project_schemas/default.json @@ -0,0 +1,39 @@ +{ + "object_types": ["Milestone", "Task", "Folder", "Asset Build", "Shot", "Library", "Sequence"], + "version_workflow": ["Pending Review", "Client Review", "On Farm", "Reviewed", "Render Complete", "Approved", "CBB", "Delivered", "Render Failed", "data"], + "task_workflow": ["Not Ready", "Ready", "Change Requested", "In progress", "Pending Review", "On Farm", "Waiting", "Render Complete", "Complete", "CBB", "On Hold", "Render Failed", "Omitted"], + "overrides": [{ + "task_types": ["Animation"], + "statuses": ["Not Ready", "Ready", "Change Requested", "Blocking", "Animating", "blocking review", "anim review", "Complete", "CBB", "On Hold", "Omitted"] + }, { + "task_types": ["Lighting"], + "statuses": ["Not Ready", "Ready", "Change Requested", "In progress", "To render", "On Farm", "Render Complete", "Complete", "CBB", "On Hold", "Render Failed", "Omitted"] + }], + "task_type_schema": ["Layout", "Animation", "Modeling", "Previz", "Lookdev", "FX", "Lighting", "Compositing", "Rigging", "Texture", "Matte-paint", "Roto-paint", "Art", "Match-moving", "Production", "Build", "Setdress", "Edit", "R&D", "Boards"], + "schemas": [{ + "object_type": "Shot", + "statuses": ["Omitted", "Normal", "Complete"], + "task_types": [] + }, { + "object_type": "Asset Build", + "statuses": ["Omitted", "Normal", "Complete"], + "task_types": ["Setups", "Sets", "Characters", "Props", "Locations", "Assembly", "R&D", "Elements"] + }, { + "object_type": "Milestone", + "statuses": ["Normal", "Complete"], + "task_types": ["Generic"] + }], + "task_templates": [{ + "name": "Character", + "task_types": ["Art", "Modeling", "Lookdev", "Rigging"] + }, { + "name": "Element", + "task_types": ["Modeling", "Lookdev"] + }, { + "name": "Prop", + "task_types": ["Modeling", "Lookdev", "Rigging"] + }, { + "name": "Location", + "task_types": ["Layout", "Setdress"] + }] +} \ No newline at end of file diff --git a/pype/tools/assetcreator/app.py b/pype/tools/assetcreator/app.py index 71b1027ef4..f025af9662 100644 --- a/pype/tools/assetcreator/app.py +++ b/pype/tools/assetcreator/app.py @@ -6,7 +6,7 @@ try: import ftrack_api_old as ftrack_api except Exception: import ftrack_api -from pype.api import config +from pype.api import get_current_project_settings from pype import lib as pypelib from avalon.vendor.Qt import QtWidgets, QtCore from avalon import io, api, style, schema @@ -196,7 +196,7 @@ class Window(QtWidgets.QDialog): ft_project = session.query(project_query).one() schema_name = ft_project['project_schema']['name'] # Load config - schemas_items = config.get_presets().get('ftrack', {}).get( + schemas_items = get_current_project_settings().get('ftrack', {}).get( 'project_schemas', {} ) # Get info if it is silo project From f668db28524e74aea87f7a7b5f1b3450e2d71103 Mon Sep 17 00:00:00 2001 From: Milan Kolar Date: Thu, 3 Dec 2020 20:46:20 +0100 Subject: [PATCH 53/54] remove slate example --- .../tools/slates/example_HD.json | 212 ------------------ 1 file changed, 212 deletions(-) delete mode 100644 pype/settings/defaults/project_settings/tools/slates/example_HD.json diff --git a/pype/settings/defaults/project_settings/tools/slates/example_HD.json b/pype/settings/defaults/project_settings/tools/slates/example_HD.json deleted file mode 100644 index b06391fb63..0000000000 --- a/pype/settings/defaults/project_settings/tools/slates/example_HD.json +++ /dev/null @@ -1,212 +0,0 @@ -{ - "width": 1920, - "height": 1080, - "destination_path": "{destination_path}", - "style": { - "*": { - "font-family": "arial", - "font-color": "#ffffff", - "font-bold": false, - "font-italic": false, - "bg-color": "#0077ff", - "alignment-horizontal": "left", - "alignment-vertical": "top" - }, - "layer": { - "padding": 0, - "margin": 0 - }, - "rectangle": { - "padding": 0, - "margin": 0, - "bg-color": "#E9324B", - "fill": true - }, - "main_frame": { - "padding": 0, - "margin": 0, - "bg-color": "#252525" - }, - "table": { - "padding": 0, - "margin": 0, - "bg-color": "transparent" - }, - "table-item": { - "padding": 5, - "padding-bottom": 10, - "margin": 0, - "bg-color": "#212121", - "bg-alter-color": "#272727", - "font-color": "#dcdcdc", - "font-bold": false, - "font-italic": false, - "alignment-horizontal": "left", - "alignment-vertical": "top", - "word-wrap": false, - "ellide": true, - "max-lines": 1 - }, - "table-item-col[0]": { - "font-size": 20, - "font-color": "#898989", - "font-bold": true, - "ellide": false, - "word-wrap": true, - "max-lines": null - }, - "table-item-col[1]": { - "font-size": 40, - "padding-left": 10 - }, - "#colorbar": { - "bg-color": "#9932CC" - } - }, - "items": [{ - "type": "layer", - "direction": 1, - "name": "MainLayer", - "style": { - "#MainLayer": { - "width": 1094, - "height": 1000, - "margin": 25, - "padding": 0 - }, - "#LeftSide": { - "margin-right": 25 - } - }, - "items": [{ - "type": "layer", - "name": "LeftSide", - "items": [{ - "type": "layer", - "direction": 1, - "style": { - "table-item": { - "bg-color": "transparent", - "padding-bottom": 20 - }, - "table-item-col[0]": { - "font-size": 20, - "font-color": "#898989", - "alignment-horizontal": "right" - }, - "table-item-col[1]": { - "alignment-horizontal": "left", - "font-bold": true, - "font-size": 40 - } - }, - "items": [{ - "type": "table", - "values": [ - ["Show:", "{project[name]}"] - ], - "style": { - "table-item-field[0:0]": { - "width": 150 - }, - "table-item-field[0:1]": { - "width": 580 - } - } - }, { - "type": "table", - "values": [ - ["Submitting For:", "{intent}"] - ], - "style": { - "table-item-field[0:0]": { - "width": 160 - }, - "table-item-field[0:1]": { - "width": 218, - "alignment-horizontal": "right" - } - } - }] - }, { - "type": "rectangle", - "style": { - "bg-color": "#bc1015", - "width": 1108, - "height": 5, - "fill": true - } - }, { - "type": "table", - "use_alternate_color": true, - "values": [ - ["Version name:", "{version_name}"], - ["Date:", "{date}"], - ["Shot Types:", "{shot_type}"], - ["Submission Note:", "{submission_note}"] - ], - "style": { - "table-item": { - "padding-bottom": 20 - }, - "table-item-field[0:1]": { - "font-bold": true - }, - "table-item-field[3:0]": { - "word-wrap": true, - "ellide": true, - "max-lines": 4 - }, - "table-item-col[0]": { - "alignment-horizontal": "right", - "width": 150 - }, - "table-item-col[1]": { - "alignment-horizontal": "left", - "width": 958 - } - } - }] - }, { - "type": "layer", - "name": "RightSide", - "items": [{ - "type": "placeholder", - "name": "thumbnail", - "path": "{thumbnail_path}", - "style": { - "width": 730, - "height": 412 - } - }, { - "type": "placeholder", - "name": "colorbar", - "path": "{color_bar_path}", - "return_data": true, - "style": { - "width": 730, - "height": 55 - } - }, { - "type": "table", - "use_alternate_color": true, - "values": [ - ["Vendor:", "{vendor}"], - ["Shot Name:", "{shot_name}"], - ["Frames:", "{frame_start} - {frame_end} ({duration})"] - ], - "style": { - "table-item-col[0]": { - "alignment-horizontal": "left", - "width": 200 - }, - "table-item-col[1]": { - "alignment-horizontal": "right", - "width": 530, - "font-size": 30 - } - } - }] - }] - }] -} From 363b70233d50617ad83aeccab1d4e2d7b70121f7 Mon Sep 17 00:00:00 2001 From: Milan Kolar Date: Thu, 3 Dec 2020 21:48:27 +0100 Subject: [PATCH 54/54] deal with hound --- pype/__init__.py | 7 +++++-- pype/hooks/global/pre_global_host_data.py | 6 ++++-- pype/hosts/harmony/__init__.py | 16 ++++++++++++---- .../actions/action_create_project_structure.py | 4 ++-- .../ftrack/events/event_user_assigment.py | 4 ++-- .../events/event_version_to_task_statuses.py | 5 ++--- .../maya/publish/extract_camera_mayaScene.py | 4 ++-- pype/plugins/maya/publish/submit_maya_muster.py | 3 ++- setup/maya/userSetup.py | 3 ++- 9 files changed, 33 insertions(+), 19 deletions(-) diff --git a/pype/__init__.py b/pype/__init__.py index 8481fa2d48..a2840e271b 100644 --- a/pype/__init__.py +++ b/pype/__init__.py @@ -48,9 +48,12 @@ def patched_discover(superclass): elif superclass.__name__.split(".")[-1] == "Creator": plugin_type = "create" - print(">>> trying to find presets for {}:{} ...".format(host, plugin_type)) + print(">>> Finding presets for {}:{} ...".format(host, plugin_type)) try: - settings = get_project_settings(os.environ['AVALON_PROJECT'])[host][plugin_type] + settings = ( + get_project_settings(os.environ['AVALON_PROJECT']) + [host][plugin_type] + ) except KeyError: print("*** no presets found.") else: diff --git a/pype/hooks/global/pre_global_host_data.py b/pype/hooks/global/pre_global_host_data.py index 09fc707e4e..4910d08010 100644 --- a/pype/hooks/global/pre_global_host_data.py +++ b/pype/hooks/global/pre_global_host_data.py @@ -285,8 +285,10 @@ class GlobalHostDataHook(PreLaunchHook): """ - project_settings = get_project_settings(project_name)['global']['tools'] - startup_presets = project_settings['Workfiles']['last_workfile_on_startup'] + project_settings = ( + get_project_settings(project_name)['global']['tools']) + startup_presets = ( + project_settings['Workfiles']['last_workfile_on_startup']) if not startup_presets: return default_output diff --git a/pype/hosts/harmony/__init__.py b/pype/hosts/harmony/__init__.py index bc91b4db2f..b91c0ad4b1 100644 --- a/pype/hosts/harmony/__init__.py +++ b/pype/hosts/harmony/__init__.py @@ -50,10 +50,18 @@ def get_asset_settings(): } try: - skip_resolution_check = \ - get_current_project_settings()["harmony"]["general"]["skip_resolution_check"] - skip_timelines_check = \ - get_current_project_settings()["harmony"]["general"]["skip_timelines_check"] + skip_resolution_check = ( + get_current_project_settings() + ["harmony"] + ["general"] + ["skip_resolution_check"] + ) + skip_timelines_check = ( + get_current_project_settings() + ["harmony"] + ["general"] + ["skip_timelines_check"] + ) except KeyError: skip_resolution_check = [] skip_timelines_check = [] diff --git a/pype/modules/ftrack/actions/action_create_project_structure.py b/pype/modules/ftrack/actions/action_create_project_structure.py index 1f7dfcec0b..0815f82a69 100644 --- a/pype/modules/ftrack/actions/action_create_project_structure.py +++ b/pype/modules/ftrack/actions/action_create_project_structure.py @@ -73,9 +73,9 @@ class CreateProjectFolders(BaseAction): project_entity = self.get_project_from_entity(entities[0]) # Load settings for project project_name = project_entity["full_name"] - get_project_settings = get_project_settings(project_name) + project_settings = get_project_settings(project_name) project_folder_structure = ( - get_project_settings["global"]["project_folder_structure"] + project_settings["global"]["project_folder_structure"] ) if not project_folder_structure: return { diff --git a/pype/modules/ftrack/events/event_user_assigment.py b/pype/modules/ftrack/events/event_user_assigment.py index f65c2334b0..9b0dfe84d1 100644 --- a/pype/modules/ftrack/events/event_user_assigment.py +++ b/pype/modules/ftrack/events/event_user_assigment.py @@ -200,9 +200,9 @@ class UserAssigmentEvent(BaseEvent): project_name = task_entity["project"]["full_name"] project_data = tmp_by_project_name.get(project_name) or {} if "scripts_by_action" not in project_data: - get_project_settings = get_project_settings(project_name) + project_settings = get_project_settings(project_name) _settings = ( - get_project_settings["ftrack"]["events"]["user_assignment"] + project_settings["ftrack"]["events"]["user_assignment"] ) project_data["scripts_by_action"] = _settings.get("scripts") tmp_by_project_name[project_name] = project_data diff --git a/pype/modules/ftrack/events/event_version_to_task_statuses.py b/pype/modules/ftrack/events/event_version_to_task_statuses.py index 39384e996e..0ea72be1cb 100644 --- a/pype/modules/ftrack/events/event_version_to_task_statuses.py +++ b/pype/modules/ftrack/events/event_version_to_task_statuses.py @@ -52,12 +52,11 @@ class VersionToTaskStatus(BaseEvent): project_entity = self.get_project_from_entity(task) project_name = project_entity["full_name"] - get_project_settings = get_project_settings(project_name) + project_settings = get_project_settings(project_name) # Load status mapping from presets status_mapping = ( - get_project_settings["ftrack"]["event"]["status_version_to_task"] - ) + project_settings["ftrack"]["events"]["status_version_to_task"]) # Skip if mapping is empty if not status_mapping: continue diff --git a/pype/plugins/maya/publish/extract_camera_mayaScene.py b/pype/plugins/maya/publish/extract_camera_mayaScene.py index a01c5885b0..0443357ba9 100644 --- a/pype/plugins/maya/publish/extract_camera_mayaScene.py +++ b/pype/plugins/maya/publish/extract_camera_mayaScene.py @@ -102,8 +102,8 @@ class ExtractCameraMayaScene(pype.api.Extractor): def process(self, instance): """Plugin entry point.""" # get settings - # TODO: load all settings directly, rather than passing them through context - ext_mapping = instance.context.data["presets"]["maya"].get("ext_mapping") # noqa: E501 + ext_mapping = (instance.context.data["presets"]["maya"] + .get("ext_mapping")) # noqa: E501 if ext_mapping: self.log.info("Looking in presets for scene type ...") # use extension mapping for first family found diff --git a/pype/plugins/maya/publish/submit_maya_muster.py b/pype/plugins/maya/publish/submit_maya_muster.py index 65889bf068..9c67b45721 100644 --- a/pype/plugins/maya/publish/submit_maya_muster.py +++ b/pype/plugins/maya/publish/submit_maya_muster.py @@ -27,7 +27,8 @@ def _get_template_id(renderer): templates = get_system_settings()["modules"]["Muster"]["templates_mapping"] if not templates: - raise RuntimeError(("Muster template mapping missing in pype-settings")) + raise RuntimeError(("Muster template mapping missing in " + "pype-settings")) try: template_id = templates[renderer] except KeyError: diff --git a/setup/maya/userSetup.py b/setup/maya/userSetup.py index e401580bd8..6ee008c5fc 100644 --- a/setup/maya/userSetup.py +++ b/setup/maya/userSetup.py @@ -14,7 +14,8 @@ shelf_preset = settings['maya'].get('project_shelf') if shelf_preset: project = os.environ["AVALON_PROJECT"] - icon_path = os.path.join(os.environ['PYPE_PROJECT_SCRIPTS'], project, "icons") + icon_path = os.path.join(os.environ['PYPE_PROJECT_SCRIPTS'], + project, "icons") icon_path = os.path.abspath(icon_path) for i in shelf_preset['imports']: