From 7c705eded6c715d478dfccbc796c107fdeb0fa9b Mon Sep 17 00:00:00 2001 From: "clement.hector" Date: Tue, 9 May 2023 15:53:38 +0200 Subject: [PATCH 001/185] add open template for maya --- openpype/hosts/maya/api/menu.py | 30 ++++++++++------ .../maya/api/workfile_template_builder.py | 34 +++++++++++++++++++ 2 files changed, 54 insertions(+), 10 deletions(-) diff --git a/openpype/hosts/maya/api/menu.py b/openpype/hosts/maya/api/menu.py index 5284c0249d..91d5b06f80 100644 --- a/openpype/hosts/maya/api/menu.py +++ b/openpype/hosts/maya/api/menu.py @@ -19,6 +19,7 @@ from .workfile_template_builder import ( update_placeholder, build_workfile_template, update_workfile_template, + open_template, ) log = logging.getLogger(__name__) @@ -158,16 +159,6 @@ def install(): tearOff=True, parent=MENU_NAME ) - cmds.menuItem( - "Create Placeholder", - parent=builder_menu, - command=create_placeholder - ) - cmds.menuItem( - "Update Placeholder", - parent=builder_menu, - command=update_placeholder - ) cmds.menuItem( "Build Workfile from template", parent=builder_menu, @@ -178,6 +169,25 @@ def install(): parent=builder_menu, command=update_workfile_template ) + cmds.menuItem( + divider=True, + parent=builder_menu + ) + cmds.menuItem( + "Open Template", + parent=builder_menu, + command=open_template, + ) + cmds.menuItem( + "Create Placeholder", + parent=builder_menu, + command=create_placeholder + ) + cmds.menuItem( + "Update Placeholder", + parent=builder_menu, + command=update_placeholder + ) cmds.setParent(MENU_NAME, menu=True) diff --git a/openpype/hosts/maya/api/workfile_template_builder.py b/openpype/hosts/maya/api/workfile_template_builder.py index d65e4c74d2..3342a86b70 100644 --- a/openpype/hosts/maya/api/workfile_template_builder.py +++ b/openpype/hosts/maya/api/workfile_template_builder.py @@ -1,4 +1,5 @@ import json +import os from maya import cmds @@ -24,6 +25,36 @@ class MayaTemplateBuilder(AbstractTemplateBuilder): use_legacy_creators = True + def open_template(self): + """Open template in current scene. + """ + template_preset = self.get_template_preset() + template_path = template_preset["path"] + + if not os.path.exists(template_path): + cmds.confirmDialog( + title="Warning", + message="Template doesn't exist: {}".format(template_path), + button=["OK"], + defaultButton="OK", + ) + return + + result = cmds.confirmDialog( + title="Warning", + message="Opening a template will clear the current scene.", + button=["OK", "Cancel"], + defaultButton="OK", + cancelButton="Cancel", + dismissString="Cancel", + ) + + if result != "OK": + return + + print("opening template {}".format(template_path)) + cmds.file(template_path, open=True, force=True) + def import_template(self, path): """Import template into current scene. Block if a template is already loaded. @@ -298,6 +329,9 @@ def update_workfile_template(*args): builder = MayaTemplateBuilder(registered_host()) builder.rebuild_template() +def open_template(*args): + builder = MayaTemplateBuilder(registered_host()) + builder.open_template() def create_placeholder(*args): host = registered_host() From 24f6cfca306033041da8c8c1c9bb79c4922335d4 Mon Sep 17 00:00:00 2001 From: "clement.hector" Date: Tue, 9 May 2023 15:54:40 +0200 Subject: [PATCH 002/185] add abstracmethod --- .../pipeline/workfile/workfile_template_builder.py | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/openpype/pipeline/workfile/workfile_template_builder.py b/openpype/pipeline/workfile/workfile_template_builder.py index a3d7340367..d234866b00 100644 --- a/openpype/pipeline/workfile/workfile_template_builder.py +++ b/openpype/pipeline/workfile/workfile_template_builder.py @@ -533,6 +533,17 @@ class AbstractTemplateBuilder(object): self.clear_shared_populate_data() + @abstractmethod + def open_template(self, template_path): + """Open template file in default application. + + Args: + template_path (str): Fullpath for current task and + host's template file. + """ + + pass + @abstractmethod def import_template(self, template_path): """ From 36fd0f9b9c709127d6a52964185068529ed31b64 Mon Sep 17 00:00:00 2001 From: "clement.hector" Date: Tue, 9 May 2023 15:59:11 +0200 Subject: [PATCH 003/185] add open template for nuke --- openpype/hosts/nuke/api/pipeline.py | 7 ++++- .../nuke/api/workfile_template_builder.py | 30 +++++++++++++++++++ 2 files changed, 36 insertions(+), 1 deletion(-) diff --git a/openpype/hosts/nuke/api/pipeline.py b/openpype/hosts/nuke/api/pipeline.py index d649ffae7f..b45a9dfe7c 100644 --- a/openpype/hosts/nuke/api/pipeline.py +++ b/openpype/hosts/nuke/api/pipeline.py @@ -49,6 +49,7 @@ from .workfile_template_builder import ( NukePlaceholderLoadPlugin, NukePlaceholderCreatePlugin, build_workfile_template, + open_template, create_placeholder, update_placeholder, ) @@ -288,7 +289,7 @@ def _install_menu(): lambda: BuildWorkfile().process() ) - menu_template = menu.addMenu("Template Builder") # creating template menu + menu_template = menu.addMenu("Template Builder") menu_template.addCommand( "Build Workfile from template", lambda: build_workfile_template() @@ -296,6 +297,10 @@ def _install_menu(): if not ASSIST: menu_template.addSeparator() + menu_template.addCommand( + "Open template", + lambda: open_template() + ) menu_template.addCommand( "Create Place Holder", lambda: create_placeholder() diff --git a/openpype/hosts/nuke/api/workfile_template_builder.py b/openpype/hosts/nuke/api/workfile_template_builder.py index 72d4ffb476..2303ab7fbb 100644 --- a/openpype/hosts/nuke/api/workfile_template_builder.py +++ b/openpype/hosts/nuke/api/workfile_template_builder.py @@ -1,4 +1,5 @@ import collections +import os import nuke from openpype.pipeline import registered_host from openpype.pipeline.workfile.workfile_template_builder import ( @@ -33,6 +34,30 @@ PLACEHOLDER_SET = "PLACEHOLDERS_SET" class NukeTemplateBuilder(AbstractTemplateBuilder): """Concrete implementation of AbstractTemplateBuilder for nuke""" + def open_template(self): + """Open template in current scene. + + Args: + path (str): A path to current template (usually given by + get_template_preset implementation) + """ + + template_preset = self.get_template_preset() + template_path = template_preset["path"] + + if not os.path.exists(template_path): + nuke.message("Template doesn't exist: {}".format(template_path)) + return + + result = nuke.ask( + "This will replace current scene with template. Continue?" + ) + if not result: + return + + print("opening template {}".format(template_path)) + nuke.scriptOpen(template_path) + def import_template(self, path): """Import template into current scene. Block if a template is already loaded. @@ -960,6 +985,11 @@ def update_workfile_template(*args): builder.rebuild_template() +def open_template(*args): + builder = NukeTemplateBuilder(registered_host()) + builder.open_template() + + def create_placeholder(*args): host = registered_host() builder = NukeTemplateBuilder(host) From bebaeee66a626196f4cb99df4728a7fa3f5b8010 Mon Sep 17 00:00:00 2001 From: "clement.hector" Date: Tue, 9 May 2023 16:21:14 +0200 Subject: [PATCH 004/185] fix linter --- openpype/hosts/maya/api/workfile_template_builder.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/openpype/hosts/maya/api/workfile_template_builder.py b/openpype/hosts/maya/api/workfile_template_builder.py index 3342a86b70..7b7c6a1fe4 100644 --- a/openpype/hosts/maya/api/workfile_template_builder.py +++ b/openpype/hosts/maya/api/workfile_template_builder.py @@ -329,10 +329,12 @@ def update_workfile_template(*args): builder = MayaTemplateBuilder(registered_host()) builder.rebuild_template() + def open_template(*args): builder = MayaTemplateBuilder(registered_host()) builder.open_template() + def create_placeholder(*args): host = registered_host() builder = MayaTemplateBuilder(host) From 9c4f1f6035139b7c6bf6873de21bb599c3025a80 Mon Sep 17 00:00:00 2001 From: "clement.hector" Date: Thu, 11 May 2023 14:08:16 +0200 Subject: [PATCH 005/185] catch exception to display the message for users --- .../maya/api/workfile_template_builder.py | 20 ++++++++++----- .../nuke/api/workfile_template_builder.py | 25 +++++++++++++------ 2 files changed, 31 insertions(+), 14 deletions(-) diff --git a/openpype/hosts/maya/api/workfile_template_builder.py b/openpype/hosts/maya/api/workfile_template_builder.py index 7b7c6a1fe4..4393ac4cf3 100644 --- a/openpype/hosts/maya/api/workfile_template_builder.py +++ b/openpype/hosts/maya/api/workfile_template_builder.py @@ -1,5 +1,4 @@ import json -import os from maya import cmds @@ -10,6 +9,9 @@ from openpype.pipeline.workfile.workfile_template_builder import ( PlaceholderPlugin, LoadPlaceholderItem, PlaceholderLoadMixin, + TemplateLoadFailed, + TemplateNotFound, + TemplateProfileNotFound, ) from openpype.tools.workfile_template_build import ( WorkfileBuildPlaceholderDialog, @@ -28,13 +30,19 @@ class MayaTemplateBuilder(AbstractTemplateBuilder): def open_template(self): """Open template in current scene. """ - template_preset = self.get_template_preset() - template_path = template_preset["path"] - if not os.path.exists(template_path): + try: + template_preset = self.get_template_preset() + template_path = template_preset["path"] + + except ( + TemplateNotFound, + TemplateProfileNotFound, + TemplateLoadFailed + ) as e: cmds.confirmDialog( - title="Warning", - message="Template doesn't exist: {}".format(template_path), + title="Error", + message="An error has occurred:\n{}".format(e), button=["OK"], defaultButton="OK", ) diff --git a/openpype/hosts/nuke/api/workfile_template_builder.py b/openpype/hosts/nuke/api/workfile_template_builder.py index 2303ab7fbb..82502f3eba 100644 --- a/openpype/hosts/nuke/api/workfile_template_builder.py +++ b/openpype/hosts/nuke/api/workfile_template_builder.py @@ -1,5 +1,4 @@ import collections -import os import nuke from openpype.pipeline import registered_host from openpype.pipeline.workfile.workfile_template_builder import ( @@ -8,7 +7,10 @@ from openpype.pipeline.workfile.workfile_template_builder import ( LoadPlaceholderItem, CreatePlaceholderItem, PlaceholderLoadMixin, - PlaceholderCreateMixin + PlaceholderCreateMixin, + TemplateNotFound, + TemplateLoadFailed, + TemplateProfileNotFound, ) from openpype.tools.workfile_template_build import ( WorkfileBuildPlaceholderDialog, @@ -27,7 +29,9 @@ from .lib import ( duplicate_node, node_tempfile, ) - +from .workio import ( + open_file, +) PLACEHOLDER_SET = "PLACEHOLDERS_SET" @@ -42,11 +46,16 @@ class NukeTemplateBuilder(AbstractTemplateBuilder): get_template_preset implementation) """ - template_preset = self.get_template_preset() - template_path = template_preset["path"] + try: + template_preset = self.get_template_preset() + template_path = template_preset["path"] - if not os.path.exists(template_path): - nuke.message("Template doesn't exist: {}".format(template_path)) + except ( + TemplateNotFound, + TemplateProfileNotFound, + TemplateLoadFailed + ) as e: + nuke.critical("An error has occurred:\n{}".format(e)) return result = nuke.ask( @@ -56,7 +65,7 @@ class NukeTemplateBuilder(AbstractTemplateBuilder): return print("opening template {}".format(template_path)) - nuke.scriptOpen(template_path) + open_file(template_path) def import_template(self, path): """Import template into current scene. From 961d7abf235ce628fcb33b74a4190b4409904940 Mon Sep 17 00:00:00 2001 From: "clement.hector" Date: Thu, 11 May 2023 14:13:37 +0200 Subject: [PATCH 006/185] fix indent --- openpype/hosts/maya/api/workfile_template_builder.py | 8 ++++---- openpype/hosts/nuke/api/workfile_template_builder.py | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/openpype/hosts/maya/api/workfile_template_builder.py b/openpype/hosts/maya/api/workfile_template_builder.py index 4393ac4cf3..b93132164a 100644 --- a/openpype/hosts/maya/api/workfile_template_builder.py +++ b/openpype/hosts/maya/api/workfile_template_builder.py @@ -36,10 +36,10 @@ class MayaTemplateBuilder(AbstractTemplateBuilder): template_path = template_preset["path"] except ( - TemplateNotFound, - TemplateProfileNotFound, - TemplateLoadFailed - ) as e: + TemplateNotFound, + TemplateProfileNotFound, + TemplateLoadFailed + ) as e: cmds.confirmDialog( title="Error", message="An error has occurred:\n{}".format(e), diff --git a/openpype/hosts/nuke/api/workfile_template_builder.py b/openpype/hosts/nuke/api/workfile_template_builder.py index 82502f3eba..d0d34e36f3 100644 --- a/openpype/hosts/nuke/api/workfile_template_builder.py +++ b/openpype/hosts/nuke/api/workfile_template_builder.py @@ -51,10 +51,10 @@ class NukeTemplateBuilder(AbstractTemplateBuilder): template_path = template_preset["path"] except ( - TemplateNotFound, - TemplateProfileNotFound, - TemplateLoadFailed - ) as e: + TemplateNotFound, + TemplateProfileNotFound, + TemplateLoadFailed + ) as e: nuke.critical("An error has occurred:\n{}".format(e)) return From 3e2c82d42f19cfd15cdb5acc7da00f23bb657ac9 Mon Sep 17 00:00:00 2001 From: "clement.hector" Date: Tue, 16 May 2023 17:58:19 +0200 Subject: [PATCH 007/185] Use Qt for popup message --- .../nuke/api/workfile_template_builder.py | 36 +-------------- .../workfile/workfile_template_builder.py | 44 +++++++++++++++++-- openpype/widgets/message_window.py | 25 ++++++++--- 3 files changed, 61 insertions(+), 44 deletions(-) diff --git a/openpype/hosts/nuke/api/workfile_template_builder.py b/openpype/hosts/nuke/api/workfile_template_builder.py index d0d34e36f3..038270ea69 100644 --- a/openpype/hosts/nuke/api/workfile_template_builder.py +++ b/openpype/hosts/nuke/api/workfile_template_builder.py @@ -8,9 +8,6 @@ from openpype.pipeline.workfile.workfile_template_builder import ( CreatePlaceholderItem, PlaceholderLoadMixin, PlaceholderCreateMixin, - TemplateNotFound, - TemplateLoadFailed, - TemplateProfileNotFound, ) from openpype.tools.workfile_template_build import ( WorkfileBuildPlaceholderDialog, @@ -29,44 +26,13 @@ from .lib import ( duplicate_node, node_tempfile, ) -from .workio import ( - open_file, -) + PLACEHOLDER_SET = "PLACEHOLDERS_SET" class NukeTemplateBuilder(AbstractTemplateBuilder): """Concrete implementation of AbstractTemplateBuilder for nuke""" - def open_template(self): - """Open template in current scene. - - Args: - path (str): A path to current template (usually given by - get_template_preset implementation) - """ - - try: - template_preset = self.get_template_preset() - template_path = template_preset["path"] - - except ( - TemplateNotFound, - TemplateProfileNotFound, - TemplateLoadFailed - ) as e: - nuke.critical("An error has occurred:\n{}".format(e)) - return - - result = nuke.ask( - "This will replace current scene with template. Continue?" - ) - if not result: - return - - print("opening template {}".format(template_path)) - open_file(template_path) - def import_template(self, path): """Import template into current scene. Block if a template is already loaded. diff --git a/openpype/pipeline/workfile/workfile_template_builder.py b/openpype/pipeline/workfile/workfile_template_builder.py index d234866b00..9cab9af9b7 100644 --- a/openpype/pipeline/workfile/workfile_template_builder.py +++ b/openpype/pipeline/workfile/workfile_template_builder.py @@ -37,7 +37,12 @@ from openpype.lib import ( attribute_definitions, ) from openpype.lib.attribute_definitions import get_attributes_keys -from openpype.pipeline import legacy_io, Anatomy +from openpype.pipeline import ( + legacy_io, + Anatomy, + registered_host, + get_current_host_name, +) from openpype.pipeline.load import ( get_loaders_by_name, get_contexts_for_repre_docs, @@ -533,16 +538,47 @@ class AbstractTemplateBuilder(object): self.clear_shared_populate_data() - @abstractmethod - def open_template(self, template_path): + def open_template(self): """Open template file in default application. Args: template_path (str): Fullpath for current task and host's template file. """ + from openpype.widgets import message_window - pass + module_name = 'openpype.hosts.{}.api.lib'.format(get_current_host_name()) + api_lib = __import__(module_name, fromlist=['get_main_window']) + main_window = api_lib.get_main_window() + + try: + template_preset = self.get_template_preset() + template_path = template_preset["path"] + + except ( + TemplateNotFound, + TemplateProfileNotFound, + TemplateLoadFailed + ) as e: + message_window.message( + title="Template Load Failed", + message=str(e), + parent= main_window, + level="critical" + ) + return + + result = message_window.message( + title="Opening template", + message="Caution! This will overwrite your current scene.\n"\ + "Do you want to continue?", + parent= main_window, + level="ask", + ) + + if result: + host = registered_host() + host.open_file(template_path) @abstractmethod def import_template(self, template_path): diff --git a/openpype/widgets/message_window.py b/openpype/widgets/message_window.py index c207702f74..59bbd5bf52 100644 --- a/openpype/widgets/message_window.py +++ b/openpype/widgets/message_window.py @@ -13,12 +13,16 @@ class Window(QtWidgets.QWidget): self.message = message self.level = level + self.setWindowTitle(self.title) + if self.level == "info": self._info() elif self.level == "warning": self._warning() elif self.level == "critical": self._critical() + elif self.level == "ask": + self._ask() def _info(self): self.setWindowTitle(self.title) @@ -28,23 +32,32 @@ class Window(QtWidgets.QWidget): self.exit() def _warning(self): - self.setWindowTitle(self.title) rc = QtWidgets.QMessageBox.warning( self, self.title, self.message) if rc: self.exit() def _critical(self): - self.setWindowTitle(self.title) rc = QtWidgets.QMessageBox.critical( self, self.title, self.message) if rc: self.exit() + def _ask(self): + self.answer = None + rc = QtWidgets.QMessageBox.question( + self, + self.title, + self.message, + QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.No + ) + self.answer = False + if rc == QtWidgets.QMessageBox.Yes: + self.answer = True + self.exit() + def exit(self): self.hide() - # self.parent.exec_() - # self.parent.hide() return @@ -78,7 +91,9 @@ def message(title=None, message=None, level="info", parent=None): except Exception: # skip all possible issues that may happen feature is not crutial log.warning("Couldn't center message.", exc_info=True) - # sys.exit(app.exec_()) + + if level == "ask": + return ex.answer class ScrollMessageBox(QtWidgets.QDialog): From 083dc5db830b5b958857655ac3976b2ba58e2a37 Mon Sep 17 00:00:00 2001 From: "clement.hector" Date: Tue, 16 May 2023 18:00:13 +0200 Subject: [PATCH 008/185] Remove code from maya lib --- .../maya/api/workfile_template_builder.py | 39 ------------------- 1 file changed, 39 deletions(-) diff --git a/openpype/hosts/maya/api/workfile_template_builder.py b/openpype/hosts/maya/api/workfile_template_builder.py index b93132164a..561d085b08 100644 --- a/openpype/hosts/maya/api/workfile_template_builder.py +++ b/openpype/hosts/maya/api/workfile_template_builder.py @@ -9,9 +9,6 @@ from openpype.pipeline.workfile.workfile_template_builder import ( PlaceholderPlugin, LoadPlaceholderItem, PlaceholderLoadMixin, - TemplateLoadFailed, - TemplateNotFound, - TemplateProfileNotFound, ) from openpype.tools.workfile_template_build import ( WorkfileBuildPlaceholderDialog, @@ -27,42 +24,6 @@ class MayaTemplateBuilder(AbstractTemplateBuilder): use_legacy_creators = True - def open_template(self): - """Open template in current scene. - """ - - try: - template_preset = self.get_template_preset() - template_path = template_preset["path"] - - except ( - TemplateNotFound, - TemplateProfileNotFound, - TemplateLoadFailed - ) as e: - cmds.confirmDialog( - title="Error", - message="An error has occurred:\n{}".format(e), - button=["OK"], - defaultButton="OK", - ) - return - - result = cmds.confirmDialog( - title="Warning", - message="Opening a template will clear the current scene.", - button=["OK", "Cancel"], - defaultButton="OK", - cancelButton="Cancel", - dismissString="Cancel", - ) - - if result != "OK": - return - - print("opening template {}".format(template_path)) - cmds.file(template_path, open=True, force=True) - def import_template(self, path): """Import template into current scene. Block if a template is already loaded. From 873c9d9a03c519143acf1fc80b649f5e79237481 Mon Sep 17 00:00:00 2001 From: "clement.hector" Date: Tue, 16 May 2023 18:11:06 +0200 Subject: [PATCH 009/185] Fix linter --- .../workfile/workfile_template_builder.py | 20 ++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/openpype/pipeline/workfile/workfile_template_builder.py b/openpype/pipeline/workfile/workfile_template_builder.py index 9cab9af9b7..1f56962eee 100644 --- a/openpype/pipeline/workfile/workfile_template_builder.py +++ b/openpype/pipeline/workfile/workfile_template_builder.py @@ -547,7 +547,9 @@ class AbstractTemplateBuilder(object): """ from openpype.widgets import message_window - module_name = 'openpype.hosts.{}.api.lib'.format(get_current_host_name()) + module_name = 'openpype.hosts.{}.api.lib'.format( + get_current_host_name() + ) api_lib = __import__(module_name, fromlist=['get_main_window']) main_window = api_lib.get_main_window() @@ -561,19 +563,19 @@ class AbstractTemplateBuilder(object): TemplateLoadFailed ) as e: message_window.message( - title="Template Load Failed", - message=str(e), - parent= main_window, - level="critical" + title = "Template Load Failed", + message = str(e), + parent = main_window, + level = "critical" ) return result = message_window.message( - title="Opening template", - message="Caution! This will overwrite your current scene.\n"\ + title = "Opening template", + message = "Caution! This will overwrite your current scene.\n"\ "Do you want to continue?", - parent= main_window, - level="ask", + parent = main_window, + level = "ask", ) if result: From 9676dec82da733a204ecb926ba05b7ae3b7a16d4 Mon Sep 17 00:00:00 2001 From: "clement.hector" Date: Wed, 17 May 2023 11:22:05 +0200 Subject: [PATCH 010/185] Fix linter --- .../workfile/workfile_template_builder.py | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/openpype/pipeline/workfile/workfile_template_builder.py b/openpype/pipeline/workfile/workfile_template_builder.py index 1f56962eee..54018b71b6 100644 --- a/openpype/pipeline/workfile/workfile_template_builder.py +++ b/openpype/pipeline/workfile/workfile_template_builder.py @@ -563,19 +563,19 @@ class AbstractTemplateBuilder(object): TemplateLoadFailed ) as e: message_window.message( - title = "Template Load Failed", - message = str(e), - parent = main_window, - level = "critical" + title="Template Load Failed", + message=str(e), + parent=main_window, + level="critical" ) return result = message_window.message( - title = "Opening template", - message = "Caution! This will overwrite your current scene.\n"\ - "Do you want to continue?", - parent = main_window, - level = "ask", + title="Opening template", + message="Caution! This will overwrite your current scene.\n" + "Do you want to continue?", + parent=main_window, + level="ask", ) if result: From 5acb386ea594ba1a6296b47241e0154dbed6ea07 Mon Sep 17 00:00:00 2001 From: "clement.hector" Date: Tue, 23 May 2023 15:58:01 +0200 Subject: [PATCH 011/185] use self.host --- openpype/pipeline/workfile/workfile_template_builder.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/openpype/pipeline/workfile/workfile_template_builder.py b/openpype/pipeline/workfile/workfile_template_builder.py index 54018b71b6..d56bf84757 100644 --- a/openpype/pipeline/workfile/workfile_template_builder.py +++ b/openpype/pipeline/workfile/workfile_template_builder.py @@ -40,7 +40,6 @@ from openpype.lib.attribute_definitions import get_attributes_keys from openpype.pipeline import ( legacy_io, Anatomy, - registered_host, get_current_host_name, ) from openpype.pipeline.load import ( @@ -579,8 +578,7 @@ class AbstractTemplateBuilder(object): ) if result: - host = registered_host() - host.open_file(template_path) + self.host.open_file(template_path) @abstractmethod def import_template(self, template_path): From ebfc0a339a553186b3624a337ee388c374367bba Mon Sep 17 00:00:00 2001 From: "clement.hector" Date: Wed, 24 May 2023 10:16:20 +0200 Subject: [PATCH 012/185] remove get_current_host_name method --- .../pipeline/workfile/workfile_template_builder.py | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/openpype/pipeline/workfile/workfile_template_builder.py b/openpype/pipeline/workfile/workfile_template_builder.py index d56bf84757..fabf3652f9 100644 --- a/openpype/pipeline/workfile/workfile_template_builder.py +++ b/openpype/pipeline/workfile/workfile_template_builder.py @@ -37,11 +37,7 @@ from openpype.lib import ( attribute_definitions, ) from openpype.lib.attribute_definitions import get_attributes_keys -from openpype.pipeline import ( - legacy_io, - Anatomy, - get_current_host_name, -) +from openpype.pipeline import legacy_io, Anatomy from openpype.pipeline.load import ( get_loaders_by_name, get_contexts_for_repre_docs, @@ -546,9 +542,7 @@ class AbstractTemplateBuilder(object): """ from openpype.widgets import message_window - module_name = 'openpype.hosts.{}.api.lib'.format( - get_current_host_name() - ) + module_name = 'openpype.hosts.{}.api.lib'.format(self.host_name) api_lib = __import__(module_name, fromlist=['get_main_window']) main_window = api_lib.get_main_window() From 7402662161441640ba10df0d0d47556a3310eae4 Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Mon, 30 Oct 2023 23:12:14 +0100 Subject: [PATCH 013/185] Remove `shelf` class and shelf build on maya `userSetup.py` --- openpype/hosts/maya/api/lib.py | 113 ----------------------- openpype/hosts/maya/startup/userSetup.py | 19 ---- 2 files changed, 132 deletions(-) diff --git a/openpype/hosts/maya/api/lib.py b/openpype/hosts/maya/api/lib.py index 7c49c837e9..f7eaf358fe 100644 --- a/openpype/hosts/maya/api/lib.py +++ b/openpype/hosts/maya/api/lib.py @@ -2921,119 +2921,6 @@ def fix_incompatible_containers(): "ReferenceLoader", type="string") -def _null(*args): - pass - - -class shelf(): - '''A simple class to build shelves in maya. Since the build method is empty, - it should be extended by the derived class to build the necessary shelf - elements. By default it creates an empty shelf called "customShelf".''' - - ########################################################################### - '''This is an example shelf.''' - # class customShelf(_shelf): - # def build(self): - # self.addButon(label="button1") - # self.addButon("button2") - # self.addButon("popup") - # p = cmds.popupMenu(b=1) - # self.addMenuItem(p, "popupMenuItem1") - # self.addMenuItem(p, "popupMenuItem2") - # sub = self.addSubMenu(p, "subMenuLevel1") - # self.addMenuItem(sub, "subMenuLevel1Item1") - # sub2 = self.addSubMenu(sub, "subMenuLevel2") - # self.addMenuItem(sub2, "subMenuLevel2Item1") - # self.addMenuItem(sub2, "subMenuLevel2Item2") - # self.addMenuItem(sub, "subMenuLevel1Item2") - # self.addMenuItem(p, "popupMenuItem3") - # self.addButon("button3") - # customShelf() - ########################################################################### - - def __init__(self, name="customShelf", iconPath="", preset={}): - self.name = name - - self.iconPath = iconPath - - self.labelBackground = (0, 0, 0, 0) - self.labelColour = (.9, .9, .9) - - self.preset = preset - - self._cleanOldShelf() - cmds.setParent(self.name) - self.build() - - def build(self): - '''This method should be overwritten in derived classes to actually - build the shelf elements. Otherwise, nothing is added to the shelf.''' - for item in self.preset['items']: - if not item.get('command'): - item['command'] = self._null - if item['type'] == 'button': - self.addButon(item['name'], - command=item['command'], - icon=item['icon']) - if item['type'] == 'menuItem': - self.addMenuItem(item['parent'], - item['name'], - command=item['command'], - icon=item['icon']) - if item['type'] == 'subMenu': - self.addMenuItem(item['parent'], - item['name'], - command=item['command'], - icon=item['icon']) - - def addButon(self, label, icon="commandButton.png", - command=_null, doubleCommand=_null): - ''' - Adds a shelf button with the specified label, command, - double click command and image. - ''' - cmds.setParent(self.name) - if icon: - icon = os.path.join(self.iconPath, icon) - print(icon) - cmds.shelfButton(width=37, height=37, image=icon, label=label, - command=command, dcc=doubleCommand, - imageOverlayLabel=label, olb=self.labelBackground, - olc=self.labelColour) - - def addMenuItem(self, parent, label, command=_null, icon=""): - ''' - Adds a shelf button with the specified label, command, - double click command and image. - ''' - if icon: - icon = os.path.join(self.iconPath, icon) - print(icon) - return cmds.menuItem(p=parent, label=label, c=command, i="") - - def addSubMenu(self, parent, label, icon=None): - ''' - Adds a sub menu item with the specified label and icon to - the specified parent popup menu. - ''' - if icon: - icon = os.path.join(self.iconPath, icon) - print(icon) - return cmds.menuItem(p=parent, label=label, i=icon, subMenu=1) - - def _cleanOldShelf(self): - ''' - Checks if the shelf exists and empties it if it does - or creates it if it does not. - ''' - if cmds.shelfLayout(self.name, ex=1): - if cmds.shelfLayout(self.name, q=1, ca=1): - for each in cmds.shelfLayout(self.name, q=1, ca=1): - cmds.deleteUI(each) - else: - cmds.shelfLayout(self.name, p="ShelfLayout") - - def _get_render_instances(): """Return all 'render-like' instances. diff --git a/openpype/hosts/maya/startup/userSetup.py b/openpype/hosts/maya/startup/userSetup.py index f2899cdb37..417f72a59f 100644 --- a/openpype/hosts/maya/startup/userSetup.py +++ b/openpype/hosts/maya/startup/userSetup.py @@ -46,24 +46,5 @@ if bool(int(os.environ.get(key, "0"))): lowestPriority=True ) -# Build a shelf. -shelf_preset = settings['maya'].get('project_shelf') -if shelf_preset: - icon_path = os.path.join( - os.environ['OPENPYPE_PROJECT_SCRIPTS'], - project_name, - "icons") - icon_path = os.path.abspath(icon_path) - - for i in shelf_preset['imports']: - import_string = "from {} import {}".format(project_name, i) - print(import_string) - exec(import_string) - - cmds.evalDeferred( - "mlib.shelf(name=shelf_preset['name'], iconPath=icon_path," - " preset=shelf_preset)" - ) - print("Finished OpenPype usersetup.") From 3d22cce9792dbdef1da19da75ff80b852e93472b Mon Sep 17 00:00:00 2001 From: Toke Stuart Jepsen Date: Tue, 30 Jan 2024 10:08:03 +0000 Subject: [PATCH 014/185] Refactor Refactored UI code out of pipeline. --- .../maya/api/workfile_template_builder.py | 4 +- .../nuke/api/workfile_template_builder.py | 4 +- .../workfile/workfile_template_builder.py | 43 ++----------------- .../tools/workfile_template_build/__init__.py | 3 ++ openpype/tools/workfile_template_build/lib.py | 29 +++++++++++++ openpype/widgets/message_window.py | 8 ++-- 6 files changed, 44 insertions(+), 47 deletions(-) create mode 100644 openpype/tools/workfile_template_build/lib.py diff --git a/openpype/hosts/maya/api/workfile_template_builder.py b/openpype/hosts/maya/api/workfile_template_builder.py index e91fa839a3..0261d87b36 100644 --- a/openpype/hosts/maya/api/workfile_template_builder.py +++ b/openpype/hosts/maya/api/workfile_template_builder.py @@ -12,6 +12,7 @@ from openpype.pipeline.workfile.workfile_template_builder import ( ) from openpype.tools.workfile_template_build import ( WorkfileBuildPlaceholderDialog, + open_template_ui ) from .lib import read, imprint, get_reference_node, get_main_window @@ -342,8 +343,7 @@ def update_workfile_template(*args): def open_template(*args): - builder = MayaTemplateBuilder(registered_host()) - builder.open_template() + open_template_ui(MayaTemplateBuilder(registered_host()), get_main_window()) def create_placeholder(*args): diff --git a/openpype/hosts/nuke/api/workfile_template_builder.py b/openpype/hosts/nuke/api/workfile_template_builder.py index b07330e5b2..b4c780ec07 100644 --- a/openpype/hosts/nuke/api/workfile_template_builder.py +++ b/openpype/hosts/nuke/api/workfile_template_builder.py @@ -11,6 +11,7 @@ from openpype.pipeline.workfile.workfile_template_builder import ( ) from openpype.tools.workfile_template_build import ( WorkfileBuildPlaceholderDialog, + open_template_ui ) from .lib import ( find_free_space_to_paste_nodes, @@ -971,8 +972,7 @@ def update_workfile_template(*args): def open_template(*args): - builder = NukeTemplateBuilder(registered_host()) - builder.open_template() + open_template_ui(NukeTemplateBuilder(registered_host()), get_main_window()) def create_placeholder(*args): diff --git a/openpype/pipeline/workfile/workfile_template_builder.py b/openpype/pipeline/workfile/workfile_template_builder.py index c6a9a608f3..fffd761d38 100644 --- a/openpype/pipeline/workfile/workfile_template_builder.py +++ b/openpype/pipeline/workfile/workfile_template_builder.py @@ -552,45 +552,10 @@ class AbstractTemplateBuilder(object): self.clear_shared_populate_data() def open_template(self): - """Open template file in default application. - - Args: - template_path (str): Fullpath for current task and - host's template file. - """ - from openpype.widgets import message_window - - module_name = 'openpype.hosts.{}.api.lib'.format(self.host_name) - api_lib = __import__(module_name, fromlist=['get_main_window']) - main_window = api_lib.get_main_window() - - try: - template_preset = self.get_template_preset() - template_path = template_preset["path"] - - except ( - TemplateNotFound, - TemplateProfileNotFound, - TemplateLoadFailed - ) as e: - message_window.message( - title="Template Load Failed", - message=str(e), - parent=main_window, - level="critical" - ) - return - - result = message_window.message( - title="Opening template", - message="Caution! This will overwrite your current scene.\n" - "Do you want to continue?", - parent=main_window, - level="ask", - ) - - if result: - self.host.open_file(template_path) + """Open template file with registered host.""" + template_preset = self.get_template_preset() + template_path = template_preset["path"] + self.host.open_file(template_path) @abstractmethod def import_template(self, template_path): diff --git a/openpype/tools/workfile_template_build/__init__.py b/openpype/tools/workfile_template_build/__init__.py index 82a22aea50..ad94ebcf79 100644 --- a/openpype/tools/workfile_template_build/__init__.py +++ b/openpype/tools/workfile_template_build/__init__.py @@ -1,5 +1,8 @@ from .window import WorkfileBuildPlaceholderDialog +from .lib import open_template_ui __all__ = ( "WorkfileBuildPlaceholderDialog", + + "open_template_ui" ) diff --git a/openpype/tools/workfile_template_build/lib.py b/openpype/tools/workfile_template_build/lib.py new file mode 100644 index 0000000000..13c6fd9a2d --- /dev/null +++ b/openpype/tools/workfile_template_build/lib.py @@ -0,0 +1,29 @@ +import traceback + +from openpype.widgets import message_window + + +def open_template_ui(builder, main_window): + """Open template from `builder` + + Asks user about overwriting current scene and feedsback exceptions. + """ + + result = message_window.message( + title="Opening template", + message="Caution! This will overwrite your current scene.\n" + "Do you want to continue?", + parent=main_window, + level="question", + ) + + if result: + try: + builder.open_template() + except Exception: + message_window.message( + title="Template Load Failed", + message="".join(traceback.format_exc()), + parent=main_window, + level="critical" + ) diff --git a/openpype/widgets/message_window.py b/openpype/widgets/message_window.py index 59bbd5bf52..940d530565 100644 --- a/openpype/widgets/message_window.py +++ b/openpype/widgets/message_window.py @@ -21,8 +21,8 @@ class Window(QtWidgets.QWidget): self._warning() elif self.level == "critical": self._critical() - elif self.level == "ask": - self._ask() + elif self.level == "question": + self._question() def _info(self): self.setWindowTitle(self.title) @@ -43,7 +43,7 @@ class Window(QtWidgets.QWidget): if rc: self.exit() - def _ask(self): + def _question(self): self.answer = None rc = QtWidgets.QMessageBox.question( self, @@ -92,7 +92,7 @@ def message(title=None, message=None, level="info", parent=None): # skip all possible issues that may happen feature is not crutial log.warning("Couldn't center message.", exc_info=True) - if level == "ask": + if level == "question": return ex.answer From c3e81c131f65e8e464852db21991aad89dff22b3 Mon Sep 17 00:00:00 2001 From: Toke Stuart Jepsen Date: Fri, 2 Feb 2024 08:38:49 +0000 Subject: [PATCH 015/185] Move open template to Maya menu.py --- openpype/hosts/maya/api/menu.py | 12 ++++++++---- openpype/hosts/maya/api/workfile_template_builder.py | 7 +------ 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/openpype/hosts/maya/api/menu.py b/openpype/hosts/maya/api/menu.py index f71c30ce15..18cac34a4a 100644 --- a/openpype/hosts/maya/api/menu.py +++ b/openpype/hosts/maya/api/menu.py @@ -9,7 +9,8 @@ import maya.cmds as cmds from openpype.pipeline import ( get_current_asset_name, - get_current_task_name + get_current_task_name, + registered_host ) from openpype.pipeline.workfile import BuildWorkfile from openpype.tools.utils import host_tools @@ -21,9 +22,10 @@ from .workfile_template_builder import ( create_placeholder, update_placeholder, build_workfile_template, - update_workfile_template, - open_template, + update_workfile_template ) +from openpype.tools.workfile_template_build import open_template_ui +from .workfile_template_builder import MayaTemplateBuilder log = logging.getLogger(__name__) @@ -185,7 +187,9 @@ def install(project_settings): cmds.menuItem( "Open Template", parent=builder_menu, - command=open_template, + command=lambda *args: open_template_ui( + MayaTemplateBuilder(registered_host()), get_main_window() + ), ) cmds.menuItem( "Create Placeholder", diff --git a/openpype/hosts/maya/api/workfile_template_builder.py b/openpype/hosts/maya/api/workfile_template_builder.py index 0261d87b36..aadf1cc21e 100644 --- a/openpype/hosts/maya/api/workfile_template_builder.py +++ b/openpype/hosts/maya/api/workfile_template_builder.py @@ -11,8 +11,7 @@ from openpype.pipeline.workfile.workfile_template_builder import ( PlaceholderLoadMixin, ) from openpype.tools.workfile_template_build import ( - WorkfileBuildPlaceholderDialog, - open_template_ui + WorkfileBuildPlaceholderDialog ) from .lib import read, imprint, get_reference_node, get_main_window @@ -342,10 +341,6 @@ def update_workfile_template(*args): builder.rebuild_template() -def open_template(*args): - open_template_ui(MayaTemplateBuilder(registered_host()), get_main_window()) - - def create_placeholder(*args): host = registered_host() builder = MayaTemplateBuilder(host) From 98f69448de6ddd1f74572774368423fc998aaf45 Mon Sep 17 00:00:00 2001 From: Toke Stuart Jepsen Date: Fri, 2 Feb 2024 08:45:44 +0000 Subject: [PATCH 016/185] Remove open_template --- openpype/hosts/nuke/api/pipeline.py | 8 ++++++-- openpype/hosts/nuke/api/workfile_template_builder.py | 7 +------ 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/openpype/hosts/nuke/api/pipeline.py b/openpype/hosts/nuke/api/pipeline.py index 3d6f3b9423..6bd7e3fb96 100644 --- a/openpype/hosts/nuke/api/pipeline.py +++ b/openpype/hosts/nuke/api/pipeline.py @@ -22,9 +22,11 @@ from openpype.pipeline import ( AVALON_CONTAINER_ID, get_current_asset_name, get_current_task_name, + registered_host, ) from openpype.pipeline.workfile import BuildWorkfile from openpype.tools.utils import host_tools +from openpype.tools.workfile_template_build import open_template_ui from .command import viewer_update_and_undo_stop from .lib import ( @@ -52,9 +54,9 @@ from .workfile_template_builder import ( NukePlaceholderLoadPlugin, NukePlaceholderCreatePlugin, build_workfile_template, - open_template, create_placeholder, update_placeholder, + NukeTemplateBuilder, ) from .workio import ( open_file, @@ -326,7 +328,9 @@ def _install_menu(): menu_template.addSeparator() menu_template.addCommand( "Open template", - lambda: open_template() + lambda: open_template_ui( + NukeTemplateBuilder(registered_host()), get_main_window() + ) ) menu_template.addCommand( "Create Place Holder", diff --git a/openpype/hosts/nuke/api/workfile_template_builder.py b/openpype/hosts/nuke/api/workfile_template_builder.py index b4c780ec07..8159840f32 100644 --- a/openpype/hosts/nuke/api/workfile_template_builder.py +++ b/openpype/hosts/nuke/api/workfile_template_builder.py @@ -10,8 +10,7 @@ from openpype.pipeline.workfile.workfile_template_builder import ( PlaceholderCreateMixin, ) from openpype.tools.workfile_template_build import ( - WorkfileBuildPlaceholderDialog, - open_template_ui + WorkfileBuildPlaceholderDialog ) from .lib import ( find_free_space_to_paste_nodes, @@ -971,10 +970,6 @@ def update_workfile_template(*args): builder.rebuild_template() -def open_template(*args): - open_template_ui(NukeTemplateBuilder(registered_host()), get_main_window()) - - def create_placeholder(*args): host = registered_host() builder = NukeTemplateBuilder(host) From b7aa3e323d74a9524a30bfb472a07b77939ef8a2 Mon Sep 17 00:00:00 2001 From: MustafaJafar Date: Fri, 2 Feb 2024 11:38:23 +0200 Subject: [PATCH 017/185] fix default redshift version --- .../deadline/plugins/publish/submit_houdini_render_deadline.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openpype/modules/deadline/plugins/publish/submit_houdini_render_deadline.py b/openpype/modules/deadline/plugins/publish/submit_houdini_render_deadline.py index bf7fb45a8b..e0e52fe6a6 100644 --- a/openpype/modules/deadline/plugins/publish/submit_houdini_render_deadline.py +++ b/openpype/modules/deadline/plugins/publish/submit_houdini_render_deadline.py @@ -45,7 +45,7 @@ class VrayRenderPluginInfo(): @attr.s class RedshiftRenderPluginInfo(): SceneFile = attr.ib(default=None) - Version = attr.ib(default=None) + Version = attr.ib(default="1") class HoudiniSubmitDeadline( From c2dbf604d8eb1fec466182f434daa332e952341f Mon Sep 17 00:00:00 2001 From: MustafaJafar Date: Fri, 2 Feb 2024 14:42:28 +0200 Subject: [PATCH 018/185] add comment about using v1 as RS default version --- .../deadline/plugins/publish/submit_houdini_render_deadline.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/openpype/modules/deadline/plugins/publish/submit_houdini_render_deadline.py b/openpype/modules/deadline/plugins/publish/submit_houdini_render_deadline.py index e0e52fe6a6..582f7d081b 100644 --- a/openpype/modules/deadline/plugins/publish/submit_houdini_render_deadline.py +++ b/openpype/modules/deadline/plugins/publish/submit_houdini_render_deadline.py @@ -45,6 +45,9 @@ class VrayRenderPluginInfo(): @attr.s class RedshiftRenderPluginInfo(): SceneFile = attr.ib(default=None) + # "1" was selected as the default RS version as it's the default + # version in RS deadline plugin. + # https://docs.thinkboxsoftware.com/products/deadline/10.1/1_User%20Manual/manual/app-redshift.html#plug-in-configuration Version = attr.ib(default="1") From 7d586f59061cabab548516c3fcde289ad8dc3501 Mon Sep 17 00:00:00 2001 From: Mustafa Taher Date: Fri, 2 Feb 2024 15:06:12 +0200 Subject: [PATCH 019/185] remove RS deadline plugin doc link Co-authored-by: Roy Nieterau --- .../deadline/plugins/publish/submit_houdini_render_deadline.py | 1 - 1 file changed, 1 deletion(-) diff --git a/openpype/modules/deadline/plugins/publish/submit_houdini_render_deadline.py b/openpype/modules/deadline/plugins/publish/submit_houdini_render_deadline.py index 582f7d081b..cf8e1617f2 100644 --- a/openpype/modules/deadline/plugins/publish/submit_houdini_render_deadline.py +++ b/openpype/modules/deadline/plugins/publish/submit_houdini_render_deadline.py @@ -47,7 +47,6 @@ class RedshiftRenderPluginInfo(): SceneFile = attr.ib(default=None) # "1" was selected as the default RS version as it's the default # version in RS deadline plugin. - # https://docs.thinkboxsoftware.com/products/deadline/10.1/1_User%20Manual/manual/app-redshift.html#plug-in-configuration Version = attr.ib(default="1") From 4e114b80324e71c808e65b872c965ce693c42923 Mon Sep 17 00:00:00 2001 From: Mustafa Taher Date: Fri, 2 Feb 2024 15:07:10 +0200 Subject: [PATCH 020/185] update comment about default RS version Co-authored-by: Roy Nieterau --- .../plugins/publish/submit_houdini_render_deadline.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/openpype/modules/deadline/plugins/publish/submit_houdini_render_deadline.py b/openpype/modules/deadline/plugins/publish/submit_houdini_render_deadline.py index cf8e1617f2..402dcaf256 100644 --- a/openpype/modules/deadline/plugins/publish/submit_houdini_render_deadline.py +++ b/openpype/modules/deadline/plugins/publish/submit_houdini_render_deadline.py @@ -45,8 +45,9 @@ class VrayRenderPluginInfo(): @attr.s class RedshiftRenderPluginInfo(): SceneFile = attr.ib(default=None) - # "1" was selected as the default RS version as it's the default - # version in RS deadline plugin. + # Use "1" as the default Redshift version just because it + # default fallback version in Deadline's Redshift plugin + # if no version was specified Version = attr.ib(default="1") From b58917fefa0940ce3500446d2b25d84c85433bd8 Mon Sep 17 00:00:00 2001 From: Toke Jepsen Date: Mon, 5 Feb 2024 08:17:25 +0000 Subject: [PATCH 021/185] Update openpype/tools/workfile_template_build/lib.py --- openpype/tools/workfile_template_build/lib.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openpype/tools/workfile_template_build/lib.py b/openpype/tools/workfile_template_build/lib.py index 13c6fd9a2d..2f6dfb414f 100644 --- a/openpype/tools/workfile_template_build/lib.py +++ b/openpype/tools/workfile_template_build/lib.py @@ -11,7 +11,7 @@ def open_template_ui(builder, main_window): result = message_window.message( title="Opening template", - message="Caution! This will overwrite your current scene.\n" + message="Caution! You will loose unsaved changes.\n" "Do you want to continue?", parent=main_window, level="question", From 02b371139a2c671e04cfdff2de5817975cdeb73c Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Thu, 8 Feb 2024 14:45:14 +0100 Subject: [PATCH 022/185] reduce usage of legay_io --- client/ayon_core/host/host.py | 3 - .../hosts/aftereffects/api/launch_logic.py | 5 +- .../ayon_core/hosts/blender/api/pipeline.py | 3 +- client/ayon_core/hosts/fusion/api/plugin.py | 3 +- client/ayon_core/hosts/maya/api/pipeline.py | 7 +- .../maya/plugins/load/load_arnold_standin.py | 8 +- .../maya/plugins/publish/collect_vrayscene.py | 5 - .../plugins/publish/validate_model_name.py | 1 - .../publish/validate_node_ids_in_database.py | 1 - .../publish/validate_renderlayer_aovs.py | 1 - .../validate_unreal_staticmesh_naming.py | 2 - .../plugins/publish/collect_batch_data.py | 3 - .../hosts/traypublisher/api/pipeline.py | 4 - .../ayon_core/hosts/tvpaint/api/pipeline.py | 6 +- .../plugins/publish/collect_workfile_data.py | 2 - .../publish/collect_sequences_from_job.py | 3 - .../publish/create_publish_royalrender_job.py | 4 - client/ayon_core/pipeline/context_tools.py | 176 +++++++----------- client/ayon_core/pipeline/create/context.py | 15 +- .../ayon_core/pipeline/create/subset_name.py | 3 +- client/ayon_core/pipeline/load/plugins.py | 5 +- .../publish/collect_from_create_context.py | 3 +- .../ayon_core/tools/sceneinventory/control.py | 3 +- client/ayon_core/tools/texture_copy/app.py | 7 +- .../tools/workfile_template_build/window.py | 5 +- 25 files changed, 90 insertions(+), 188 deletions(-) diff --git a/client/ayon_core/host/host.py b/client/ayon_core/host/host.py index 6d129e18d9..2dd98c8126 100644 --- a/client/ayon_core/host/host.py +++ b/client/ayon_core/host/host.py @@ -49,7 +49,6 @@ class HostBase(object): Todo: - move content of 'install_host' as method of this class - register host object - - install legacy_io - install global plugin paths - store registered plugin paths to this object - handle current context (project, asset, task) @@ -133,8 +132,6 @@ class HostBase(object): can be opened multiple workfiles at one moment and change of context can't be caught properly. - Default implementation returns values from 'legacy_io.Session'. - Returns: Dict[str, Union[str, None]]: Context with 3 keys 'project_name', 'asset_name' and 'task_name'. All of them can be 'None'. diff --git a/client/ayon_core/hosts/aftereffects/api/launch_logic.py b/client/ayon_core/hosts/aftereffects/api/launch_logic.py index ad521c2f01..3d09f4d53c 100644 --- a/client/ayon_core/hosts/aftereffects/api/launch_logic.py +++ b/client/ayon_core/hosts/aftereffects/api/launch_logic.py @@ -17,7 +17,7 @@ from qtpy import QtCore from ayon_core.lib import Logger from ayon_core.tests.lib import is_in_tests -from ayon_core.pipeline import install_host, legacy_io +from ayon_core.pipeline import install_host from ayon_core.addon import AddonsManager from ayon_core.tools.utils import host_tools, get_ayon_qt_app from ayon_core.tools.adobe_webserver.app import WebServerTool @@ -298,13 +298,10 @@ class AfterEffectsRoute(WebSocketRoute): log.info("Setting context change") log.info("project {} asset {} ".format(project, asset)) if project: - legacy_io.Session["AVALON_PROJECT"] = project os.environ["AVALON_PROJECT"] = project if asset: - legacy_io.Session["AVALON_ASSET"] = asset os.environ["AVALON_ASSET"] = asset if task: - legacy_io.Session["AVALON_TASK"] = task os.environ["AVALON_TASK"] = task async def read(self): diff --git a/client/ayon_core/hosts/blender/api/pipeline.py b/client/ayon_core/hosts/blender/api/pipeline.py index 6801b1f71b..77731a0fd3 100644 --- a/client/ayon_core/hosts/blender/api/pipeline.py +++ b/client/ayon_core/hosts/blender/api/pipeline.py @@ -19,7 +19,6 @@ from ayon_core.host import ( from ayon_core.client import get_asset_by_name from ayon_core.pipeline import ( schema, - legacy_io, get_current_project_name, get_current_asset_name, register_loader_plugin_path, @@ -380,7 +379,7 @@ def _on_task_changed(): # `directory` attribute, so it opens in that directory (does it?). # https://docs.blender.org/api/blender2.8/bpy.types.Operator.html#calling-a-file-selector # https://docs.blender.org/api/blender2.8/bpy.types.WindowManager.html#bpy.types.WindowManager.fileselect_add - workdir = legacy_io.Session["AVALON_WORKDIR"] + workdir = os.getenv("AVALON_WORKDIR") log.debug("New working directory: %s", workdir) diff --git a/client/ayon_core/hosts/fusion/api/plugin.py b/client/ayon_core/hosts/fusion/api/plugin.py index 12a29d2986..80e194ea68 100644 --- a/client/ayon_core/hosts/fusion/api/plugin.py +++ b/client/ayon_core/hosts/fusion/api/plugin.py @@ -11,7 +11,6 @@ from ayon_core.lib import ( EnumDef, ) from ayon_core.pipeline import ( - legacy_io, Creator, CreatedInstance ) @@ -136,7 +135,7 @@ class GenericCreateSaver(Creator): ext = data["creator_attributes"]["image_format"] # Subset change detected - workdir = os.path.normpath(legacy_io.Session["AVALON_WORKDIR"]) + workdir = os.path.normpath(os.getenv("AVALON_WORKDIR")) formatting_data.update({ "workdir": workdir, "frame": "0" * frame_padding, diff --git a/client/ayon_core/hosts/maya/api/pipeline.py b/client/ayon_core/hosts/maya/api/pipeline.py index 95617cb90a..dc6353618a 100644 --- a/client/ayon_core/hosts/maya/api/pipeline.py +++ b/client/ayon_core/hosts/maya/api/pipeline.py @@ -26,7 +26,6 @@ from ayon_core.lib import ( emit_event ) from ayon_core.pipeline import ( - legacy_io, get_current_project_name, register_loader_plugin_path, register_inventory_action_path, @@ -247,7 +246,7 @@ def _set_project(): None """ - workdir = legacy_io.Session["AVALON_WORKDIR"] + workdir = os.getenv("AVALON_WORKDIR") try: os.makedirs(workdir) @@ -629,7 +628,7 @@ def on_task_changed(): # Run menu.update_menu_task_label() - workdir = legacy_io.Session["AVALON_WORKDIR"] + workdir = os.getenv("AVALON_WORKDIR") if os.path.exists(workdir): log.info("Updating Maya workspace for task change to %s", workdir) _set_project() @@ -678,7 +677,7 @@ def workfile_save_before_xgen(event): import xgenm - current_work_dir = legacy_io.Session["AVALON_WORKDIR"].replace("\\", "/") + current_work_dir = os.getenv("AVALON_WORKDIR").replace("\\", "/") expected_work_dir = event.data["workdir_path"].replace("\\", "/") if current_work_dir == expected_work_dir: return diff --git a/client/ayon_core/hosts/maya/plugins/load/load_arnold_standin.py b/client/ayon_core/hosts/maya/plugins/load/load_arnold_standin.py index c690d1c205..97407fbcc2 100644 --- a/client/ayon_core/hosts/maya/plugins/load/load_arnold_standin.py +++ b/client/ayon_core/hosts/maya/plugins/load/load_arnold_standin.py @@ -6,7 +6,6 @@ import maya.cmds as cmds from ayon_core.settings import get_project_settings from ayon_core.pipeline import ( load, - legacy_io, get_representation_path ) from ayon_core.hosts.maya.api.lib import ( @@ -26,11 +25,6 @@ def is_sequence(files): return sequence -def get_current_session_fps(): - session_fps = float(legacy_io.Session.get('AVALON_FPS', 25)) - return convert_to_maya_fps(session_fps) - - class ArnoldStandinLoader(load.LoaderPlugin): """Load as Arnold standin""" @@ -99,7 +93,7 @@ class ArnoldStandinLoader(load.LoaderPlugin): sequence = is_sequence(os.listdir(os.path.dirname(repre_path))) cmds.setAttr(standin_shape + ".useFrameExtension", sequence) - fps = float(version["data"].get("fps"))or get_current_session_fps() + fps = float(version["data"].get("fps")) or 25 cmds.setAttr(standin_shape + ".abcFPS", fps) nodes = [root, standin, standin_shape] diff --git a/client/ayon_core/hosts/maya/plugins/publish/collect_vrayscene.py b/client/ayon_core/hosts/maya/plugins/publish/collect_vrayscene.py index 0efefe72c7..db008cc2be 100644 --- a/client/ayon_core/hosts/maya/plugins/publish/collect_vrayscene.py +++ b/client/ayon_core/hosts/maya/plugins/publish/collect_vrayscene.py @@ -1,13 +1,8 @@ # -*- coding: utf-8 -*- """Collect Vray Scene and prepare it for extraction and publishing.""" -import re - -import maya.app.renderSetup.model.renderSetup as renderSetup -from maya import cmds import pyblish.api -from ayon_core.pipeline import legacy_io from ayon_core.lib import get_formatted_current_time from ayon_core.hosts.maya.api import lib diff --git a/client/ayon_core/hosts/maya/plugins/publish/validate_model_name.py b/client/ayon_core/hosts/maya/plugins/publish/validate_model_name.py index 7812877fd3..cf2bbcd77c 100644 --- a/client/ayon_core/hosts/maya/plugins/publish/validate_model_name.py +++ b/client/ayon_core/hosts/maya/plugins/publish/validate_model_name.py @@ -12,7 +12,6 @@ import ayon_core.hosts.maya.api.action from ayon_core.client.mongo import OpenPypeMongoConnection from ayon_core.hosts.maya.api.shader_definition_editor import ( DEFINITION_FILENAME) -from ayon_core.pipeline import legacy_io from ayon_core.pipeline.publish import ( OptionalPyblishPluginMixin, PublishValidationError, ValidateContentsOrder) diff --git a/client/ayon_core/hosts/maya/plugins/publish/validate_node_ids_in_database.py b/client/ayon_core/hosts/maya/plugins/publish/validate_node_ids_in_database.py index bf12def5e9..de86ffe575 100644 --- a/client/ayon_core/hosts/maya/plugins/publish/validate_node_ids_in_database.py +++ b/client/ayon_core/hosts/maya/plugins/publish/validate_node_ids_in_database.py @@ -3,7 +3,6 @@ import pyblish.api import ayon_core.hosts.maya.api.action from ayon_core.client import get_assets from ayon_core.hosts.maya.api import lib -from ayon_core.pipeline import legacy_io from ayon_core.pipeline.publish import ( PublishValidationError, ValidatePipelineOrder) diff --git a/client/ayon_core/hosts/maya/plugins/publish/validate_renderlayer_aovs.py b/client/ayon_core/hosts/maya/plugins/publish/validate_renderlayer_aovs.py index 71cd6d7112..b5bfdcc9ec 100644 --- a/client/ayon_core/hosts/maya/plugins/publish/validate_renderlayer_aovs.py +++ b/client/ayon_core/hosts/maya/plugins/publish/validate_renderlayer_aovs.py @@ -2,7 +2,6 @@ import pyblish.api import ayon_core.hosts.maya.api.action from ayon_core.client import get_subset_by_name -from ayon_core.pipeline import legacy_io from ayon_core.pipeline.publish import PublishValidationError diff --git a/client/ayon_core/hosts/maya/plugins/publish/validate_unreal_staticmesh_naming.py b/client/ayon_core/hosts/maya/plugins/publish/validate_unreal_staticmesh_naming.py index d43e04da60..21ea827f68 100644 --- a/client/ayon_core/hosts/maya/plugins/publish/validate_unreal_staticmesh_naming.py +++ b/client/ayon_core/hosts/maya/plugins/publish/validate_unreal_staticmesh_naming.py @@ -5,8 +5,6 @@ import re import pyblish.api import ayon_core.hosts.maya.api.action -from ayon_core.pipeline import legacy_io -from ayon_core.settings import get_project_settings from ayon_core.pipeline.publish import ( ValidateContentsOrder, OptionalPyblishPluginMixin, diff --git a/client/ayon_core/hosts/photoshop/plugins/publish/collect_batch_data.py b/client/ayon_core/hosts/photoshop/plugins/publish/collect_batch_data.py index 5e43a021c3..6639040bd7 100644 --- a/client/ayon_core/hosts/photoshop/plugins/publish/collect_batch_data.py +++ b/client/ayon_core/hosts/photoshop/plugins/publish/collect_batch_data.py @@ -17,7 +17,6 @@ import os import pyblish.api -from ayon_core.pipeline import legacy_io from openpype_modules.webpublisher.lib import ( get_batch_asset_task_info, parse_json @@ -71,8 +70,6 @@ class CollectBatchData(pyblish.api.ContextPlugin): os.environ["AVALON_ASSET"] = asset_name os.environ["AVALON_TASK"] = task_name - legacy_io.Session["AVALON_ASSET"] = asset_name - legacy_io.Session["AVALON_TASK"] = task_name context.data["asset"] = asset_name context.data["task"] = task_name diff --git a/client/ayon_core/hosts/traypublisher/api/pipeline.py b/client/ayon_core/hosts/traypublisher/api/pipeline.py index 87177705c9..88fa3239a5 100644 --- a/client/ayon_core/hosts/traypublisher/api/pipeline.py +++ b/client/ayon_core/hosts/traypublisher/api/pipeline.py @@ -7,7 +7,6 @@ import pyblish.api from ayon_core.pipeline import ( register_creator_plugin_path, - legacy_io, ) from ayon_core.host import HostBase, IPublishHost @@ -24,7 +23,6 @@ class TrayPublisherHost(HostBase, IPublishHost): def install(self): os.environ["AVALON_APP"] = self.name - legacy_io.Session["AVALON_APP"] = self.name pyblish.api.register_host("traypublisher") pyblish.api.register_plugin_path(PUBLISH_PATH) @@ -43,8 +41,6 @@ class TrayPublisherHost(HostBase, IPublishHost): # TODO Deregister project specific plugins and register new project # plugins os.environ["AVALON_PROJECT"] = project_name - legacy_io.Session["AVALON_PROJECT"] = project_name - legacy_io.install() HostContext.set_project_name(project_name) diff --git a/client/ayon_core/hosts/tvpaint/api/pipeline.py b/client/ayon_core/hosts/tvpaint/api/pipeline.py index 1360b423b3..d636e68cfa 100644 --- a/client/ayon_core/hosts/tvpaint/api/pipeline.py +++ b/client/ayon_core/hosts/tvpaint/api/pipeline.py @@ -13,7 +13,6 @@ from ayon_core.hosts.tvpaint import TVPAINT_ROOT_DIR from ayon_core.settings import get_current_project_settings from ayon_core.lib import register_event_callback from ayon_core.pipeline import ( - legacy_io, register_loader_plugin_path, register_creator_plugin_path, AVALON_CONTAINER_ID, @@ -66,11 +65,10 @@ class TVPaintHost(HostBase, IWorkfileHost, ILoadHost, IPublishHost): def install(self): """Install TVPaint-specific functionality.""" - log.info("OpenPype - Installing TVPaint integration") - legacy_io.install() + log.info("AYON - Installing TVPaint integration") # Create workdir folder if does not exist yet - workdir = legacy_io.Session["AVALON_WORKDIR"] + workdir = os.getenv("AVALON_WORKDIR") if not os.path.exists(workdir): os.makedirs(workdir) diff --git a/client/ayon_core/hosts/tvpaint/plugins/publish/collect_workfile_data.py b/client/ayon_core/hosts/tvpaint/plugins/publish/collect_workfile_data.py index 9fbf67863a..05ceb143e9 100644 --- a/client/ayon_core/hosts/tvpaint/plugins/publish/collect_workfile_data.py +++ b/client/ayon_core/hosts/tvpaint/plugins/publish/collect_workfile_data.py @@ -4,7 +4,6 @@ import tempfile import pyblish.api -from ayon_core.pipeline import legacy_io from ayon_core.hosts.tvpaint.api.lib import ( execute_george, execute_george_through_file, @@ -90,7 +89,6 @@ class CollectWorkfileData(pyblish.api.ContextPlugin): ("AVALON_TASK", "task_name") ) for env_key, key in key_map: - legacy_io.Session[env_key] = workfile_context[key] os.environ[env_key] = workfile_context[key] self.log.info("Context changed to: {}".format(workfile_context)) diff --git a/client/ayon_core/modules/royalrender/plugins/publish/collect_sequences_from_job.py b/client/ayon_core/modules/royalrender/plugins/publish/collect_sequences_from_job.py index a253a1ec5b..cd34ba9bb3 100644 --- a/client/ayon_core/modules/royalrender/plugins/publish/collect_sequences_from_job.py +++ b/client/ayon_core/modules/royalrender/plugins/publish/collect_sequences_from_job.py @@ -8,8 +8,6 @@ from pprint import pformat import pyblish.api -from ayon_core.pipeline import legacy_io - def collect(root, regex=None, @@ -132,7 +130,6 @@ class CollectSequencesFromJob(pyblish.api.ContextPlugin): session = metadata.get("session") if session: self.log.info("setting session using metadata") - legacy_io.Session.update(session) os.environ.update(session) else: diff --git a/client/ayon_core/modules/royalrender/plugins/publish/create_publish_royalrender_job.py b/client/ayon_core/modules/royalrender/plugins/publish/create_publish_royalrender_job.py index 680795a329..abc8d7dccd 100644 --- a/client/ayon_core/modules/royalrender/plugins/publish/create_publish_royalrender_job.py +++ b/client/ayon_core/modules/royalrender/plugins/publish/create_publish_royalrender_job.py @@ -13,9 +13,6 @@ from ayon_core.modules.royalrender.rr_job import ( get_rr_platform ) from ayon_core.pipeline.publish import KnownPublishError -from ayon_core.pipeline import ( - legacy_io, -) from ayon_core.pipeline.farm.pyblish_functions import ( create_skeleton_instance, create_instances_for_aov, @@ -145,7 +142,6 @@ class CreatePublishRoyalRenderJob(pyblish.api.InstancePlugin, "intent": instance.context.data.get("intent"), "comment": instance.context.data.get("comment"), "job": attr.asdict(rr_job), - "session": legacy_io.Session.copy(), "instances": instances } diff --git a/client/ayon_core/pipeline/context_tools.py b/client/ayon_core/pipeline/context_tools.py index 197b1eb6e6..64d8e1f6d6 100644 --- a/client/ayon_core/pipeline/context_tools.py +++ b/client/ayon_core/pipeline/context_tools.py @@ -29,11 +29,11 @@ from .publish.lib import filter_pyblish_plugins from .anatomy import Anatomy from .template_data import get_template_data_with_names from .workfile import ( + get_workdir, get_workfile_template_key, get_custom_workfile_template_by_string_context, ) from . import ( - legacy_io, register_loader_plugin_path, register_inventory_action_path, register_creator_plugin_path, @@ -116,22 +116,15 @@ def install_host(host): # Make sure global AYON connection has set site id and version get_ayon_server_api_connection() - legacy_io.install() addons_manager = _get_addons_manager() - missing = list() - for key in ("AVALON_PROJECT", "AVALON_ASSET"): - if key not in legacy_io.Session: - missing.append(key) + project_name = os.getenv("AVALON_PROJECT") + if not project_name: + raise ValueError( + "AVALON_PROJECT is missing in environment variables." + ) - assert not missing, ( - "%s missing from environment, %s" % ( - ", ".join(missing), - json.dumps(legacy_io.Session, indent=4, sort_keys=True) - )) - - project_name = legacy_io.Session["AVALON_PROJECT"] - log.info("Activating %s.." % project_name) + log.info("Activating {}..".format(project_name)) # Optional host install function if hasattr(host, "install"): @@ -158,7 +151,6 @@ def install_host(host): print("Registering pyblish target: automated") pyblish.api.register_target("automated") - project_name = os.environ.get("AVALON_PROJECT") host_name = os.environ.get("AVALON_APP") # Give option to handle host installation @@ -256,8 +248,6 @@ def uninstall_host(): deregister_host() - legacy_io.uninstall() - log.info("Successfully uninstalled Avalon!") @@ -482,13 +472,17 @@ def get_template_data_from_session(session=None, system_settings=None): Dict[str, Any]: All available data from session. """ - if session is None: - session = legacy_io.Session - - project_name = session["AVALON_PROJECT"] - asset_name = session["AVALON_ASSET"] - task_name = session["AVALON_TASK"] - host_name = session["AVALON_APP"] + if session is not None: + project_name = session["AVALON_PROJECT"] + asset_name = session["AVALON_ASSET"] + task_name = session["AVALON_TASK"] + host_name = session["AVALON_APP"] + else: + context = get_current_context() + project_name = context["project_name"] + asset_name = context["asset_name"] + task_name = context["task_name"] + host_name = get_current_host_name() return get_template_data_with_names( project_name, asset_name, task_name, host_name, system_settings @@ -529,10 +523,12 @@ def get_workdir_from_session(session=None, template_key=None): str: Workdir path. """ - if session is None: - session = legacy_io.Session - project_name = session["AVALON_PROJECT"] - host_name = session["AVALON_APP"] + if session is not None: + project_name = session["AVALON_PROJECT"] + host_name = session["AVALON_APP"] + else: + project_name = get_current_project_name() + host_name = get_current_host_name() template_data = get_template_data_from_session(session) if not template_key: @@ -556,86 +552,39 @@ def get_custom_workfile_template_from_session( ): """Filter and fill workfile template profiles by current context. - Current context is defined by `legacy_io.Session`. That's why this - function should be used only inside host where context is set and stable. + This function cab be used only inside host where context is set. Args: - session (Union[None, Dict[str, str]]): Session from which are taken + session (Optional[Dict[str, str]]): Session from which are taken data. - project_settings(Dict[str, Any]): Template profiles from settings. + project_settings(Optional[Dict[str, Any]]): Project settings. Returns: str: Path to template or None if none of profiles match current context. (Existence of formatted path is not validated.) """ - if session is None: - session = legacy_io.Session + if session is not None: + project_name = session["AVALON_PROJECT"] + asset_name = session["AVALON_ASSET"] + task_name = session["AVALON_TASK"] + host_name = session["AVALON_APP"] + else: + context = get_current_context() + project_name = context["project_name"] + asset_name = context["asset_name"] + task_name = context["task_name"] + host_name = get_current_host_name() return get_custom_workfile_template_by_string_context( - session["AVALON_PROJECT"], - session["AVALON_ASSET"], - session["AVALON_TASK"], - session["AVALON_APP"], + project_name, + asset_name, + task_name, + host_name, project_settings=project_settings ) -def compute_session_changes( - session, asset_doc, task_name, template_key=None -): - """Compute the changes for a session object on task under asset. - - Function does not change the session object, only returns changes. - - Args: - session (Dict[str, str]): The initial session to compute changes to. - This is required for computing the full Work Directory, as that - also depends on the values that haven't changed. - asset_doc (Dict[str, Any]): Asset document to switch to. - task_name (str): Name of task to switch to. - template_key (Union[str, None]): Prepare workfile template key in - anatomy templates. - - Returns: - Dict[str, str]: Changes in the Session dictionary. - """ - - # Get asset document and asset - if not asset_doc: - task_name = None - asset_name = None - else: - asset_name = get_asset_name_identifier(asset_doc) - - # Detect any changes compared session - mapping = { - "AVALON_ASSET": asset_name, - "AVALON_TASK": task_name, - } - changes = { - key: value - for key, value in mapping.items() - if value != session.get(key) - } - if not changes: - return changes - - # Compute work directory (with the temporary changed session so far) - changed_session = session.copy() - changed_session.update(changes) - - workdir = None - if asset_doc: - workdir = get_workdir_from_session( - changed_session, template_key - ) - - changes["AVALON_WORKDIR"] = workdir - - return changes - - def change_current_context(asset_doc, task_name, template_key=None): """Update active Session to a new task work area. @@ -651,32 +600,47 @@ def change_current_context(asset_doc, task_name, template_key=None): Dict[str, str]: The changed key, values in the current Session. """ - changes = compute_session_changes( - legacy_io.Session, - asset_doc, - task_name, - template_key=template_key - ) + project_name = get_current_project_name() + workdir = None + if asset_doc: + project_doc = get_project(project_name) + host_name = get_current_host_name() + workdir = get_workdir( + project_doc, + asset_doc, + task_name, + host_name, + template_key=template_key + ) + + folder_path = get_asset_name_identifier(asset_doc) + envs = { + "AVALON_PROJECT": project_name, + "AVALON_ASSET": folder_path, + "AVALON_TASK": task_name, + "AVALON_WORKDIR": workdir, + } # Update the Session and environments. Pop from environments all keys with # value set to None. - for key, value in changes.items(): - legacy_io.Session[key] = value + for key, value in envs.items(): if value is None: os.environ.pop(key, None) else: os.environ[key] = value - data = changes.copy() + data = envs.copy() + # Convert env keys to human readable keys - data["project_name"] = legacy_io.Session["AVALON_PROJECT"] - data["asset_name"] = legacy_io.Session["AVALON_ASSET"] - data["task_name"] = legacy_io.Session["AVALON_TASK"] + data["project_name"] = project_name + data["asset_name"] = get_asset_name_identifier(asset_doc) + data["task_name"] = task_name + data["workdir_path"] = workdir # Emit session change emit_event("taskChanged", data) - return changes + return data def get_process_id(): diff --git a/client/ayon_core/pipeline/create/context.py b/client/ayon_core/pipeline/create/context.py index 8990d50324..be685ea2cc 100644 --- a/client/ayon_core/pipeline/create/context.py +++ b/client/ayon_core/pipeline/create/context.py @@ -27,7 +27,7 @@ from ayon_core.lib.attribute_definitions import ( get_default_values, ) from ayon_core.host import IPublishHost, IWorkfileHost -from ayon_core.pipeline import legacy_io, Anatomy +from ayon_core.pipeline import Anatomy from ayon_core.pipeline.plugin_discover import DiscoverResult from .creator_plugins import ( @@ -1684,25 +1684,16 @@ class CreateContext: if isinstance(self.host, IWorkfileHost): workfile_path = self.host.get_current_workfile() - # --- TODO remove these conditions --- - if not project_name: - project_name = legacy_io.Session.get("AVALON_PROJECT") - if not asset_name: - asset_name = legacy_io.Session.get("AVALON_ASSET") - if not task_name: - task_name = legacy_io.Session.get("AVALON_TASK") - # --- return project_name, asset_name, task_name, workfile_path def reset_current_context(self): """Refresh current context. Reset is based on optional host implementation of `get_current_context` - function or using `legacy_io.Session`. + function. Some hosts have ability to change context file without using workfiles - tool but that change is not propagated to 'legacy_io.Session' - nor 'os.environ'. + tool but that change is not propagated to 'os.environ'. Todos: UI: Current context should be also checked on save - compare diff --git a/client/ayon_core/pipeline/create/subset_name.py b/client/ayon_core/pipeline/create/subset_name.py index 3892971ce8..2973b1e54e 100644 --- a/client/ayon_core/pipeline/create/subset_name.py +++ b/client/ayon_core/pipeline/create/subset_name.py @@ -2,7 +2,6 @@ import os from ayon_core.settings import get_project_settings from ayon_core.lib import filter_profiles, prepare_template_data -from ayon_core.pipeline import legacy_io from .constants import DEFAULT_SUBSET_TEMPLATE @@ -135,7 +134,7 @@ def get_subset_name( family = family.rsplit(".", 1)[-1] if project_name is None: - project_name = legacy_io.Session["AVALON_PROJECT"] + project_name = os.environ.get("AVALON_PROJECT") asset_tasks = asset_doc.get("data", {}).get("tasks") or {} task_info = asset_tasks.get(task_name) or {} diff --git a/client/ayon_core/pipeline/load/plugins.py b/client/ayon_core/pipeline/load/plugins.py index e13260d296..fc64edf2ae 100644 --- a/client/ayon_core/pipeline/load/plugins.py +++ b/client/ayon_core/pipeline/load/plugins.py @@ -2,10 +2,7 @@ import os import logging from ayon_core.settings import get_system_settings, get_project_settings -from ayon_core.pipeline import ( - schema, - legacy_io, -) +from ayon_core.pipeline import schema from ayon_core.pipeline.plugin_discover import ( discover, register_plugin, diff --git a/client/ayon_core/plugins/publish/collect_from_create_context.py b/client/ayon_core/plugins/publish/collect_from_create_context.py index d38138b2e9..d8e803a43c 100644 --- a/client/ayon_core/plugins/publish/collect_from_create_context.py +++ b/client/ayon_core/plugins/publish/collect_from_create_context.py @@ -5,7 +5,7 @@ import os import pyblish.api from ayon_core.host import IPublishHost -from ayon_core.pipeline import legacy_io, registered_host +from ayon_core.pipeline import registered_host from ayon_core.pipeline.create import CreateContext @@ -61,7 +61,6 @@ class CollectFromCreateContext(pyblish.api.ContextPlugin): ("AVALON_ASSET", asset_name), ("AVALON_TASK", task_name) ): - legacy_io.Session[key] = value os.environ[key] = value def create_instance( diff --git a/client/ayon_core/tools/sceneinventory/control.py b/client/ayon_core/tools/sceneinventory/control.py index 409f92b506..54e4e9941e 100644 --- a/client/ayon_core/tools/sceneinventory/control.py +++ b/client/ayon_core/tools/sceneinventory/control.py @@ -14,8 +14,7 @@ from .models import SiteSyncModel class SceneInventoryController: """This is a temporary controller for AYON. - Goal of this temporary controller is to provide a way to get current - context instead of using 'AvalonMongoDB' object (or 'legacy_io'). + Goal of this controller is to provide a way to get current context. Also provides (hopefully) cleaner api for site sync. """ diff --git a/client/ayon_core/tools/texture_copy/app.py b/client/ayon_core/tools/texture_copy/app.py index 064f4e5577..9b4406d8e7 100644 --- a/client/ayon_core/tools/texture_copy/app.py +++ b/client/ayon_core/tools/texture_copy/app.py @@ -6,7 +6,7 @@ import speedcopy from ayon_core.client import get_project, get_asset_by_name from ayon_core.lib import Terminal -from ayon_core.pipeline import legacy_io, Anatomy +from ayon_core.pipeline import Anatomy t = Terminal() @@ -16,11 +16,6 @@ texture_extensions = ['.tif', '.tiff', '.jpg', '.jpeg', '.tx', '.png', '.tga', class TextureCopy: - - def __init__(self): - if not legacy_io.Session: - legacy_io.install() - def _get_textures(self, path): textures = [] for dir, subdir, files in os.walk(path): diff --git a/client/ayon_core/tools/workfile_template_build/window.py b/client/ayon_core/tools/workfile_template_build/window.py index 7f95bac60a..ae4946d41d 100644 --- a/client/ayon_core/tools/workfile_template_build/window.py +++ b/client/ayon_core/tools/workfile_template_build/window.py @@ -1,8 +1,9 @@ +import os + from qtpy import QtWidgets from ayon_core import style from ayon_core.lib import Logger -from ayon_core.pipeline import legacy_io from ayon_core.tools.attribute_defs import AttributeDefinitionsWidget @@ -26,7 +27,7 @@ class WorkfileBuildPlaceholderDialog(QtWidgets.QDialog): host_name = getattr(self._host, "name", None) if not host_name: - host_name = legacy_io.Session.get("AVALON_APP") or "NA" + host_name = os.getenv("AVALON_APP") or "NA" self._host_name = host_name plugins_combo = QtWidgets.QComboBox(self) From e40cc563004524b7c576f17c6e83d279f9f17e28 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Thu, 8 Feb 2024 14:51:15 +0100 Subject: [PATCH 023/185] don't use legacy_io in farm deadline --- .../publish/submit_aftereffects_deadline.py | 9 ++++-- .../publish/submit_blender_deadline.py | 9 ++++-- .../plugins/publish/submit_fusion_deadline.py | 9 ++++-- .../publish/submit_harmony_deadline.py | 9 ++++-- .../publish/submit_houdini_cache_deadline.py | 9 ++++-- .../publish/submit_houdini_render_deadline.py | 10 +++++-- .../plugins/publish/submit_max_deadline.py | 9 ++++-- .../plugins/publish/submit_maya_deadline.py | 9 ++++-- .../submit_maya_remote_publish_deadline.py | 10 ++++--- .../plugins/publish/submit_nuke_deadline.py | 8 ++++-- .../publish/submit_publish_cache_job.py | 5 ++-- .../plugins/publish/submit_publish_job.py | 5 ++-- .../plugins/publish/collect_rendered_files.py | 28 +++++++++++-------- 13 files changed, 80 insertions(+), 49 deletions(-) diff --git a/client/ayon_core/modules/deadline/plugins/publish/submit_aftereffects_deadline.py b/client/ayon_core/modules/deadline/plugins/publish/submit_aftereffects_deadline.py index f7bc5529fb..618b71bbaf 100644 --- a/client/ayon_core/modules/deadline/plugins/publish/submit_aftereffects_deadline.py +++ b/client/ayon_core/modules/deadline/plugins/publish/submit_aftereffects_deadline.py @@ -8,7 +8,6 @@ from ayon_core.lib import ( env_value_to_bool, collect_frames, ) -from ayon_core.pipeline import legacy_io from openpype_modules.deadline import abstract_submit_deadline from openpype_modules.deadline.abstract_submit_deadline import DeadlineJobInfo from ayon_core.tests.lib import is_in_tests @@ -84,13 +83,17 @@ class AfterEffectsSubmitDeadline( "AVALON_PROJECT", "AVALON_ASSET", "AVALON_TASK", + "AVALON_WORKDIR", "AVALON_APP_NAME", "AYON_LOG_NO_COLORS", "IS_TEST" ] - environment = dict({key: os.environ[key] for key in keys - if key in os.environ}, **legacy_io.Session) + environment = { + key: os.environ[key] + for key in keys + if key in os.environ + } for key in keys: value = environment.get(key) if value: diff --git a/client/ayon_core/modules/deadline/plugins/publish/submit_blender_deadline.py b/client/ayon_core/modules/deadline/plugins/publish/submit_blender_deadline.py index c8b72ca52b..af864ace5b 100644 --- a/client/ayon_core/modules/deadline/plugins/publish/submit_blender_deadline.py +++ b/client/ayon_core/modules/deadline/plugins/publish/submit_blender_deadline.py @@ -11,7 +11,6 @@ from ayon_core.lib import ( NumberDef, TextDef, ) -from ayon_core.pipeline import legacy_io from ayon_core.pipeline.publish import AYONPyblishPluginMixin from ayon_core.pipeline.farm.tools import iter_expected_files from ayon_core.tests.lib import is_in_tests @@ -106,12 +105,16 @@ class BlenderSubmitDeadline(abstract_submit_deadline.AbstractSubmitDeadline, "AVALON_PROJECT", "AVALON_ASSET", "AVALON_TASK", + "AVALON_WORKDIR", "AVALON_APP_NAME", "IS_TEST" ] - environment = dict({key: os.environ[key] for key in keys - if key in os.environ}, **legacy_io.Session) + environment = { + key: os.environ[key] + for key in keys + if key in os.environ + } for key in keys: value = environment.get(key) diff --git a/client/ayon_core/modules/deadline/plugins/publish/submit_fusion_deadline.py b/client/ayon_core/modules/deadline/plugins/publish/submit_fusion_deadline.py index 77505eb623..7aa8546bb6 100644 --- a/client/ayon_core/modules/deadline/plugins/publish/submit_fusion_deadline.py +++ b/client/ayon_core/modules/deadline/plugins/publish/submit_fusion_deadline.py @@ -6,7 +6,6 @@ import requests import pyblish.api -from ayon_core.pipeline import legacy_io from ayon_core.pipeline.publish import ( AYONPyblishPluginMixin ) @@ -224,14 +223,18 @@ class FusionSubmitDeadline( "AVALON_PROJECT", "AVALON_ASSET", "AVALON_TASK", + "AVALON_WORKDIR", "AVALON_APP_NAME", "AYON_LOG_NO_COLORS", "IS_TEST", "AYON_BUNDLE_NAME", ] - environment = dict({key: os.environ[key] for key in keys - if key in os.environ}, **legacy_io.Session) + environment = { + key: os.environ[key] + for key in keys + if key in os.environ + } # to recognize render jobs environment["AYON_RENDER_JOB"] = "1" diff --git a/client/ayon_core/modules/deadline/plugins/publish/submit_harmony_deadline.py b/client/ayon_core/modules/deadline/plugins/publish/submit_harmony_deadline.py index f2f1c90559..4d375299fa 100644 --- a/client/ayon_core/modules/deadline/plugins/publish/submit_harmony_deadline.py +++ b/client/ayon_core/modules/deadline/plugins/publish/submit_harmony_deadline.py @@ -10,7 +10,6 @@ from datetime import datetime import attr import pyblish.api -from ayon_core.pipeline import legacy_io from openpype_modules.deadline import abstract_submit_deadline from openpype_modules.deadline.abstract_submit_deadline import DeadlineJobInfo from ayon_core.tests.lib import is_in_tests @@ -277,13 +276,17 @@ class HarmonySubmitDeadline( "AVALON_PROJECT", "AVALON_ASSET", "AVALON_TASK", + "AVALON_WORKDIR", "AVALON_APP_NAME", "AYON_LOG_NO_COLORS" "IS_TEST" ] - environment = dict({key: os.environ[key] for key in keys - if key in os.environ}, **legacy_io.Session) + environment = { + key: os.environ[key] + for key in keys + if key in os.environ + } for key in keys: value = environment.get(key) if value: diff --git a/client/ayon_core/modules/deadline/plugins/publish/submit_houdini_cache_deadline.py b/client/ayon_core/modules/deadline/plugins/publish/submit_houdini_cache_deadline.py index eed930e372..96ee80c4d7 100644 --- a/client/ayon_core/modules/deadline/plugins/publish/submit_houdini_cache_deadline.py +++ b/client/ayon_core/modules/deadline/plugins/publish/submit_houdini_cache_deadline.py @@ -9,7 +9,6 @@ from ayon_core.lib import ( NumberDef, ) from ayon_core.pipeline import ( - legacy_io, AYONPyblishPluginMixin ) from ayon_core.tests.lib import is_in_tests @@ -102,12 +101,16 @@ class HoudiniCacheSubmitDeadline(abstract_submit_deadline.AbstractSubmitDeadline "AVALON_PROJECT", "AVALON_ASSET", "AVALON_TASK", + "AVALON_WORKDIR", "AVALON_APP_NAME", "AYON_LOG_NO_COLORS", ] - environment = dict({key: os.environ[key] for key in keys - if key in os.environ}, **legacy_io.Session) + environment = { + key: os.environ[key] + for key in keys + if key in os.environ + } for key in keys: value = environment.get(key) diff --git a/client/ayon_core/modules/deadline/plugins/publish/submit_houdini_render_deadline.py b/client/ayon_core/modules/deadline/plugins/publish/submit_houdini_render_deadline.py index 9988248957..d7a062c9a6 100644 --- a/client/ayon_core/modules/deadline/plugins/publish/submit_houdini_render_deadline.py +++ b/client/ayon_core/modules/deadline/plugins/publish/submit_houdini_render_deadline.py @@ -5,7 +5,7 @@ from datetime import datetime import pyblish.api -from ayon_core.pipeline import legacy_io, AYONPyblishPluginMixin +from ayon_core.pipeline import AYONPyblishPluginMixin from ayon_core.tests.lib import is_in_tests from openpype_modules.deadline import abstract_submit_deadline from openpype_modules.deadline.abstract_submit_deadline import DeadlineJobInfo @@ -207,12 +207,16 @@ class HoudiniSubmitDeadline( "AVALON_PROJECT", "AVALON_ASSET", "AVALON_TASK", + "AVALON_WORKDIR", "AVALON_APP_NAME", "AYON_LOG_NO_COLORS", ] - environment = dict({key: os.environ[key] for key in keys - if key in os.environ}, **legacy_io.Session) + environment = { + key: os.environ[key] + for key in keys + if key in os.environ + } for key in keys: value = environment.get(key) diff --git a/client/ayon_core/modules/deadline/plugins/publish/submit_max_deadline.py b/client/ayon_core/modules/deadline/plugins/publish/submit_max_deadline.py index 0a7c96008e..8908283164 100644 --- a/client/ayon_core/modules/deadline/plugins/publish/submit_max_deadline.py +++ b/client/ayon_core/modules/deadline/plugins/publish/submit_max_deadline.py @@ -9,7 +9,6 @@ from ayon_core.lib import ( NumberDef, ) from ayon_core.pipeline import ( - legacy_io, AYONPyblishPluginMixin ) from ayon_core.pipeline.publish.lib import ( @@ -110,12 +109,16 @@ class MaxSubmitDeadline(abstract_submit_deadline.AbstractSubmitDeadline, "AVALON_PROJECT", "AVALON_ASSET", "AVALON_TASK", + "AVALON_WORKDIR", "AVALON_APP_NAME", "IS_TEST" ] - environment = dict({key: os.environ[key] for key in keys - if key in os.environ}, **legacy_io.Session) + environment = { + key: os.environ[key] + for key in keys + if key in os.environ + } for key in keys: value = environment.get(key) diff --git a/client/ayon_core/modules/deadline/plugins/publish/submit_maya_deadline.py b/client/ayon_core/modules/deadline/plugins/publish/submit_maya_deadline.py index 84e6e93e6a..2b7a7cf698 100644 --- a/client/ayon_core/modules/deadline/plugins/publish/submit_maya_deadline.py +++ b/client/ayon_core/modules/deadline/plugins/publish/submit_maya_deadline.py @@ -29,7 +29,6 @@ from collections import OrderedDict import attr from ayon_core.pipeline import ( - legacy_io, AYONPyblishPluginMixin ) from ayon_core.lib import ( @@ -203,12 +202,16 @@ class MayaSubmitDeadline(abstract_submit_deadline.AbstractSubmitDeadline, "AVALON_PROJECT", "AVALON_ASSET", "AVALON_TASK", + "AVALON_WORKDIR", "AVALON_APP_NAME", "IS_TEST" ] - environment = dict({key: os.environ[key] for key in keys - if key in os.environ}, **legacy_io.Session) + environment = { + key: os.environ[key] + for key in keys + if key in os.environ + } for key in keys: value = environment.get(key) diff --git a/client/ayon_core/modules/deadline/plugins/publish/submit_maya_remote_publish_deadline.py b/client/ayon_core/modules/deadline/plugins/publish/submit_maya_remote_publish_deadline.py index 02338c5c32..ed360d84ae 100644 --- a/client/ayon_core/modules/deadline/plugins/publish/submit_maya_remote_publish_deadline.py +++ b/client/ayon_core/modules/deadline/plugins/publish/submit_maya_remote_publish_deadline.py @@ -2,7 +2,7 @@ import os import attr from datetime import datetime -from ayon_core.pipeline import legacy_io, PublishXmlValidationError +from ayon_core.pipeline import PublishXmlValidationError from ayon_core.tests.lib import is_in_tests from openpype_modules.deadline import abstract_submit_deadline from openpype_modules.deadline.abstract_submit_deadline import DeadlineJobInfo @@ -98,10 +98,12 @@ class MayaSubmitRemotePublishDeadline( "FTRACK_SERVER" ] - environment = dict({key: os.environ[key] for key in keys - if key in os.environ}, **legacy_io.Session) + environment = { + key: os.environ[key] + for key in keys + if key in os.environ + } - # TODO replace legacy_io with context.data environment["AVALON_PROJECT"] = project_name environment["AVALON_ASSET"] = instance.context.data["asset"] environment["AVALON_TASK"] = instance.context.data["task"] diff --git a/client/ayon_core/modules/deadline/plugins/publish/submit_nuke_deadline.py b/client/ayon_core/modules/deadline/plugins/publish/submit_nuke_deadline.py index 9fff8edee6..61a334e184 100644 --- a/client/ayon_core/modules/deadline/plugins/publish/submit_nuke_deadline.py +++ b/client/ayon_core/modules/deadline/plugins/publish/submit_nuke_deadline.py @@ -7,7 +7,6 @@ from datetime import datetime import requests import pyblish.api -from ayon_core.pipeline import legacy_io from ayon_core.pipeline.publish import ( AYONPyblishPluginMixin ) @@ -393,8 +392,11 @@ class NukeSubmitDeadline(pyblish.api.InstancePlugin, if self.env_allowed_keys: keys += self.env_allowed_keys - environment = dict({key: os.environ[key] for key in keys - if key in os.environ}, **legacy_io.Session) + environment = { + key: os.environ[key] + for key in keys + if key in os.environ + } # to recognize render jobs environment["AYON_RENDER_JOB"] = "1" diff --git a/client/ayon_core/modules/deadline/plugins/publish/submit_publish_cache_job.py b/client/ayon_core/modules/deadline/plugins/publish/submit_publish_cache_job.py index a90397baa2..38ea31ab7b 100644 --- a/client/ayon_core/modules/deadline/plugins/publish/submit_publish_cache_job.py +++ b/client/ayon_core/modules/deadline/plugins/publish/submit_publish_cache_job.py @@ -11,8 +11,8 @@ import pyblish.api from ayon_core.client import ( get_last_version_by_subset_name, ) -from ayon_core.pipeline import publish, legacy_io -from ayon_core.lib import EnumDef, is_running_from_build +from ayon_core.pipeline import publish +from ayon_core.lib import EnumDef from ayon_core.tests.lib import is_in_tests from ayon_core.pipeline.version_start import get_versioning_start @@ -370,7 +370,6 @@ class ProcessSubmittedCacheJobOnFarm(pyblish.api.InstancePlugin, "intent": instance.context.data.get("intent"), "comment": instance.context.data.get("comment"), "job": render_job or None, - "session": legacy_io.Session.copy(), "instances": instances } diff --git a/client/ayon_core/modules/deadline/plugins/publish/submit_publish_job.py b/client/ayon_core/modules/deadline/plugins/publish/submit_publish_job.py index bd343e103a..c4ab6a2932 100644 --- a/client/ayon_core/modules/deadline/plugins/publish/submit_publish_job.py +++ b/client/ayon_core/modules/deadline/plugins/publish/submit_publish_job.py @@ -12,8 +12,8 @@ import pyblish.api from ayon_core.client import ( get_last_version_by_subset_name, ) -from ayon_core.pipeline import publish, legacy_io -from ayon_core.lib import EnumDef, is_running_from_build +from ayon_core.pipeline import publish +from ayon_core.lib import EnumDef from ayon_core.tests.lib import is_in_tests from ayon_core.pipeline.version_start import get_versioning_start @@ -604,7 +604,6 @@ class ProcessSubmittedJobOnFarm(pyblish.api.InstancePlugin, "intent": instance.context.data.get("intent"), "comment": instance.context.data.get("comment"), "job": render_job or None, - "session": legacy_io.Session.copy(), "instances": instances } diff --git a/client/ayon_core/plugins/publish/collect_rendered_files.py b/client/ayon_core/plugins/publish/collect_rendered_files.py index 5ffcd669a0..714d790269 100644 --- a/client/ayon_core/plugins/publish/collect_rendered_files.py +++ b/client/ayon_core/plugins/publish/collect_rendered_files.py @@ -12,7 +12,7 @@ import json import pyblish.api -from ayon_core.pipeline import legacy_io, KnownPublishError +from ayon_core.pipeline import KnownPublishError from ayon_core.pipeline.publish.lib import add_repre_files_for_cleanup @@ -165,24 +165,28 @@ class CollectRenderedFiles(pyblish.api.ContextPlugin): path = anatomy.fill_root(path) data = self._load_json(path) assert data, "failed to load json file" - if not session_is_set: - session_data = data["session"] - remapped = anatomy.roots_obj.path_remapper( - session_data["AVALON_WORKDIR"] - ) - if remapped: - session_data["AVALON_WORKDIR"] = remapped - - self.log.debug("Setting session using data from file") - legacy_io.Session.update(session_data) - os.environ.update(session_data) + session_data = data.get("session") + if not session_is_set and session_data: session_is_set = True + self.log.debug("Setting session using data from file") + os.environ.update(session_data) + staging_dir_persistent = self._process_path(data, anatomy) if not staging_dir_persistent: context.data["cleanupFullPaths"].append(path) context.data["cleanupEmptyDirs"].append( os.path.dirname(path) ) + + # Remap workdir if it's set + workdir = os.getenv("AVALON_WORKDIR") + remapped_workdir = None + if workdir: + remapped_workdir = anatomy.roots_obj.path_remapper( + os.getenv("AVALON_WORKDIR") + ) + if remapped_workdir: + os.environ["AVALON_WORKDIR"] = remapped_workdir except Exception as e: self.log.error(e, exc_info=True) raise Exception("Error") from e From acaefb0a71f84186825432bfb3a150cbf3a37e0c Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Thu, 8 Feb 2024 18:28:25 +0100 Subject: [PATCH 024/185] AssetsWidget does not expect 'dbcon' --- client/ayon_core/hosts/houdini/api/usd.py | 5 +- .../tools/publisher/widgets/assets_widget.py | 9 ++- .../tools/publisher/widgets/create_widget.py | 2 +- client/ayon_core/tools/utils/assets_widget.py | 65 +++++++++---------- 4 files changed, 42 insertions(+), 39 deletions(-) diff --git a/client/ayon_core/hosts/houdini/api/usd.py b/client/ayon_core/hosts/houdini/api/usd.py index e900bc5fac..e9c02a0307 100644 --- a/client/ayon_core/hosts/houdini/api/usd.py +++ b/client/ayon_core/hosts/houdini/api/usd.py @@ -7,7 +7,7 @@ from qtpy import QtWidgets, QtCore, QtGui from ayon_core import style from ayon_core.client import get_asset_by_name -from ayon_core.pipeline import legacy_io, get_current_project_name +from ayon_core.pipeline import get_current_project_name from ayon_core.tools.utils.assets_widget import SingleSelectAssetsWidget from pxr import Sdf @@ -27,7 +27,8 @@ class SelectAssetDialog(QtWidgets.QWidget): self.setWindowTitle("Pick Asset") self.setWindowFlags(QtCore.Qt.FramelessWindowHint | QtCore.Qt.Popup) - assets_widget = SingleSelectAssetsWidget(legacy_io, parent=self) + assets_widget = SingleSelectAssetsWidget(self) + assets_widget.set_project_name(get_current_project_name(), False) layout = QtWidgets.QHBoxLayout(self) layout.addWidget(assets_widget) diff --git a/client/ayon_core/tools/publisher/widgets/assets_widget.py b/client/ayon_core/tools/publisher/widgets/assets_widget.py index 8a72c03e8b..faad37104d 100644 --- a/client/ayon_core/tools/publisher/widgets/assets_widget.py +++ b/client/ayon_core/tools/publisher/widgets/assets_widget.py @@ -21,7 +21,7 @@ class CreateWidgetAssetsWidget(SingleSelectAssetsWidget): def __init__(self, controller, parent): self._controller = controller - super(CreateWidgetAssetsWidget, self).__init__(None, parent) + super(CreateWidgetAssetsWidget, self).__init__(parent) self.set_refresh_btn_visibility(False) self.set_current_asset_btn_visibility(False) @@ -31,6 +31,9 @@ class CreateWidgetAssetsWidget(SingleSelectAssetsWidget): self._last_filter_height = None + def get_project_name(self): + return self._controller.project_name + def get_selected_asset_name(self): selection_model = self._view.selectionModel() indexes = selection_model.selectedRows() @@ -79,10 +82,10 @@ class CreateWidgetAssetsWidget(SingleSelectAssetsWidget): def update_current_asset(self): # Hide set current asset if there is no one - asset_name = self._get_current_session_asset() + asset_name = self._get_current_asset_name() self.set_current_asset_btn_visibility(bool(asset_name)) - def _get_current_session_asset(self): + def _get_current_asset_name(self): return self._controller.current_asset_name def _create_source_model(self): diff --git a/client/ayon_core/tools/publisher/widgets/create_widget.py b/client/ayon_core/tools/publisher/widgets/create_widget.py index 12135c6891..8eae205882 100644 --- a/client/ayon_core/tools/publisher/widgets/create_widget.py +++ b/client/ayon_core/tools/publisher/widgets/create_widget.py @@ -565,7 +565,7 @@ class CreateWidget(QtWidgets.QWidget): self._last_thumbnail_path = None def _on_current_session_context_request(self): - self._assets_widget.set_current_session_asset() + self._assets_widget.select_current_asset() task_name = self.current_task_name if task_name: self._tasks_widget.select_task_name(task_name) diff --git a/client/ayon_core/tools/utils/assets_widget.py b/client/ayon_core/tools/utils/assets_widget.py index c05f3de850..7bacf3291d 100644 --- a/client/ayon_core/tools/utils/assets_widget.py +++ b/client/ayon_core/tools/utils/assets_widget.py @@ -111,7 +111,6 @@ class _AssetModel(QtGui.QStandardItemModel): 'refreshed' signal. Args: - dbcon (AvalonMongoDB): Ready to use connection to mongo with. parent (QObject): Parent Qt object. """ @@ -128,9 +127,8 @@ class _AssetModel(QtGui.QStandardItemModel): "data.color": 1 } - def __init__(self, dbcon, parent=None): + def __init__(self, parent=None): super(_AssetModel, self).__init__(parent=parent) - self.dbcon = dbcon self._refreshing = False self._doc_fetching_thread = None @@ -142,6 +140,7 @@ class _AssetModel(QtGui.QStandardItemModel): self._item_ids_with_color = set() self._items_by_asset_id = {} + self._project_name = None self._last_project_name = None @property @@ -185,6 +184,16 @@ class _AssetModel(QtGui.QStandardItemModel): return self.get_indexes_by_asset_ids(asset_ids) + def get_project_name(self): + return self._project_name + + def set_project_name(self, project_name, refresh): + if self._project_name == project_name: + return + self._project_name = project_name + if refresh: + self.refresh() + def refresh(self, force=False): """Refresh the data for the model. @@ -197,7 +206,7 @@ class _AssetModel(QtGui.QStandardItemModel): return self.stop_refresh() - project_name = self.dbcon.Session.get("AVALON_PROJECT") + project_name = self._project_name clear_model = False if project_name != self._last_project_name: clear_model = True @@ -216,23 +225,6 @@ class _AssetModel(QtGui.QStandardItemModel): def stop_refresh(self): self._stop_fetch_thread() - def clear_underlines(self): - for asset_id in set(self._item_ids_with_color): - self._item_ids_with_color.remove(asset_id) - item = self._items_by_asset_id.get(asset_id) - if item is not None: - item.setData(None, ASSET_UNDERLINE_COLORS_ROLE) - - def set_underline_colors(self, colors_by_asset_id): - self.clear_underlines() - - for asset_id, colors in colors_by_asset_id.items(): - item = self._items_by_asset_id.get(asset_id) - if item is None: - continue - item.setData(colors, ASSET_UNDERLINE_COLORS_ROLE) - self._item_ids_with_color.add(asset_id) - def _clear_items(self): root_item = self.invisibleRootItem() root_item.removeRows(0, root_item.rowCount()) @@ -357,7 +349,7 @@ class _AssetModel(QtGui.QStandardItemModel): self._doc_fetched.emit() def _fetch_asset_docs(self): - project_name = self.dbcon.current_project() + project_name = self.get_project_name() if not project_name: return [] @@ -392,7 +384,6 @@ class _AssetsWidget(QtWidgets.QWidget): inheritance changes. Args: - dbcon (AvalonMongoDB): Connection to avalon mongo db. parent (QWidget): Parent Qt widget. """ @@ -404,11 +395,9 @@ class _AssetsWidget(QtWidgets.QWidget): # It was double clicked on view double_clicked = QtCore.Signal() - def __init__(self, dbcon, parent=None): + def __init__(self, parent=None): super(_AssetsWidget, self).__init__(parent=parent) - self.dbcon = dbcon - # Tree View model = self._create_source_model() proxy = self._create_proxy_model(model) @@ -477,18 +466,28 @@ class _AssetsWidget(QtWidgets.QWidget): self._model = model self._proxy = proxy self._view = view - self._last_project_name = None self._last_btns_height = None + self._current_asset_name = None + self.model_selection = {} @property def header_widget(self): return self._header_widget + def get_project_name(self): + self._model.get_project_name() + + def set_project_name(self, project_name, refresh=True): + self._model.set_project_name(project_name, refresh) + + def set_current_asset_name(self, asset_name): + self._current_asset_name = asset_name + def _create_source_model(self): - model = _AssetModel(dbcon=self.dbcon, parent=self) + model = _AssetModel(parent=self) model.refreshed.connect(self._on_model_refresh) return model @@ -509,8 +508,8 @@ class _AssetsWidget(QtWidgets.QWidget): def stop_refresh(self): self._model.stop_refresh() - def _get_current_session_asset(self): - return self.dbcon.Session.get("AVALON_ASSET") + def _get_current_asset_name(self): + return self._current_asset_name def _on_current_asset_click(self): """Trigger change of asset to current context asset. @@ -518,10 +517,10 @@ class _AssetsWidget(QtWidgets.QWidget): in differnt way. """ - self.set_current_session_asset() + self.select_current_asset() - def set_current_session_asset(self): - asset_name = self._get_current_session_asset() + def select_current_asset(self): + asset_name = self._get_current_asset_name() if asset_name: self.select_asset_by_name(asset_name) From a6a04bb443c0a9b047de57798c8839dc88f322e6 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Thu, 8 Feb 2024 18:55:58 +0100 Subject: [PATCH 025/185] moved TasksWidget to publisher --- .../tools/publisher/widgets/tasks_widget.py | 171 +++++++++- client/ayon_core/tools/utils/tasks_widget.py | 303 ------------------ 2 files changed, 157 insertions(+), 317 deletions(-) delete mode 100644 client/ayon_core/tools/utils/tasks_widget.py diff --git a/client/ayon_core/tools/publisher/widgets/tasks_widget.py b/client/ayon_core/tools/publisher/widgets/tasks_widget.py index 44e290408a..9a1b22b9a5 100644 --- a/client/ayon_core/tools/publisher/widgets/tasks_widget.py +++ b/client/ayon_core/tools/publisher/widgets/tasks_widget.py @@ -1,8 +1,12 @@ -from qtpy import QtCore, QtGui +from qtpy import QtWidgets, QtCore, QtGui -from ayon_core.tools.utils.tasks_widget import TasksWidget, TASK_NAME_ROLE +from ayon_core.tools.utils.views import DeselectableTreeView from ayon_core.tools.utils.lib import get_default_task_icon +TASK_NAME_ROLE = QtCore.Qt.UserRole + 1 +TASK_TYPE_ROLE = QtCore.Qt.UserRole + 2 +TASK_ORDER_ROLE = QtCore.Qt.UserRole + 3 + class TasksModel(QtGui.QStandardItemModel): """Tasks model. @@ -141,15 +145,159 @@ class TasksModel(QtGui.QStandardItemModel): return super(TasksModel, self).headerData(section, orientation, role) -class CreateWidgetTasksWidget(TasksWidget): +class TasksProxyModel(QtCore.QSortFilterProxyModel): + def lessThan(self, x_index, y_index): + x_order = x_index.data(TASK_ORDER_ROLE) + y_order = y_index.data(TASK_ORDER_ROLE) + if x_order is not None and y_order is not None: + if x_order < y_order: + return True + if x_order > y_order: + return False + + elif x_order is None and y_order is not None: + return True + + elif y_order is None and x_order is not None: + return False + + x_name = x_index.data(QtCore.Qt.DisplayRole) + y_name = y_index.data(QtCore.Qt.DisplayRole) + if x_name == y_name: + return True + + if x_name == tuple(sorted((x_name, y_name)))[0]: + return True + return False + + +class CreateWidgetTasksWidget(QtWidgets.QWidget): + """Widget showing active Tasks + + Deprecated: + This widget will be removed soon. Please do not use it in new code. + """ + + task_changed = QtCore.Signal() + def __init__(self, controller, parent): self._controller = controller - super(CreateWidgetTasksWidget, self).__init__(None, parent) self._enabled = None - def _create_source_model(self): - return TasksModel(self._controller) + super(CreateWidgetTasksWidget, self).__init__(parent) + + tasks_view = DeselectableTreeView(self) + tasks_view.setIndentation(0) + tasks_view.setSortingEnabled(True) + tasks_view.setEditTriggers(QtWidgets.QAbstractItemView.NoEditTriggers) + + header_view = tasks_view.header() + header_view.setSortIndicator(0, QtCore.Qt.AscendingOrder) + + tasks_model = TasksModel(self._controller) + tasks_proxy = TasksProxyModel() + tasks_proxy.setSourceModel(tasks_model) + tasks_view.setModel(tasks_proxy) + + layout = QtWidgets.QVBoxLayout(self) + layout.setContentsMargins(0, 0, 0, 0) + layout.addWidget(tasks_view) + + selection_model = tasks_view.selectionModel() + selection_model.selectionChanged.connect(self._on_task_change) + + self._tasks_model = tasks_model + self._tasks_proxy = tasks_proxy + self._tasks_view = tasks_view + + self._last_selected_task_name = None + + def refresh(self): + self._tasks_model.refresh() + + def set_asset_id(self, asset_id): + # Try and preserve the last selected task and reselect it + # after switching assets. If there's no currently selected + # asset keep whatever the "last selected" was prior to it. + current = self.get_selected_task_name() + if current: + self._last_selected_task_name = current + + self._tasks_model.set_asset_id(asset_id) + + if self._last_selected_task_name: + self.select_task_name(self._last_selected_task_name) + + # Force a task changed emit. + self.task_changed.emit() + + def _clear_selection(self): + selection_model = self._tasks_view.selectionModel() + selection_model.clearSelection() + + def select_task_name(self, task_name): + """Select a task by name. + + If the task does not exist in the current model then selection is only + cleared. + + Args: + task_name (str): Name of the task to select. + + """ + task_view_model = self._tasks_view.model() + if not task_view_model: + return + + # Clear selection + selection_model = self._tasks_view.selectionModel() + selection_model.clearSelection() + + # Select the task + mode = ( + QtCore.QItemSelectionModel.Select + | QtCore.QItemSelectionModel.Rows + ) + for row in range(task_view_model.rowCount()): + index = task_view_model.index(row, 0) + name = index.data(TASK_NAME_ROLE) + if name == task_name: + selection_model.select(index, mode) + + # Set the currently active index + self._tasks_view.setCurrentIndex(index) + break + + last_selected_task_name = self.get_selected_task_name() + if last_selected_task_name: + self._last_selected_task_name = last_selected_task_name + + if not self._enabled: + current = self.get_selected_task_name() + if current: + self._last_selected_task_name = current + self._clear_selection() + + def get_selected_task_name(self): + """Return name of task at current index (selected) + + Returns: + str: Name of the current task. + + """ + index = self._tasks_view.currentIndex() + selection_model = self._tasks_view.selectionModel() + if index.isValid() and selection_model.isSelected(index): + return index.data(TASK_NAME_ROLE) + return None + + def get_selected_task_type(self): + index = self._tasks_view.currentIndex() + selection_model = self._tasks_view.selectionModel() + if index.isValid() and selection_model.isSelected(index): + return index.data(TASK_TYPE_ROLE) + return None def set_asset_name(self, asset_name): current = self.get_selected_task_name() @@ -163,14 +311,6 @@ class CreateWidgetTasksWidget(TasksWidget): # Force a task changed emit. self.task_changed.emit() - def select_task_name(self, task_name): - super(CreateWidgetTasksWidget, self).select_task_name(task_name) - if not self._enabled: - current = self.get_selected_task_name() - if current: - self._last_selected_task_name = current - self._clear_selection() - def set_enabled(self, enabled): self._enabled = enabled if not enabled: @@ -181,3 +321,6 @@ class CreateWidgetTasksWidget(TasksWidget): elif self._last_selected_task_name is not None: self.select_task_name(self._last_selected_task_name) + + def _on_task_change(self): + self.task_changed.emit() diff --git a/client/ayon_core/tools/utils/tasks_widget.py b/client/ayon_core/tools/utils/tasks_widget.py deleted file mode 100644 index 12e074f910..0000000000 --- a/client/ayon_core/tools/utils/tasks_widget.py +++ /dev/null @@ -1,303 +0,0 @@ -from qtpy import QtWidgets, QtCore, QtGui -import qtawesome - -from ayon_core.client import ( - get_project, - get_asset_by_id, -) -from ayon_core.style import get_disabled_entity_icon_color -from ayon_core.tools.utils.lib import get_task_icon - -from .views import DeselectableTreeView - - -TASK_NAME_ROLE = QtCore.Qt.UserRole + 1 -TASK_TYPE_ROLE = QtCore.Qt.UserRole + 2 -TASK_ORDER_ROLE = QtCore.Qt.UserRole + 3 -TASK_ASSIGNEE_ROLE = QtCore.Qt.UserRole + 4 - - -class _TasksModel(QtGui.QStandardItemModel): - """A model listing the tasks combined for a list of assets""" - - def __init__(self, dbcon, parent=None): - super(_TasksModel, self).__init__(parent=parent) - self.dbcon = dbcon - self.setHeaderData( - 0, QtCore.Qt.Horizontal, "Tasks", QtCore.Qt.DisplayRole - ) - - self._no_tasks_icon = qtawesome.icon( - "fa.exclamation-circle", - color=get_disabled_entity_icon_color() - ) - self._cached_icons = {} - self._project_doc = {} - - self._empty_tasks_item = None - self._last_asset_id = None - self._loaded_project_name = None - - def _context_is_valid(self): - if self._get_current_project(): - return True - return False - - def refresh(self): - self._refresh_project_doc() - self.set_asset_id(self._last_asset_id) - - def _refresh_project_doc(self): - # Get the project configured icons from database - project_doc = {} - if self._context_is_valid(): - project_name = self.dbcon.active_project() - project_doc = get_project(project_name) - - self._loaded_project_name = self._get_current_project() - self._project_doc = project_doc - - def headerData(self, section, orientation, role=None): - if role is None: - role = QtCore.Qt.EditRole - # Show nice labels in the header - if section == 0: - if ( - role in (QtCore.Qt.DisplayRole, QtCore.Qt.EditRole) - and orientation == QtCore.Qt.Horizontal - ): - return "Tasks" - - return super(_TasksModel, self).headerData(section, orientation, role) - - def _get_current_project(self): - return self.dbcon.Session.get("AVALON_PROJECT") - - def set_asset_id(self, asset_id): - asset_doc = None - if asset_id and self._context_is_valid(): - project_name = self._get_current_project() - asset_doc = get_asset_by_id( - project_name, asset_id, fields=["data.tasks"] - ) - self._set_asset(asset_doc) - - def _get_empty_task_item(self): - if self._empty_tasks_item is None: - item = QtGui.QStandardItem("No task") - item.setData(self._no_tasks_icon, QtCore.Qt.DecorationRole) - item.setFlags(QtCore.Qt.NoItemFlags) - self._empty_tasks_item = item - return self._empty_tasks_item - - def _set_asset(self, asset_doc): - """Set assets to track by their database id - - Arguments: - asset_doc (dict): Asset document from MongoDB. - """ - if self._loaded_project_name != self._get_current_project(): - self._refresh_project_doc() - - asset_tasks = {} - self._last_asset_id = None - if asset_doc: - asset_tasks = asset_doc.get("data", {}).get("tasks") or {} - self._last_asset_id = asset_doc["_id"] - - root_item = self.invisibleRootItem() - root_item.removeRows(0, root_item.rowCount()) - - items = [] - - for task_name, task_info in asset_tasks.items(): - task_type = task_info.get("type") - task_order = task_info.get("order") - icon = get_task_icon(self._project_doc, asset_doc, task_name) - - task_assignees = set() - assignees_data = task_info.get("assignees") or [] - for assignee in assignees_data: - username = assignee.get("username") - if username: - task_assignees.add(username) - - label = "{} ({})".format(task_name, task_type or "type N/A") - item = QtGui.QStandardItem(label) - item.setData(task_name, TASK_NAME_ROLE) - item.setData(task_type, TASK_TYPE_ROLE) - item.setData(task_order, TASK_ORDER_ROLE) - item.setData(task_assignees, TASK_ASSIGNEE_ROLE) - item.setData(icon, QtCore.Qt.DecorationRole) - item.setFlags(QtCore.Qt.ItemIsEnabled | QtCore.Qt.ItemIsSelectable) - items.append(item) - - if not items: - item = QtGui.QStandardItem("No task") - item.setData(self._no_tasks_icon, QtCore.Qt.DecorationRole) - item.setFlags(QtCore.Qt.NoItemFlags) - items.append(item) - - root_item.appendRows(items) - - -class _TasksProxyModel(QtCore.QSortFilterProxyModel): - def lessThan(self, x_index, y_index): - x_order = x_index.data(TASK_ORDER_ROLE) - y_order = y_index.data(TASK_ORDER_ROLE) - if x_order is not None and y_order is not None: - if x_order < y_order: - return True - if x_order > y_order: - return False - - elif x_order is None and y_order is not None: - return True - - elif y_order is None and x_order is not None: - return False - - x_name = x_index.data(QtCore.Qt.DisplayRole) - y_name = y_index.data(QtCore.Qt.DisplayRole) - if x_name == y_name: - return True - - if x_name == tuple(sorted((x_name, y_name)))[0]: - return True - return False - - -class TasksWidget(QtWidgets.QWidget): - """Widget showing active Tasks - - Deprecated: - This widget will be removed soon. Please do not use it in new code. - """ - - task_changed = QtCore.Signal() - - def __init__(self, dbcon, parent=None): - self._dbcon = dbcon - - super(TasksWidget, self).__init__(parent) - - tasks_view = DeselectableTreeView(self) - tasks_view.setIndentation(0) - tasks_view.setSortingEnabled(True) - tasks_view.setEditTriggers(QtWidgets.QAbstractItemView.NoEditTriggers) - - header_view = tasks_view.header() - header_view.setSortIndicator(0, QtCore.Qt.AscendingOrder) - - tasks_model = self._create_source_model() - tasks_proxy = self._create_proxy_model(tasks_model) - tasks_view.setModel(tasks_proxy) - - layout = QtWidgets.QVBoxLayout(self) - layout.setContentsMargins(0, 0, 0, 0) - layout.addWidget(tasks_view) - - selection_model = tasks_view.selectionModel() - selection_model.selectionChanged.connect(self._on_task_change) - - self._tasks_model = tasks_model - self._tasks_proxy = tasks_proxy - self._tasks_view = tasks_view - - self._last_selected_task_name = None - - def _create_source_model(self): - """Create source model of tasks widget. - - Model must have available 'refresh' method and 'set_asset_id' to change - context of asset. - """ - return _TasksModel(self._dbcon) - - def _create_proxy_model(self, source_model): - proxy = _TasksProxyModel() - proxy.setSourceModel(source_model) - return proxy - - def refresh(self): - self._tasks_model.refresh() - - def set_asset_id(self, asset_id): - # Try and preserve the last selected task and reselect it - # after switching assets. If there's no currently selected - # asset keep whatever the "last selected" was prior to it. - current = self.get_selected_task_name() - if current: - self._last_selected_task_name = current - - self._tasks_model.set_asset_id(asset_id) - - if self._last_selected_task_name: - self.select_task_name(self._last_selected_task_name) - - # Force a task changed emit. - self.task_changed.emit() - - def _clear_selection(self): - selection_model = self._tasks_view.selectionModel() - selection_model.clearSelection() - - def select_task_name(self, task_name): - """Select a task by name. - - If the task does not exist in the current model then selection is only - cleared. - - Args: - task (str): Name of the task to select. - - """ - task_view_model = self._tasks_view.model() - if not task_view_model: - return - - # Clear selection - selection_model = self._tasks_view.selectionModel() - selection_model.clearSelection() - - # Select the task - mode = ( - QtCore.QItemSelectionModel.Select - | QtCore.QItemSelectionModel.Rows - ) - for row in range(task_view_model.rowCount()): - index = task_view_model.index(row, 0) - name = index.data(TASK_NAME_ROLE) - if name == task_name: - selection_model.select(index, mode) - - # Set the currently active index - self._tasks_view.setCurrentIndex(index) - break - - last_selected_task_name = self.get_selected_task_name() - if last_selected_task_name: - self._last_selected_task_name = last_selected_task_name - - def get_selected_task_name(self): - """Return name of task at current index (selected) - - Returns: - str: Name of the current task. - - """ - index = self._tasks_view.currentIndex() - selection_model = self._tasks_view.selectionModel() - if index.isValid() and selection_model.isSelected(index): - return index.data(TASK_NAME_ROLE) - return None - - def get_selected_task_type(self): - index = self._tasks_view.currentIndex() - selection_model = self._tasks_view.selectionModel() - if index.isValid() and selection_model.isSelected(index): - return index.data(TASK_TYPE_ROLE) - return None - - def _on_task_change(self): - self.task_changed.emit() From 2e63f282c1b624897857421986e091673018137a Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Thu, 8 Feb 2024 19:01:25 +0100 Subject: [PATCH 026/185] disable validation of AVALON_PROJECT environment variable --- client/ayon_core/pipeline/context_tools.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/client/ayon_core/pipeline/context_tools.py b/client/ayon_core/pipeline/context_tools.py index 64d8e1f6d6..fdf4c85660 100644 --- a/client/ayon_core/pipeline/context_tools.py +++ b/client/ayon_core/pipeline/context_tools.py @@ -119,10 +119,12 @@ def install_host(host): addons_manager = _get_addons_manager() project_name = os.getenv("AVALON_PROJECT") - if not project_name: - raise ValueError( - "AVALON_PROJECT is missing in environment variables." - ) + # WARNING: This might be an issue + # - commented out because 'traypublisher' does not have set project + # if not project_name: + # raise ValueError( + # "AVALON_PROJECT is missing in environment variables." + # ) log.info("Activating {}..".format(project_name)) From 4c3f6a5645c68fc091289067e6b66d6f12c164f9 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Thu, 8 Feb 2024 19:01:47 +0100 Subject: [PATCH 027/185] use correct function --- client/ayon_core/pipeline/context_tools.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/ayon_core/pipeline/context_tools.py b/client/ayon_core/pipeline/context_tools.py index fdf4c85660..6986a062d7 100644 --- a/client/ayon_core/pipeline/context_tools.py +++ b/client/ayon_core/pipeline/context_tools.py @@ -159,7 +159,7 @@ def install_host(host): for addon in addons_manager.get_enabled_addons(): addon.on_host_install(host, host_name, project_name) - install_openpype_plugins(project_name, host_name) + install_ayon_plugins(project_name, host_name) def install_ayon_plugins(project_name=None, host_name=None): From e02883dcd41eddc73027aadaa1927c67617efc6c Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Thu, 8 Feb 2024 19:01:54 +0100 Subject: [PATCH 028/185] removed unused import --- client/ayon_core/pipeline/context_tools.py | 1 - 1 file changed, 1 deletion(-) diff --git a/client/ayon_core/pipeline/context_tools.py b/client/ayon_core/pipeline/context_tools.py index 6986a062d7..339ef9187f 100644 --- a/client/ayon_core/pipeline/context_tools.py +++ b/client/ayon_core/pipeline/context_tools.py @@ -1,7 +1,6 @@ """Core pipeline functionality""" import os -import json import types import logging import platform From eedf7368670efb2a9cee3f0fbc9841ee0b144393 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Thu, 8 Feb 2024 19:10:49 +0100 Subject: [PATCH 029/185] removed content of legacy_io --- client/ayon_core/pipeline/legacy_io.py | 97 ++++---------------------- 1 file changed, 12 insertions(+), 85 deletions(-) diff --git a/client/ayon_core/pipeline/legacy_io.py b/client/ayon_core/pipeline/legacy_io.py index cd09da2917..d5b555845b 100644 --- a/client/ayon_core/pipeline/legacy_io.py +++ b/client/ayon_core/pipeline/legacy_io.py @@ -1,109 +1,36 @@ -"""Wrapper around interactions with the database""" - -import os -import sys import logging -import functools - -from . import schema - -module = sys.modules[__name__] +from ayon_core.pipeline import get_current_project_name Session = {} -_is_installed = False log = logging.getLogger(__name__) - -SESSION_CONTEXT_KEYS = ( - # Name of current Project - "AVALON_PROJECT", - # Name of current Asset - "AVALON_ASSET", - # Name of current task - "AVALON_TASK", - # Name of current app - "AVALON_APP", - # Path to working directory - "AVALON_WORKDIR", - # Optional path to scenes directory (see Work Files API) - "AVALON_SCENEDIR" +log.warning( + "DEPRECATION WARNING: 'legacy_io' is deprecated and will be removed in" + " future versions of ayon-core addon." + "\nReading from Session won't give you updated information and changing" + " values won't affect global state of a process." ) def session_data_from_environment(context_keys=False): - session_data = {} - if context_keys: - for key in SESSION_CONTEXT_KEYS: - value = os.environ.get(key) - session_data[key] = value or "" - else: - for key in SESSION_CONTEXT_KEYS: - session_data[key] = None - - for key, default_value in ( - # Name of Avalon in graphical user interfaces - # Use this to customise the visual appearance of Avalon - # to better integrate with your surrounding pipeline - ("AVALON_LABEL", "Avalon"), - - # Used during any connections to the outside world - ("AVALON_TIMEOUT", "1000"), - - # Name of database used in MongoDB - ("AVALON_DB", "avalon"), - ): - value = os.environ.get(key) or default_value - if value is not None: - session_data[key] = value - - return session_data + return {} def is_installed(): - return module._is_installed + return False def install(): - """Establish a persistent connection to the database""" - if is_installed(): - return - - session = session_data_from_environment(context_keys=True) - - session["schema"] = "openpype:session-4.0" - try: - schema.validate(session) - except schema.ValidationError as e: - # TODO(marcus): Make this mandatory - log.warning(e) - - Session.update(session) - - module._is_installed = True + pass def uninstall(): - """Close any connection to the database. - - Deprecated: - This function does nothing should be removed. - """ - module._is_installed = False + pass -def requires_install(func): - @functools.wraps(func) - def decorated(*args, **kwargs): - if not is_installed(): - install() - return func(*args, **kwargs) - return decorated - - -@requires_install def active_project(*args, **kwargs): - return Session["AVALON_PROJECT"] + return get_current_project_name() def current_project(*args, **kwargs): - return Session.get("AVALON_PROJECT") + return get_current_project_name() From 4e76c9f5dc9282fa65c97faeaf3598f5b9f5e07b Mon Sep 17 00:00:00 2001 From: Toke Stuart Jepsen Date: Fri, 9 Feb 2024 08:16:23 +0000 Subject: [PATCH 030/185] Add submodule --- client/ayon_core/hosts/unreal/integration | 1 + 1 file changed, 1 insertion(+) create mode 160000 client/ayon_core/hosts/unreal/integration diff --git a/client/ayon_core/hosts/unreal/integration b/client/ayon_core/hosts/unreal/integration new file mode 160000 index 0000000000..6d2793170e --- /dev/null +++ b/client/ayon_core/hosts/unreal/integration @@ -0,0 +1 @@ +Subproject commit 6d2793170ed57187842f683a943593973abcc337 From ce5a563b4c55dceababeea459d25b3429d9a14be Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Fri, 9 Feb 2024 09:56:42 +0100 Subject: [PATCH 031/185] do not convert applications settings --- client/ayon_core/lib/applications.py | 225 ++++++++------------- client/ayon_core/settings/ayon_settings.py | 85 +------- 2 files changed, 91 insertions(+), 219 deletions(-) diff --git a/client/ayon_core/lib/applications.py b/client/ayon_core/lib/applications.py index febdaacdd1..70aa9811c7 100644 --- a/client/ayon_core/lib/applications.py +++ b/client/ayon_core/lib/applications.py @@ -230,29 +230,25 @@ class ApplicationGroup: self.manager = manager self._data = data - self.enabled = data.get("enabled", True) - self.label = data.get("label") or None - self.icon = data.get("icon") or None - self._environment = data.get("environment") or {} + self.enabled = data["enabled"] + self.label = data["label"] or None + self.icon = data["icon"] or None + env = {} + try: + env = json.loads(data["environment"]) + except Exception: + pass + self._environment = env - host_name = data.get("host_name", None) + host_name = data["host_name"] or None self.is_host = host_name is not None self.host_name = host_name - variants = data.get("variants") or {} - key_label_mapping = variants.pop(M_DYNAMIC_KEY_LABEL, {}) - for variant_name, variant_data in variants.items(): - if variant_name in METADATA_KEYS: - continue - - if "variant_label" not in variant_data: - variant_label = key_label_mapping.get(variant_name) - if variant_label: - variant_data["variant_label"] = variant_label - - variants[variant_name] = Application( - variant_name, variant_data, self - ) + settings_variants = data["variants"] + variants = {} + for variant_data in settings_variants: + app_variant = Application(variant_data, self) + variants[app_variant.name] = app_variant self.variants = variants @@ -274,62 +270,56 @@ class Application: Object by itself does nothing special. Args: - name (str): Specific version (or variant) of application. - e.g. "maya2020", "nuke11.3", etc. data (dict): Data for the version containing information about executables, variant label or if is enabled. Only required key is `executables`. group (ApplicationGroup): App group object that created the application and under which application belongs. + """ - - def __init__(self, name, data, group): - self.name = name - self.group = group + def __init__(self, data, group): self._data = data - + name = data["name"] + label = data["label"] or name enabled = False if group.enabled: enabled = data.get("enabled", True) - self.enabled = enabled - self.use_python_2 = data.get("use_python_2", False) - - self.label = data.get("variant_label") or name - self.full_name = "/".join((group.name, name)) if group.label: - full_label = " ".join((group.label, self.label)) + full_label = " ".join((group.label, label)) else: - full_label = self.label - self.full_label = full_label - self._environment = data.get("environment") or {} + full_label = label + env = {} + try: + env = json.loads(data["environment"]) + except Exception: + pass - arguments = data.get("arguments") + arguments = data["arguments"] if isinstance(arguments, dict): arguments = arguments.get(platform.system().lower()) if not arguments: arguments = [] + + _executables = data["executables"].get(platform.system().lower(), []) + executables = [ + ApplicationExecutable(executable) + for executable in _executables + ] + + self.group = group + + self.name = name + self.label = label + self.enabled = enabled + self.use_python_2 = data.get("use_python_2", False) + + self.full_name = "/".join((group.name, name)) + self.full_label = full_label self.arguments = arguments - - if "executables" not in data: - self.executables = [ - UndefinedApplicationExecutable() - ] - return - - _executables = data["executables"] - if isinstance(_executables, dict): - _executables = _executables.get(platform.system().lower()) - - if not _executables: - _executables = [] - - executables = [] - for executable in _executables: - executables.append(ApplicationExecutable(executable)) - self.executables = executables + self._environment = env def __repr__(self): return "<{}> - {}".format(self.__class__.__name__, self.full_name) @@ -384,12 +374,12 @@ class ApplicationManager: """Load applications and tools and store them by their full name. Args: - system_settings (dict): Preloaded system settings. When passed manager + studio_settings (dict): Preloaded studio settings. When passed manager will always use these values. Gives ability to create manager using different settings. """ - def __init__(self, system_settings=None): + def __init__(self, studio_settings=None): self.log = Logger.get_logger(self.__class__.__name__) self.app_groups = {} @@ -397,16 +387,16 @@ class ApplicationManager: self.tool_groups = {} self.tools = {} - self._system_settings = system_settings + self._studio_settings = studio_settings self.refresh() - def set_system_settings(self, system_settings): + def set_studio_settings(self, studio_settings): """Ability to change init system settings. This will trigger refresh of manager. """ - self._system_settings = system_settings + self._studio_settings = studio_settings self.refresh() @@ -417,72 +407,30 @@ class ApplicationManager: self.tool_groups.clear() self.tools.clear() - if self._system_settings is not None: - settings = copy.deepcopy(self._system_settings) + if self._studio_settings is not None: + settings = copy.deepcopy(self._studio_settings) else: settings = get_system_settings( clear_metadata=False, exclude_locals=False ) - all_app_defs = {} + applications_addon_settings = settings["applications"] + # Prepare known applications - app_defs = settings["applications"] - additional_apps = {} + app_defs = applications_addon_settings["applications"] + additional_apps = app_defs.pop("additional_apps") + app_defs.update(additional_apps) + for group_name, variant_defs in app_defs.items(): - if group_name in METADATA_KEYS: - continue - - if group_name == "additional_apps": - additional_apps = variant_defs - else: - all_app_defs[group_name] = variant_defs - - # Prepare additional applications - # - First find dynamic keys that can be used as labels of group - dynamic_keys = {} - for group_name, variant_defs in additional_apps.items(): - if group_name == M_DYNAMIC_KEY_LABEL: - dynamic_keys = variant_defs - break - - # Add additional apps to known applications - for group_name, variant_defs in additional_apps.items(): - if group_name in METADATA_KEYS: - continue - - # Determine group label - label = variant_defs.get("label") - if not label: - # Look for label set in dynamic labels - label = dynamic_keys.get(group_name) - if not label: - label = group_name - variant_defs["label"] = label - - all_app_defs[group_name] = variant_defs - - for group_name, variant_defs in all_app_defs.items(): - if group_name in METADATA_KEYS: - continue - group = ApplicationGroup(group_name, variant_defs, self) self.app_groups[group_name] = group for app in group: self.applications[app.full_name] = app - tools_definitions = settings["tools"]["tool_groups"] - tool_label_mapping = tools_definitions.pop(M_DYNAMIC_KEY_LABEL, {}) - for tool_group_name, tool_group_data in tools_definitions.items(): - if not tool_group_name or tool_group_name in METADATA_KEYS: - continue - - tool_group_label = ( - tool_label_mapping.get(tool_group_name) or tool_group_name - ) - group = EnvironmentToolGroup( - tool_group_name, tool_group_label, tool_group_data, self - ) - self.tool_groups[tool_group_name] = group + tools_definitions = applications_addon_settings["tool_groups"] + for tool_group_data in tools_definitions: + group = EnvironmentToolGroup(tool_group_data, self) + self.tool_groups[group.name] = group for tool in group: self.tools[tool.full_name] = tool @@ -571,30 +519,31 @@ class EnvironmentToolGroup: are same. Args: - name (str): Name of the tool group. - data (dict): Group's information with it's variants. + data (dict): Group information with variants. manager (ApplicationManager): Manager that creates the group. """ - def __init__(self, name, label, data, manager): + def __init__(self, data, manager): + name = data["name"] + label = data["label"] + self.name = name self.label = label self._data = data self.manager = manager - self._environment = data["environment"] - variants = data.get("variants") or {} - label_by_key = variants.pop(M_DYNAMIC_KEY_LABEL, {}) + environment = {} + try: + environment = json.loads(data["environment"]) + except Exception: + pass + self._environment = environment + + variants = data.get("variants") or [] variants_by_name = {} - for variant_name, variant_data in variants.items(): - if variant_name in METADATA_KEYS: - continue - - variant_label = label_by_key.get(variant_name) or variant_name - tool = EnvironmentTool( - variant_name, variant_label, variant_data, self - ) - variants_by_name[variant_name] = tool + for variant_data in variants: + tool = EnvironmentTool(variant_data, self) + variants_by_name[tool.name] = tool self.variants = variants_by_name def __repr__(self): @@ -615,23 +564,25 @@ class EnvironmentTool: Structure of tool information. Args: - name (str): Name of the tool. variant_data (dict): Variant data with environments and host and app variant filters. - group (str): Name of group which wraps tool. + group (EnvironmentToolGroup): Name of group which wraps tool. """ - def __init__(self, name, label, variant_data, group): + def __init__(self, variant_data, group): # Backwards compatibility 3.9.1 - 3.9.2 # - 'variant_data' contained only environments but contain also host # and application variant filters - host_names = variant_data.get("host_names", []) - app_variants = variant_data.get("app_variants", []) + name = variant_data["name"] + label = variant_data["label"] + host_names = variant_data["host_names"] + app_variants = variant_data["app_variants"] - if "environment" in variant_data: - environment = variant_data["environment"] - else: - environment = variant_data + environment = {} + try: + environment = json.loads(variant_data["environment"]) + except Exception: + pass self.host_names = host_names self.app_variants = app_variants diff --git a/client/ayon_core/settings/ayon_settings.py b/client/ayon_core/settings/ayon_settings.py index ed1199d517..acf5e0bb30 100644 --- a/client/ayon_core/settings/ayon_settings.py +++ b/client/ayon_core/settings/ayon_settings.py @@ -72,77 +72,6 @@ def _convert_host_imageio(host_settings): imageio_file_rules["rules"] = new_rules -def _convert_applications_groups(groups, clear_metadata): - environment_key = "environment" - if isinstance(groups, dict): - new_groups = [] - for name, item in groups.items(): - item["name"] = name - new_groups.append(item) - groups = new_groups - - output = {} - group_dynamic_labels = {} - for group in groups: - group_name = group.pop("name") - if "label" in group: - group_dynamic_labels[group_name] = group["label"] - - tool_group_envs = group[environment_key] - if isinstance(tool_group_envs, six.string_types): - group[environment_key] = json.loads(tool_group_envs) - - variants = {} - variant_dynamic_labels = {} - for variant in group.pop("variants"): - variant_name = variant.pop("name") - label = variant.get("label") - if label and label != variant_name: - variant_dynamic_labels[variant_name] = label - variant_envs = variant[environment_key] - if isinstance(variant_envs, six.string_types): - variant[environment_key] = json.loads(variant_envs) - variants[variant_name] = variant - group["variants"] = variants - - if not clear_metadata: - variants["__dynamic_keys_labels__"] = variant_dynamic_labels - output[group_name] = group - - if not clear_metadata: - output["__dynamic_keys_labels__"] = group_dynamic_labels - return output - - -def _convert_applications_system_settings( - ayon_settings, output, clear_metadata -): - # Addon settings - addon_settings = ayon_settings["applications"] - - # Remove project settings - addon_settings.pop("only_available", None) - - # Applications settings - ayon_apps = addon_settings["applications"] - - additional_apps = ayon_apps.pop("additional_apps") - applications = _convert_applications_groups( - ayon_apps, clear_metadata - ) - applications["additional_apps"] = _convert_applications_groups( - additional_apps, clear_metadata - ) - - # Tools settings - tools = _convert_applications_groups( - addon_settings["tool_groups"], clear_metadata - ) - - output["applications"] = applications - output["tools"] = {"tool_groups": tools} - - def _convert_general(ayon_settings, output, default_settings): # TODO get studio name/code core_settings = ayon_settings["core"] @@ -290,7 +219,7 @@ def convert_system_settings(ayon_settings, default_settings, addon_versions): "modules": {} } if "applications" in ayon_settings: - _convert_applications_system_settings(ayon_settings, output, False) + output["applications"] = ayon_settings["applications"] if "core" in ayon_settings: _convert_general(ayon_settings, output, default_settings) @@ -313,15 +242,6 @@ def convert_system_settings(ayon_settings, default_settings, addon_versions): # --------- Project settings --------- -def _convert_applications_project_settings(ayon_settings, output): - if "applications" not in ayon_settings: - return - - output["applications"] = { - "only_available": ayon_settings["applications"]["only_available"] - } - - def _convert_blender_project_settings(ayon_settings, output): if "blender" not in ayon_settings: return @@ -1373,7 +1293,8 @@ def convert_project_settings(ayon_settings, default_settings): output[key] = ayon_settings[key] _convert_host_imageio(output[key]) - _convert_applications_project_settings(ayon_settings, output) + if "applications" in ayon_settings: + output["applications"] = ayon_settings["applications"] _convert_blender_project_settings(ayon_settings, output) _convert_celaction_project_settings(ayon_settings, output) _convert_flame_project_settings(ayon_settings, output) From 6538f5b75d96545d0e0089663f2a6c7454b9e2b1 Mon Sep 17 00:00:00 2001 From: Toke Jepsen Date: Fri, 9 Feb 2024 09:05:31 +0000 Subject: [PATCH 032/185] Update client/ayon_core/hosts/maya/api/menu.py Co-authored-by: Jakub Trllo <43494761+iLLiCiTiT@users.noreply.github.com> --- client/ayon_core/hosts/maya/api/menu.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/ayon_core/hosts/maya/api/menu.py b/client/ayon_core/hosts/maya/api/menu.py index e92878e3e5..70347e91b6 100644 --- a/client/ayon_core/hosts/maya/api/menu.py +++ b/client/ayon_core/hosts/maya/api/menu.py @@ -24,7 +24,7 @@ from .workfile_template_builder import ( build_workfile_template, update_workfile_template ) -from openpype.tools.workfile_template_build import open_template_ui +from ayon_core.tools.workfile_template_build import open_template_ui from .workfile_template_builder import MayaTemplateBuilder log = logging.getLogger(__name__) From 1b3ac1f5eba703726f244eeb2ac7e41bde85766a Mon Sep 17 00:00:00 2001 From: Toke Stuart Jepsen Date: Fri, 9 Feb 2024 11:37:15 +0000 Subject: [PATCH 033/185] Move question code to open_template_ui --- .../tools/workfile_template_build/lib.py | 21 ++- openpype/widgets/message_window.py | 156 ------------------ 2 files changed, 10 insertions(+), 167 deletions(-) delete mode 100644 openpype/widgets/message_window.py diff --git a/client/ayon_core/tools/workfile_template_build/lib.py b/client/ayon_core/tools/workfile_template_build/lib.py index 2f6dfb414f..de3a0d0084 100644 --- a/client/ayon_core/tools/workfile_template_build/lib.py +++ b/client/ayon_core/tools/workfile_template_build/lib.py @@ -1,6 +1,8 @@ import traceback -from openpype.widgets import message_window +from qtpy import QtWidgets + +from ayon_core.tools.utils.dialogs import show_message_dialog def open_template_ui(builder, main_window): @@ -8,20 +10,17 @@ def open_template_ui(builder, main_window): Asks user about overwriting current scene and feedsback exceptions. """ - - result = message_window.message( - title="Opening template", - message="Caution! You will loose unsaved changes.\n" - "Do you want to continue?", - parent=main_window, - level="question", + result = QtWidgets.QMessageBox.question( + main_window, + "Opening template", + "Caution! You will loose unsaved changes.\nDo you want to continue?", + QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.No ) - - if result: + if result == QtWidgets.QMessageBox.Yes: try: builder.open_template() except Exception: - message_window.message( + show_message_dialog( title="Template Load Failed", message="".join(traceback.format_exc()), parent=main_window, diff --git a/openpype/widgets/message_window.py b/openpype/widgets/message_window.py deleted file mode 100644 index 940d530565..0000000000 --- a/openpype/widgets/message_window.py +++ /dev/null @@ -1,156 +0,0 @@ -import sys -import logging -from qtpy import QtWidgets, QtCore - -log = logging.getLogger(__name__) - - -class Window(QtWidgets.QWidget): - def __init__(self, parent, title, message, level): - super(Window, self).__init__() - self.parent = parent - self.title = title - self.message = message - self.level = level - - self.setWindowTitle(self.title) - - if self.level == "info": - self._info() - elif self.level == "warning": - self._warning() - elif self.level == "critical": - self._critical() - elif self.level == "question": - self._question() - - def _info(self): - self.setWindowTitle(self.title) - rc = QtWidgets.QMessageBox.information( - self, self.title, self.message) - if rc: - self.exit() - - def _warning(self): - rc = QtWidgets.QMessageBox.warning( - self, self.title, self.message) - if rc: - self.exit() - - def _critical(self): - rc = QtWidgets.QMessageBox.critical( - self, self.title, self.message) - if rc: - self.exit() - - def _question(self): - self.answer = None - rc = QtWidgets.QMessageBox.question( - self, - self.title, - self.message, - QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.No - ) - self.answer = False - if rc == QtWidgets.QMessageBox.Yes: - self.answer = True - self.exit() - - def exit(self): - self.hide() - return - - -def message(title=None, message=None, level="info", parent=None): - """ - Produces centered dialog with specific level denoting severity - Args: - title: (string) dialog title - message: (string) message - level: (string) info|warning|critical - parent: (QtWidgets.QApplication) - - Returns: - None - """ - app = parent - if not app: - app = QtWidgets.QApplication(sys.argv) - - ex = Window(app, title, message, level) - ex.show() - - # Move widget to center of screen - try: - desktop_rect = QtWidgets.QApplication.desktop().availableGeometry(ex) - center = desktop_rect.center() - ex.move( - center.x() - (ex.width() * 0.5), - center.y() - (ex.height() * 0.5) - ) - except Exception: - # skip all possible issues that may happen feature is not crutial - log.warning("Couldn't center message.", exc_info=True) - - if level == "question": - return ex.answer - - -class ScrollMessageBox(QtWidgets.QDialog): - """ - Basic version of scrollable QMessageBox. No other existing dialog - implementation is scrollable. - Args: - icon: - title: - messages: of messages - cancelable: - True if Cancel button should be added - """ - def __init__(self, icon, title, messages, cancelable=False): - super(ScrollMessageBox, self).__init__() - self.setWindowTitle(title) - self.icon = icon - - self.setWindowFlags(QtCore.Qt.WindowTitleHint) - - layout = QtWidgets.QVBoxLayout(self) - - scroll_widget = QtWidgets.QScrollArea(self) - scroll_widget.setWidgetResizable(True) - content_widget = QtWidgets.QWidget(self) - scroll_widget.setWidget(content_widget) - - message_len = 0 - content_layout = QtWidgets.QVBoxLayout(content_widget) - for message in messages: - label_widget = QtWidgets.QLabel(message, content_widget) - content_layout.addWidget(label_widget) - message_len = max(message_len, len(message)) - - # guess size of scrollable area - desktop = QtWidgets.QApplication.desktop() - max_width = desktop.availableGeometry().width() - scroll_widget.setMinimumWidth( - min(max_width, message_len * 6) - ) - layout.addWidget(scroll_widget) - - if not cancelable: # if no specific buttons OK only - buttons = QtWidgets.QDialogButtonBox.Ok - else: - buttons = QtWidgets.QDialogButtonBox.Ok | \ - QtWidgets.QDialogButtonBox.Cancel - - btn_box = QtWidgets.QDialogButtonBox(buttons) - btn_box.accepted.connect(self.accept) - - if cancelable: - btn_box.reject.connect(self.reject) - - btn = QtWidgets.QPushButton('Copy to clipboard') - btn.clicked.connect(lambda: QtWidgets.QApplication. - clipboard().setText("\n".join(messages))) - btn_box.addButton(btn, QtWidgets.QDialogButtonBox.NoRole) - - layout.addWidget(btn_box) - self.show() From 2534ee9cd7c279301fbc68de4cc10efb0c54616f Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Fri, 9 Feb 2024 12:57:19 +0100 Subject: [PATCH 034/185] CollectAudio can read AYON settings --- client/ayon_core/plugins/publish/collect_audio.py | 10 +++++----- client/ayon_core/settings/ayon_settings.py | 5 ----- 2 files changed, 5 insertions(+), 10 deletions(-) diff --git a/client/ayon_core/plugins/publish/collect_audio.py b/client/ayon_core/plugins/publish/collect_audio.py index 94477e5578..6da3fd0685 100644 --- a/client/ayon_core/plugins/publish/collect_audio.py +++ b/client/ayon_core/plugins/publish/collect_audio.py @@ -43,7 +43,7 @@ class CollectAudio(pyblish.api.ContextPlugin): "unreal" ] - audio_subset_name = "audioMain" + audio_product_name = "audioMain" def process(self, context): # Fake filtering by family inside context plugin @@ -71,9 +71,9 @@ class CollectAudio(pyblish.api.ContextPlugin): asset_names = set(instances_by_asset_name.keys()) self.log.debug(( - "Searching for audio subset '{subset}' in assets {assets}" + "Searching for audio product '{subset}' in assets {assets}" ).format( - subset=self.audio_subset_name, + subset=self.audio_product_name, assets=", ".join([ '"{}"'.format(asset_name) for asset_name in asset_names @@ -130,11 +130,11 @@ class CollectAudio(pyblish.api.ContextPlugin): } asset_ids = set(asset_id_by_name.values()) - # Query subsets with name define by 'audio_subset_name' attr + # Query subsets with name define by 'audio_product_name' attr # - one or none subsets with the name should be available on an asset subset_docs = get_subsets( project_name, - subset_names=[self.audio_subset_name], + subset_names=[self.audio_product_name], asset_ids=asset_ids, fields=["_id", "parent"] ) diff --git a/client/ayon_core/settings/ayon_settings.py b/client/ayon_core/settings/ayon_settings.py index acf5e0bb30..11a9f45367 100644 --- a/client/ayon_core/settings/ayon_settings.py +++ b/client/ayon_core/settings/ayon_settings.py @@ -1080,11 +1080,6 @@ def _convert_global_project_settings(ayon_settings, output, default_settings): # Publish conversion ayon_publish = ayon_core["publish"] - ayon_collect_audio = ayon_publish["CollectAudio"] - if "audio_product_name" in ayon_collect_audio: - ayon_collect_audio["audio_subset_name"] = ( - ayon_collect_audio.pop("audio_product_name")) - for profile in ayon_publish["ExtractReview"]["profiles"]: if "product_types" in profile: profile["families"] = profile.pop("product_types") From 163d0269e5c9178f8d4d7cbf68f4dadf5ced9c0b Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Fri, 9 Feb 2024 12:58:18 +0100 Subject: [PATCH 035/185] ExtractReview can read AYON settings --- .../plugins/publish/extract_review.py | 57 +++++++++++-------- client/ayon_core/settings/ayon_settings.py | 28 --------- server/settings/publish_plugins.py | 8 +-- 3 files changed, 38 insertions(+), 55 deletions(-) diff --git a/client/ayon_core/plugins/publish/extract_review.py b/client/ayon_core/plugins/publish/extract_review.py index 91d39882ae..a6e0196dc7 100644 --- a/client/ayon_core/plugins/publish/extract_review.py +++ b/client/ayon_core/plugins/publish/extract_review.py @@ -74,7 +74,7 @@ class ExtractReview(pyblish.api.InstancePlugin): alpha_exts = ["exr", "png", "dpx"] # Preset attributes - profiles = None + profiles = [] def process(self, instance): self.log.debug(str(instance.data["representations"])) @@ -112,7 +112,7 @@ class ExtractReview(pyblish.api.InstancePlugin): self.profiles, { "hosts": host_name, - "families": family, + "product_types": family, }, logger=self.log) if not profile: @@ -719,12 +719,12 @@ class ExtractReview(pyblish.api.InstancePlugin): lut_filters = self.lut_filters(new_repre, instance, ffmpeg_input_args) ffmpeg_video_filters.extend(lut_filters) - bg_alpha = 0 + bg_alpha = 0.0 bg_color = output_def.get("bg_color") if bg_color: bg_red, bg_green, bg_blue, bg_alpha = bg_color - if bg_alpha > 0: + if bg_alpha > 0.0: if not temp_data["input_allow_bg"]: self.log.info(( "Output definition has defined BG color input was" @@ -734,8 +734,7 @@ class ExtractReview(pyblish.api.InstancePlugin): bg_color_hex = "#{0:0>2X}{1:0>2X}{2:0>2X}".format( bg_red, bg_green, bg_blue ) - bg_color_alpha = float(bg_alpha) / 255 - bg_color_str = "{}@{}".format(bg_color_hex, bg_color_alpha) + bg_color_str = "{}@{}".format(bg_color_hex, bg_alpha) self.log.info("Applying BG color {}".format(bg_color_str)) color_args = [ @@ -1060,8 +1059,10 @@ class ExtractReview(pyblish.api.InstancePlugin): # NOTE: value in "-ac" was hardcoded to 2, changed to audio inputs len. # Need to merge audio if there are more than 1 input. if len(audio_inputs) > 1: - audio_out_args.append("-filter_complex amerge") - audio_out_args.append("-ac {}".format(len(audio_inputs))) + audio_out_args.extend([ + "-filter_complex", "amerge", + "-ac", str(len(audio_inputs)) + ]) return audio_in_args, audio_filters, audio_out_args @@ -1079,7 +1080,7 @@ class ExtractReview(pyblish.api.InstancePlugin): fill_color_hex = "{0:0>2X}{1:0>2X}{2:0>2X}".format( f_red, f_green, f_blue ) - fill_color_alpha = float(f_alpha) / 255 + fill_color_alpha = f_alpha line_thickness = letter_box_def["line_thickness"] line_color = letter_box_def["line_color"] @@ -1087,7 +1088,7 @@ class ExtractReview(pyblish.api.InstancePlugin): line_color_hex = "{0:0>2X}{1:0>2X}{2:0>2X}".format( l_red, l_green, l_blue ) - line_color_alpha = float(l_alpha) / 255 + line_color_alpha = l_alpha # test ratios and define if pillar or letter boxes output_ratio = float(output_width) / float(output_height) @@ -1283,8 +1284,12 @@ class ExtractReview(pyblish.api.InstancePlugin): # NOTE Setting only one of `width` or `heigth` is not allowed # - settings value can't have None but has value of 0 - output_width = output_def.get("width") or output_width or None - output_height = output_def.get("height") or output_height or None + output_width = ( + output_def.get("output_width") or output_width or None + ) + output_height = ( + output_def.get("output_height") or output_height or None + ) # Force to use input resolution if output resolution was not defined # in settings. Resolution from instance is not used when # 'use_input_res' is set to 'True'. @@ -1294,7 +1299,12 @@ class ExtractReview(pyblish.api.InstancePlugin): overscan_color_value = "black" overscan_color = output_def.get("overscan_color") if overscan_color: - bg_red, bg_green, bg_blue, _ = overscan_color + if len(overscan_color) == 3: + bg_red, bg_green, bg_blue = overscan_color + else: + # Backwards compatibility + bg_red, bg_green, bg_blue, _ = overscan_color + overscan_color_value = "#{0:0>2X}{1:0>2X}{2:0>2X}".format( bg_red, bg_green, bg_blue ) @@ -1505,12 +1515,13 @@ class ExtractReview(pyblish.api.InstancePlugin): Returns: list: Containg all output definitions matching entered families. """ - outputs = profile.get("outputs") or {} + outputs = profile.get("outputs") if not outputs: - return outputs + return [] filtered_outputs = {} - for filename_suffix, output_def in outputs.items(): + for output_def in outputs: + filename_suffix = output_def["name"] output_filters = output_def.get("filter") # If no filter on output preset, skip filtering and add output # profile for farther processing @@ -1523,16 +1534,16 @@ class ExtractReview(pyblish.api.InstancePlugin): continue # Subsets name filters - subset_filters = [ - subset_filter - for subset_filter in output_filters.get("subsets", []) + product_name_filters = [ + name_filter + for name_filter in output_filters.get("product_names", []) # Skip empty strings - if subset_filter + if name_filter ] - if subset_name and subset_filters: + if subset_name and product_name_filters: match = False - for subset_filter in subset_filters: - compiled = re.compile(subset_filter) + for product_name_filter in product_name_filters: + compiled = re.compile(product_name_filter) if compiled.search(subset_name): match = True break diff --git a/client/ayon_core/settings/ayon_settings.py b/client/ayon_core/settings/ayon_settings.py index 11a9f45367..4a59bb9438 100644 --- a/client/ayon_core/settings/ayon_settings.py +++ b/client/ayon_core/settings/ayon_settings.py @@ -1080,34 +1080,6 @@ def _convert_global_project_settings(ayon_settings, output, default_settings): # Publish conversion ayon_publish = ayon_core["publish"] - for profile in ayon_publish["ExtractReview"]["profiles"]: - if "product_types" in profile: - profile["families"] = profile.pop("product_types") - new_outputs = {} - for output_def in profile.pop("outputs"): - name = output_def.pop("name") - new_outputs[name] = output_def - - output_def_filter = output_def["filter"] - if "product_names" in output_def_filter: - output_def_filter["subsets"] = ( - output_def_filter.pop("product_names")) - - for color_key in ("overscan_color", "bg_color"): - output_def[color_key] = _convert_color(output_def[color_key]) - - letter_box = output_def["letter_box"] - for color_key in ("fill_color", "line_color"): - letter_box[color_key] = _convert_color(letter_box[color_key]) - - if "output_width" in output_def: - output_def["width"] = output_def.pop("output_width") - - if "output_height" in output_def: - output_def["height"] = output_def.pop("output_height") - - profile["outputs"] = new_outputs - # ExtractThumbnail plugin ayon_extract_thumbnail = ayon_publish["ExtractThumbnail"] # fix display and view at oiio defaults diff --git a/server/settings/publish_plugins.py b/server/settings/publish_plugins.py index 7aa86aafa6..f1b93b03b5 100644 --- a/server/settings/publish_plugins.py +++ b/server/settings/publish_plugins.py @@ -9,7 +9,7 @@ from ayon_server.settings import ( task_types_enum, ) -from ayon_server.types import ColorRGBA_uint8 +from ayon_server.types import ColorRGB_uint8, ColorRGBA_uint8 class ValidateBaseModel(BaseSettingsModel): @@ -383,8 +383,8 @@ class ExtractReviewOutputDefModel(BaseSettingsModel): "Crop input overscan. See the documentation for more information." ) ) - overscan_color: ColorRGBA_uint8 = SettingsField( - (0, 0, 0, 0.0), + overscan_color: ColorRGB_uint8 = SettingsField( + (0, 0, 0), title="Overscan color", description=( "Overscan color is used when input aspect ratio is not" @@ -896,7 +896,7 @@ DEFAULT_PUBLISH_VALUES = { "single_frame_filter": "single_frame" }, "overscan_crop": "", - "overscan_color": [0, 0, 0, 1.0], + "overscan_color": [0, 0, 0], "width": 1920, "height": 1080, "scale_pixel_aspect": True, From b5f7fb3162195790c762d7cc314a8f277c43e0d0 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Fri, 9 Feb 2024 13:00:28 +0100 Subject: [PATCH 036/185] deadline can read AYON settings --- .../plugins/publish/submit_maya_deadline.py | 12 ++++- .../plugins/publish/submit_nuke_deadline.py | 16 ++++--- .../plugins/publish/submit_publish_job.py | 45 +++++++++++++++---- client/ayon_core/settings/ayon_settings.py | 45 +------------------ 4 files changed, 57 insertions(+), 61 deletions(-) diff --git a/client/ayon_core/modules/deadline/plugins/publish/submit_maya_deadline.py b/client/ayon_core/modules/deadline/plugins/publish/submit_maya_deadline.py index 84e6e93e6a..baa389cb12 100644 --- a/client/ayon_core/modules/deadline/plugins/publish/submit_maya_deadline.py +++ b/client/ayon_core/modules/deadline/plugins/publish/submit_maya_deadline.py @@ -18,6 +18,7 @@ Attributes: from __future__ import print_function import os +import json import getpass import copy import re @@ -131,8 +132,15 @@ class MayaSubmitDeadline(abstract_submit_deadline.AbstractSubmitDeadline, cls.group = settings.get("group", cls.group) cls.strict_error_checking = settings.get("strict_error_checking", cls.strict_error_checking) - cls.jobInfo = settings.get("jobInfo", cls.jobInfo) - cls.pluginInfo = settings.get("pluginInfo", cls.pluginInfo) + job_info = settings.get("jobInfo") + if job_info: + job_info = json.loads(job_info) + plugin_info = settings.get("pluginInfo") + if plugin_info: + plugin_info = json.loads(plugin_info) + + cls.jobInfo = job_info or cls.jobInfo + cls.pluginInfo = plugin_info or cls.pluginInfo def get_job_info(self): job_info = DeadlineJobInfo(Plugin="MayaBatch") diff --git a/client/ayon_core/modules/deadline/plugins/publish/submit_nuke_deadline.py b/client/ayon_core/modules/deadline/plugins/publish/submit_nuke_deadline.py index 9fff8edee6..ce4fd96da4 100644 --- a/client/ayon_core/modules/deadline/plugins/publish/submit_nuke_deadline.py +++ b/client/ayon_core/modules/deadline/plugins/publish/submit_nuke_deadline.py @@ -40,10 +40,10 @@ class NukeSubmitDeadline(pyblish.api.InstancePlugin, concurrent_tasks = 1 group = "" department = "" - limit_groups = {} + limit_groups = [] use_gpu = False env_allowed_keys = [] - env_search_replace_values = {} + env_search_replace_values = [] workfile_dependency = True use_published_workfile = True @@ -402,8 +402,10 @@ class NukeSubmitDeadline(pyblish.api.InstancePlugin, # finally search replace in values of any key if self.env_search_replace_values: for key, value in environment.items(): - for _k, _v in self.env_search_replace_values.items(): - environment[key] = value.replace(_k, _v) + for item in self.env_search_replace_values: + environment[key] = value.replace( + item["name"], item["value"] + ) payload["JobInfo"].update({ "EnvironmentKeyValue%d" % index: "{key}={value}".format( @@ -539,8 +541,10 @@ class NukeSubmitDeadline(pyblish.api.InstancePlugin, import nuke captured_groups = [] - for lg_name, list_node_class in self.limit_groups.items(): - for node_class in list_node_class: + for limit_group in self.limit_groups: + lg_name = limit_group["name"] + + for node_class in limit_group["value"]: for node in nuke.allNodes(recurseGroups=True): # ignore all nodes not member of defined class if node.Class() not in node_class: diff --git a/client/ayon_core/modules/deadline/plugins/publish/submit_publish_job.py b/client/ayon_core/modules/deadline/plugins/publish/submit_publish_job.py index bd343e103a..3e9514204d 100644 --- a/client/ayon_core/modules/deadline/plugins/publish/submit_publish_job.py +++ b/client/ayon_core/modules/deadline/plugins/publish/submit_publish_job.py @@ -99,12 +99,33 @@ class ProcessSubmittedJobOnFarm(pyblish.api.InstancePlugin, "karma_rop", "vray_rop", "redshift_rop"] - aov_filter = {"maya": [r".*([Bb]eauty).*"], - "blender": [r".*([Bb]eauty).*"], - "aftereffects": [r".*"], # for everything from AE - "harmony": [r".*"], # for everything from AE - "celaction": [r".*"], - "max": [r".*"]} + aov_filter = [ + { + "name": "maya", + "value": [r".*([Bb]eauty).*"] + }, + { + "name": "blender", + "value": [r".*([Bb]eauty).*"] + }, + { + # for everything from AE + "name": "aftereffects", + "value": [r".*"] + }, + { + "name": "harmony", + "value": [r".*"] + }, + { + "name": "celaction", + "value": [r".*"] + }, + { + "name": "max", + "value": [r".*"] + }, + ] environ_keys = [ "FTRACK_API_USER", @@ -506,17 +527,23 @@ class ProcessSubmittedJobOnFarm(pyblish.api.InstancePlugin, self.log.debug("Instance has review explicitly disabled.") do_not_add_review = True + aov_filter = { + item["name"]: item["value"] + for item in self.aov_filter + } if isinstance(instance.data.get("expectedFiles")[0], dict): instances = create_instances_for_aov( instance, instance_skeleton_data, - self.aov_filter, self.skip_integration_repre_list, - do_not_add_review) + aov_filter, + self.skip_integration_repre_list, + do_not_add_review + ) else: representations = prepare_representations( instance_skeleton_data, instance.data.get("expectedFiles"), anatomy, - self.aov_filter, + aov_filter, self.skip_integration_repre_list, do_not_add_review, instance.context, diff --git a/client/ayon_core/settings/ayon_settings.py b/client/ayon_core/settings/ayon_settings.py index 4a59bb9438..bca5198f95 100644 --- a/client/ayon_core/settings/ayon_settings.py +++ b/client/ayon_core/settings/ayon_settings.py @@ -951,49 +951,6 @@ def _convert_webpublisher_project_settings(ayon_settings, output): output["webpublisher"] = ayon_webpublisher -def _convert_deadline_project_settings(ayon_settings, output): - if "deadline" not in ayon_settings: - return - - ayon_deadline = ayon_settings["deadline"] - - for key in ("deadline_urls",): - ayon_deadline.pop(key) - - ayon_deadline_publish = ayon_deadline["publish"] - limit_groups = { - item["name"]: item["value"] - for item in ayon_deadline_publish["NukeSubmitDeadline"]["limit_groups"] - } - ayon_deadline_publish["NukeSubmitDeadline"]["limit_groups"] = limit_groups - - maya_submit = ayon_deadline_publish["MayaSubmitDeadline"] - for json_key in ("jobInfo", "pluginInfo"): - src_text = maya_submit.pop(json_key) - try: - value = json.loads(src_text) - except ValueError: - value = {} - maya_submit[json_key] = value - - nuke_submit = ayon_deadline_publish["NukeSubmitDeadline"] - nuke_submit["env_search_replace_values"] = { - item["name"]: item["value"] - for item in nuke_submit.pop("env_search_replace_values") - } - nuke_submit["limit_groups"] = { - item["name"]: item["value"] for item in nuke_submit.pop("limit_groups") - } - - process_subsetted_job = ayon_deadline_publish["ProcessSubmittedJobOnFarm"] - process_subsetted_job["aov_filter"] = { - item["name"]: item["value"] - for item in process_subsetted_job.pop("aov_filter") - } - - output["deadline"] = ayon_deadline - - def _convert_royalrender_project_settings(ayon_settings, output): if "royalrender" not in ayon_settings: return @@ -1254,6 +1211,7 @@ def convert_project_settings(ayon_settings, default_settings): "houdini", "resolve", "unreal", + "deadline", } for key in exact_match: if key in ayon_settings: @@ -1276,7 +1234,6 @@ def convert_project_settings(ayon_settings, default_settings): _convert_traypublisher_project_settings(ayon_settings, output) _convert_webpublisher_project_settings(ayon_settings, output) - _convert_deadline_project_settings(ayon_settings, output) _convert_royalrender_project_settings(ayon_settings, output) _convert_kitsu_project_settings(ayon_settings, output) _convert_shotgrid_project_settings(ayon_settings, output) From aac11597aaf3d54898e9c4428c9358baea139872 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Fri, 9 Feb 2024 13:00:55 +0100 Subject: [PATCH 037/185] simplify how applications are applied --- client/ayon_core/settings/ayon_settings.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/client/ayon_core/settings/ayon_settings.py b/client/ayon_core/settings/ayon_settings.py index bca5198f95..1521a0dc25 100644 --- a/client/ayon_core/settings/ayon_settings.py +++ b/client/ayon_core/settings/ayon_settings.py @@ -1211,6 +1211,7 @@ def convert_project_settings(ayon_settings, default_settings): "houdini", "resolve", "unreal", + "applications", "deadline", } for key in exact_match: @@ -1218,8 +1219,6 @@ def convert_project_settings(ayon_settings, default_settings): output[key] = ayon_settings[key] _convert_host_imageio(output[key]) - if "applications" in ayon_settings: - output["applications"] = ayon_settings["applications"] _convert_blender_project_settings(ayon_settings, output) _convert_celaction_project_settings(ayon_settings, output) _convert_flame_project_settings(ayon_settings, output) From 40a5b0e6d9c271c3e6faf8e708d1013a0ae18324 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Fri, 9 Feb 2024 13:07:00 +0100 Subject: [PATCH 038/185] photoshop plugins can use AYON settings --- .../plugins/publish/collect_color_coded_instances.py | 6 +++--- .../photoshop/plugins/publish/collect_review.py | 2 -- client/ayon_core/settings/ayon_settings.py | 12 ------------ 3 files changed, 3 insertions(+), 17 deletions(-) diff --git a/client/ayon_core/hosts/photoshop/plugins/publish/collect_color_coded_instances.py b/client/ayon_core/hosts/photoshop/plugins/publish/collect_color_coded_instances.py index e309da62ba..987097f4ff 100644 --- a/client/ayon_core/hosts/photoshop/plugins/publish/collect_color_coded_instances.py +++ b/client/ayon_core/hosts/photoshop/plugins/publish/collect_color_coded_instances.py @@ -42,7 +42,7 @@ class CollectColorCodedInstances(pyblish.api.ContextPlugin): # flattened template cannot subset_template_name = "" create_flatten_image = "no" - flatten_subset_template = "" + flatten_product_name_template = "" def process(self, context): self.log.info("CollectColorCodedInstances") @@ -124,12 +124,12 @@ class CollectColorCodedInstances(pyblish.api.ContextPlugin): if self.create_flatten_image != "no" and publishable_layers: self.log.debug("create_flatten_image") - if not self.flatten_subset_template: + if not self.flatten_product_name_template: self.log.warning("No template for flatten image") return fill_pairs.pop("layer") - subset = self.flatten_subset_template.format( + subset = self.flatten_product_name_template.format( **prepare_template_data(fill_pairs)) first_layer = publishable_layers[0] # dummy layer diff --git a/client/ayon_core/hosts/photoshop/plugins/publish/collect_review.py b/client/ayon_core/hosts/photoshop/plugins/publish/collect_review.py index e487760736..e51dd253ca 100644 --- a/client/ayon_core/hosts/photoshop/plugins/publish/collect_review.py +++ b/client/ayon_core/hosts/photoshop/plugins/publish/collect_review.py @@ -22,8 +22,6 @@ class CollectReview(pyblish.api.ContextPlugin): hosts = ["photoshop"] order = pyblish.api.CollectorOrder + 0.1 - publish = True - def process(self, context): for instance in context: creator_attributes = instance.data["creator_attributes"] diff --git a/client/ayon_core/settings/ayon_settings.py b/client/ayon_core/settings/ayon_settings.py index 1521a0dc25..b90de7946b 100644 --- a/client/ayon_core/settings/ayon_settings.py +++ b/client/ayon_core/settings/ayon_settings.py @@ -808,18 +808,6 @@ def _convert_photoshop_project_settings(ayon_settings, output): ayon_photoshop = ayon_settings["photoshop"] _convert_host_imageio(ayon_photoshop) - - ayon_publish_photoshop = ayon_photoshop["publish"] - - ayon_colorcoded = ayon_publish_photoshop["CollectColorCodedInstances"] - if "flatten_product_type_template" in ayon_colorcoded: - ayon_colorcoded["flatten_subset_template"] = ( - ayon_colorcoded.pop("flatten_product_type_template")) - - collect_review = ayon_publish_photoshop["CollectReview"] - if "active" in collect_review: - collect_review["publish"] = collect_review.pop("active") - output["photoshop"] = ayon_photoshop From 94b50b2d96e783eb3706af4a593ed2a73f502f7d Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Fri, 9 Feb 2024 13:07:42 +0100 Subject: [PATCH 039/185] cleanup photoshop plugin attributes --- .../plugins/publish/collect_color_coded_instances.py | 3 +-- .../hosts/photoshop/plugins/publish/collect_review.py | 7 +------ 2 files changed, 2 insertions(+), 8 deletions(-) diff --git a/client/ayon_core/hosts/photoshop/plugins/publish/collect_color_coded_instances.py b/client/ayon_core/hosts/photoshop/plugins/publish/collect_color_coded_instances.py index 987097f4ff..236fe878ba 100644 --- a/client/ayon_core/hosts/photoshop/plugins/publish/collect_color_coded_instances.py +++ b/client/ayon_core/hosts/photoshop/plugins/publish/collect_color_coded_instances.py @@ -29,9 +29,8 @@ class CollectColorCodedInstances(pyblish.api.ContextPlugin): Identifier: id (str): "pyblish.avalon.instance" """ - order = pyblish.api.CollectorOrder + 0.100 - label = "Instances" + label = "Collect Color-coded Instances" order = pyblish.api.CollectorOrder hosts = ["photoshop"] targets = ["automated"] diff --git a/client/ayon_core/hosts/photoshop/plugins/publish/collect_review.py b/client/ayon_core/hosts/photoshop/plugins/publish/collect_review.py index e51dd253ca..3a4b7b5828 100644 --- a/client/ayon_core/hosts/photoshop/plugins/publish/collect_review.py +++ b/client/ayon_core/hosts/photoshop/plugins/publish/collect_review.py @@ -6,19 +6,14 @@ Provides: instance -> family ("review") """ -import os - import pyblish.api -from ayon_core.pipeline.create import get_subset_name - class CollectReview(pyblish.api.ContextPlugin): """Adds review to families for instances marked to be reviewable. """ - label = "Collect Review" - label = "Review" + label = "Collect Review Family" hosts = ["photoshop"] order = pyblish.api.CollectorOrder + 0.1 From f6f09ce43b2f1c9b4618bbaf508a8ad643f07dad Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Fri, 9 Feb 2024 13:10:19 +0100 Subject: [PATCH 040/185] substance can read shelves from AYON settings --- .../hosts/substancepainter/api/pipeline.py | 17 +++++++++-------- client/ayon_core/settings/ayon_settings.py | 8 -------- 2 files changed, 9 insertions(+), 16 deletions(-) diff --git a/client/ayon_core/hosts/substancepainter/api/pipeline.py b/client/ayon_core/hosts/substancepainter/api/pipeline.py index 2bbcf2aded..03cb22136c 100644 --- a/client/ayon_core/hosts/substancepainter/api/pipeline.py +++ b/client/ayon_core/hosts/substancepainter/api/pipeline.py @@ -240,33 +240,34 @@ class SubstanceHost(HostBase, IWorkfileHost, ILoadHost, IPublishHost): def _install_shelves(self, project_settings): - shelves = project_settings["substancepainter"].get("shelves", {}) + shelves = project_settings["substancepainter"].get("shelves", []) if not shelves: return # Prepare formatting data if we detect any path which might have # template tokens like {asset} in there. formatting_data = {} - has_formatting_entries = any("{" in path for path in shelves.values()) + has_formatting_entries = any("{" in item["value"] for item in shelves) if has_formatting_entries: project_name = self.get_current_project_name() asset_name = self.get_current_asset_name() task_name = self.get_current_asset_name() system_settings = get_system_settings() - formatting_data = get_template_data_with_names(project_name, - asset_name, - task_name, - system_settings) + formatting_data = get_template_data_with_names( + project_name, asset_name, task_name, system_settings + ) anatomy = Anatomy(project_name) formatting_data["root"] = anatomy.roots - for name, path in shelves.items(): - shelf_name = None + for shelve_item in shelves: # Allow formatting with anatomy for the paths + path = shelve_item["value"] if "{" in path: path = StringTemplate.format_template(path, formatting_data) + name = shelve_item["name"] + shelf_name = None try: shelf_name = lib.load_shelf(path, name=name) except ValueError as exc: diff --git a/client/ayon_core/settings/ayon_settings.py b/client/ayon_core/settings/ayon_settings.py index b90de7946b..726b2147cd 100644 --- a/client/ayon_core/settings/ayon_settings.py +++ b/client/ayon_core/settings/ayon_settings.py @@ -817,14 +817,6 @@ def _convert_substancepainter_project_settings(ayon_settings, output): ayon_substance_painter = ayon_settings["substancepainter"] _convert_host_imageio(ayon_substance_painter) - if "shelves" in ayon_substance_painter: - shelves_items = ayon_substance_painter["shelves"] - new_shelves_items = { - item["name"]: item["value"] - for item in shelves_items - } - ayon_substance_painter["shelves"] = new_shelves_items - output["substancepainter"] = ayon_substance_painter From 8fb6e1e4d43b58254f01e2e7957cf8380d7653bd Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Fri, 9 Feb 2024 13:14:16 +0100 Subject: [PATCH 041/185] fix photoshop settings --- server_addon/photoshop/server/settings/publish_plugins.py | 6 +++--- server_addon/photoshop/server/version.py | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/server_addon/photoshop/server/settings/publish_plugins.py b/server_addon/photoshop/server/settings/publish_plugins.py index c4a392d490..d04faaf53a 100644 --- a/server_addon/photoshop/server/settings/publish_plugins.py +++ b/server_addon/photoshop/server/settings/publish_plugins.py @@ -62,9 +62,9 @@ class CollectColorCodedInstancesPlugin(BaseSettingsModel): enum_resolver=lambda: create_flatten_image_enum, ) - flatten_product_type_template: str = SettingsField( + flatten_product_name_template: str = SettingsField( "", - title="Subset template for flatten image" + title="Product name template for flatten image" ) color_code_mapping: list[ColorCodeMappings] = SettingsField( @@ -178,7 +178,7 @@ class PhotoshopPublishPlugins(BaseSettingsModel): DEFAULT_PUBLISH_SETTINGS = { "CollectColorCodedInstances": { "create_flatten_image": "no", - "flatten_product_type_template": "", + "flatten_product_name_template": "", "color_code_mapping": [] }, "CollectReview": { diff --git a/server_addon/photoshop/server/version.py b/server_addon/photoshop/server/version.py index a242f0e757..df0c92f1e2 100644 --- a/server_addon/photoshop/server/version.py +++ b/server_addon/photoshop/server/version.py @@ -1,3 +1,3 @@ # -*- coding: utf-8 -*- """Package declaring addon version.""" -__version__ = "0.1.1" +__version__ = "0.1.2" From 53df65a4127d6fba8cfc4350d6189c55d104055c Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Fri, 9 Feb 2024 13:14:57 +0100 Subject: [PATCH 042/185] TVPaint can read AYON settings --- client/ayon_core/settings/ayon_settings.py | 23 +------------------ .../server/settings/publish_plugins.py | 8 +++---- server_addon/tvpaint/server/version.py | 2 +- 3 files changed, 6 insertions(+), 27 deletions(-) diff --git a/client/ayon_core/settings/ayon_settings.py b/client/ayon_core/settings/ayon_settings.py index 726b2147cd..e151043afb 100644 --- a/client/ayon_core/settings/ayon_settings.py +++ b/client/ayon_core/settings/ayon_settings.py @@ -823,30 +823,9 @@ def _convert_substancepainter_project_settings(ayon_settings, output): def _convert_tvpaint_project_settings(ayon_settings, output): if "tvpaint" not in ayon_settings: return + ayon_tvpaint = ayon_settings["tvpaint"] - _convert_host_imageio(ayon_tvpaint) - - ayon_publish_settings = ayon_tvpaint["publish"] - for plugin_name in ( - "ValidateProjectSettings", - "ValidateMarks", - "ValidateStartFrame", - "ValidateAssetName", - ): - ayon_value = ayon_publish_settings[plugin_name] - for src_key, dst_key in ( - ("action_enabled", "optional"), - ("action_enable", "active"), - ): - if src_key in ayon_value: - ayon_value[dst_key] = ayon_value.pop(src_key) - - extract_sequence_setting = ayon_publish_settings["ExtractSequence"] - extract_sequence_setting["review_bg"] = _convert_color( - extract_sequence_setting["review_bg"] - ) - output["tvpaint"] = ayon_tvpaint diff --git a/server_addon/tvpaint/server/settings/publish_plugins.py b/server_addon/tvpaint/server/settings/publish_plugins.py index 0623524c92..37ad3e0e70 100644 --- a/server_addon/tvpaint/server/settings/publish_plugins.py +++ b/server_addon/tvpaint/server/settings/publish_plugins.py @@ -1,5 +1,5 @@ from ayon_server.settings import BaseSettingsModel, SettingsField -from ayon_server.types import ColorRGBA_uint8 +from ayon_server.types import ColorRGB_uint8 class CollectRenderInstancesModel(BaseSettingsModel): @@ -11,8 +11,8 @@ class CollectRenderInstancesModel(BaseSettingsModel): class ExtractSequenceModel(BaseSettingsModel): """Review BG color is used for whole scene review and for thumbnails.""" # TODO Use alpha color - review_bg: ColorRGBA_uint8 = SettingsField( - (255, 255, 255, 1.0), + review_bg: ColorRGB_uint8 = SettingsField( + (255, 255, 255), title="Review BG color") @@ -100,7 +100,7 @@ DEFAULT_PUBLISH_SETTINGS = { "ignore_render_pass_transparency": False }, "ExtractSequence": { - "review_bg": [255, 255, 255, 1.0] + "review_bg": [255, 255, 255] }, "ValidateProjectSettings": { "enabled": True, diff --git a/server_addon/tvpaint/server/version.py b/server_addon/tvpaint/server/version.py index 485f44ac21..b3f4756216 100644 --- a/server_addon/tvpaint/server/version.py +++ b/server_addon/tvpaint/server/version.py @@ -1 +1 @@ -__version__ = "0.1.1" +__version__ = "0.1.2" From 00e2bebd125615bf31b120aaa452773391245a51 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Fri, 9 Feb 2024 14:44:30 +0100 Subject: [PATCH 043/185] blender can use AYON settings --- .../hosts/blender/plugins/publish/extract_playblast.py | 9 ++++++--- .../hosts/blender/plugins/publish/extract_thumbnail.py | 6 ++++-- client/ayon_core/settings/ayon_settings.py | 6 ------ 3 files changed, 10 insertions(+), 11 deletions(-) diff --git a/client/ayon_core/hosts/blender/plugins/publish/extract_playblast.py b/client/ayon_core/hosts/blender/plugins/publish/extract_playblast.py index 83e6b26fbe..04fc2c5c39 100644 --- a/client/ayon_core/hosts/blender/plugins/publish/extract_playblast.py +++ b/client/ayon_core/hosts/blender/plugins/publish/extract_playblast.py @@ -1,9 +1,11 @@ import os +import json + import clique +import pyblish.api import bpy -import pyblish.api from ayon_core.pipeline import publish from ayon_core.hosts.blender.api import capture from ayon_core.hosts.blender.api.lib import maintained_time @@ -23,6 +25,8 @@ class ExtractPlayblast(publish.Extractor, publish.OptionalPyblishPluginMixin): optional = True order = pyblish.api.ExtractorOrder + 0.01 + presets = "{}" + def process(self, instance): if not self.is_active(instance.data): return @@ -59,8 +63,7 @@ class ExtractPlayblast(publish.Extractor, publish.OptionalPyblishPluginMixin): self.log.debug(f"Outputting images to {path}") - project_settings = instance.context.data["project_settings"]["blender"] - presets = project_settings["publish"]["ExtractPlayblast"]["presets"] + presets = json.loads(self.presets) preset = presets.get("default") preset.update({ "camera": camera, diff --git a/client/ayon_core/hosts/blender/plugins/publish/extract_thumbnail.py b/client/ayon_core/hosts/blender/plugins/publish/extract_thumbnail.py index 7b445a0113..ec701610ce 100644 --- a/client/ayon_core/hosts/blender/plugins/publish/extract_thumbnail.py +++ b/client/ayon_core/hosts/blender/plugins/publish/extract_thumbnail.py @@ -1,5 +1,6 @@ import os import glob +import json import pyblish.api from ayon_core.pipeline import publish @@ -21,7 +22,7 @@ class ExtractThumbnail(publish.Extractor): hosts = ["blender"] families = ["review"] order = pyblish.api.ExtractorOrder + 0.01 - presets = {} + presets = "{}" def process(self, instance): self.log.debug("Extracting capture..") @@ -44,7 +45,8 @@ class ExtractThumbnail(publish.Extractor): family = instance.data.get("family") isolate = instance.data("isolate", None) - preset = self.presets.get(family, {}) + presets = json.loads(self.presets) + preset = presets.get(family, {}) preset.update({ "camera": camera, diff --git a/client/ayon_core/settings/ayon_settings.py b/client/ayon_core/settings/ayon_settings.py index e151043afb..e2e569c233 100644 --- a/client/ayon_core/settings/ayon_settings.py +++ b/client/ayon_core/settings/ayon_settings.py @@ -248,12 +248,6 @@ def _convert_blender_project_settings(ayon_settings, output): ayon_blender = ayon_settings["blender"] _convert_host_imageio(ayon_blender) - ayon_publish = ayon_blender["publish"] - - for plugin in ("ExtractThumbnail", "ExtractPlayblast"): - plugin_settings = ayon_publish[plugin] - plugin_settings["presets"] = json.loads(plugin_settings["presets"]) - output["blender"] = ayon_blender From 5c0d866c1efa4b194b0b0534ac1dd410042f8ad2 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Fri, 9 Feb 2024 14:50:53 +0100 Subject: [PATCH 044/185] fusion is handling AYON settings in code --- client/ayon_core/hosts/fusion/api/plugin.py | 11 ++++++- client/ayon_core/settings/ayon_settings.py | 33 --------------------- 2 files changed, 10 insertions(+), 34 deletions(-) diff --git a/client/ayon_core/hosts/fusion/api/plugin.py b/client/ayon_core/hosts/fusion/api/plugin.py index 12a29d2986..5d7a9dd87d 100644 --- a/client/ayon_core/hosts/fusion/api/plugin.py +++ b/client/ayon_core/hosts/fusion/api/plugin.py @@ -148,7 +148,16 @@ class GenericCreateSaver(Creator): }) # build file path to render - filepath = self.temp_rendering_path_template.format(**formatting_data) + # TODO make sure the keys are available in 'formatting_data' + temp_rendering_path_template = ( + self.temp_rendering_path_template + .replace("{product[name]}", "{subset}") + .replace("{product[type]}", "{family}") + .replace("{folder[name]}", "{asset}") + .replace("{task[name]}", "{task}") + ) + + filepath = temp_rendering_path_template.format(**formatting_data) comp = get_current_comp() tool["Clip"] = comp.ReverseMapPath(os.path.normpath(filepath)) diff --git a/client/ayon_core/settings/ayon_settings.py b/client/ayon_core/settings/ayon_settings.py index e2e569c233..39b0b117f7 100644 --- a/client/ayon_core/settings/ayon_settings.py +++ b/client/ayon_core/settings/ayon_settings.py @@ -324,39 +324,6 @@ def _convert_fusion_project_settings(ayon_settings, output): ayon_fusion = ayon_settings["fusion"] _convert_host_imageio(ayon_fusion) - ayon_imageio_fusion = ayon_fusion["imageio"] - - if "ocioSettings" in ayon_imageio_fusion: - ayon_ocio_setting = ayon_imageio_fusion.pop("ocioSettings") - paths = ayon_ocio_setting.pop("ocioPathModel") - for key, value in tuple(paths.items()): - new_value = [] - if value: - new_value.append(value) - paths[key] = new_value - - ayon_ocio_setting["configFilePath"] = paths - ayon_imageio_fusion["ocio"] = ayon_ocio_setting - elif "ocio" in ayon_imageio_fusion: - paths = ayon_imageio_fusion["ocio"].pop("configFilePath") - for key, value in tuple(paths.items()): - new_value = [] - if value: - new_value.append(value) - paths[key] = new_value - ayon_imageio_fusion["ocio"]["configFilePath"] = paths - - _convert_host_imageio(ayon_imageio_fusion) - - ayon_create_saver = ayon_fusion["create"]["CreateSaver"] - ayon_create_saver["temp_rendering_path_template"] = ( - ayon_create_saver["temp_rendering_path_template"] - .replace("{product[name]}", "{subset}") - .replace("{product[type]}", "{family}") - .replace("{folder[name]}", "{asset}") - .replace("{task[name]}", "{task}") - ) - output["fusion"] = ayon_fusion From cd1ac5c15b8268158ff5a5ad8b64cf31fd25a340 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Fri, 9 Feb 2024 15:04:57 +0100 Subject: [PATCH 045/185] maya use render settings from AYON --- .../ayon_core/hosts/maya/api/lib_rendersettings.py | 14 +++++++------- .../hosts/maya/plugins/create/create_render.py | 2 +- .../hosts/maya/plugins/create/create_vrayscene.py | 2 +- .../plugins/publish/validate_render_image_rule.py | 2 +- client/ayon_core/settings/ayon_settings.py | 3 --- 5 files changed, 10 insertions(+), 13 deletions(-) diff --git a/client/ayon_core/hosts/maya/api/lib_rendersettings.py b/client/ayon_core/hosts/maya/api/lib_rendersettings.py index 54ee7888b3..1e2c95ac73 100644 --- a/client/ayon_core/hosts/maya/api/lib_rendersettings.py +++ b/client/ayon_core/hosts/maya/api/lib_rendersettings.py @@ -46,7 +46,7 @@ class RenderSettings(object): project_settings = get_project_settings( get_current_project_name() ) - render_settings = project_settings["maya"]["RenderSettings"] + render_settings = project_settings["maya"]["render_settings"] image_prefixes = { "vray": render_settings["vray_renderer"]["image_prefix"], "arnold": render_settings["arnold_renderer"]["image_prefix"], @@ -82,12 +82,12 @@ class RenderSettings(object): try: aov_separator = self._aov_chars[( self._project_settings["maya"] - ["RenderSettings"] + ["render_settings"] ["aov_separator"] )] except KeyError: aov_separator = "_" - reset_frame = self._project_settings["maya"]["RenderSettings"]["reset_current_frame"] # noqa + reset_frame = self._project_settings["maya"]["render_settings"]["reset_current_frame"] # noqa if reset_frame: start_frame = cmds.getAttr("defaultRenderGlobals.startFrame") @@ -131,7 +131,7 @@ class RenderSettings(object): import maya.mel as mel # noqa: F401 createOptions() - render_settings = self._project_settings["maya"]["RenderSettings"] + render_settings = self._project_settings["maya"]["render_settings"] arnold_render_presets = render_settings["arnold_renderer"] # noqa # Force resetting settings and AOV list to avoid having to deal with # AOV checking logic, for now. @@ -180,7 +180,7 @@ class RenderSettings(object): from maya import cmds # noqa: F401 import maya.mel as mel # noqa: F401 - render_settings = self._project_settings["maya"]["RenderSettings"] + render_settings = self._project_settings["maya"]["render_settings"] redshift_render_presets = render_settings["redshift_renderer"] remove_aovs = render_settings["remove_aovs"] @@ -239,7 +239,7 @@ class RenderSettings(object): rman_render_presets = ( self._project_settings ["maya"] - ["RenderSettings"] + ["render_settings"] ["renderman_renderer"] ) display_filters = rman_render_presets["display_filters"] @@ -304,7 +304,7 @@ class RenderSettings(object): settings = cmds.ls(type="VRaySettingsNode") node = settings[0] if settings else cmds.createNode("VRaySettingsNode") - render_settings = self._project_settings["maya"]["RenderSettings"] + render_settings = self._project_settings["maya"]["render_settings"] vray_render_presets = render_settings["vray_renderer"] # vrayRenderElement remove_aovs = render_settings["remove_aovs"] diff --git a/client/ayon_core/hosts/maya/plugins/create/create_render.py b/client/ayon_core/hosts/maya/plugins/create/create_render.py index f537f249cd..4481836c89 100644 --- a/client/ayon_core/hosts/maya/plugins/create/create_render.py +++ b/client/ayon_core/hosts/maya/plugins/create/create_render.py @@ -35,7 +35,7 @@ class CreateRenderlayer(plugin.RenderlayerCreator): @classmethod def apply_settings(cls, project_settings): - cls.render_settings = project_settings["maya"]["RenderSettings"] + cls.render_settings = project_settings["maya"]["render_settings"] def create(self, subset_name, instance_data, pre_create_data): # Only allow a single render instance to exist diff --git a/client/ayon_core/hosts/maya/plugins/create/create_vrayscene.py b/client/ayon_core/hosts/maya/plugins/create/create_vrayscene.py index 3642f5f689..bc8110eff1 100644 --- a/client/ayon_core/hosts/maya/plugins/create/create_vrayscene.py +++ b/client/ayon_core/hosts/maya/plugins/create/create_vrayscene.py @@ -23,7 +23,7 @@ class CreateVRayScene(plugin.RenderlayerCreator): @classmethod def apply_settings(cls, project_settings): - cls.render_settings = project_settings["maya"]["RenderSettings"] + cls.render_settings = project_settings["maya"]["render_settings"] def create(self, subset_name, instance_data, pre_create_data): # Only allow a single render instance to exist diff --git a/client/ayon_core/hosts/maya/plugins/publish/validate_render_image_rule.py b/client/ayon_core/hosts/maya/plugins/publish/validate_render_image_rule.py index 576886072d..efc622c416 100644 --- a/client/ayon_core/hosts/maya/plugins/publish/validate_render_image_rule.py +++ b/client/ayon_core/hosts/maya/plugins/publish/validate_render_image_rule.py @@ -55,7 +55,7 @@ class ValidateRenderImageRule(pyblish.api.InstancePlugin): if staging_dir: cls.log.debug( "Staging dir found: \"{}\". Ignoring setting from " - "`project_settings/maya/RenderSettings/" + "`project_settings/maya/render_settings/" "default_render_image_folder`.".format(staging_dir) ) return staging_dir diff --git a/client/ayon_core/settings/ayon_settings.py b/client/ayon_core/settings/ayon_settings.py index 39b0b117f7..0c7acc1854 100644 --- a/client/ayon_core/settings/ayon_settings.py +++ b/client/ayon_core/settings/ayon_settings.py @@ -333,9 +333,6 @@ def _convert_maya_project_settings(ayon_settings, output): ayon_maya = ayon_settings["maya"] - # Change key of render settings - ayon_maya["RenderSettings"] = ayon_maya.pop("render_settings") - # Convert extensions mapping ayon_maya["ext_mapping"] = { item["name"]: item["value"] From 8d830ae37406ad0ae9df91fc4b4bb250261e1643 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Fri, 9 Feb 2024 15:05:38 +0100 Subject: [PATCH 046/185] maya can handle ext_mapping from AYON --- .../maya/plugins/publish/extract_camera_mayaScene.py | 8 +++++--- .../maya/plugins/publish/extract_import_reference.py | 8 +++++--- .../ayon_core/hosts/maya/plugins/publish/extract_look.py | 8 +++++--- .../hosts/maya/plugins/publish/extract_maya_scene_raw.py | 8 +++++--- .../ayon_core/hosts/maya/plugins/publish/extract_model.py | 8 +++++--- .../ayon_core/hosts/maya/plugins/publish/extract_rig.py | 8 +++++--- .../hosts/maya/plugins/publish/extract_yeti_rig.py | 8 +++++--- client/ayon_core/settings/ayon_settings.py | 6 ------ 8 files changed, 35 insertions(+), 27 deletions(-) diff --git a/client/ayon_core/hosts/maya/plugins/publish/extract_camera_mayaScene.py b/client/ayon_core/hosts/maya/plugins/publish/extract_camera_mayaScene.py index 8ca1fd9d3a..689eed09f8 100644 --- a/client/ayon_core/hosts/maya/plugins/publish/extract_camera_mayaScene.py +++ b/client/ayon_core/hosts/maya/plugins/publish/extract_camera_mayaScene.py @@ -112,9 +112,11 @@ class ExtractCameraMayaScene(publish.Extractor, def process(self, instance): """Plugin entry point.""" # get settings - ext_mapping = ( - instance.context.data["project_settings"]["maya"]["ext_mapping"] - ) + maya_settings = instance.context.data["project_settings"]["maya"] + ext_mapping = { + item["name"]: item["value"] + for item in maya_settings["ext_mapping"] + } if ext_mapping: self.log.debug("Looking in settings for scene type ...") # use extension mapping for first family found diff --git a/client/ayon_core/hosts/maya/plugins/publish/extract_import_reference.py b/client/ayon_core/hosts/maya/plugins/publish/extract_import_reference.py index 2a43a30b8d..3fb84c8d83 100644 --- a/client/ayon_core/hosts/maya/plugins/publish/extract_import_reference.py +++ b/client/ayon_core/hosts/maya/plugins/publish/extract_import_reference.py @@ -37,9 +37,11 @@ class ExtractImportReference(publish.Extractor, if not self.is_active(instance.data): return - ext_mapping = ( - instance.context.data["project_settings"]["maya"]["ext_mapping"] - ) + maya_settings = instance.context.data["project_settings"]["maya"] + ext_mapping = { + item["name"]: item["value"] + for item in maya_settings["ext_mapping"] + } if ext_mapping: self.log.debug("Looking in settings for scene type ...") # use extension mapping for first family found diff --git a/client/ayon_core/hosts/maya/plugins/publish/extract_look.py b/client/ayon_core/hosts/maya/plugins/publish/extract_look.py index 7f97a7bf82..29390e2c7d 100644 --- a/client/ayon_core/hosts/maya/plugins/publish/extract_look.py +++ b/client/ayon_core/hosts/maya/plugins/publish/extract_look.py @@ -431,9 +431,11 @@ class ExtractLook(publish.Extractor): project settings. """ - ext_mapping = ( - instance.context.data["project_settings"]["maya"]["ext_mapping"] - ) + maya_settings = instance.context.data["project_settings"]["maya"] + ext_mapping = { + item["name"]: item["value"] + for item in maya_settings["ext_mapping"] + } if ext_mapping: self.log.debug("Looking in settings for scene type ...") # use extension mapping for first family found diff --git a/client/ayon_core/hosts/maya/plugins/publish/extract_maya_scene_raw.py b/client/ayon_core/hosts/maya/plugins/publish/extract_maya_scene_raw.py index 5045a8d252..cd6f3bab6a 100644 --- a/client/ayon_core/hosts/maya/plugins/publish/extract_maya_scene_raw.py +++ b/client/ayon_core/hosts/maya/plugins/publish/extract_maya_scene_raw.py @@ -43,9 +43,11 @@ class ExtractMayaSceneRaw(publish.Extractor, AYONPyblishPluginMixin): def process(self, instance): """Plugin entry point.""" - ext_mapping = ( - instance.context.data["project_settings"]["maya"]["ext_mapping"] - ) + maya_settings = instance.context.data["project_settings"]["maya"] + ext_mapping = { + item["name"]: item["value"] + for item in maya_settings["ext_mapping"] + } if ext_mapping: self.log.debug("Looking in settings for scene type ...") # use extension mapping for first family found diff --git a/client/ayon_core/hosts/maya/plugins/publish/extract_model.py b/client/ayon_core/hosts/maya/plugins/publish/extract_model.py index b6ae4d537a..543af59e8f 100644 --- a/client/ayon_core/hosts/maya/plugins/publish/extract_model.py +++ b/client/ayon_core/hosts/maya/plugins/publish/extract_model.py @@ -35,9 +35,11 @@ class ExtractModel(publish.Extractor, if not self.is_active(instance.data): return - ext_mapping = ( - instance.context.data["project_settings"]["maya"]["ext_mapping"] - ) + maya_settings = instance.context.data["project_settings"]["maya"] + ext_mapping = { + item["name"]: item["value"] + for item in maya_settings["ext_mapping"] + } if ext_mapping: self.log.debug("Looking in settings for scene type ...") # use extension mapping for first family found diff --git a/client/ayon_core/hosts/maya/plugins/publish/extract_rig.py b/client/ayon_core/hosts/maya/plugins/publish/extract_rig.py index 13e3d7c6b4..305f4698c6 100644 --- a/client/ayon_core/hosts/maya/plugins/publish/extract_rig.py +++ b/client/ayon_core/hosts/maya/plugins/publish/extract_rig.py @@ -18,9 +18,11 @@ class ExtractRig(publish.Extractor): def process(self, instance): """Plugin entry point.""" - ext_mapping = ( - instance.context.data["project_settings"]["maya"]["ext_mapping"] - ) + maya_settings = instance.context.data["project_settings"]["maya"] + ext_mapping = { + item["name"]: item["value"] + for item in maya_settings["ext_mapping"] + } if ext_mapping: self.log.debug("Looking in settings for scene type ...") # use extension mapping for first family found diff --git a/client/ayon_core/hosts/maya/plugins/publish/extract_yeti_rig.py b/client/ayon_core/hosts/maya/plugins/publish/extract_yeti_rig.py index 7387849736..0b67117ebc 100644 --- a/client/ayon_core/hosts/maya/plugins/publish/extract_yeti_rig.py +++ b/client/ayon_core/hosts/maya/plugins/publish/extract_yeti_rig.py @@ -100,9 +100,11 @@ class ExtractYetiRig(publish.Extractor): def process(self, instance): """Plugin entry point.""" - ext_mapping = ( - instance.context.data["project_settings"]["maya"]["ext_mapping"] - ) + maya_settings = instance.context.data["project_settings"]["maya"] + ext_mapping = { + item["name"]: item["value"] + for item in maya_settings["ext_mapping"] + } if ext_mapping: self.log.debug("Looking in settings for scene type ...") # use extension mapping for first family found diff --git a/client/ayon_core/settings/ayon_settings.py b/client/ayon_core/settings/ayon_settings.py index 0c7acc1854..14af455d5b 100644 --- a/client/ayon_core/settings/ayon_settings.py +++ b/client/ayon_core/settings/ayon_settings.py @@ -333,12 +333,6 @@ def _convert_maya_project_settings(ayon_settings, output): ayon_maya = ayon_settings["maya"] - # Convert extensions mapping - ayon_maya["ext_mapping"] = { - item["name"]: item["value"] - for item in ayon_maya["ext_mapping"] - } - # Maya dirmap ayon_maya_dirmap = ayon_maya.pop("maya_dirmap") ayon_maya_dirmap_path = ayon_maya_dirmap["paths"] From 2c7da1a6de01c0d7821475c600950bd0626cde65 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Fri, 9 Feb 2024 15:09:04 +0100 Subject: [PATCH 047/185] dirmap settings are using AYON settings --- client/ayon_core/host/dirmap.py | 24 ++++++++++----------- client/ayon_core/hosts/maya/api/plugin.py | 2 +- client/ayon_core/hosts/nuke/api/pipeline.py | 2 +- client/ayon_core/settings/ayon_settings.py | 20 ----------------- 4 files changed, 14 insertions(+), 34 deletions(-) diff --git a/client/ayon_core/host/dirmap.py b/client/ayon_core/host/dirmap.py index cecd689a4c..9756657386 100644 --- a/client/ayon_core/host/dirmap.py +++ b/client/ayon_core/host/dirmap.py @@ -92,8 +92,8 @@ class HostDirmap(object): self.on_enable_dirmap() - for k, sp in enumerate(mapping["source-path"]): - dst = mapping["destination-path"][k] + for k, sp in enumerate(mapping["source_path"]): + dst = mapping["destination_path"][k] try: # add trailing slash if missing sp = os.path.join(sp, '') @@ -116,7 +116,7 @@ class HostDirmap(object): continue def get_mappings(self): - """Get translation from source-path to destination-path. + """Get translation from source_path to destination_path. It checks if Site Sync is enabled and user chose to use local site, in that case configuration in Local Settings takes precedence @@ -138,8 +138,8 @@ class HostDirmap(object): if ( not mapping - or not mapping.get("destination-path") - or not mapping.get("source-path") + or not mapping.get("destination_path") + or not mapping.get("source_path") ): return {} self.log.info("Processing directory mapping ...") @@ -154,7 +154,7 @@ class HostDirmap(object): in Local Settings. Returns: - dict : { "source-path": [XXX], "destination-path": [YYYY]} + dict : { "source_path": [XXX], "destination_path": [YYYY]} """ project_name = self.project_name @@ -210,13 +210,13 @@ class HostDirmap(object): continue if os.path.isdir(active_site_dir): - if "destination-path" not in mapping: - mapping["destination-path"] = [] - mapping["destination-path"].append(active_site_dir) + if "destination_path" not in mapping: + mapping["destination_path"] = [] + mapping["destination_path"].append(active_site_dir) - if "source-path" not in mapping: - mapping["source-path"] = [] - mapping["source-path"].append(remote_site_dir) + if "source_path" not in mapping: + mapping["source_path"] = [] + mapping["source_path"].append(remote_site_dir) self.log.debug("local sync mapping:: {}".format(mapping)) return mapping diff --git a/client/ayon_core/hosts/maya/api/plugin.py b/client/ayon_core/hosts/maya/api/plugin.py index c5e3f42d10..e0ff900c01 100644 --- a/client/ayon_core/hosts/maya/api/plugin.py +++ b/client/ayon_core/hosts/maya/api/plugin.py @@ -937,7 +937,7 @@ class ReferenceLoader(Loader): """ settings = get_project_settings(project_name) use_env_var_as_root = (settings["maya"] - ["maya-dirmap"] + ["maya_dirmap"] ["use_env_var_as_root"]) if use_env_var_as_root: anatomy = Anatomy(project_name) diff --git a/client/ayon_core/hosts/nuke/api/pipeline.py b/client/ayon_core/hosts/nuke/api/pipeline.py index bdba0757b6..99bd5616cb 100644 --- a/client/ayon_core/hosts/nuke/api/pipeline.py +++ b/client/ayon_core/hosts/nuke/api/pipeline.py @@ -176,7 +176,7 @@ def add_nuke_callbacks(): nuke.addOnScriptLoad(WorkfileSettings().set_context_settings) - if nuke_settings["nuke-dirmap"]["enabled"]: + if nuke_settings["nuke_dirmap"]["enabled"]: log.info("Added Nuke's dir-mapping callback ...") # Add dirmap for file paths. nuke.addFilenameFilter(dirmap_file_name_filter) diff --git a/client/ayon_core/settings/ayon_settings.py b/client/ayon_core/settings/ayon_settings.py index 14af455d5b..6114b5767c 100644 --- a/client/ayon_core/settings/ayon_settings.py +++ b/client/ayon_core/settings/ayon_settings.py @@ -333,17 +333,6 @@ def _convert_maya_project_settings(ayon_settings, output): ayon_maya = ayon_settings["maya"] - # Maya dirmap - ayon_maya_dirmap = ayon_maya.pop("maya_dirmap") - ayon_maya_dirmap_path = ayon_maya_dirmap["paths"] - ayon_maya_dirmap_path["source-path"] = ( - ayon_maya_dirmap_path.pop("source_path") - ) - ayon_maya_dirmap_path["destination-path"] = ( - ayon_maya_dirmap_path.pop("destination_path") - ) - ayon_maya["maya-dirmap"] = ayon_maya_dirmap - # Create plugins ayon_create = ayon_maya["create"] ayon_create_static_mesh = ayon_create["CreateUnrealStaticMesh"] @@ -580,15 +569,6 @@ def _convert_nuke_project_settings(ayon_settings, output): ayon_nuke = ayon_settings["nuke"] - # --- Dirmap --- - dirmap = ayon_nuke.pop("dirmap") - for src_key, dst_key in ( - ("source_path", "source-path"), - ("destination_path", "destination-path"), - ): - dirmap["paths"][dst_key] = dirmap["paths"].pop(src_key) - ayon_nuke["nuke-dirmap"] = dirmap - # --- Load --- ayon_load = ayon_nuke["load"] ayon_load["LoadClip"]["_representations"] = ( From c35bae324373af98722f91c802d49d7fde24f024 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Fri, 9 Feb 2024 15:23:01 +0100 Subject: [PATCH 048/185] Validate attributes converts attributes on own --- .../plugins/publish/validate_attributes.py | 18 ++++++++++++------ client/ayon_core/settings/ayon_settings.py | 7 ------- 2 files changed, 12 insertions(+), 13 deletions(-) diff --git a/client/ayon_core/hosts/maya/plugins/publish/validate_attributes.py b/client/ayon_core/hosts/maya/plugins/publish/validate_attributes.py index 3dfe2f4f2d..fc39756bf0 100644 --- a/client/ayon_core/hosts/maya/plugins/publish/validate_attributes.py +++ b/client/ayon_core/hosts/maya/plugins/publish/validate_attributes.py @@ -1,3 +1,4 @@ +import json from collections import defaultdict import pyblish.api @@ -23,19 +24,19 @@ class ValidateAttributes(pyblish.api.InstancePlugin, """ order = ValidateContentsOrder - label = "Attributes" + label = "Validate Attributes" hosts = ["maya"] actions = [RepairAction] optional = True - attributes = None + attributes = "{}" def process(self, instance): if not self.is_active(instance.data): return # Check for preset existence. - if not self.attributes: + if not self.get_attributes_data(): return invalid = self.get_invalid(instance, compute=True) @@ -44,6 +45,10 @@ class ValidateAttributes(pyblish.api.InstancePlugin, "Found attributes with invalid values: {}".format(invalid) ) + @classmethod + def get_attributes_data(cls): + return json.loads(cls.attributes) + @classmethod def get_invalid(cls, instance, compute=False): if compute: @@ -55,21 +60,22 @@ class ValidateAttributes(pyblish.api.InstancePlugin, def get_invalid_attributes(cls, instance): invalid_attributes = [] + attributes_data = cls.get_attributes_data() # Filter families. families = [instance.data["family"]] families += instance.data.get("families", []) - families = set(families) & set(cls.attributes.keys()) + families = set(families) & set(attributes_data.keys()) if not families: return [] # Get all attributes to validate. attributes = defaultdict(dict) for family in families: - if family not in cls.attributes: + if family not in attributes_data: # No attributes to validate for family continue - for preset_attr, preset_value in cls.attributes[family].items(): + for preset_attr, preset_value in attributes_data[family].items(): node_name, attribute_name = preset_attr.split(".", 1) attributes[node_name][attribute_name] = preset_value diff --git a/client/ayon_core/settings/ayon_settings.py b/client/ayon_core/settings/ayon_settings.py index 6114b5767c..a27f071e7c 100644 --- a/client/ayon_core/settings/ayon_settings.py +++ b/client/ayon_core/settings/ayon_settings.py @@ -343,13 +343,6 @@ def _convert_maya_project_settings(ayon_settings, output): # --- Publish (START) --- ayon_publish = ayon_maya["publish"] - try: - attributes = json.loads( - ayon_publish["ValidateAttributes"]["attributes"] - ) - except ValueError: - attributes = {} - ayon_publish["ValidateAttributes"]["attributes"] = attributes try: SUFFIX_NAMING_TABLE = json.loads( From 649d6478e083143fcedfa640a47d8c8fc70790fc Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Fri, 9 Feb 2024 15:23:28 +0100 Subject: [PATCH 049/185] removed deprecated conversion --- client/ayon_core/settings/ayon_settings.py | 8 -------- 1 file changed, 8 deletions(-) diff --git a/client/ayon_core/settings/ayon_settings.py b/client/ayon_core/settings/ayon_settings.py index a27f071e7c..251fafa597 100644 --- a/client/ayon_core/settings/ayon_settings.py +++ b/client/ayon_core/settings/ayon_settings.py @@ -333,14 +333,6 @@ def _convert_maya_project_settings(ayon_settings, output): ayon_maya = ayon_settings["maya"] - # Create plugins - ayon_create = ayon_maya["create"] - ayon_create_static_mesh = ayon_create["CreateUnrealStaticMesh"] - if "static_mesh_prefixes" in ayon_create_static_mesh: - ayon_create_static_mesh["static_mesh_prefix"] = ( - ayon_create_static_mesh.pop("static_mesh_prefixes") - ) - # --- Publish (START) --- ayon_publish = ayon_maya["publish"] From bf4c8c7b3d4e41a7472d076a8e71d8f5568dda3d Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Fri, 9 Feb 2024 15:23:52 +0100 Subject: [PATCH 050/185] SUFFIX_NAMING_TABLE is converted in plugin --- .../validate_transform_naming_suffix.py | 67 +++++++++++-------- client/ayon_core/settings/ayon_settings.py | 12 ---- 2 files changed, 40 insertions(+), 39 deletions(-) diff --git a/client/ayon_core/hosts/maya/plugins/publish/validate_transform_naming_suffix.py b/client/ayon_core/hosts/maya/plugins/publish/validate_transform_naming_suffix.py index 1f8d6b7470..e565866778 100644 --- a/client/ayon_core/hosts/maya/plugins/publish/validate_transform_naming_suffix.py +++ b/client/ayon_core/hosts/maya/plugins/publish/validate_transform_naming_suffix.py @@ -1,5 +1,6 @@ # -*- coding: utf-8 -*- """Plugin for validating naming conventions.""" +import json from maya import cmds import pyblish.api @@ -35,29 +36,37 @@ class ValidateTransformNamingSuffix(pyblish.api.InstancePlugin, """ order = ValidateContentsOrder - hosts = ['maya'] - families = ['model'] + hosts = ["maya"] + families = ["model"] optional = True - label = 'Suffix Naming Conventions' + label = "Suffix Naming Conventions" actions = [ayon_core.hosts.maya.api.action.SelectInvalidAction] - SUFFIX_NAMING_TABLE = {"mesh": ["_GEO", "_GES", "_GEP", "_OSD"], - "nurbsCurve": ["_CRV"], - "nurbsSurface": ["_NRB"], - "locator": ["_LOC"], - "group": ["_GRP"]} + SUFFIX_NAMING_TABLE = json.dumps({ + "mesh": ["_GEO", "_GES", "_GEP", "_OSD"], + "nurbsCurve": ["_CRV"], + "nurbsSurface": ["_NRB"], + "locator": ["_LOC"], + "group": ["_GRP"] + }) ALLOW_IF_NOT_IN_SUFFIX_TABLE = True @classmethod def get_table_for_invalid(cls): - ss = [] - for k, v in cls.SUFFIX_NAMING_TABLE.items(): - ss.append(" - {}: {}".format(k, ", ".join(v))) + suffix_naming_table = json.loads(cls.SUFFIX_NAMING_TABLE) + ss = [ + " - {}: {}".format(k, ", ".join(v)) + for k, v in suffix_naming_table.items() + ] return "
".join(ss) @staticmethod - def is_valid_name(node_name, shape_type, - SUFFIX_NAMING_TABLE, ALLOW_IF_NOT_IN_SUFFIX_TABLE): + def is_valid_name( + node_name, + shape_type, + suffix_naming_table, + allow_if_not_in_suffix_table + ): """Return whether node's name is correct. The correctness for a transform's suffix is dependent on what @@ -70,18 +79,18 @@ class ValidateTransformNamingSuffix(pyblish.api.InstancePlugin, Args: node_name (str): Node name. shape_type (str): Type of node. - SUFFIX_NAMING_TABLE (dict): Mapping dict for suffixes. - ALLOW_IF_NOT_IN_SUFFIX_TABLE (dict): Filter dict. + suffix_naming_table (dict): Mapping dict for suffixes. + allow_if_not_in_suffix_table (bool): Default output. """ - if shape_type not in SUFFIX_NAMING_TABLE: - return ALLOW_IF_NOT_IN_SUFFIX_TABLE - else: - suffices = SUFFIX_NAMING_TABLE[shape_type] - for suffix in suffices: - if node_name.endswith(suffix): - return True - return False + if shape_type not in suffix_naming_table: + return allow_if_not_in_suffix_table + + suffices = suffix_naming_table[shape_type] + for suffix in suffices: + if node_name.endswith(suffix): + return True + return False @classmethod def get_invalid(cls, instance): @@ -91,9 +100,10 @@ class ValidateTransformNamingSuffix(pyblish.api.InstancePlugin, instance (:class:`pyblish.api.Instance`): published instance. """ - transforms = cmds.ls(instance, type='transform', long=True) + transforms = cmds.ls(instance, type="transform", long=True) invalid = [] + suffix_naming_table = json.loads(cls.SUFFIX_NAMING_TABLE) for transform in transforms: shapes = cmds.listRelatives(transform, shapes=True, @@ -101,9 +111,12 @@ class ValidateTransformNamingSuffix(pyblish.api.InstancePlugin, noIntermediate=True) shape_type = cmds.nodeType(shapes[0]) if shapes else "group" - if not cls.is_valid_name(transform, shape_type, - cls.SUFFIX_NAMING_TABLE, - cls.ALLOW_IF_NOT_IN_SUFFIX_TABLE): + if not cls.is_valid_name( + transform, + shape_type, + suffix_naming_table, + cls.ALLOW_IF_NOT_IN_SUFFIX_TABLE + ): invalid.append(transform) return invalid diff --git a/client/ayon_core/settings/ayon_settings.py b/client/ayon_core/settings/ayon_settings.py index 251fafa597..165e47da1a 100644 --- a/client/ayon_core/settings/ayon_settings.py +++ b/client/ayon_core/settings/ayon_settings.py @@ -336,18 +336,6 @@ def _convert_maya_project_settings(ayon_settings, output): # --- Publish (START) --- ayon_publish = ayon_maya["publish"] - try: - SUFFIX_NAMING_TABLE = json.loads( - ayon_publish - ["ValidateTransformNamingSuffix"] - ["SUFFIX_NAMING_TABLE"] - ) - except ValueError: - SUFFIX_NAMING_TABLE = {} - ayon_publish["ValidateTransformNamingSuffix"]["SUFFIX_NAMING_TABLE"] = ( - SUFFIX_NAMING_TABLE - ) - validate_frame_range = ayon_publish["ValidateFrameRange"] if "exclude_product_types" in validate_frame_range: validate_frame_range["exclude_families"] = ( From a657dfac4e3416d6f7e8f6c4560c3844c21522df Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Fri, 9 Feb 2024 15:30:53 +0100 Subject: [PATCH 051/185] maya 'ValidateFrameRange' is handling AYON settings --- .../hosts/maya/plugins/publish/validate_frame_range.py | 6 ++++-- client/ayon_core/settings/ayon_settings.py | 5 ----- 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/client/ayon_core/hosts/maya/plugins/publish/validate_frame_range.py b/client/ayon_core/hosts/maya/plugins/publish/validate_frame_range.py index 85cc606b25..d5f99e5563 100644 --- a/client/ayon_core/hosts/maya/plugins/publish/validate_frame_range.py +++ b/client/ayon_core/hosts/maya/plugins/publish/validate_frame_range.py @@ -39,7 +39,7 @@ class ValidateFrameRange(pyblish.api.InstancePlugin, "yeticache"] optional = True actions = [RepairAction] - exclude_families = [] + exclude_product_types = [] def process(self, instance): if not self.is_active(instance.data): @@ -73,7 +73,9 @@ class ValidateFrameRange(pyblish.api.InstancePlugin, # compare with data on instance errors = [] - if [ef for ef in self.exclude_families + # QUESTION shouldn't this be just: + # 'if instance.data["family"] in self.exclude_product_types:' + if [ef for ef in self.exclude_product_types if instance.data["family"] in ef]: return if (inst_start != frame_start_handle): diff --git a/client/ayon_core/settings/ayon_settings.py b/client/ayon_core/settings/ayon_settings.py index 165e47da1a..9cadb36869 100644 --- a/client/ayon_core/settings/ayon_settings.py +++ b/client/ayon_core/settings/ayon_settings.py @@ -336,11 +336,6 @@ def _convert_maya_project_settings(ayon_settings, output): # --- Publish (START) --- ayon_publish = ayon_maya["publish"] - validate_frame_range = ayon_publish["ValidateFrameRange"] - if "exclude_product_types" in validate_frame_range: - validate_frame_range["exclude_families"] = ( - validate_frame_range.pop("exclude_product_types")) - # Extract playblast capture settings validate_rendern_settings = ayon_publish["ValidateRenderSettings"] for key in ( From 6ae8537983ba2d885744ac831a79e95f4b766499 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Fri, 9 Feb 2024 15:31:41 +0100 Subject: [PATCH 052/185] maya 'ValidateRenderSettings' can handle AYON settings --- .../plugins/publish/validate_rendersettings.py | 13 ++++++++++--- client/ayon_core/settings/ayon_settings.py | 15 --------------- 2 files changed, 10 insertions(+), 18 deletions(-) diff --git a/client/ayon_core/hosts/maya/plugins/publish/validate_rendersettings.py b/client/ayon_core/hosts/maya/plugins/publish/validate_rendersettings.py index ed70d81b63..7f6c0bab1d 100644 --- a/client/ayon_core/hosts/maya/plugins/publish/validate_rendersettings.py +++ b/client/ayon_core/hosts/maya/plugins/publish/validate_rendersettings.py @@ -281,6 +281,8 @@ class ValidateRenderSettings(pyblish.api.InstancePlugin): # if so, compare its value from the one required. for data in cls.get_nodes(instance, renderer): for node in data["nodes"]: + # Why is captured 'PublishValidationError'? How it can be + # raised by 'cmds.getAttr(...)'? try: render_value = cmds.getAttr( "{}.{}".format(node, data["attribute"]) @@ -310,11 +312,16 @@ class ValidateRenderSettings(pyblish.api.InstancePlugin): @classmethod def get_nodes(cls, instance, renderer): maya_settings = instance.context.data["project_settings"]["maya"] + renderer_key = "{}_render_attributes".format(renderer) validation_settings = ( maya_settings["publish"]["ValidateRenderSettings"].get( - "{}_render_attributes".format(renderer) - ) or [] - ) + renderer_key + ) + ) or [] + validation_settings = [ + (item["type"], item["value"]) + for item in validation_settings + ] result = [] for attr, values in OrderedDict(validation_settings).items(): values = [convert_to_int_or_float(v) for v in values if v] diff --git a/client/ayon_core/settings/ayon_settings.py b/client/ayon_core/settings/ayon_settings.py index 9cadb36869..e9ec2ba650 100644 --- a/client/ayon_core/settings/ayon_settings.py +++ b/client/ayon_core/settings/ayon_settings.py @@ -336,21 +336,6 @@ def _convert_maya_project_settings(ayon_settings, output): # --- Publish (START) --- ayon_publish = ayon_maya["publish"] - # Extract playblast capture settings - validate_rendern_settings = ayon_publish["ValidateRenderSettings"] - for key in ( - "arnold_render_attributes", - "vray_render_attributes", - "redshift_render_attributes", - "renderman_render_attributes", - ): - if key not in validate_rendern_settings: - continue - validate_rendern_settings[key] = [ - [item["type"], item["value"]] - for item in validate_rendern_settings[key] - ] - plugin_path_attributes = ayon_publish["ValidatePluginPathAttributes"] plugin_path_attributes["attribute"] = { item["name"]: item["value"] From 43167dbb094dc97124d2ae8239c1f87a0a68cb28 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Fri, 9 Feb 2024 15:33:20 +0100 Subject: [PATCH 053/185] maya 'ValidatePluginPathAttributes' can handle AYON settings --- .../plugins/publish/validate_plugin_path_attributes.py | 8 ++++++-- client/ayon_core/settings/ayon_settings.py | 6 ------ 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/client/ayon_core/hosts/maya/plugins/publish/validate_plugin_path_attributes.py b/client/ayon_core/hosts/maya/plugins/publish/validate_plugin_path_attributes.py index d672be6fa0..fd71039e30 100644 --- a/client/ayon_core/hosts/maya/plugins/publish/validate_plugin_path_attributes.py +++ b/client/ayon_core/hosts/maya/plugins/publish/validate_plugin_path_attributes.py @@ -30,14 +30,18 @@ class ValidatePluginPathAttributes(pyblish.api.InstancePlugin): def get_invalid(cls, instance): invalid = list() - file_attrs = cls.attribute + file_attrs = { + item["name"]: item["value"] + for item in cls.attribute + } if not file_attrs: return invalid # Consider only valid node types to avoid "Unknown object type" warning all_node_types = set(cmds.allNodeTypes()) node_types = [ - key for key in file_attrs.keys() + key + for key in file_attrs.keys() if key in all_node_types ] diff --git a/client/ayon_core/settings/ayon_settings.py b/client/ayon_core/settings/ayon_settings.py index e9ec2ba650..3d58b8f272 100644 --- a/client/ayon_core/settings/ayon_settings.py +++ b/client/ayon_core/settings/ayon_settings.py @@ -336,12 +336,6 @@ def _convert_maya_project_settings(ayon_settings, output): # --- Publish (START) --- ayon_publish = ayon_maya["publish"] - plugin_path_attributes = ayon_publish["ValidatePluginPathAttributes"] - plugin_path_attributes["attribute"] = { - item["name"]: item["value"] - for item in plugin_path_attributes["attribute"] - } - ayon_capture_preset = ayon_publish["ExtractPlayblast"]["capture_preset"] display_options = ayon_capture_preset["DisplayOptions"] for key in ("background", "backgroundBottom", "backgroundTop"): From 1256816f1cf5d8b4ecc840933efd233d386168f3 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Fri, 9 Feb 2024 15:56:52 +0100 Subject: [PATCH 054/185] maya 'ExtractPlayblast' can use AYON settings --- client/ayon_core/hosts/maya/api/lib.py | 29 +++++++++----- .../maya/plugins/create/create_review.py | 2 +- .../maya/plugins/publish/collect_review.py | 2 +- client/ayon_core/settings/ayon_settings.py | 39 ------------------- .../maya/server/settings/publish_playblast.py | 35 ++++++++--------- 5 files changed, 38 insertions(+), 69 deletions(-) diff --git a/client/ayon_core/hosts/maya/api/lib.py b/client/ayon_core/hosts/maya/api/lib.py index 7b791c3d51..f46471b94d 100644 --- a/client/ayon_core/hosts/maya/api/lib.py +++ b/client/ayon_core/hosts/maya/api/lib.py @@ -329,7 +329,7 @@ def generate_capture_preset(instance, camera, path, # Update preset with current panel setting # if override_viewport_options is turned off - if not capture_preset["Viewport Options"]["override_viewport_options"]: + if not capture_preset["ViewportOptions"]["override_viewport_options"]: panel_preset = capture.parse_view(preset["panel"]) panel_preset.pop("camera") preset.update(panel_preset) @@ -2937,14 +2937,15 @@ def load_capture_preset(data): options.update(data["Generic"]) options.update(data["Resolution"]) - camera_options.update(data['Camera Options']) + camera_options.update(data["CameraOptions"]) viewport_options.update(data["Renderer"]) # DISPLAY OPTIONS disp_options = {} - for key, value in data['Display Options'].items(): - if key.startswith('background'): + for key, value in data["DisplayOptions"].items(): + if key.startswith("background"): # Convert background, backgroundTop, backgroundBottom colors + if len(value) == 4: # Ignore alpha + convert RGB to float value = [ @@ -2956,7 +2957,7 @@ def load_capture_preset(data): elif key == "displayGradient": disp_options[key] = value - options['display_options'] = disp_options + options["display_options"] = disp_options # Viewport Options has a mixture of Viewport2 Options and Viewport Options # to pass along to capture. So we'll need to differentiate between the two @@ -2981,7 +2982,7 @@ def load_capture_preset(data): "motionBlurShutterOpenFraction", "lineAAEnable" } - for key, value in data['Viewport Options'].items(): + for key, value in data["ViewportOptions"].items(): # There are some keys we want to ignore if key in {"override_viewport_options", "high_quality"}: @@ -4059,10 +4060,10 @@ def get_capture_preset(task_name, task_type, subset, project_settings, log): Args: task_name (str): Task name. - take_type (str): Task type. + task_type (str): Task type. subset (str): Subset name. project_settings (dict): Project settings. - log (object): Logging object. + log (logging.Logger): Logging object. """ capture_preset = None filtering_criteria = { @@ -4091,8 +4092,18 @@ def get_capture_preset(task_name, task_type, subset, project_settings, log): "Falling back to deprecated Extract Playblast capture preset " "because no new style playblast profiles are defined." ) - capture_preset = plugin_settings["capture_preset"] + capture_preset = plugin_settings.get("capture_preset") + if capture_preset: + # Create deepcopy of preset as we'll change the values + capture_preset = copy.deepcopy(capture_preset) + + viewport_options = capture_preset["ViewportOptions"] + # Change 'list' to 'dict' for 'capture.py' + viewport_options["pluginObjects"] = { + item["name"]: item["value"] + for item in viewport_options["pluginObjects"] + } return capture_preset or {} diff --git a/client/ayon_core/hosts/maya/plugins/create/create_review.py b/client/ayon_core/hosts/maya/plugins/create/create_review.py index 6f7c0ca802..3e75b52556 100644 --- a/client/ayon_core/hosts/maya/plugins/create/create_review.py +++ b/client/ayon_core/hosts/maya/plugins/create/create_review.py @@ -75,7 +75,7 @@ class CreateReview(plugin.MayaCreator): "review_width": preset["Resolution"]["width"], "review_height": preset["Resolution"]["height"], "isolate": preset["Generic"]["isolate_view"], - "imagePlane": preset["Viewport Options"]["imagePlane"], + "imagePlane": preset["ViewportOptions"]["imagePlane"], "panZoom": preset["Generic"]["pan_zoom"] } for key, value in mapping.items(): diff --git a/client/ayon_core/hosts/maya/plugins/publish/collect_review.py b/client/ayon_core/hosts/maya/plugins/publish/collect_review.py index 679a21243a..205c871c93 100644 --- a/client/ayon_core/hosts/maya/plugins/publish/collect_review.py +++ b/client/ayon_core/hosts/maya/plugins/publish/collect_review.py @@ -39,7 +39,7 @@ class CollectReview(pyblish.api.InstancePlugin): if display_lights == "project_settings": settings = instance.context.data["project_settings"] settings = settings["maya"]["publish"]["ExtractPlayblast"] - settings = settings["capture_preset"]["Viewport Options"] + settings = settings["capture_preset"]["ViewportOptions"] display_lights = settings["displayLights"] # Collect camera focal length. diff --git a/client/ayon_core/settings/ayon_settings.py b/client/ayon_core/settings/ayon_settings.py index 3d58b8f272..8e4c5abe10 100644 --- a/client/ayon_core/settings/ayon_settings.py +++ b/client/ayon_core/settings/ayon_settings.py @@ -336,45 +336,6 @@ def _convert_maya_project_settings(ayon_settings, output): # --- Publish (START) --- ayon_publish = ayon_maya["publish"] - ayon_capture_preset = ayon_publish["ExtractPlayblast"]["capture_preset"] - display_options = ayon_capture_preset["DisplayOptions"] - for key in ("background", "backgroundBottom", "backgroundTop"): - display_options[key] = _convert_color(display_options[key]) - - for src_key, dst_key in ( - ("DisplayOptions", "Display Options"), - ("ViewportOptions", "Viewport Options"), - ("CameraOptions", "Camera Options"), - ): - ayon_capture_preset[dst_key] = ayon_capture_preset.pop(src_key) - - viewport_options = ayon_capture_preset["Viewport Options"] - viewport_options["pluginObjects"] = { - item["name"]: item["value"] - for item in viewport_options["pluginObjects"] - } - - ayon_playblast_settings = ayon_publish["ExtractPlayblast"]["profiles"] - if ayon_playblast_settings: - for setting in ayon_playblast_settings: - capture_preset = setting["capture_preset"] - display_options = capture_preset["DisplayOptions"] - for key in ("background", "backgroundBottom", "backgroundTop"): - display_options[key] = _convert_color(display_options[key]) - - for src_key, dst_key in ( - ("DisplayOptions", "Display Options"), - ("ViewportOptions", "Viewport Options"), - ("CameraOptions", "Camera Options"), - ): - capture_preset[dst_key] = capture_preset.pop(src_key) - - viewport_options = capture_preset["Viewport Options"] - viewport_options["pluginObjects"] = { - item["name"]: item["value"] - for item in viewport_options["pluginObjects"] - } - # Extract Camera Alembic bake attributes try: bake_attributes = json.loads( diff --git a/server_addon/maya/server/settings/publish_playblast.py b/server_addon/maya/server/settings/publish_playblast.py index 0461a18cc8..dcedf3ccc9 100644 --- a/server_addon/maya/server/settings/publish_playblast.py +++ b/server_addon/maya/server/settings/publish_playblast.py @@ -6,7 +6,7 @@ from ayon_server.settings import ( ensure_unique_names, task_types_enum, ) -from ayon_server.types import ColorRGBA_uint8 +from ayon_server.types import ColorRGB_float def hardware_falloff_enum(): @@ -54,17 +54,17 @@ class DisplayOptionsSetting(BaseSettingsModel): override_display: bool = SettingsField( True, title="Override display options" ) - background: ColorRGBA_uint8 = SettingsField( - (125, 125, 125, 1.0), title="Background Color" + background: ColorRGB_float = SettingsField( + (0.5, 0.5, 0.5), title="Background Color" ) displayGradient: bool = SettingsField( True, title="Display background gradient" ) - backgroundTop: ColorRGBA_uint8 = SettingsField( - (125, 125, 125, 1.0), title="Background Top" + backgroundTop: ColorRGB_float = SettingsField( + (0.5, 0.5, 0.5), title="Background Top" ) - backgroundBottom: ColorRGBA_uint8 = SettingsField( - (125, 125, 125, 1.0), title="Background Bottom" + backgroundBottom: ColorRGB_float = SettingsField( + (0.5, 0.5, 0.5), title="Background Bottom" ) @@ -283,22 +283,19 @@ DEFAULT_PLAYBLAST_SETTING = { "DisplayOptions": { "override_display": True, "background": [ - 125, - 125, - 125, - 1.0 + 0.5, + 0.5, + 0.5 ], "backgroundBottom": [ - 125, - 125, - 125, - 1.0 + 0.5, + 0.5, + 0.5 ], "backgroundTop": [ - 125, - 125, - 125, - 1.0 + 0.5, + 0.5, + 0.5 ], "displayGradient": True }, From 6a3b475be5595ddc9a47fabe9febbde15a941836 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Fri, 9 Feb 2024 15:57:17 +0100 Subject: [PATCH 055/185] maya 'ExtractCameraAlembic' can use AYON settings --- .../maya/plugins/publish/extract_camera_alembic.py | 8 +++++--- client/ayon_core/settings/ayon_settings.py | 13 ------------- 2 files changed, 5 insertions(+), 16 deletions(-) diff --git a/client/ayon_core/hosts/maya/plugins/publish/extract_camera_alembic.py b/client/ayon_core/hosts/maya/plugins/publish/extract_camera_alembic.py index b9561e299e..2be9cfec95 100644 --- a/client/ayon_core/hosts/maya/plugins/publish/extract_camera_alembic.py +++ b/client/ayon_core/hosts/maya/plugins/publish/extract_camera_alembic.py @@ -1,4 +1,5 @@ import os +import json from maya import cmds @@ -21,7 +22,7 @@ class ExtractCameraAlembic(publish.Extractor, label = "Extract Camera (Alembic)" hosts = ["maya"] families = ["camera", "matchmove"] - bake_attributes = [] + bake_attributes = "[]" def process(self, instance): @@ -95,11 +96,12 @@ class ExtractCameraAlembic(publish.Extractor, job_str += ' -file "{0}"'.format(path) + bake_attributes = json.loads(self.bake_attributes) # bake specified attributes in preset - assert isinstance(self.bake_attributes, (list, tuple)), ( + assert isinstance(bake_attributes, list), ( "Attributes to bake must be specified as a list" ) - for attr in self.bake_attributes: + for attr in bake_attributes: self.log.debug("Adding {} attribute".format(attr)) job_str += " -attr {0}".format(attr) diff --git a/client/ayon_core/settings/ayon_settings.py b/client/ayon_core/settings/ayon_settings.py index 8e4c5abe10..f9e674b2c1 100644 --- a/client/ayon_core/settings/ayon_settings.py +++ b/client/ayon_core/settings/ayon_settings.py @@ -333,19 +333,6 @@ def _convert_maya_project_settings(ayon_settings, output): ayon_maya = ayon_settings["maya"] - # --- Publish (START) --- - ayon_publish = ayon_maya["publish"] - - # Extract Camera Alembic bake attributes - try: - bake_attributes = json.loads( - ayon_publish["ExtractCameraAlembic"]["bake_attributes"] - ) - except ValueError: - bake_attributes = [] - ayon_publish["ExtractCameraAlembic"]["bake_attributes"] = bake_attributes - - # --- Publish (END) --- for renderer_settings in ayon_maya["RenderSettings"].values(): if ( not isinstance(renderer_settings, dict) From 6c48e74bd2350bf8a8829d09b7556547f771d5e8 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Fri, 9 Feb 2024 16:04:55 +0100 Subject: [PATCH 056/185] additional options for renderer can us AYON settings --- client/ayon_core/hosts/maya/api/lib_rendersettings.py | 3 ++- client/ayon_core/settings/ayon_settings.py | 11 ----------- 2 files changed, 2 insertions(+), 12 deletions(-) diff --git a/client/ayon_core/hosts/maya/api/lib_rendersettings.py b/client/ayon_core/hosts/maya/api/lib_rendersettings.py index 1e2c95ac73..b8a4d04a10 100644 --- a/client/ayon_core/hosts/maya/api/lib_rendersettings.py +++ b/client/ayon_core/hosts/maya/api/lib_rendersettings.py @@ -390,7 +390,8 @@ class RenderSettings(object): import maya.mel as mel # noqa: F401 for item in additional_attribs: - attribute, value = item + attribute = item["attribute"] + value = item["value"] attribute = str(attribute) # ensure str conversion from settings attribute_type = cmds.getAttr(attribute, type=True) if attribute_type in {"long", "bool"}: diff --git a/client/ayon_core/settings/ayon_settings.py b/client/ayon_core/settings/ayon_settings.py index f9e674b2c1..5d7a9e0356 100644 --- a/client/ayon_core/settings/ayon_settings.py +++ b/client/ayon_core/settings/ayon_settings.py @@ -333,17 +333,6 @@ def _convert_maya_project_settings(ayon_settings, output): ayon_maya = ayon_settings["maya"] - for renderer_settings in ayon_maya["RenderSettings"].values(): - if ( - not isinstance(renderer_settings, dict) - or "additional_options" not in renderer_settings - ): - continue - renderer_settings["additional_options"] = [ - [item["attribute"], item["value"]] - for item in renderer_settings["additional_options"] - ] - # Workfile build ayon_workfile_build = ayon_maya["workfile_build"] for item in ayon_workfile_build["profiles"]: From 0404e27e8eeb5eb598852d946c9d80bb36892dbf Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Fri, 9 Feb 2024 16:07:37 +0100 Subject: [PATCH 057/185] added product key to template formatting data --- client/ayon_core/hosts/maya/api/plugin.py | 31 +++++++++++++--------- client/ayon_core/settings/ayon_settings.py | 13 --------- 2 files changed, 18 insertions(+), 26 deletions(-) diff --git a/client/ayon_core/hosts/maya/api/plugin.py b/client/ayon_core/hosts/maya/api/plugin.py index e0ff900c01..01ca4f7875 100644 --- a/client/ayon_core/hosts/maya/api/plugin.py +++ b/client/ayon_core/hosts/maya/api/plugin.py @@ -611,33 +611,38 @@ class Loader(LoaderPlugin): options["attach_to_root"] = True custom_naming = self.load_settings[loader_key] - if not custom_naming['namespace']: + if not custom_naming["namespace"]: raise LoadError("No namespace specified in " "Maya ReferenceLoader settings") - elif not custom_naming['group_name']: + elif not custom_naming["group_name"]: self.log.debug("No custom group_name, no group will be created.") options["attach_to_root"] = False - asset = context['asset'] - subset = context['subset'] + asset = context["asset"] + subset = context["subset"] + family = ( + subset["data"].get("family") + or subset["data"]["families"][0] + ) formatting_data = { - "asset_name": asset['name'], - "asset_type": asset['type'], + "asset_name": asset["name"], + "asset_type": asset["type"], "folder": { "name": asset["name"], }, - "subset": subset['name'], - "family": ( - subset['data'].get('family') or - subset['data']['families'][0] - ) + "subset": subset["name"], + "product": { + "name": subset["name"], + "type": family, + }, + "family": family } - custom_namespace = custom_naming['namespace'].format( + custom_namespace = custom_naming["namespace"].format( **formatting_data ) - custom_group_name = custom_naming['group_name'].format( + custom_group_name = custom_naming["group_name"].format( **formatting_data ) diff --git a/client/ayon_core/settings/ayon_settings.py b/client/ayon_core/settings/ayon_settings.py index 5d7a9e0356..1a353a5a64 100644 --- a/client/ayon_core/settings/ayon_settings.py +++ b/client/ayon_core/settings/ayon_settings.py @@ -351,19 +351,6 @@ def _convert_maya_project_settings(ayon_settings, output): for key, color in tuple(load_colors.items()): load_colors[key] = _convert_color(color) - reference_loader = ayon_maya_load["reference_loader"] - reference_loader["namespace"] = ( - reference_loader["namespace"] - .replace("{product[name]}", "{subset}") - ) - - if ayon_maya_load.get("import_loader"): - import_loader = ayon_maya_load["import_loader"] - import_loader["namespace"] = ( - import_loader["namespace"] - .replace("{product[name]}", "{subset}") - ) - output["maya"] = ayon_maya From dcd1f0946b6609b2f9264ee7bbbe3999ea3e9e2b Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Fri, 9 Feb 2024 16:47:00 +0100 Subject: [PATCH 058/185] use load plugin colors from AYON settings --- client/ayon_core/hosts/maya/api/plugin.py | 34 +++ .../maya/plugins/load/load_arnold_standin.py | 6 +- .../hosts/maya/plugins/load/load_gpucache.py | 10 +- .../maya/plugins/load/load_redshift_proxy.py | 12 +- .../hosts/maya/plugins/load/load_reference.py | 21 +- .../maya/plugins/load/load_vdb_to_arnold.py | 14 +- .../maya/plugins/load/load_vdb_to_redshift.py | 14 +- .../maya/plugins/load/load_vdb_to_vray.py | 13 +- .../hosts/maya/plugins/load/load_vrayproxy.py | 12 +- .../hosts/maya/plugins/load/load_vrayscene.py | 14 +- .../maya/plugins/load/load_yeti_cache.py | 14 +- .../hosts/maya/plugins/load/load_yeti_rig.py | 15 +- client/ayon_core/settings/ayon_settings.py | 7 - server_addon/maya/server/settings/loaders.py | 226 ++++++++++++++---- 14 files changed, 275 insertions(+), 137 deletions(-) diff --git a/client/ayon_core/hosts/maya/api/plugin.py b/client/ayon_core/hosts/maya/api/plugin.py index 01ca4f7875..aba5fd8903 100644 --- a/client/ayon_core/hosts/maya/api/plugin.py +++ b/client/ayon_core/hosts/maya/api/plugin.py @@ -22,6 +22,7 @@ from ayon_core.pipeline import ( LegacyCreator, LoaderPlugin, get_representation_path, + get_current_project_name, ) from ayon_core.pipeline.load import LoadError from ayon_core.client import get_asset_by_name @@ -585,6 +586,39 @@ class RenderlayerCreator(NewCreator, MayaCreatorBase): project_name) +def get_load_color_for_family(family, settings=None): + """Get color for family from settings. + + Args: + family (str): Family name. + settings (Optional[dict]): Settings dictionary. + + Returns: + Union[tuple[float, float, float], None]: RGB color. + + """ + if settings is None: + settings = get_project_settings(get_current_project_name()) + + colors = settings["maya"]["load"]["colors"] + color = colors.get(family) + if not color: + return None + + if len(color) == 3: + red, green, blue = color + elif len(color) == 4: + red, green, blue, _ = color + else: + raise ValueError("Invalid color definition {}".format(str(color))) + + if type(red, int): + red = red / 255.0 + green = green / 255.0 + blue = blue / 255.0 + return red, green, blue + + class Loader(LoaderPlugin): hosts = ["maya"] diff --git a/client/ayon_core/hosts/maya/plugins/load/load_arnold_standin.py b/client/ayon_core/hosts/maya/plugins/load/load_arnold_standin.py index c690d1c205..d70a43a8c3 100644 --- a/client/ayon_core/hosts/maya/plugins/load/load_arnold_standin.py +++ b/client/ayon_core/hosts/maya/plugins/load/load_arnold_standin.py @@ -16,6 +16,7 @@ from ayon_core.hosts.maya.api.lib import ( convert_to_maya_fps ) from ayon_core.hosts.maya.api.pipeline import containerise +from ayon_core.hosts.maya.api.plugin import get_load_color_for_family def is_sequence(files): @@ -72,11 +73,12 @@ class ArnoldStandinLoader(load.LoaderPlugin): # Set color. settings = get_project_settings(context["project"]["name"]) - color = settings['maya']['load']['colors'].get('ass') + color = get_load_color_for_family("ass", settings) if color is not None: + red, green, blue = color cmds.setAttr(root + ".useOutlinerColor", True) cmds.setAttr( - root + ".outlinerColor", color[0], color[1], color[2] + root + ".outlinerColor", red, green, blue ) with maintained_selection(): diff --git a/client/ayon_core/hosts/maya/plugins/load/load_gpucache.py b/client/ayon_core/hosts/maya/plugins/load/load_gpucache.py index 00a76d374b..cdaaeeae6a 100644 --- a/client/ayon_core/hosts/maya/plugins/load/load_gpucache.py +++ b/client/ayon_core/hosts/maya/plugins/load/load_gpucache.py @@ -9,6 +9,7 @@ from ayon_core.pipeline import ( get_representation_path ) from ayon_core.settings import get_project_settings +from ayon_core.hosts.maya.api.plugin import get_load_color_for_family class GpuCacheLoader(load.LoaderPlugin): @@ -39,13 +40,12 @@ class GpuCacheLoader(load.LoaderPlugin): project_name = context["project"]["name"] settings = get_project_settings(project_name) - colors = settings['maya']['load']['colors'] - c = colors.get('model') - if c is not None: + color = get_load_color_for_family("model", settings) + if color is not None: + red, green, blue = color cmds.setAttr(root + ".useOutlinerColor", 1) cmds.setAttr( - root + ".outlinerColor", - (float(c[0]) / 255), (float(c[1]) / 255), (float(c[2]) / 255) + root + ".outlinerColor", red, green, blue ) # Create transform with shape diff --git a/client/ayon_core/hosts/maya/plugins/load/load_redshift_proxy.py b/client/ayon_core/hosts/maya/plugins/load/load_redshift_proxy.py index dd378602c9..8910d0fcd0 100644 --- a/client/ayon_core/hosts/maya/plugins/load/load_redshift_proxy.py +++ b/client/ayon_core/hosts/maya/plugins/load/load_redshift_proxy.py @@ -16,6 +16,7 @@ from ayon_core.hosts.maya.api.lib import ( unique_namespace ) from ayon_core.hosts.maya.api.pipeline import containerise +from ayon_core.hosts.maya.api.plugin import get_load_color_for_family class RedshiftProxyLoader(load.LoaderPlugin): @@ -59,12 +60,13 @@ class RedshiftProxyLoader(load.LoaderPlugin): # colour the group node project_name = context["project"]["name"] settings = get_project_settings(project_name) - colors = settings['maya']['load']['colors'] - c = colors.get(family) - if c is not None: + color = get_load_color_for_family(family, settings) + if color is not None: + red, green, blue = color cmds.setAttr("{0}.useOutlinerColor".format(group_node), 1) - cmds.setAttr("{0}.outlinerColor".format(group_node), - c[0], c[1], c[2]) + cmds.setAttr( + "{0}.outlinerColor".format(group_node), red, green, blue + ) return containerise( name=name, diff --git a/client/ayon_core/hosts/maya/plugins/load/load_reference.py b/client/ayon_core/hosts/maya/plugins/load/load_reference.py index 36bd2e5969..75f42a9fe6 100644 --- a/client/ayon_core/hosts/maya/plugins/load/load_reference.py +++ b/client/ayon_core/hosts/maya/plugins/load/load_reference.py @@ -1,4 +1,3 @@ -import os import difflib import contextlib @@ -6,7 +5,7 @@ from maya import cmds import qargparse from ayon_core.settings import get_project_settings -import ayon_core.hosts.maya.api.plugin +from ayon_core.hosts.maya.api import plugin from ayon_core.hosts.maya.api.lib import ( maintained_selection, get_container_members, @@ -87,7 +86,7 @@ def preserve_modelpanel_cameras(container, log=None): cmds.modelPanel(panel, edit=True, camera=new_camera) -class ReferenceLoader(ayon_core.hosts.maya.api.plugin.ReferenceLoader): +class ReferenceLoader(plugin.ReferenceLoader): """Reference file""" families = ["model", @@ -185,14 +184,16 @@ class ReferenceLoader(ayon_core.hosts.maya.api.plugin.ReferenceLoader): "{}.displayHandle".format(group_name), display_handle ) - colors = settings['maya']['load']['colors'] - c = colors.get(family) - if c is not None: + color = plugin.get_load_color_for_family(family, settings) + if color is not None: + red, green, blue = color cmds.setAttr("{}.useOutlinerColor".format(group_name), 1) - cmds.setAttr("{}.outlinerColor".format(group_name), - (float(c[0]) / 255), - (float(c[1]) / 255), - (float(c[2]) / 255)) + cmds.setAttr( + "{}.outlinerColor".format(group_name), + red, + green, + blue + ) cmds.setAttr( "{}.displayHandle".format(group_name), display_handle diff --git a/client/ayon_core/hosts/maya/plugins/load/load_vdb_to_arnold.py b/client/ayon_core/hosts/maya/plugins/load/load_vdb_to_arnold.py index 98f98330d7..c68fddc60a 100644 --- a/client/ayon_core/hosts/maya/plugins/load/load_vdb_to_arnold.py +++ b/client/ayon_core/hosts/maya/plugins/load/load_vdb_to_arnold.py @@ -5,6 +5,7 @@ from ayon_core.pipeline import ( load, get_representation_path ) +from ayon_core.hosts.maya.api.plugin import get_load_color_for_family # TODO aiVolume doesn't automatically set velocity fps correctly, set manual? @@ -50,16 +51,11 @@ class LoadVDBtoArnold(load.LoaderPlugin): project_name = context["project"]["name"] settings = get_project_settings(project_name) - colors = settings['maya']['load']['colors'] - - c = colors.get(family) - if c is not None: + color = get_load_color_for_family(family, settings) + if color is not None: + red, green, blue = color cmds.setAttr(root + ".useOutlinerColor", 1) - cmds.setAttr(root + ".outlinerColor", - (float(c[0]) / 255), - (float(c[1]) / 255), - (float(c[2]) / 255) - ) + cmds.setAttr(root + ".outlinerColor", red, green, blue) # Create VRayVolumeGrid grid_node = cmds.createNode("aiVolume", diff --git a/client/ayon_core/hosts/maya/plugins/load/load_vdb_to_redshift.py b/client/ayon_core/hosts/maya/plugins/load/load_vdb_to_redshift.py index 426e85cf7c..1bc75ae4c6 100644 --- a/client/ayon_core/hosts/maya/plugins/load/load_vdb_to_redshift.py +++ b/client/ayon_core/hosts/maya/plugins/load/load_vdb_to_redshift.py @@ -5,6 +5,7 @@ from ayon_core.pipeline import ( load, get_representation_path ) +from ayon_core.hosts.maya.api.plugin import get_load_color_for_family class LoadVDBtoRedShift(load.LoaderPlugin): @@ -69,16 +70,11 @@ class LoadVDBtoRedShift(load.LoaderPlugin): project_name = context["project"]["name"] settings = get_project_settings(project_name) - colors = settings['maya']['load']['colors'] - - c = colors.get(family) - if c is not None: + color = get_load_color_for_family(family, settings) + if color is not None: + red, green, blue = color cmds.setAttr(root + ".useOutlinerColor", 1) - cmds.setAttr(root + ".outlinerColor", - (float(c[0])/255), - (float(c[1])/255), - (float(c[2])/255) - ) + cmds.setAttr(root + ".outlinerColor", red, green, blue) # Create VR volume_node = cmds.createNode("RedshiftVolumeShape", diff --git a/client/ayon_core/hosts/maya/plugins/load/load_vdb_to_vray.py b/client/ayon_core/hosts/maya/plugins/load/load_vdb_to_vray.py index ca0519900b..0c87162629 100644 --- a/client/ayon_core/hosts/maya/plugins/load/load_vdb_to_vray.py +++ b/client/ayon_core/hosts/maya/plugins/load/load_vdb_to_vray.py @@ -5,6 +5,7 @@ from ayon_core.pipeline import ( load, get_representation_path ) +from ayon_core.hosts.maya.api.plugin import get_load_color_for_family from maya import cmds @@ -129,15 +130,11 @@ class LoadVDBtoVRay(load.LoaderPlugin): project_name = context["project"]["name"] settings = get_project_settings(project_name) - colors = settings['maya']['load']['colors'] - - c = colors.get(family) - if c is not None: + color = get_load_color_for_family(family, settings) + if color is not None: + red, green, blue = color cmds.setAttr(root + ".useOutlinerColor", 1) - cmds.setAttr(root + ".outlinerColor", - float(c[0]) / 255, - float(c[1]) / 255, - float(c[2]) / 255) + cmds.setAttr(root + ".outlinerColor", red, green, blue) # Create VRayVolumeGrid grid_node = cmds.createNode("VRayVolumeGrid", diff --git a/client/ayon_core/hosts/maya/plugins/load/load_vrayproxy.py b/client/ayon_core/hosts/maya/plugins/load/load_vrayproxy.py index 9b36303b64..50b63f4f11 100644 --- a/client/ayon_core/hosts/maya/plugins/load/load_vrayproxy.py +++ b/client/ayon_core/hosts/maya/plugins/load/load_vrayproxy.py @@ -22,6 +22,7 @@ from ayon_core.hosts.maya.api.lib import ( unique_namespace ) from ayon_core.hosts.maya.api.pipeline import containerise +from ayon_core.hosts.maya.api.plugin import get_load_color_for_family class VRayProxyLoader(load.LoaderPlugin): @@ -80,15 +81,12 @@ class VRayProxyLoader(load.LoaderPlugin): # colour the group node project_name = context["project"]["name"] settings = get_project_settings(project_name) - colors = settings['maya']['load']['colors'] - c = colors.get(family) - if c is not None: + color = get_load_color_for_family(family, settings) + if color is not None: + red, green, blue = color cmds.setAttr("{0}.useOutlinerColor".format(group_node), 1) cmds.setAttr( - "{0}.outlinerColor".format(group_node), - (float(c[0]) / 255), - (float(c[1]) / 255), - (float(c[2]) / 255) + "{0}.outlinerColor".format(group_node), red, green, blue ) return containerise( diff --git a/client/ayon_core/hosts/maya/plugins/load/load_vrayscene.py b/client/ayon_core/hosts/maya/plugins/load/load_vrayscene.py index 92d2b32549..7b4edb0567 100644 --- a/client/ayon_core/hosts/maya/plugins/load/load_vrayscene.py +++ b/client/ayon_core/hosts/maya/plugins/load/load_vrayscene.py @@ -1,5 +1,4 @@ # -*- coding: utf-8 -*- -import os import maya.cmds as cmds # noqa from ayon_core.settings import get_project_settings from ayon_core.pipeline import ( @@ -12,6 +11,7 @@ from ayon_core.hosts.maya.api.lib import ( unique_namespace ) from ayon_core.hosts.maya.api.pipeline import containerise +from ayon_core.hosts.maya.api.plugin import get_load_color_for_family class VRaySceneLoader(load.LoaderPlugin): @@ -58,14 +58,12 @@ class VRaySceneLoader(load.LoaderPlugin): # colour the group node project_name = context["project"]["name"] settings = get_project_settings(project_name) - colors = settings['maya']['load']['colors'] - c = colors.get(family) - if c is not None: + color = get_load_color_for_family(family, settings) + if color is not None: + red, green, blue = color cmds.setAttr("{0}.useOutlinerColor".format(root_node), 1) - cmds.setAttr("{0}.outlinerColor".format(root_node), - (float(c[0])/255), - (float(c[1])/255), - (float(c[2])/255) + cmds.setAttr( + "{0}.outlinerColor".format(root_node), red, green, blue ) return containerise( diff --git a/client/ayon_core/hosts/maya/plugins/load/load_yeti_cache.py b/client/ayon_core/hosts/maya/plugins/load/load_yeti_cache.py index d2fc1c0ab0..afbb632d87 100644 --- a/client/ayon_core/hosts/maya/plugins/load/load_yeti_cache.py +++ b/client/ayon_core/hosts/maya/plugins/load/load_yeti_cache.py @@ -13,6 +13,7 @@ from ayon_core.pipeline import ( ) from ayon_core.hosts.maya.api import lib from ayon_core.hosts.maya.api.pipeline import containerise +from ayon_core.hosts.maya.api.plugin import get_load_color_for_family # Do not reset these values on update but only apply on first load @@ -81,16 +82,11 @@ class YetiCacheLoader(load.LoaderPlugin): project_name = context["project"]["name"] settings = get_project_settings(project_name) - colors = settings['maya']['load']['colors'] - - c = colors.get(family) - if c is not None: + color = get_load_color_for_family(family, settings) + if color is not None: + red, green, blue = color cmds.setAttr(group_node + ".useOutlinerColor", 1) - cmds.setAttr(group_node + ".outlinerColor", - (float(c[0])/255), - (float(c[1])/255), - (float(c[2])/255) - ) + cmds.setAttr(group_node + ".outlinerColor", red, green, blue) nodes.append(group_node) diff --git a/client/ayon_core/hosts/maya/plugins/load/load_yeti_rig.py b/client/ayon_core/hosts/maya/plugins/load/load_yeti_rig.py index 2572e550e2..e7178be38b 100644 --- a/client/ayon_core/hosts/maya/plugins/load/load_yeti_rig.py +++ b/client/ayon_core/hosts/maya/plugins/load/load_yeti_rig.py @@ -1,11 +1,10 @@ import maya.cmds as cmds -from ayon_core.settings import get_current_project_settings -import ayon_core.hosts.maya.api.plugin +from ayon_core.hosts.maya.api import plugin from ayon_core.hosts.maya.api import lib -class YetiRigLoader(ayon_core.hosts.maya.api.plugin.ReferenceLoader): +class YetiRigLoader(plugin.ReferenceLoader): """This loader will load Yeti rig.""" families = ["yetiRig"] @@ -41,14 +40,12 @@ class YetiRigLoader(ayon_core.hosts.maya.api.plugin.ReferenceLoader): groupName=group_name ) - settings = get_current_project_settings() - colors = settings["maya"]["load"]["colors"] - c = colors.get("yetiRig") - if c is not None: + color = plugin.get_load_color_for_family("yetiRig") + if color is not None: + red, green, blue = color cmds.setAttr(group_name + ".useOutlinerColor", 1) cmds.setAttr( - group_name + ".outlinerColor", - (float(c[0]) / 255), (float(c[1]) / 255), (float(c[2]) / 255) + group_name + ".outlinerColor", red, green, blue ) self[:] = nodes diff --git a/client/ayon_core/settings/ayon_settings.py b/client/ayon_core/settings/ayon_settings.py index 1a353a5a64..5734ac0707 100644 --- a/client/ayon_core/settings/ayon_settings.py +++ b/client/ayon_core/settings/ayon_settings.py @@ -344,13 +344,6 @@ def _convert_maya_project_settings(ayon_settings, output): subitem["subset_name_filters"] = subitem.pop( "product_name_filters") - _convert_host_imageio(ayon_maya) - - ayon_maya_load = ayon_maya["load"] - load_colors = ayon_maya_load["colors"] - for key, color in tuple(load_colors.items()): - load_colors[key] = _convert_color(color) - output["maya"] = ayon_maya diff --git a/server_addon/maya/server/settings/loaders.py b/server_addon/maya/server/settings/loaders.py index 15d4275b80..df1172ae7d 100644 --- a/server_addon/maya/server/settings/loaders.py +++ b/server_addon/maya/server/settings/loaders.py @@ -1,40 +1,136 @@ from ayon_server.settings import BaseSettingsModel, SettingsField -from ayon_server.types import ColorRGBA_uint8 +from ayon_server.types import ColorRGB_float class ColorsSetting(BaseSettingsModel): - model: ColorRGBA_uint8 = SettingsField( - (209, 132, 30, 1.0), title="Model:") - rig: ColorRGBA_uint8 = SettingsField( - (59, 226, 235, 1.0), title="Rig:") - pointcache: ColorRGBA_uint8 = SettingsField( - (94, 209, 30, 1.0), title="Pointcache:") - animation: ColorRGBA_uint8 = SettingsField( - (94, 209, 30, 1.0), title="Animation:") - ass: ColorRGBA_uint8 = SettingsField( - (249, 135, 53, 1.0), title="Arnold StandIn:") - camera: ColorRGBA_uint8 = SettingsField( - (136, 114, 244, 1.0), title="Camera:") - fbx: ColorRGBA_uint8 = SettingsField( - (215, 166, 255, 1.0), title="FBX:") - mayaAscii: ColorRGBA_uint8 = SettingsField( - (67, 174, 255, 1.0), title="Maya Ascii:") - mayaScene: ColorRGBA_uint8 = SettingsField( - (67, 174, 255, 1.0), title="Maya Scene:") - setdress: ColorRGBA_uint8 = SettingsField( - (255, 250, 90, 1.0), title="Set Dress:") - layout: ColorRGBA_uint8 = SettingsField(( - 255, 250, 90, 1.0), title="Layout:") - vdbcache: ColorRGBA_uint8 = SettingsField( - (249, 54, 0, 1.0), title="VDB Cache:") - vrayproxy: ColorRGBA_uint8 = SettingsField( - (255, 150, 12, 1.0), title="VRay Proxy:") - vrayscene_layer: ColorRGBA_uint8 = SettingsField( - (255, 150, 12, 1.0), title="VRay Scene:") - yeticache: ColorRGBA_uint8 = SettingsField( - (99, 206, 220, 1.0), title="Yeti Cache:") - yetiRig: ColorRGBA_uint8 = SettingsField( - (0, 205, 125, 1.0), title="Yeti Rig:") + model: ColorRGB_float = SettingsField( + ( + 0.8196078431372549, + 0.5176470588235295, + 0.11764705882352941 + ), + title="Model:" + ) + rig: ColorRGB_float = SettingsField( + ( + 0.23137254901960785, + 0.8862745098039215, + 0.9215686274509803 + ), + title="Rig:" + ) + pointcache: ColorRGB_float = SettingsField( + ( + 0.3686274509803922, + 0.8196078431372549, + 0.11764705882352941 + ), + title="Pointcache:" + ) + animation: ColorRGB_float = SettingsField( + ( + 0.3686274509803922, + 0.8196078431372549, + 0.11764705882352941 + ), + title="Animation:" + ) + ass: ColorRGB_float = SettingsField( + ( + 0.9764705882352941, + 0.5294117647058824, + 0.20784313725490197 + ), + title="Arnold StandIn:" + ) + camera: ColorRGB_float = SettingsField( + ( + 0.5333333333333333, + 0.4470588235294118, + 0.9568627450980393 + ), + title="Camera:" + ) + fbx: ColorRGB_float = SettingsField( + ( + 0.8431372549019608, + 0.6509803921568628, + 1.0 + ), + title="FBX:" + ) + mayaAscii: ColorRGB_float = SettingsField( + ( + 0.2627450980392157, + 0.6823529411764706, + 1.0 + ), + title="Maya Ascii:" + ) + mayaScene: ColorRGB_float = SettingsField( + ( + 0.2627450980392157, + 0.6823529411764706, + 1.0 + ), + title="Maya Scene:" + ) + setdress: ColorRGB_float = SettingsField( + ( + 1.0, + 0.9803921568627451, + 0.35294117647058826 + ), + title="Set Dress:" + ) + layout: ColorRGB_float = SettingsField( + ( + 1.0, + 0.9803921568627451, + 0.35294117647058826 + ), + title="Layout:" + ) + vdbcache: ColorRGB_float = SettingsField( + ( + 0.9764705882352941, + 0.21176470588235294, + 0.0 + ), + title="VDB Cache:" + ) + vrayproxy: ColorRGB_float = SettingsField( + ( + 1.0, + 0.5882352941176471, + 0.047058823529411764 + ), + title="VRay Proxy:" + ) + vrayscene_layer: ColorRGB_float = SettingsField( + ( + 1.0, + 0.5882352941176471, + 0.047058823529411764 + ), + title="VRay Scene:" + ) + yeticache: ColorRGB_float = SettingsField( + ( + 0.38823529411764707, + 0.807843137254902, + 0.8627450980392157 + ), + title="Yeti Cache:" + ) + yetiRig: ColorRGB_float = SettingsField( + ( + 0.0, + 0.803921568627451, + 0.49019607843137253 + ), + title="Yeti Rig:" + ) class ReferenceLoaderModel(BaseSettingsModel): @@ -68,52 +164,84 @@ class LoadersModel(BaseSettingsModel): DEFAULT_LOADERS_SETTING = { "colors": { "model": [ - 209, 132, 30, 1.0 + 0.8196078431372549, + 0.5176470588235295, + 0.11764705882352941 ], "rig": [ - 59, 226, 235, 1.0 + 0.23137254901960785, + 0.8862745098039215, + 0.9215686274509803 ], "pointcache": [ - 94, 209, 30, 1.0 + 0.3686274509803922, + 0.8196078431372549, + 0.11764705882352941 ], "animation": [ - 94, 209, 30, 1.0 + 0.3686274509803922, + 0.8196078431372549, + 0.11764705882352941 ], "ass": [ - 249, 135, 53, 1.0 + 0.9764705882352941, + 0.5294117647058824, + 0.20784313725490197 ], "camera": [ - 136, 114, 244, 1.0 + 0.5333333333333333, + 0.4470588235294118, + 0.9568627450980393 ], "fbx": [ - 215, 166, 255, 1.0 + 0.8431372549019608, + 0.6509803921568628, + 1.0 ], "mayaAscii": [ - 67, 174, 255, 1.0 + 0.2627450980392157, + 0.6823529411764706, + 1.0 ], "mayaScene": [ - 67, 174, 255, 1.0 + 0.2627450980392157, + 0.6823529411764706, + 1.0 ], "setdress": [ - 255, 250, 90, 1.0 + 1.0, + 0.9803921568627451, + 0.35294117647058826 ], "layout": [ - 255, 250, 90, 1.0 + 1.0, + 0.9803921568627451, + 0.35294117647058826 ], "vdbcache": [ - 249, 54, 0, 1.0 + 0.9764705882352941, + 0.21176470588235294, + 0.0 ], "vrayproxy": [ - 255, 150, 12, 1.0 + 1.0, + 0.5882352941176471, + 0.047058823529411764 ], "vrayscene_layer": [ - 255, 150, 12, 1.0 + 1.0, + 0.5882352941176471, + 0.047058823529411764 ], "yeticache": [ - 99, 206, 220, 1.0 + 0.38823529411764707, + 0.807843137254902, + 0.8627450980392157 ], "yetiRig": [ - 0, 205, 125, 1.0 + 0.0, + 0.803921568627451, + 0.49019607843137253 ] }, "reference_loader": { From da5a0589e6a0e2af1f0971442d46a7b99cf91d97 Mon Sep 17 00:00:00 2001 From: JackP Date: Fri, 9 Feb 2024 15:50:06 +0000 Subject: [PATCH 059/185] feat: implemented has_unsaved_changes --- client/ayon_core/hosts/max/api/pipeline.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/client/ayon_core/hosts/max/api/pipeline.py b/client/ayon_core/hosts/max/api/pipeline.py index ff5ef0640b..b0c85c070b 100644 --- a/client/ayon_core/hosts/max/api/pipeline.py +++ b/client/ayon_core/hosts/max/api/pipeline.py @@ -61,8 +61,7 @@ class MaxHost(HostBase, IWorkfileHost, ILoadHost, IPublishHost): lib.check_colorspace) def has_unsaved_changes(self): - # TODO: how to get it from 3dsmax? - return True + return rt.getSaveRequired() def get_workfile_extensions(self): return [".max"] From 8bd7fde33e7fc331c268bfa4142e39e94b2298c4 Mon Sep 17 00:00:00 2001 From: JackP Date: Fri, 9 Feb 2024 15:50:43 +0000 Subject: [PATCH 060/185] feat: save_scene to use host functions to check if saving is required --- .../hosts/max/plugins/publish/save_scene.py | 22 ++++++++++--------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/client/ayon_core/hosts/max/plugins/publish/save_scene.py b/client/ayon_core/hosts/max/plugins/publish/save_scene.py index a40788ab41..37ff38bc59 100644 --- a/client/ayon_core/hosts/max/plugins/publish/save_scene.py +++ b/client/ayon_core/hosts/max/plugins/publish/save_scene.py @@ -1,11 +1,9 @@ import pyblish.api -import os +from openpype.pipeline import registered_host class SaveCurrentScene(pyblish.api.ContextPlugin): - """Save current scene - - """ + """Save current scene""" label = "Save current file" order = pyblish.api.ExtractorOrder - 0.49 @@ -13,9 +11,13 @@ class SaveCurrentScene(pyblish.api.ContextPlugin): families = ["maxrender", "workfile"] def process(self, context): - from pymxs import runtime as rt - folder = rt.maxFilePath - file = rt.maxFileName - current = os.path.join(folder, file) - assert context.data["currentFile"] == current - rt.saveMaxFile(current) + host = registered_host() + current_file = host.get_current_workfile() + + assert context.data["currentFile"] == current_file + + if host.workfile_has_unsaved_changes(): + self.log.info(f"Saving current file: {current_file}") + host.save_workfile(current_file) + else: + self.log.debug("No unsaved changes, skipping file save..")") \ No newline at end of file From 3cddbb809e581cf27f2ee562f398af99aba45b8f Mon Sep 17 00:00:00 2001 From: JackP Date: Fri, 9 Feb 2024 15:51:04 +0000 Subject: [PATCH 061/185] feat: startup.ms to restore default view menu --- client/ayon_core/hosts/max/startup/startup.ms | 3 +++ 1 file changed, 3 insertions(+) diff --git a/client/ayon_core/hosts/max/startup/startup.ms b/client/ayon_core/hosts/max/startup/startup.ms index b80ead4b74..4c597901f3 100644 --- a/client/ayon_core/hosts/max/startup/startup.ms +++ b/client/ayon_core/hosts/max/startup/startup.ms @@ -8,5 +8,8 @@ local pythonpath = systemTools.getEnvVariable "MAX_PYTHONPATH" systemTools.setEnvVariable "PYTHONPATH" pythonpath + /*opens the create menu on startup to ensure users are presented with a useful default view.*/ + max create mode + python.ExecuteFile startup ) \ No newline at end of file From c3a8c2ac7f1f7869ef8c7ec09988e571c2a399e4 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Fri, 9 Feb 2024 16:55:54 +0100 Subject: [PATCH 062/185] build workfile works with new keys --- client/ayon_core/pipeline/workfile/build_workfile.py | 10 +++++----- client/ayon_core/settings/ayon_settings.py | 11 +---------- 2 files changed, 6 insertions(+), 15 deletions(-) diff --git a/client/ayon_core/pipeline/workfile/build_workfile.py b/client/ayon_core/pipeline/workfile/build_workfile.py index c62facaaa9..8df3830d6e 100644 --- a/client/ayon_core/pipeline/workfile/build_workfile.py +++ b/client/ayon_core/pipeline/workfile/build_workfile.py @@ -321,7 +321,7 @@ class BuildWorkfile: continue # Check families - profile_families = profile.get("families") + profile_families = profile.get("product_types") if not profile_families: self.log.warning(( "Build profile is missing families configuration: {0}" @@ -338,7 +338,7 @@ class BuildWorkfile: continue # Prepare lowered families and representation names - profile["families_lowered"] = [ + profile["product_types_lowered"] = [ fam.lower() for fam in profile_families ] profile["repre_names_lowered"] = [ @@ -375,11 +375,11 @@ class BuildWorkfile: family_low = family.lower() for profile in profiles: # Skip profile if does not contain family - if family_low not in profile["families_lowered"]: + if family_low not in profile["product_types_lowered"]: continue # Precompile name filters as regexes - profile_regexes = profile.get("subset_name_filters") + profile_regexes = profile.get("product_name_filters") if profile_regexes: _profile_regexes = [] for regex in profile_regexes: @@ -538,7 +538,7 @@ class BuildWorkfile: build_presets += self.build_presets.get("linked_assets", []) subset_ids_ordered = [] for preset in build_presets: - for preset_family in preset["families"]: + for preset_family in preset["product_types"]: for id, subset in subsets_by_id.items(): if preset_family not in subset["data"].get("families", []): continue diff --git a/client/ayon_core/settings/ayon_settings.py b/client/ayon_core/settings/ayon_settings.py index 5734ac0707..40d4c775be 100644 --- a/client/ayon_core/settings/ayon_settings.py +++ b/client/ayon_core/settings/ayon_settings.py @@ -333,16 +333,7 @@ def _convert_maya_project_settings(ayon_settings, output): ayon_maya = ayon_settings["maya"] - # Workfile build - ayon_workfile_build = ayon_maya["workfile_build"] - for item in ayon_workfile_build["profiles"]: - for key in ("current_context", "linked_assets"): - for subitem in item[key]: - if "families" in subitem: - break - subitem["families"] = subitem.pop("product_types") - subitem["subset_name_filters"] = subitem.pop( - "product_name_filters") + _convert_host_imageio(ayon_maya) output["maya"] = ayon_maya From 1d9a4dd737b12a33a67acdf66ad75e3e9fad764d Mon Sep 17 00:00:00 2001 From: JackP Date: Fri, 9 Feb 2024 15:56:31 +0000 Subject: [PATCH 063/185] refactor: replaced has_unsaved_changes with workfile_has_unsaved_changes --- client/ayon_core/hosts/max/api/pipeline.py | 1 + 1 file changed, 1 insertion(+) diff --git a/client/ayon_core/hosts/max/api/pipeline.py b/client/ayon_core/hosts/max/api/pipeline.py index b0c85c070b..5f20891329 100644 --- a/client/ayon_core/hosts/max/api/pipeline.py +++ b/client/ayon_core/hosts/max/api/pipeline.py @@ -61,6 +61,7 @@ class MaxHost(HostBase, IWorkfileHost, ILoadHost, IPublishHost): lib.check_colorspace) def has_unsaved_changes(self): + def workfile_has_unsaved_changes(self): return rt.getSaveRequired() def get_workfile_extensions(self): From 57815d19a1e9e42d7abe24721b121d6eb1b5ff45 Mon Sep 17 00:00:00 2001 From: JackP Date: Fri, 9 Feb 2024 16:03:02 +0000 Subject: [PATCH 064/185] chore: removed has_unsaved_changes --- client/ayon_core/hosts/max/api/pipeline.py | 1 - 1 file changed, 1 deletion(-) diff --git a/client/ayon_core/hosts/max/api/pipeline.py b/client/ayon_core/hosts/max/api/pipeline.py index 5f20891329..2dc3eb6da8 100644 --- a/client/ayon_core/hosts/max/api/pipeline.py +++ b/client/ayon_core/hosts/max/api/pipeline.py @@ -60,7 +60,6 @@ class MaxHost(HostBase, IWorkfileHost, ILoadHost, IPublishHost): rt.callbacks.addScript(rt.Name('filePostOpen'), lib.check_colorspace) - def has_unsaved_changes(self): def workfile_has_unsaved_changes(self): return rt.getSaveRequired() From 85526b41ad8f3dccca1a98fc000367c63e3084fa Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Fri, 9 Feb 2024 17:05:14 +0100 Subject: [PATCH 065/185] flame 'ExtractProductResources' uses AYON settings --- .../publish/extract_subset_resources.py | 19 ++++++++++++------- client/ayon_core/settings/ayon_settings.py | 19 ------------------- 2 files changed, 12 insertions(+), 26 deletions(-) diff --git a/client/ayon_core/hosts/flame/plugins/publish/extract_subset_resources.py b/client/ayon_core/hosts/flame/plugins/publish/extract_subset_resources.py index af699fd03a..9e55dbce96 100644 --- a/client/ayon_core/hosts/flame/plugins/publish/extract_subset_resources.py +++ b/client/ayon_core/hosts/flame/plugins/publish/extract_subset_resources.py @@ -1,6 +1,5 @@ import os import re -import tempfile from copy import deepcopy import pyblish.api @@ -15,12 +14,12 @@ from ayon_core.pipeline.editorial import ( import flame -class ExtractSubsetResources(publish.Extractor): +class ExtractProductResources(publish.Extractor): """ Extractor for transcoding files from Flame clip """ - label = "Extract subset resources" + label = "Extract product resources" order = pyblish.api.ExtractorOrder families = ["clip"] hosts = ["flame"] @@ -47,7 +46,7 @@ class ExtractSubsetResources(publish.Extractor): hide_ui_on_process = True # settings - export_presets_mapping = {} + export_presets_mapping = [] def process(self, instance): if not self.keep_original_representation: @@ -146,15 +145,21 @@ class ExtractSubsetResources(publish.Extractor): # append staging dir for later cleanup instance.context.data["cleanupFullPaths"].append(staging_dir) + export_presets_mapping = {} + for preset_mapping in deepcopy(self.export_presets_mapping): + name = preset_mapping.pop("name") + export_presets_mapping[name] = preset_mapping + # add default preset type for thumbnail and reviewable video # update them with settings and override in case the same # are found in there - _preset_keys = [k.split('_')[0] for k in self.export_presets_mapping] + _preset_keys = [k.split('_')[0] for k in export_presets_mapping] export_presets = { - k: v for k, v in deepcopy(self.default_presets).items() + k: v + for k, v in deepcopy(self.default_presets).items() if k not in _preset_keys } - export_presets.update(self.export_presets_mapping) + export_presets.update(export_presets_mapping) if not instance.data.get("versionData"): instance.data["versionData"] = {} diff --git a/client/ayon_core/settings/ayon_settings.py b/client/ayon_core/settings/ayon_settings.py index 40d4c775be..7de6011916 100644 --- a/client/ayon_core/settings/ayon_settings.py +++ b/client/ayon_core/settings/ayon_settings.py @@ -268,25 +268,6 @@ def _convert_flame_project_settings(ayon_settings, output): ayon_flame = ayon_settings["flame"] ayon_publish_flame = ayon_flame["publish"] - # Plugin 'ExtractSubsetResources' renamed to 'ExtractProductResources' - if "ExtractSubsetResources" in ayon_publish_flame: - ayon_product_resources = ayon_publish_flame["ExtractSubsetResources"] - else: - ayon_product_resources = ( - ayon_publish_flame.pop("ExtractProductResources")) - ayon_publish_flame["ExtractSubsetResources"] = ayon_product_resources - - # 'ExtractSubsetResources' changed model of 'export_presets_mapping' - # - some keys were moved under 'other_parameters' - new_subset_resources = {} - for item in ayon_product_resources.pop("export_presets_mapping"): - name = item.pop("name") - if "other_parameters" in item: - other_parameters = item.pop("other_parameters") - item.update(other_parameters) - new_subset_resources[name] = item - - ayon_product_resources["export_presets_mapping"] = new_subset_resources # 'imageio' changed model # - missing subkey 'project' which is in root of 'imageio' model From f19d8762df971ac9802c163d2e29d379bbadcf6d Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Fri, 9 Feb 2024 17:10:47 +0100 Subject: [PATCH 066/185] flame Loaders can use AYON settings --- .../flame/plugins/load/load_clip_batch.py | 19 ++++++++++--- client/ayon_core/settings/ayon_settings.py | 27 ------------------- 2 files changed, 15 insertions(+), 31 deletions(-) diff --git a/client/ayon_core/hosts/flame/plugins/load/load_clip_batch.py b/client/ayon_core/hosts/flame/plugins/load/load_clip_batch.py index a66bf53622..57797e5a44 100644 --- a/client/ayon_core/hosts/flame/plugins/load/load_clip_batch.py +++ b/client/ayon_core/hosts/flame/plugins/load/load_clip_batch.py @@ -50,17 +50,28 @@ class LoadClipBatch(opfapi.ClipLoader): version_name = version.get("name", None) colorspace = self.get_colorspace(context) + # TODO remove '{folder[name]}' and '{product[name]}' replacement + clip_name_template = ( + self.clip_name_template + .replace("{folder[name]}", "{asset}") + .replace("{product[name]}", "{subset}") + ) + layer_rename_template = ( + self.layer_rename_template + .replace("{folder[name]}", "{asset}") + .replace("{product[name]}", "{subset}") + ) # in case output is not in context replace key to representation if not context["representation"]["context"].get("output"): - self.clip_name_template = self.clip_name_template.replace( + clip_name_template = clip_name_template.replace( "output", "representation") - self.layer_rename_template = self.layer_rename_template.replace( + layer_rename_template = layer_rename_template.replace( "output", "representation") formatting_data = deepcopy(context["representation"]["context"]) formatting_data["batch"] = self.batch.name.get_value() - clip_name = StringTemplate(self.clip_name_template).format( + clip_name = StringTemplate(clip_name_template).format( formatting_data) # convert colorspace with ocio to flame mapping @@ -86,7 +97,7 @@ class LoadClipBatch(opfapi.ClipLoader): "path": path.replace("\\", "/"), "colorspace": colorspace, "version": "v{:0>3}".format(version_name), - "layer_rename_template": self.layer_rename_template, + "layer_rename_template": layer_rename_template, "layer_rename_patterns": self.layer_rename_patterns, "context_data": formatting_data } diff --git a/client/ayon_core/settings/ayon_settings.py b/client/ayon_core/settings/ayon_settings.py index 7de6011916..39e30d4846 100644 --- a/client/ayon_core/settings/ayon_settings.py +++ b/client/ayon_core/settings/ayon_settings.py @@ -267,34 +267,7 @@ def _convert_flame_project_settings(ayon_settings, output): ayon_flame = ayon_settings["flame"] - ayon_publish_flame = ayon_flame["publish"] - - # 'imageio' changed model - # - missing subkey 'project' which is in root of 'imageio' model _convert_host_imageio(ayon_flame) - ayon_imageio_flame = ayon_flame["imageio"] - if "project" not in ayon_imageio_flame: - profile_mapping = ayon_imageio_flame.pop("profilesMapping") - ayon_flame["imageio"] = { - "project": ayon_imageio_flame, - "profilesMapping": profile_mapping - } - - ayon_load_flame = ayon_flame["load"] - for plugin_name in ("LoadClip", "LoadClipBatch"): - plugin_settings = ayon_load_flame[plugin_name] - plugin_settings["families"] = plugin_settings.pop("product_types") - plugin_settings["clip_name_template"] = ( - plugin_settings["clip_name_template"] - .replace("{folder[name]}", "{asset}") - .replace("{product[name]}", "{subset}") - ) - plugin_settings["layer_rename_template"] = ( - plugin_settings["layer_rename_template"] - .replace("{folder[name]}", "{asset}") - .replace("{product[name]}", "{subset}") - ) - output["flame"] = ayon_flame From b0dd56326135d4c16214cb347d576bd821a0a84d Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Fri, 9 Feb 2024 17:13:52 +0100 Subject: [PATCH 067/185] max PointCloud uses AYON settings --- .../hosts/max/plugins/publish/extract_pointcloud.py | 4 +++- .../hosts/max/plugins/publish/validate_pointcloud.py | 4 +++- client/ayon_core/settings/ayon_settings.py | 7 ------- 3 files changed, 6 insertions(+), 9 deletions(-) diff --git a/client/ayon_core/hosts/max/plugins/publish/extract_pointcloud.py b/client/ayon_core/hosts/max/plugins/publish/extract_pointcloud.py index 294d63794e..67dde7f0a6 100644 --- a/client/ayon_core/hosts/max/plugins/publish/extract_pointcloud.py +++ b/client/ayon_core/hosts/max/plugins/publish/extract_pointcloud.py @@ -155,7 +155,9 @@ class ExtractPointCloud(publish.Extractor): custom_attr_list = [] attr_settings = self.settings["attribute"] - for key, value in attr_settings.items(): + for attr in attr_settings: + key = attr["name"] + value = attr["value"] custom_attr = "{0}.PRTChannels_{1}=True".format(operator, value) self.log.debug( diff --git a/client/ayon_core/hosts/max/plugins/publish/validate_pointcloud.py b/client/ayon_core/hosts/max/plugins/publish/validate_pointcloud.py index a025ed3992..73b18984ed 100644 --- a/client/ayon_core/hosts/max/plugins/publish/validate_pointcloud.py +++ b/client/ayon_core/hosts/max/plugins/publish/validate_pointcloud.py @@ -59,7 +59,9 @@ class ValidatePointCloud(pyblish.api.InstancePlugin): event_name = sub_anim.name opt = "${0}.{1}.export_particles".format(sel.name, event_name) - for key, value in attr_settings.items(): + for attr in attr_settings: + key = attr["name"] + value = attr["value"] custom_attr = "{0}.PRTChannels_{1}".format(opt, value) try: diff --git a/client/ayon_core/settings/ayon_settings.py b/client/ayon_core/settings/ayon_settings.py index 39e30d4846..5a1fbfb947 100644 --- a/client/ayon_core/settings/ayon_settings.py +++ b/client/ayon_core/settings/ayon_settings.py @@ -298,13 +298,6 @@ def _convert_3dsmax_project_settings(ayon_settings, output): ayon_max = ayon_settings["max"] _convert_host_imageio(ayon_max) - if "PointCloud" in ayon_max: - point_cloud_attribute = ayon_max["PointCloud"]["attribute"] - new_point_cloud_attribute = { - item["name"]: item["value"] - for item in point_cloud_attribute - } - ayon_max["PointCloud"]["attribute"] = new_point_cloud_attribute # --- Publish (START) --- ayon_publish = ayon_max["publish"] if "ValidateAttributes" in ayon_publish: From 96cbbeb823809ae68071a883f19b877d0cd7452e Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Fri, 9 Feb 2024 17:15:51 +0100 Subject: [PATCH 068/185] max 'ValidateAttributes' can use AYON settings --- .../plugins/publish/validate_attributes.py | 22 ++++++++++++++----- client/ayon_core/settings/ayon_settings.py | 8 ------- 2 files changed, 16 insertions(+), 14 deletions(-) diff --git a/client/ayon_core/hosts/max/plugins/publish/validate_attributes.py b/client/ayon_core/hosts/max/plugins/publish/validate_attributes.py index 444a8f0829..354539871f 100644 --- a/client/ayon_core/hosts/max/plugins/publish/validate_attributes.py +++ b/client/ayon_core/hosts/max/plugins/publish/validate_attributes.py @@ -1,5 +1,7 @@ # -*- coding: utf-8 -*- """Validator for Attributes.""" +import json + from pyblish.api import ContextPlugin, ValidatorOrder from pymxs import runtime as rt @@ -61,9 +63,13 @@ class ValidateAttributes(OptionalPyblishPluginMixin, @classmethod def get_invalid(cls, context): - attributes = ( - context.data["project_settings"]["max"]["publish"] - ["ValidateAttributes"]["attributes"] + attributes = json.loads( + context.data + ["project_settings"] + ["max"] + ["publish"] + ["ValidateAttributes"] + ["attributes"] ) if not attributes: return @@ -112,9 +118,13 @@ class ValidateAttributes(OptionalPyblishPluginMixin, @classmethod def repair(cls, context): - attributes = ( - context.data["project_settings"]["max"]["publish"] - ["ValidateAttributes"]["attributes"] + attributes = json.loads( + context.data + ["project_settings"] + ["max"] + ["publish"] + ["ValidateAttributes"] + ["attributes"] ) invalid_attributes = cls.get_invalid(context) for attrs in invalid_attributes: diff --git a/client/ayon_core/settings/ayon_settings.py b/client/ayon_core/settings/ayon_settings.py index 5a1fbfb947..4d79e922b3 100644 --- a/client/ayon_core/settings/ayon_settings.py +++ b/client/ayon_core/settings/ayon_settings.py @@ -300,14 +300,6 @@ def _convert_3dsmax_project_settings(ayon_settings, output): _convert_host_imageio(ayon_max) # --- Publish (START) --- ayon_publish = ayon_max["publish"] - if "ValidateAttributes" in ayon_publish: - try: - attributes = json.loads( - ayon_publish["ValidateAttributes"]["attributes"] - ) - except ValueError: - attributes = {} - ayon_publish["ValidateAttributes"]["attributes"] = attributes if "ValidateLoadedPlugin" in ayon_publish: loaded_plugin = ( From d8c8f7f0ec9687afa782eb3fa225e50186a85fc0 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Fri, 9 Feb 2024 17:23:10 +0100 Subject: [PATCH 069/185] max 'ValidateLoadedPlugin' can use AYON settings --- .../max/plugins/publish/validate_loaded_plugin.py | 12 ++++++++++-- client/ayon_core/settings/ayon_settings.py | 10 ---------- server_addon/max/server/settings/publishers.py | 4 ++-- 3 files changed, 12 insertions(+), 14 deletions(-) diff --git a/client/ayon_core/hosts/max/plugins/publish/validate_loaded_plugin.py b/client/ayon_core/hosts/max/plugins/publish/validate_loaded_plugin.py index fe6e32b27b..bf5ac26fef 100644 --- a/client/ayon_core/hosts/max/plugins/publish/validate_loaded_plugin.py +++ b/client/ayon_core/hosts/max/plugins/publish/validate_loaded_plugin.py @@ -25,7 +25,7 @@ class ValidateLoadedPlugin(OptionalPyblishPluginMixin, optional = True actions = [RepairAction] - family_plugins_mapping = {} + family_plugins_mapping = [] @classmethod def get_invalid(cls, instance): @@ -34,6 +34,12 @@ class ValidateLoadedPlugin(OptionalPyblishPluginMixin, if not family_plugins_mapping: return + # Backward compatibility - settings did have 'product_types' + if "product_types" in family_plugins_mapping: + family_plugins_mapping["families"] = family_plugins_mapping.pop( + "product_types" + ) + invalid = [] # Find all plug-in requirements for current instance instance_families = {instance.data["family"]} @@ -47,7 +53,9 @@ class ValidateLoadedPlugin(OptionalPyblishPluginMixin, if not mapping: return - match_families = {fam.strip() for fam in mapping["families"]} + match_families = { + fam.strip() for fam in mapping["families"] + } has_match = "*" in match_families or match_families.intersection( instance_families) diff --git a/client/ayon_core/settings/ayon_settings.py b/client/ayon_core/settings/ayon_settings.py index 4d79e922b3..02442645bb 100644 --- a/client/ayon_core/settings/ayon_settings.py +++ b/client/ayon_core/settings/ayon_settings.py @@ -297,16 +297,6 @@ def _convert_3dsmax_project_settings(ayon_settings, output): return ayon_max = ayon_settings["max"] - _convert_host_imageio(ayon_max) - # --- Publish (START) --- - ayon_publish = ayon_max["publish"] - - if "ValidateLoadedPlugin" in ayon_publish: - loaded_plugin = ( - ayon_publish["ValidateLoadedPlugin"]["family_plugins_mapping"] - ) - for item in loaded_plugin: - item["families"] = item.pop("product_types") output["max"] = ayon_max diff --git a/server_addon/max/server/settings/publishers.py b/server_addon/max/server/settings/publishers.py index da782cb494..e8a48ec3d1 100644 --- a/server_addon/max/server/settings/publishers.py +++ b/server_addon/max/server/settings/publishers.py @@ -28,9 +28,9 @@ class ValidateAttributesModel(BaseSettingsModel): class FamilyMappingItemModel(BaseSettingsModel): - product_types: list[str] = SettingsField( + families: list[str] = SettingsField( default_factory=list, - title="Product Types" + title="Families" ) plugins: list[str] = SettingsField( default_factory=list, From 7e2331467df72d8c8a1a72ffdfba8c940cbcfad1 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Fri, 9 Feb 2024 17:35:22 +0100 Subject: [PATCH 070/185] simplify general settings conversion --- client/ayon_core/pipeline/template_data.py | 7 ++-- client/ayon_core/settings/__init__.py | 2 -- client/ayon_core/settings/ayon_settings.py | 40 ++++------------------ client/ayon_core/settings/lib.py | 12 +++---- 4 files changed, 14 insertions(+), 47 deletions(-) diff --git a/client/ayon_core/pipeline/template_data.py b/client/ayon_core/pipeline/template_data.py index a1b944a431..a5ca84c754 100644 --- a/client/ayon_core/pipeline/template_data.py +++ b/client/ayon_core/pipeline/template_data.py @@ -17,12 +17,11 @@ def get_general_template_data(system_settings=None): if not system_settings: system_settings = get_system_settings() - studio_name = system_settings["general"]["studio_name"] - studio_code = system_settings["general"]["studio_code"] + core_settings = system_settings["core"] return { "studio": { - "name": studio_name, - "code": studio_code + "name": core_settings["studio_name"], + "code": core_settings["studio_code"] }, "user": get_ayon_username() } diff --git a/client/ayon_core/settings/__init__.py b/client/ayon_core/settings/__init__.py index 51019ca570..ed3aaef7d4 100644 --- a/client/ayon_core/settings/__init__.py +++ b/client/ayon_core/settings/__init__.py @@ -4,7 +4,6 @@ from .constants import ( ) from .lib import ( get_general_environments, - get_global_settings, get_system_settings, get_project_settings, get_current_project_settings, @@ -17,7 +16,6 @@ __all__ = ( "PROJECT_SETTINGS_KEY", "get_general_environments", - "get_global_settings", "get_system_settings", "get_project_settings", "get_current_project_settings", diff --git a/client/ayon_core/settings/ayon_settings.py b/client/ayon_core/settings/ayon_settings.py index 02442645bb..1aa82995b6 100644 --- a/client/ayon_core/settings/ayon_settings.py +++ b/client/ayon_core/settings/ayon_settings.py @@ -73,31 +73,13 @@ def _convert_host_imageio(host_settings): def _convert_general(ayon_settings, output, default_settings): - # TODO get studio name/code - core_settings = ayon_settings["core"] - environments = core_settings["environments"] - if isinstance(environments, six.string_types): - environments = json.loads(environments) - - general = default_settings["general"] - general.update({ - "log_to_server": False, - "studio_name": core_settings["studio_name"], - "studio_code": core_settings["studio_code"], - "environment": environments - }) - output["general"] = general - - -def _convert_kitsu_system_settings( - ayon_settings, output, addon_versions, default_settings -): - enabled = addon_versions.get("kitsu") is not None - kitsu_settings = default_settings["modules"]["kitsu"] - kitsu_settings["enabled"] = enabled - if enabled: - kitsu_settings["server"] = ayon_settings["kitsu"]["server"] - output["modules"]["kitsu"] = kitsu_settings + output["core"] = ayon_settings["core"] + version_check_interval = ( + default_settings["general"]["version_check_interval"] + ) + output["general"] = { + "version_check_interval": version_check_interval + } def _convert_timers_manager_system_settings( @@ -701,14 +683,6 @@ def _convert_global_project_settings(ayon_settings, output, default_settings): ayon_core = ayon_settings["core"] _convert_host_imageio(ayon_core) - - for key in ( - "environments", - "studio_name", - "studio_code", - ): - ayon_core.pop(key, None) - # Publish conversion ayon_publish = ayon_core["publish"] diff --git a/client/ayon_core/settings/lib.py b/client/ayon_core/settings/lib.py index beae376b7c..ee453956d2 100644 --- a/client/ayon_core/settings/lib.py +++ b/client/ayon_core/settings/lib.py @@ -15,7 +15,8 @@ from .constants import ( from .ayon_settings import ( get_ayon_project_settings, - get_ayon_system_settings + get_ayon_system_settings, + get_ayon_settings, ) log = logging.getLogger(__name__) @@ -253,14 +254,9 @@ def get_current_project_settings(): return get_project_settings(project_name) -def get_global_settings(): - default_settings = load_openpype_default_settings() - return default_settings["system_settings"]["general"] - - def get_general_environments(): - value = get_system_settings() - return value["general"]["environment"] + settings = get_ayon_settings() + return json.loads(settings["core"]["environments"]) def get_system_settings(*args, **kwargs): From b0d7e1601165e74cbf7ff50c4a49d5cf729be1c4 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Fri, 9 Feb 2024 17:40:13 +0100 Subject: [PATCH 071/185] bump addon versions --- server_addon/max/server/version.py | 2 +- server_addon/maya/server/version.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/server_addon/max/server/version.py b/server_addon/max/server/version.py index bbab0242f6..1276d0254f 100644 --- a/server_addon/max/server/version.py +++ b/server_addon/max/server/version.py @@ -1 +1 @@ -__version__ = "0.1.4" +__version__ = "0.1.5" diff --git a/server_addon/maya/server/version.py b/server_addon/maya/server/version.py index 684d830189..8202425a2d 100644 --- a/server_addon/maya/server/version.py +++ b/server_addon/maya/server/version.py @@ -1,3 +1,3 @@ # -*- coding: utf-8 -*- """Package declaring addon version.""" -__version__ = "0.1.8" +__version__ = "0.1.9" From 2e925ea64b32848097a34abbf9e13f89ec0e805a Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Fri, 9 Feb 2024 21:50:30 +0100 Subject: [PATCH 072/185] fix variable check --- client/ayon_core/plugins/publish/collect_rendered_files.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/ayon_core/plugins/publish/collect_rendered_files.py b/client/ayon_core/plugins/publish/collect_rendered_files.py index 714d790269..1442111a31 100644 --- a/client/ayon_core/plugins/publish/collect_rendered_files.py +++ b/client/ayon_core/plugins/publish/collect_rendered_files.py @@ -144,7 +144,7 @@ class CollectRenderedFiles(pyblish.api.ContextPlugin): os.environ.get("AYON_PUBLISH_DATA") or os.environ.get("OPENPYPE_PUBLISH_DATA") ) - if publish_data_paths: + if not publish_data_paths: raise KnownPublishError("Missing `AYON_PUBLISH_DATA`") # QUESTION From 9d807f28f069ffff23c7306d88c756526246379d Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Fri, 9 Feb 2024 22:16:43 +0100 Subject: [PATCH 073/185] session is not required key --- client/ayon_core/plugins/publish/collect_rendered_files.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/ayon_core/plugins/publish/collect_rendered_files.py b/client/ayon_core/plugins/publish/collect_rendered_files.py index 1442111a31..a7b6064b7a 100644 --- a/client/ayon_core/plugins/publish/collect_rendered_files.py +++ b/client/ayon_core/plugins/publish/collect_rendered_files.py @@ -72,7 +72,7 @@ class CollectRenderedFiles(pyblish.api.ContextPlugin): # validate basic necessary data data_err = "invalid json file - missing data" required = ["asset", "user", "comment", - "job", "instances", "session", "version"] + "job", "instances", "version"] assert all(elem in data.keys() for elem in required), data_err # set context by first json file From a1900487649617447d92133a6219867e5b60d722 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Mon, 12 Feb 2024 10:31:56 +0100 Subject: [PATCH 074/185] removed unnecessary changes --- client/ayon_core/plugins/publish/extract_review.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/client/ayon_core/plugins/publish/extract_review.py b/client/ayon_core/plugins/publish/extract_review.py index a6e0196dc7..4e6ece0038 100644 --- a/client/ayon_core/plugins/publish/extract_review.py +++ b/client/ayon_core/plugins/publish/extract_review.py @@ -1059,10 +1059,8 @@ class ExtractReview(pyblish.api.InstancePlugin): # NOTE: value in "-ac" was hardcoded to 2, changed to audio inputs len. # Need to merge audio if there are more than 1 input. if len(audio_inputs) > 1: - audio_out_args.extend([ - "-filter_complex", "amerge", - "-ac", str(len(audio_inputs)) - ]) + audio_out_args.append("-filter_complex amerge") + audio_out_args.append("-ac {}".format(len(audio_inputs))) return audio_in_args, audio_filters, audio_out_args From 0057e4509f4e476a459e3ffd9f9ed1b9acb095e7 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Mon, 12 Feb 2024 15:25:05 +0100 Subject: [PATCH 075/185] removed tests in client codebase --- client/ayon_core/tests/README.md | 4 - client/ayon_core/tests/__init__.py | 0 client/ayon_core/tests/lib.py | 88 ------ client/ayon_core/tests/mongo_performance.py | 288 ------------------ .../tests/test_avalon_plugin_presets.py | 43 --- .../tests/test_lib_restructuralization.py | 25 -- client/ayon_core/tests/test_pyblish_filter.py | 60 ---- 7 files changed, 508 deletions(-) delete mode 100644 client/ayon_core/tests/README.md delete mode 100644 client/ayon_core/tests/__init__.py delete mode 100644 client/ayon_core/tests/lib.py delete mode 100644 client/ayon_core/tests/mongo_performance.py delete mode 100644 client/ayon_core/tests/test_avalon_plugin_presets.py delete mode 100644 client/ayon_core/tests/test_lib_restructuralization.py delete mode 100644 client/ayon_core/tests/test_pyblish_filter.py diff --git a/client/ayon_core/tests/README.md b/client/ayon_core/tests/README.md deleted file mode 100644 index c05166767c..0000000000 --- a/client/ayon_core/tests/README.md +++ /dev/null @@ -1,4 +0,0 @@ -Tests for Pype --------------- -Trigger by: - `pype test --pype` \ No newline at end of file diff --git a/client/ayon_core/tests/__init__.py b/client/ayon_core/tests/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/client/ayon_core/tests/lib.py b/client/ayon_core/tests/lib.py deleted file mode 100644 index c7d4423aba..0000000000 --- a/client/ayon_core/tests/lib.py +++ /dev/null @@ -1,88 +0,0 @@ -import os -import sys -import shutil -import tempfile -import contextlib - -import pyblish -import pyblish.plugin -from pyblish.vendor import six - - -# Setup -HOST = 'python' -FAMILY = 'test.family' - -REGISTERED = pyblish.plugin.registered_paths() -PACKAGEPATH = pyblish.lib.main_package_path() -ENVIRONMENT = os.environ.get("PYBLISHPLUGINPATH", "") -PLUGINPATH = os.path.join(PACKAGEPATH, '..', 'tests', 'plugins') - - -def setup(): - pyblish.plugin.deregister_all_paths() - - -def setup_empty(): - """Disable all plug-ins""" - setup() - pyblish.plugin.deregister_all_plugins() - pyblish.plugin.deregister_all_paths() - pyblish.plugin.deregister_all_hosts() - pyblish.plugin.deregister_all_callbacks() - pyblish.plugin.deregister_all_targets() - pyblish.api.deregister_all_discovery_filters() - - -def teardown(): - """Restore previously REGISTERED paths""" - - pyblish.plugin.deregister_all_paths() - for path in REGISTERED: - pyblish.plugin.register_plugin_path(path) - - os.environ["PYBLISHPLUGINPATH"] = ENVIRONMENT - pyblish.api.deregister_all_plugins() - pyblish.api.deregister_all_hosts() - pyblish.api.deregister_all_discovery_filters() - pyblish.api.deregister_test() - pyblish.api.__init__() - - -@contextlib.contextmanager -def captured_stdout(): - """Temporarily reassign stdout to a local variable""" - try: - sys.stdout = six.StringIO() - yield sys.stdout - finally: - sys.stdout = sys.__stdout__ - - -@contextlib.contextmanager -def captured_stderr(): - """Temporarily reassign stderr to a local variable""" - try: - sys.stderr = six.StringIO() - yield sys.stderr - finally: - sys.stderr = sys.__stderr__ - - -@contextlib.contextmanager -def tempdir(): - """Provide path to temporary directory""" - try: - tempdir = tempfile.mkdtemp() - yield tempdir - finally: - shutil.rmtree(tempdir) - - -def is_in_tests(): - """Returns if process is running in automatic tests mode. - - In tests mode different source DB is used, some plugins might be disabled - etc. - """ - return os.environ.get("IS_TEST") == '1' diff --git a/client/ayon_core/tests/mongo_performance.py b/client/ayon_core/tests/mongo_performance.py deleted file mode 100644 index 2df3363f4b..0000000000 --- a/client/ayon_core/tests/mongo_performance.py +++ /dev/null @@ -1,288 +0,0 @@ -import pymongo -import bson -import random -from datetime import datetime -import os - - -class TestPerformance(): - ''' - Class for testing performance of representation and their 'files' - parts. - Discussion is if embedded array: - 'files' : [ {'_id': '1111', 'path':'....}, - {'_id'...}] - OR documents: - 'files' : { - '1111': {'path':'....'}, - '2222': {'path':'...'} - } - is faster. - - Current results: - without additional partial index documents is 3x faster - With index is array 50x faster then document - - Partial index something like: - db.getCollection('performance_test').createIndex - ({'files._id': 1}, - {partialFilterExpresion: {'files': {'$exists': true}}}) - !DIDNT work for me, had to create manually in Compass - - ''' - - MONGO_URL = 'mongodb://localhost:27017' - MONGO_DB = 'performance_test' - MONGO_COLLECTION = 'performance_test' - - MAX_FILE_SIZE_B = 5000 - MAX_NUMBER_OF_SITES = 50 - ROOT_DIR = "C:/projects" - - inserted_ids = [] - - def __init__(self, version='array'): - ''' - It creates and fills collection, based on value of 'version'. - - :param version: 'array' - files as embedded array, - 'doc' - as document - ''' - self.client = pymongo.MongoClient(self.MONGO_URL) - self.db = self.client[self.MONGO_DB] - self.collection_name = self.MONGO_COLLECTION - - self.version = version - - if self.version != 'array': - self.collection_name = self.MONGO_COLLECTION + '_doc' - - self.collection = self.db[self.collection_name] - - self.ids = [] # for testing - self.inserted_ids = [] - - def prepare(self, no_of_records=100000, create_files=False): - ''' - Produce 'no_of_records' of representations with 'files' segment. - It depends on 'version' value in constructor, 'arrray' or 'doc' - :return: - ''' - print('Purging {} collection'.format(self.collection_name)) - self.collection.delete_many({}) - - id = bson.objectid.ObjectId() - - insert_recs = [] - for i in range(no_of_records): - file_id = bson.objectid.ObjectId() - file_id2 = bson.objectid.ObjectId() - file_id3 = bson.objectid.ObjectId() - - self.inserted_ids.extend([file_id, file_id2, file_id3]) - version_str = "v{:03d}".format(i + 1) - file_name = "test_Cylinder_workfileLookdev_{}.mb".\ - format(version_str) - - document = {"files": self.get_files(self.version, i + 1, - file_id, file_id2, file_id3, - create_files) - , - "context": { - "subset": "workfileLookdev", - "username": "petrk", - "task": "lookdev", - "family": "workfile", - "hierarchy": "Assets", - "project": {"code": "test", "name": "Test"}, - "version": i + 1, - "asset": "Cylinder", - "representation": "mb", - "root": self.ROOT_DIR - }, - "dependencies": [], - "name": "mb", - "parent": {"oid": '{}'.format(id)}, - "data": { - "path": "C:\\projects\\test_performance\\Assets\\Cylinder\\publish\\workfile\\workfileLookdev\\{}\\{}".format(version_str, file_name), # noqa: E501 - "template": "{root[work]}\\{project[name]}\\{hierarchy}\\{asset}\\publish\\{family}\\{subset}\\v{version:0>3}\\{project[code]}_{asset}_{subset}_v{version:0>3}<_{output}><.{frame:0>4}>.{representation}" # noqa: E501 - }, - "type": "representation", - "schema": "openpype:representation-2.0" - } - - insert_recs.append(document) - - print('Prepared {} records in {} collection'. - format(no_of_records, self.collection_name)) - - self.collection.insert_many(insert_recs) - # TODO refactore to produce real array and not needeing ugly regex - self.collection.insert_one({"inserted_id": self.inserted_ids}) - print('-' * 50) - - def run(self, queries=1000, loops=3): - ''' - Run X'queries' that are searching collection Y'loops' times - :param queries: how many times do ..find(...) - :param loops: loop of testing X queries - :return: None - ''' - print('Testing version {} on {}'.format(self.version, - self.collection_name)) - print('Queries rung {} in {} loops'.format(queries, loops)) - - inserted_ids = list(self.collection. - find({"inserted_id": {"$exists": True}})) - import re - self.ids = re.findall("'[0-9a-z]*'", str(inserted_ids)) - - import time - - found_cnt = 0 - for _ in range(loops): - print('Starting loop {}'.format(_)) - start = time.time() - for _ in range(queries): - # val = random.choice(self.ids) - # val = val.replace("'", '') - val = random.randint(0, 50) - print(val) - - if (self.version == 'array'): - # prepared for partial index, without 'files': exists - # wont engage - found = self.collection.\ - find({'files': {"$exists": True}, - 'files.sites.name': "local_{}".format(val)}).\ - count() - else: - key = "files.{}".format(val) - found = self.collection.find_one({key: {"$exists": True}}) - print("found {} records".format(found)) - # if found: - # found_cnt += len(list(found)) - - end = time.time() - print('duration per loop {}'.format(end - start)) - print("found_cnt {}".format(found_cnt)) - - def get_files(self, mode, i, file_id, file_id2, file_id3, - create_files=False): - ''' - Wrapper to decide if 'array' or document version should be used - :param mode: 'array'|'doc' - :param i: step number - :param file_id: ObjectId of first dummy file - :param file_id2: .. - :param file_id3: .. - :return: - ''' - if mode == 'array': - return self.get_files_array(i, file_id, file_id2, file_id3, - create_files) - else: - return self.get_files_doc(i, file_id, file_id2, file_id3) - - def get_files_array(self, i, file_id, file_id2, file_id3, - create_files=False): - ret = [ - { - "path": "{root[work]}" + "{root[work]}/test_performance/Assets/Cylinder/publish/workfile/workfileLookdev/v{:03d}/test_Cylinder_A_workfileLookdev_v{:03d}.dat".format(i, i), # noqa: E501 - "_id": '{}'.format(file_id), - "hash": "temphash", - "sites": self.get_sites(self.MAX_NUMBER_OF_SITES), - "size": random.randint(0, self.MAX_FILE_SIZE_B) - }, - { - "path": "{root[work]}" + "/test_performance/Assets/Cylinder/publish/workfile/workfileLookdev/v{:03d}/test_Cylinder_B_workfileLookdev_v{:03d}.dat".format(i, i), # noqa: E501 - "_id": '{}'.format(file_id2), - "hash": "temphash", - "sites": self.get_sites(self.MAX_NUMBER_OF_SITES), - "size": random.randint(0, self.MAX_FILE_SIZE_B) - }, - { - "path": "{root[work]}" + "/test_performance/Assets/Cylinder/publish/workfile/workfileLookdev/v{:03d}/test_Cylinder_C_workfileLookdev_v{:03d}.dat".format(i, i), # noqa: E501 - "_id": '{}'.format(file_id3), - "hash": "temphash", - "sites": self.get_sites(self.MAX_NUMBER_OF_SITES), - "size": random.randint(0, self.MAX_FILE_SIZE_B) - } - - ] - if create_files: - for f in ret: - path = f.get("path").replace("{root[work]}", self.ROOT_DIR) - os.makedirs(os.path.dirname(path), exist_ok=True) - with open(path, 'wb') as fp: - fp.write(os.urandom(f.get("size"))) - - return ret - - def get_files_doc(self, i, file_id, file_id2, file_id3): - ret = {} - ret['{}'.format(file_id)] = { - "path": "{root[work]}" + - "/test_performance/Assets/Cylinder/publish/workfile/workfileLookdev/" # noqa: E501 - "v{:03d}/test_CylinderA_workfileLookdev_v{:03d}.mb".format(i, i), # noqa: E501 - "hash": "temphash", - "sites": ["studio"], - "size": 87236 - } - - ret['{}'.format(file_id2)] = { - "path": "{root[work]}" + - "/test_performance/Assets/Cylinder/publish/workfile/workfileLookdev/" # noqa: E501 - "v{:03d}/test_CylinderB_workfileLookdev_v{:03d}.mb".format(i, i), # noqa: E501 - "hash": "temphash", - "sites": ["studio"], - "size": 87236 - } - ret['{}'.format(file_id3)] = { - "path": "{root[work]}" + - "/test_performance/Assets/Cylinder/publish/workfile/workfileLookdev/" # noqa: E501 - "v{:03d}/test_CylinderC_workfileLookdev_v{:03d}.mb".format(i, i), # noqa: E501 - "hash": "temphash", - "sites": ["studio"], - "size": 87236 - } - - return ret - - def get_sites(self, number_of_sites=50): - """ - Return array of sites declaration. - Currently on 1st site has "created_dt" fillled, which should - trigger upload to 'gdrive' site. - 'gdrive' site is appended, its destination for syncing for - Sync Server - Args: - number_of_sites: - - Returns: - - """ - sites = [] - for i in range(number_of_sites): - site = {'name': "local_{}".format(i)} - # do not create null 'created_dt' field, Mongo doesnt like it - if i == 0: - site['created_dt'] = datetime.now() - - sites.append(site) - - sites.append({'name': "gdrive"}) - - return sites - - -if __name__ == '__main__': - tp = TestPerformance('array') - tp.prepare(no_of_records=10000, create_files=True) - # tp.run(10, 3) - - # print('-'*50) - # - # tp = TestPerformance('doc') - # tp.prepare() # enable to prepare data - # tp.run(1000, 3) diff --git a/client/ayon_core/tests/test_avalon_plugin_presets.py b/client/ayon_core/tests/test_avalon_plugin_presets.py deleted file mode 100644 index 4926286ca3..0000000000 --- a/client/ayon_core/tests/test_avalon_plugin_presets.py +++ /dev/null @@ -1,43 +0,0 @@ -from ayon_core.pipeline import ( - install_host, - LegacyCreator, - register_creator_plugin, - discover_creator_plugins, -) - - -class MyTestCreator(LegacyCreator): - - my_test_property = "A" - - def __init__(self, name, asset, options=None, data=None): - super(MyTestCreator, self).__init__(self, name, asset, - options=None, data=None) - - -# this is hack like no other - we need to inject our own avalon host -# and bypass all its validation. Avalon hosts are modules that needs -# `ls` callable as attribute. Voila: -class Test: - __name__ = "test" - ls = len - - @staticmethod - def install(): - register_creator_plugin(MyTestCreator) - - -def test_avalon_plugin_presets(monkeypatch, printer): - install_host(Test) - - plugins = discover_creator_plugins() - printer("Test if we got our test plugin") - assert MyTestCreator in plugins - for p in plugins: - if p.__name__ == "MyTestCreator": - printer("Test if we have overridden existing property") - assert p.my_test_property == "B" - printer("Test if we have overridden superclass property") - assert p.active is False - printer("Test if we have added new property") - assert p.new_property == "new" diff --git a/client/ayon_core/tests/test_lib_restructuralization.py b/client/ayon_core/tests/test_lib_restructuralization.py deleted file mode 100644 index ffbd62b045..0000000000 --- a/client/ayon_core/tests/test_lib_restructuralization.py +++ /dev/null @@ -1,25 +0,0 @@ -# Test for backward compatibility of restructure of lib.py into lib library -# Contains simple imports that should still work - - -def test_backward_compatibility(printer): - printer("Test if imports still work") - try: - from ayon_core.lib import execute_hook - from ayon_core.lib import PypeHook - - from ayon_core.lib import ApplicationLaunchFailed - - from ayon_core.lib import get_ffmpeg_tool_path - from ayon_core.lib import get_last_version_from_path - from ayon_core.lib import get_paths_from_environ - from ayon_core.lib import get_version_from_path - from ayon_core.lib import version_up - - from ayon_core.lib import get_ffprobe_streams - - from ayon_core.lib import source_hash - from ayon_core.lib import run_subprocess - - except ImportError as e: - raise diff --git a/client/ayon_core/tests/test_pyblish_filter.py b/client/ayon_core/tests/test_pyblish_filter.py deleted file mode 100644 index bc20f863c9..0000000000 --- a/client/ayon_core/tests/test_pyblish_filter.py +++ /dev/null @@ -1,60 +0,0 @@ -import os -import pyblish.api -import pyblish.util -import pyblish.plugin -from ayon_core.pipeline.publish.lib import filter_pyblish_plugins -from . import lib - - -def test_pyblish_plugin_filter_modifier(printer, monkeypatch): - """ - Test if pyblish filter can filter and modify plugins on-the-fly. - """ - - lib.setup_empty() - monkeypatch.setitem(os.environ, 'PYBLISHPLUGINPATH', '') - plugins = pyblish.api.registered_plugins() - printer("Test if we have no registered plugins") - assert len(plugins) == 0 - paths = pyblish.api.registered_paths() - printer("Test if we have no registered plugin paths") - assert len(paths) == 0 - - class MyTestPlugin(pyblish.api.InstancePlugin): - my_test_property = 1 - label = "Collect Renderable Camera(s)" - hosts = ["test"] - families = ["default"] - - pyblish.api.register_host("test") - pyblish.api.register_plugin(MyTestPlugin) - pyblish.api.register_discovery_filter(filter_pyblish_plugins) - plugins = pyblish.api.discover() - - printer("Test if only one plugin was discovered") - assert len(plugins) == 1 - printer("Test if properties are modified correctly") - assert plugins[0].label == "loaded from preset" - assert plugins[0].families == ["changed", "by", "preset"] - assert plugins[0].optional is True - - lib.teardown() - - -def test_pyblish_plugin_filter_removal(monkeypatch): - """ Test that plugin can be removed by filter """ - lib.setup_empty() - monkeypatch.setitem(os.environ, 'PYBLISHPLUGINPATH', '') - plugins = pyblish.api.registered_plugins() - - class MyTestRemovedPlugin(pyblish.api.InstancePlugin): - my_test_property = 1 - label = "Collect Renderable Camera(s)" - hosts = ["test"] - families = ["default"] - - pyblish.api.register_host("test") - pyblish.api.register_plugin(MyTestRemovedPlugin) - pyblish.api.register_discovery_filter(filter_pyblish_plugins) - plugins = pyblish.api.discover() - assert len(plugins) == 0 From 531ce4e695808b371373ead6b924fa64db904117 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Mon, 12 Feb 2024 15:26:14 +0100 Subject: [PATCH 076/185] removed mongo dependencies from client --- client/pyproject.toml | 2 -- 1 file changed, 2 deletions(-) diff --git a/client/pyproject.toml b/client/pyproject.toml index c21ca305a7..7b4329a31a 100644 --- a/client/pyproject.toml +++ b/client/pyproject.toml @@ -10,8 +10,6 @@ wsrpc_aiohttp = "^3.1.1" # websocket server Click = "^8" clique = "1.6.*" jsonschema = "^2.6.0" -pymongo = "^3.11.2" -log4mongo = "^1.7" pyblish-base = "^1.8.11" pynput = "^1.7.2" # Timers manager - TODO remove speedcopy = "^2.1" From 5edf44903cd214d156833af6630a417c19a7ec81 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Mon, 12 Feb 2024 16:13:17 +0100 Subject: [PATCH 077/185] use AYON prefix in context environment variables --- client/ayon_core/cli_commands.py | 14 +++++- .../hooks/pre_create_extra_workdir_folders.py | 2 +- client/ayon_core/host/host.py | 6 +-- client/ayon_core/host/interfaces.py | 2 +- .../hosts/aftereffects/api/launch_logic.py | 6 +-- .../ayon_core/hosts/blender/api/pipeline.py | 6 +-- client/ayon_core/hosts/blender/api/workio.py | 2 +- client/ayon_core/hosts/flame/api/workio.py | 2 +- .../hosts/flame/plugins/load/load_clip.py | 2 +- .../flame/plugins/load/load_clip_batch.py | 2 +- client/ayon_core/hosts/fusion/addon.py | 2 +- client/ayon_core/hosts/fusion/api/pipeline.py | 2 +- client/ayon_core/hosts/fusion/api/plugin.py | 2 +- .../fusion/hooks/pre_fusion_profile_hook.py | 2 +- .../hosts/fusion/hooks/pre_fusion_setup.py | 2 +- client/ayon_core/hosts/harmony/api/workio.py | 2 +- .../publish/validate_scene_settings.py | 2 +- client/ayon_core/hosts/hiero/api/workio.py | 2 +- .../hosts/houdini/hooks/set_paths.py | 2 +- client/ayon_core/hosts/max/hooks/set_paths.py | 2 +- client/ayon_core/hosts/maya/api/pipeline.py | 6 +-- .../maya/api/shader_definition_editor.py | 2 +- client/ayon_core/hosts/maya/api/workio.py | 2 +- .../hosts/maya/hooks/pre_copy_mel.py | 2 +- .../maya/plugins/publish/collect_render.py | 2 +- .../ayon_core/hosts/maya/startup/userSetup.py | 2 +- client/ayon_core/hosts/nuke/api/lib.py | 8 ++-- client/ayon_core/hosts/nuke/api/workio.py | 2 +- .../hosts/nuke/startup/custom_write_node.py | 2 +- .../ayon_core/hosts/photoshop/api/pipeline.py | 2 +- .../plugins/publish/collect_batch_data.py | 8 ++-- client/ayon_core/hosts/resolve/api/workio.py | 4 +- .../hosts/traypublisher/api/pipeline.py | 4 +- .../plugins/create/create_from_settings.py | 2 +- .../ayon_core/hosts/tvpaint/api/pipeline.py | 6 +-- .../plugins/publish/collect_workfile_data.py | 4 +- .../publish/validate_workfile_project_name.py | 2 +- .../ayon_core/hosts/unreal/api/rendering.py | 2 +- .../unreal/hooks/pre_workfile_preparation.py | 2 +- client/ayon_core/lib/applications.py | 14 +++--- client/ayon_core/lib/log.py | 2 +- .../launcher_actions/ClockifyStart.py | 8 ++-- .../clockify/launcher_actions/ClockifySync.py | 2 +- .../publish/submit_aftereffects_deadline.py | 10 ++-- .../publish/submit_blender_deadline.py | 10 ++-- .../plugins/publish/submit_fusion_deadline.py | 10 ++-- .../publish/submit_harmony_deadline.py | 10 ++-- .../publish/submit_houdini_cache_deadline.py | 10 ++-- .../publish/submit_houdini_render_deadline.py | 10 ++-- .../plugins/publish/submit_max_deadline.py | 10 ++-- .../plugins/publish/submit_maya_deadline.py | 10 ++-- .../submit_maya_remote_publish_deadline.py | 8 ++-- .../plugins/publish/submit_nuke_deadline.py | 8 ++-- .../publish/submit_publish_cache_job.py | 8 ++-- .../plugins/publish/submit_publish_job.py | 8 ++-- .../custom/plugins/GlobalJobPreLoad.py | 21 +++++--- client/ayon_core/modules/royalrender/lib.py | 4 +- .../publish/create_publish_royalrender_job.py | 8 ++-- .../perjob/m50__openpype_publish_render.py | 24 ++++++---- client/ayon_core/pipeline/actions.py | 2 +- client/ayon_core/pipeline/anatomy.py | 2 +- client/ayon_core/pipeline/context_tools.py | 48 +++++++++---------- client/ayon_core/pipeline/create/context.py | 2 +- .../pipeline/create/legacy_create.py | 2 +- .../ayon_core/pipeline/create/subset_name.py | 4 +- .../pipeline/farm/pyblish_functions.py | 6 +-- client/ayon_core/pipeline/load/plugins.py | 2 +- client/ayon_core/pipeline/publish/lib.py | 2 +- .../pipeline/workfile/build_workfile.py | 4 +- .../pipeline/workfile/path_resolving.py | 2 +- .../workfile/workfile_template_builder.py | 10 ++-- .../plugins/actions/open_file_explorer.py | 8 ++-- .../plugins/load/delete_old_versions.py | 2 +- .../publish/collect_anatomy_context_data.py | 2 +- .../publish/collect_context_entities.py | 1 - .../publish/collect_from_create_context.py | 6 +-- .../plugins/publish/collect_host_name.py | 8 ++-- .../plugins/publish/collect_rendered_files.py | 6 +-- .../scripts/non_python_host_launch.py | 4 +- client/ayon_core/settings/lib.py | 6 +-- .../tools/experimental_tools/tools_def.py | 2 +- .../tools/launcher/models/actions.py | 18 ++++--- client/ayon_core/tools/publisher/control.py | 4 +- client/ayon_core/tools/texture_copy/app.py | 4 +- .../tools/workfile_template_build/window.py | 2 +- 85 files changed, 257 insertions(+), 225 deletions(-) diff --git a/client/ayon_core/cli_commands.py b/client/ayon_core/cli_commands.py index c07b72afdf..31429c488b 100644 --- a/client/ayon_core/cli_commands.py +++ b/client/ayon_core/cli_commands.py @@ -73,6 +73,18 @@ class Commands: import pyblish.api import pyblish.util + # Fix older jobs + for src_key, dst_key in ( + ("AVALON_PROJECT", "AYON_PROJECT_NAME"), + ("AVALON_ASSET", "AYON_FOLDER_PATH"), + ("AVALON_TASK", "AYON_TASK_NAME"), + ("AVALON_WORKDIR", "AYON_WORKDIR"), + ("AVALON_APP_NAME", "AYON_APP_NAME"), + ("AVALON_APP", "AYON_HOST_NAME"), + ): + if src_key in os.environ and dst_key not in os.environ: + os.environ[dst_key] = os.environ[src_key] + log = Logger.get_logger("CLI-publish") install_ayon_plugins() @@ -87,7 +99,7 @@ class Commands: if not any(paths): raise RuntimeError("No publish paths specified") - app_full_name = os.getenv("AVALON_APP_NAME") + app_full_name = os.getenv("AYON_APP_NAME") if app_full_name: context = get_global_context() env = get_app_environments_for_context( diff --git a/client/ayon_core/hooks/pre_create_extra_workdir_folders.py b/client/ayon_core/hooks/pre_create_extra_workdir_folders.py index 6116d5fbd3..72c6bf2f68 100644 --- a/client/ayon_core/hooks/pre_create_extra_workdir_folders.py +++ b/client/ayon_core/hooks/pre_create_extra_workdir_folders.py @@ -21,7 +21,7 @@ class CreateWorkdirExtraFolders(PreLaunchHook): return env = self.data.get("env") or {} - workdir = env.get("AVALON_WORKDIR") + workdir = env.get("AYON_WORKDIR") if not workdir or not os.path.exists(workdir): return diff --git a/client/ayon_core/host/host.py b/client/ayon_core/host/host.py index 2dd98c8126..51dff9d558 100644 --- a/client/ayon_core/host/host.py +++ b/client/ayon_core/host/host.py @@ -106,7 +106,7 @@ class HostBase(object): Union[str, None]: Current project name. """ - return os.environ.get("AVALON_PROJECT") + return os.environ.get("AYON_PROJECT_NAME") def get_current_asset_name(self): """ @@ -114,7 +114,7 @@ class HostBase(object): Union[str, None]: Current asset name. """ - return os.environ.get("AVALON_ASSET") + return os.environ.get("AYON_FOLDER_PATH") def get_current_task_name(self): """ @@ -122,7 +122,7 @@ class HostBase(object): Union[str, None]: Current task name. """ - return os.environ.get("AVALON_TASK") + return os.environ.get("AYON_TASK_NAME") def get_current_context(self): """Get current context information. diff --git a/client/ayon_core/host/interfaces.py b/client/ayon_core/host/interfaces.py index 7c6057acf0..7157ad6f7e 100644 --- a/client/ayon_core/host/interfaces.py +++ b/client/ayon_core/host/interfaces.py @@ -234,7 +234,7 @@ class IWorkfileHost: str: Path to new workdir. """ - return session["AVALON_WORKDIR"] + return session["AYON_WORKDIR"] # --- Deprecated method names --- def file_extensions(self): diff --git a/client/ayon_core/hosts/aftereffects/api/launch_logic.py b/client/ayon_core/hosts/aftereffects/api/launch_logic.py index 3d09f4d53c..8c54908fe5 100644 --- a/client/ayon_core/hosts/aftereffects/api/launch_logic.py +++ b/client/ayon_core/hosts/aftereffects/api/launch_logic.py @@ -298,11 +298,11 @@ class AfterEffectsRoute(WebSocketRoute): log.info("Setting context change") log.info("project {} asset {} ".format(project, asset)) if project: - os.environ["AVALON_PROJECT"] = project + os.environ["AYON_PROJECT_NAME"] = project if asset: - os.environ["AVALON_ASSET"] = asset + os.environ["AYON_FOLDER_PATH"] = asset if task: - os.environ["AVALON_TASK"] = task + os.environ["AYON_TASK_NAME"] = task async def read(self): log.debug("aftereffects.read client calls server server calls " diff --git a/client/ayon_core/hosts/blender/api/pipeline.py b/client/ayon_core/hosts/blender/api/pipeline.py index 77731a0fd3..a49afeea6b 100644 --- a/client/ayon_core/hosts/blender/api/pipeline.py +++ b/client/ayon_core/hosts/blender/api/pipeline.py @@ -272,7 +272,7 @@ def set_resolution(data): def on_new(): - project = os.environ.get("AVALON_PROJECT") + project = os.environ.get("AYON_PROJECT_NAME") settings = get_project_settings(project).get("blender") set_resolution_startup = settings.get("set_resolution_startup") @@ -293,7 +293,7 @@ def on_new(): def on_open(): - project = os.environ.get("AVALON_PROJECT") + project = os.environ.get("AYON_PROJECT_NAME") settings = get_project_settings(project).get("blender") set_resolution_startup = settings.get("set_resolution_startup") @@ -379,7 +379,7 @@ def _on_task_changed(): # `directory` attribute, so it opens in that directory (does it?). # https://docs.blender.org/api/blender2.8/bpy.types.Operator.html#calling-a-file-selector # https://docs.blender.org/api/blender2.8/bpy.types.WindowManager.html#bpy.types.WindowManager.fileselect_add - workdir = os.getenv("AVALON_WORKDIR") + workdir = os.getenv("AYON_WORKDIR") log.debug("New working directory: %s", workdir) diff --git a/client/ayon_core/hosts/blender/api/workio.py b/client/ayon_core/hosts/blender/api/workio.py index a8f6193abc..e0f333843a 100644 --- a/client/ayon_core/hosts/blender/api/workio.py +++ b/client/ayon_core/hosts/blender/api/workio.py @@ -82,7 +82,7 @@ def file_extensions() -> List[str]: def work_root(session: dict) -> str: """Return the default root to browse for work files.""" - work_dir = session["AVALON_WORKDIR"] + work_dir = session["AYON_WORKDIR"] scene_dir = session.get("AVALON_SCENEDIR") if scene_dir: return str(Path(work_dir, scene_dir)) diff --git a/client/ayon_core/hosts/flame/api/workio.py b/client/ayon_core/hosts/flame/api/workio.py index 0e3cb7f5fd..eef10a4847 100644 --- a/client/ayon_core/hosts/flame/api/workio.py +++ b/client/ayon_core/hosts/flame/api/workio.py @@ -34,4 +34,4 @@ def current_file(): def work_root(session): - return os.path.normpath(session["AVALON_WORKDIR"]).replace("\\", "/") + return os.path.normpath(session["AYON_WORKDIR"]).replace("\\", "/") diff --git a/client/ayon_core/hosts/flame/plugins/load/load_clip.py b/client/ayon_core/hosts/flame/plugins/load/load_clip.py index 6f35196932..47d0331255 100644 --- a/client/ayon_core/hosts/flame/plugins/load/load_clip.py +++ b/client/ayon_core/hosts/flame/plugins/load/load_clip.py @@ -70,7 +70,7 @@ class LoadClip(opfapi.ClipLoader): self.log.info("Loading with colorspace: `{}`".format(colorspace)) # create workfile path - workfile_dir = os.environ["AVALON_WORKDIR"] + workfile_dir = os.environ["AYON_WORKDIR"] openclip_dir = os.path.join( workfile_dir, clip_name ) diff --git a/client/ayon_core/hosts/flame/plugins/load/load_clip_batch.py b/client/ayon_core/hosts/flame/plugins/load/load_clip_batch.py index a66bf53622..46ed9ef58b 100644 --- a/client/ayon_core/hosts/flame/plugins/load/load_clip_batch.py +++ b/client/ayon_core/hosts/flame/plugins/load/load_clip_batch.py @@ -69,7 +69,7 @@ class LoadClipBatch(opfapi.ClipLoader): self.log.info("Loading with colorspace: `{}`".format(colorspace)) # create workfile path - workfile_dir = options.get("workdir") or os.environ["AVALON_WORKDIR"] + workfile_dir = options.get("workdir") or os.environ["AYON_WORKDIR"] openclip_dir = os.path.join( workfile_dir, clip_name ) diff --git a/client/ayon_core/hosts/fusion/addon.py b/client/ayon_core/hosts/fusion/addon.py index 391ee770c4..54e48ea7bf 100644 --- a/client/ayon_core/hosts/fusion/addon.py +++ b/client/ayon_core/hosts/fusion/addon.py @@ -22,7 +22,7 @@ def get_fusion_version(app_name): The function is triggered by the prelaunch hooks to get the fusion version. `app_name` is obtained by prelaunch hooks from the - `launch_context.env.get("AVALON_APP_NAME")`. + `launch_context.env.get("AYON_APP_NAME")`. To get a correct Fusion version, a version number should be present in the `applications/fusion/variants` key diff --git a/client/ayon_core/hosts/fusion/api/pipeline.py b/client/ayon_core/hosts/fusion/api/pipeline.py index 7c480704a5..0e9e0724c7 100644 --- a/client/ayon_core/hosts/fusion/api/pipeline.py +++ b/client/ayon_core/hosts/fusion/api/pipeline.py @@ -135,7 +135,7 @@ class FusionHost(HostBase, IWorkfileHost, ILoadHost, IPublishHost): return current_filepath def work_root(self, session): - work_dir = session["AVALON_WORKDIR"] + work_dir = session["AYON_WORKDIR"] scene_dir = session.get("AVALON_SCENEDIR") if scene_dir: return os.path.join(work_dir, scene_dir) diff --git a/client/ayon_core/hosts/fusion/api/plugin.py b/client/ayon_core/hosts/fusion/api/plugin.py index 80e194ea68..0d9409b4f5 100644 --- a/client/ayon_core/hosts/fusion/api/plugin.py +++ b/client/ayon_core/hosts/fusion/api/plugin.py @@ -135,7 +135,7 @@ class GenericCreateSaver(Creator): ext = data["creator_attributes"]["image_format"] # Subset change detected - workdir = os.path.normpath(os.getenv("AVALON_WORKDIR")) + workdir = os.path.normpath(os.getenv("AYON_WORKDIR")) formatting_data.update({ "workdir": workdir, "frame": "0" * frame_padding, diff --git a/client/ayon_core/hosts/fusion/hooks/pre_fusion_profile_hook.py b/client/ayon_core/hosts/fusion/hooks/pre_fusion_profile_hook.py index f63aaa1eb4..5aa2783129 100644 --- a/client/ayon_core/hosts/fusion/hooks/pre_fusion_profile_hook.py +++ b/client/ayon_core/hosts/fusion/hooks/pre_fusion_profile_hook.py @@ -131,7 +131,7 @@ class FusionCopyPrefsPrelaunch(PreLaunchHook): ) = self.get_copy_fusion_prefs_settings() # Get launched application context and return correct app version - app_name = self.launch_context.env.get("AVALON_APP_NAME") + app_name = self.launch_context.env.get("AYON_APP_NAME") app_version = get_fusion_version(app_name) if app_version is None: version_names = ", ".join(str(x) for x in FUSION_VERSIONS_DICT) diff --git a/client/ayon_core/hosts/fusion/hooks/pre_fusion_setup.py b/client/ayon_core/hosts/fusion/hooks/pre_fusion_setup.py index 7cfa9d0a26..7eaf2ddc02 100644 --- a/client/ayon_core/hosts/fusion/hooks/pre_fusion_setup.py +++ b/client/ayon_core/hosts/fusion/hooks/pre_fusion_setup.py @@ -28,7 +28,7 @@ class FusionPrelaunch(PreLaunchHook): def execute(self): # making sure python 3 is installed at provided path # Py 3.3-3.10 for Fusion 18+ or Py 3.6 for Fu 16-17 - app_data = self.launch_context.env.get("AVALON_APP_NAME") + app_data = self.launch_context.env.get("AYON_APP_NAME") app_version = get_fusion_version(app_data) if not app_version: raise ApplicationLaunchFailed( diff --git a/client/ayon_core/hosts/harmony/api/workio.py b/client/ayon_core/hosts/harmony/api/workio.py index 8df5ede917..1f95148e75 100644 --- a/client/ayon_core/hosts/harmony/api/workio.py +++ b/client/ayon_core/hosts/harmony/api/workio.py @@ -74,4 +74,4 @@ def current_file(): def work_root(session): - return os.path.normpath(session["AVALON_WORKDIR"]).replace("\\", "/") + return os.path.normpath(session["AYON_WORKDIR"]).replace("\\", "/") diff --git a/client/ayon_core/hosts/harmony/plugins/publish/validate_scene_settings.py b/client/ayon_core/hosts/harmony/plugins/publish/validate_scene_settings.py index 0cf96e70b0..6d46fbcd33 100644 --- a/client/ayon_core/hosts/harmony/plugins/publish/validate_scene_settings.py +++ b/client/ayon_core/hosts/harmony/plugins/publish/validate_scene_settings.py @@ -77,7 +77,7 @@ class ValidateSceneSettings(pyblish.api.InstancePlugin): expected_settings.pop("resolutionWidth") expected_settings.pop("resolutionHeight") - if (any(re.search(pattern, os.getenv('AVALON_TASK')) + if (any(re.search(pattern, os.getenv('AYON_TASK_NAME')) for pattern in self.skip_timelines_check)): self.log.info("Skipping frames check because of " "task name and pattern {}".format( diff --git a/client/ayon_core/hosts/hiero/api/workio.py b/client/ayon_core/hosts/hiero/api/workio.py index 14d9439344..4c2416ca38 100644 --- a/client/ayon_core/hosts/hiero/api/workio.py +++ b/client/ayon_core/hosts/hiero/api/workio.py @@ -70,4 +70,4 @@ def current_file(): def work_root(session): - return os.path.normpath(session["AVALON_WORKDIR"]).replace("\\", "/") + return os.path.normpath(session["AYON_WORKDIR"]).replace("\\", "/") diff --git a/client/ayon_core/hosts/houdini/hooks/set_paths.py b/client/ayon_core/hosts/houdini/hooks/set_paths.py index 1f24a8dd7d..7eb346cc74 100644 --- a/client/ayon_core/hosts/houdini/hooks/set_paths.py +++ b/client/ayon_core/hosts/houdini/hooks/set_paths.py @@ -10,7 +10,7 @@ class SetPath(PreLaunchHook): launch_types = {LaunchTypes.local} def execute(self): - workdir = self.launch_context.env.get("AVALON_WORKDIR", "") + workdir = self.launch_context.env.get("AYON_WORKDIR", "") if not workdir: self.log.warning("BUG: Workdir is not filled.") return diff --git a/client/ayon_core/hosts/max/hooks/set_paths.py b/client/ayon_core/hosts/max/hooks/set_paths.py index c18fd29295..0ee1b0dab7 100644 --- a/client/ayon_core/hosts/max/hooks/set_paths.py +++ b/client/ayon_core/hosts/max/hooks/set_paths.py @@ -10,7 +10,7 @@ class SetPath(PreLaunchHook): launch_types = {LaunchTypes.local} def execute(self): - workdir = self.launch_context.env.get("AVALON_WORKDIR", "") + workdir = self.launch_context.env.get("AYON_WORKDIR", "") if not workdir: self.log.warning("BUG: Workdir is not filled.") return diff --git a/client/ayon_core/hosts/maya/api/pipeline.py b/client/ayon_core/hosts/maya/api/pipeline.py index dc6353618a..e58316030e 100644 --- a/client/ayon_core/hosts/maya/api/pipeline.py +++ b/client/ayon_core/hosts/maya/api/pipeline.py @@ -246,7 +246,7 @@ def _set_project(): None """ - workdir = os.getenv("AVALON_WORKDIR") + workdir = os.getenv("AYON_WORKDIR") try: os.makedirs(workdir) @@ -628,7 +628,7 @@ def on_task_changed(): # Run menu.update_menu_task_label() - workdir = os.getenv("AVALON_WORKDIR") + workdir = os.getenv("AYON_WORKDIR") if os.path.exists(workdir): log.info("Updating Maya workspace for task change to %s", workdir) _set_project() @@ -677,7 +677,7 @@ def workfile_save_before_xgen(event): import xgenm - current_work_dir = os.getenv("AVALON_WORKDIR").replace("\\", "/") + current_work_dir = os.getenv("AYON_WORKDIR").replace("\\", "/") expected_work_dir = event.data["workdir_path"].replace("\\", "/") if current_work_dir == expected_work_dir: return diff --git a/client/ayon_core/hosts/maya/api/shader_definition_editor.py b/client/ayon_core/hosts/maya/api/shader_definition_editor.py index 04e8dded6f..bfa531eb87 100644 --- a/client/ayon_core/hosts/maya/api/shader_definition_editor.py +++ b/client/ayon_core/hosts/maya/api/shader_definition_editor.py @@ -12,7 +12,7 @@ import gridfs DEFINITION_FILENAME = "{}/maya/shader_definition.txt".format( - os.getenv("AVALON_PROJECT")) + os.getenv("AYON_PROJECT_NAME")) class ShaderDefinitionsEditor(QtWidgets.QWidget): diff --git a/client/ayon_core/hosts/maya/api/workio.py b/client/ayon_core/hosts/maya/api/workio.py index 8c31974c73..ff6c11eb4f 100644 --- a/client/ayon_core/hosts/maya/api/workio.py +++ b/client/ayon_core/hosts/maya/api/workio.py @@ -35,7 +35,7 @@ def current_file(): def work_root(session): - work_dir = session["AVALON_WORKDIR"] + work_dir = session["AYON_WORKDIR"] scene_dir = None # Query scene file rule from workspace.mel if it exists in WORKDIR diff --git a/client/ayon_core/hosts/maya/hooks/pre_copy_mel.py b/client/ayon_core/hosts/maya/hooks/pre_copy_mel.py index 7198f98131..03ca8661bd 100644 --- a/client/ayon_core/hosts/maya/hooks/pre_copy_mel.py +++ b/client/ayon_core/hosts/maya/hooks/pre_copy_mel.py @@ -12,7 +12,7 @@ class PreCopyMel(PreLaunchHook): def execute(self): project_doc = self.data["project_doc"] - workdir = self.launch_context.env.get("AVALON_WORKDIR") + workdir = self.launch_context.env.get("AYON_WORKDIR") if not workdir: self.log.warning("BUG: Workdir is not filled.") return diff --git a/client/ayon_core/hosts/maya/plugins/publish/collect_render.py b/client/ayon_core/hosts/maya/plugins/publish/collect_render.py index e4221a091c..7daab19f4a 100644 --- a/client/ayon_core/hosts/maya/plugins/publish/collect_render.py +++ b/client/ayon_core/hosts/maya/plugins/publish/collect_render.py @@ -13,7 +13,7 @@ Requires: context -> workspaceDir context -> user - session -> AVALON_ASSET + session -> AYON_FOLDER_PATH Optional: diff --git a/client/ayon_core/hosts/maya/startup/userSetup.py b/client/ayon_core/hosts/maya/startup/userSetup.py index 882f2df27c..22b776915c 100644 --- a/client/ayon_core/hosts/maya/startup/userSetup.py +++ b/client/ayon_core/hosts/maya/startup/userSetup.py @@ -38,7 +38,7 @@ if explicit_plugins_loading["enabled"]: key = "AYON_OPEN_WORKFILE_POST_INITIALIZATION" if bool(int(os.environ.get(key, "0"))): def _log_and_open(): - path = os.environ["AVALON_LAST_WORKFILE"] + path = os.environ["AYON_LAST_WORKFILE"] print("Opening \"{}\"".format(path)) cmds.file(path, open=True, force=True) cmds.evalDeferred( diff --git a/client/ayon_core/hosts/nuke/api/lib.py b/client/ayon_core/hosts/nuke/api/lib.py index 2ac33de68e..c320df9361 100644 --- a/client/ayon_core/hosts/nuke/api/lib.py +++ b/client/ayon_core/hosts/nuke/api/lib.py @@ -120,7 +120,7 @@ def deprecated(new_destination): class Context: main_window = None context_action_item = None - project_name = os.getenv("AVALON_PROJECT") + project_name = os.getenv("AYON_PROJECT_NAME") # Workfile related code workfiles_launched = False workfiles_tool_timer = None @@ -2605,7 +2605,7 @@ Reopening Nuke should synchronize these paths and resolve any discrepancies. def set_favorites(self): from .utils import set_context_favorites - work_dir = os.getenv("AVALON_WORKDIR") + work_dir = os.getenv("AYON_WORKDIR") asset = get_current_asset_name() favorite_items = OrderedDict() @@ -2953,7 +2953,7 @@ def process_workfile_builder(): create_fv_on = workfile_builder.get("create_first_version") or None builder_on = workfile_builder.get("builder_on_start") or None - last_workfile_path = os.environ.get("AVALON_LAST_WORKFILE") + last_workfile_path = os.environ.get("AYON_LAST_WORKFILE") # generate first version in file not existing and feature is enabled if create_fv_on and not os.path.exists(last_workfile_path): @@ -3203,7 +3203,7 @@ class DirmapCache: @classmethod def project_name(cls): if cls._project_name is None: - cls._project_name = os.getenv("AVALON_PROJECT") + cls._project_name = os.getenv("AYON_PROJECT_NAME") return cls._project_name @classmethod diff --git a/client/ayon_core/hosts/nuke/api/workio.py b/client/ayon_core/hosts/nuke/api/workio.py index 98e59eff71..b2445fd3d2 100644 --- a/client/ayon_core/hosts/nuke/api/workio.py +++ b/client/ayon_core/hosts/nuke/api/workio.py @@ -68,7 +68,7 @@ def current_file(): def work_root(session): - work_dir = session["AVALON_WORKDIR"] + work_dir = session["AYON_WORKDIR"] scene_dir = session.get("AVALON_SCENEDIR") if scene_dir: path = os.path.join(work_dir, scene_dir) diff --git a/client/ayon_core/hosts/nuke/startup/custom_write_node.py b/client/ayon_core/hosts/nuke/startup/custom_write_node.py index 01e255d0c0..89dfde297c 100644 --- a/client/ayon_core/hosts/nuke/startup/custom_write_node.py +++ b/client/ayon_core/hosts/nuke/startup/custom_write_node.py @@ -112,7 +112,7 @@ class WriteNodeKnobSettingPanel(nukescripts.PythonPanel): for write_node in write_selected_nodes: # data for mapping the path data = { - "work": os.getenv("AVALON_WORKDIR"), + "work": os.getenv("AYON_WORKDIR"), "subset": write_node["name"].value(), "frame": "#" * frame_padding, "ext": ext diff --git a/client/ayon_core/hosts/photoshop/api/pipeline.py b/client/ayon_core/hosts/photoshop/api/pipeline.py index 046ec8e6ee..ebde175053 100644 --- a/client/ayon_core/hosts/photoshop/api/pipeline.py +++ b/client/ayon_core/hosts/photoshop/api/pipeline.py @@ -62,7 +62,7 @@ class PhotoshopHost(HostBase, IWorkfileHost, ILoadHost, IPublishHost): return None def work_root(self, session): - return os.path.normpath(session["AVALON_WORKDIR"]).replace("\\", "/") + return os.path.normpath(session["AYON_WORKDIR"]).replace("\\", "/") def open_workfile(self, filepath): lib.stub().open(filepath) diff --git a/client/ayon_core/hosts/photoshop/plugins/publish/collect_batch_data.py b/client/ayon_core/hosts/photoshop/plugins/publish/collect_batch_data.py index 6639040bd7..0ed891c8cf 100644 --- a/client/ayon_core/hosts/photoshop/plugins/publish/collect_batch_data.py +++ b/client/ayon_core/hosts/photoshop/plugins/publish/collect_batch_data.py @@ -52,10 +52,10 @@ class CollectBatchData(pyblish.api.ContextPlugin): assert os.path.exists(batch_dir), \ "Folder {} doesn't exist".format(batch_dir) - project_name = os.environ.get("AVALON_PROJECT") + project_name = os.environ.get("AYON_PROJECT_NAME") if project_name is None: raise AssertionError( - "Environment `AVALON_PROJECT` was not found." + "Environment `AYON_PROJECT_NAME` was not found." "Could not set project `root` which may cause issues." ) @@ -68,8 +68,8 @@ class CollectBatchData(pyblish.api.ContextPlugin): batch_data["context"] ) - os.environ["AVALON_ASSET"] = asset_name - os.environ["AVALON_TASK"] = task_name + os.environ["AYON_FOLDER_PATH"] = asset_name + os.environ["AYON_TASK_NAME"] = task_name context.data["asset"] = asset_name context.data["task"] = task_name diff --git a/client/ayon_core/hosts/resolve/api/workio.py b/client/ayon_core/hosts/resolve/api/workio.py index 5e4865ddc5..b6c2f63432 100644 --- a/client/ayon_core/hosts/resolve/api/workio.py +++ b/client/ayon_core/hosts/resolve/api/workio.py @@ -79,7 +79,7 @@ def open_file(filepath): def current_file(): pm = get_project_manager() file_ext = file_extensions()[0] - workdir_path = os.getenv("AVALON_WORKDIR") + workdir_path = os.getenv("AYON_WORKDIR") project = pm.GetCurrentProject() project_name = project.GetName() file_name = project_name + file_ext @@ -93,4 +93,4 @@ def current_file(): def work_root(session): - return os.path.normpath(session["AVALON_WORKDIR"]).replace("\\", "/") + return os.path.normpath(session["AYON_WORKDIR"]).replace("\\", "/") diff --git a/client/ayon_core/hosts/traypublisher/api/pipeline.py b/client/ayon_core/hosts/traypublisher/api/pipeline.py index 88fa3239a5..f4526ddf4b 100644 --- a/client/ayon_core/hosts/traypublisher/api/pipeline.py +++ b/client/ayon_core/hosts/traypublisher/api/pipeline.py @@ -22,7 +22,7 @@ class TrayPublisherHost(HostBase, IPublishHost): name = "traypublisher" def install(self): - os.environ["AVALON_APP"] = self.name + os.environ["AYON_HOST_NAME"] = self.name pyblish.api.register_host("traypublisher") pyblish.api.register_plugin_path(PUBLISH_PATH) @@ -40,7 +40,7 @@ class TrayPublisherHost(HostBase, IPublishHost): def set_project_name(self, project_name): # TODO Deregister project specific plugins and register new project # plugins - os.environ["AVALON_PROJECT"] = project_name + os.environ["AYON_PROJECT_NAME"] = project_name HostContext.set_project_name(project_name) diff --git a/client/ayon_core/hosts/traypublisher/plugins/create/create_from_settings.py b/client/ayon_core/hosts/traypublisher/plugins/create/create_from_settings.py index 20f8dd792a..cc1429901d 100644 --- a/client/ayon_core/hosts/traypublisher/plugins/create/create_from_settings.py +++ b/client/ayon_core/hosts/traypublisher/plugins/create/create_from_settings.py @@ -8,7 +8,7 @@ log = Logger.get_logger(__name__) def initialize(): from ayon_core.hosts.traypublisher.api.plugin import SettingsCreator - project_name = os.environ["AVALON_PROJECT"] + project_name = os.environ["AYON_PROJECT_NAME"] project_settings = get_project_settings(project_name) simple_creators = project_settings["traypublisher"]["simple_creators"] diff --git a/client/ayon_core/hosts/tvpaint/api/pipeline.py b/client/ayon_core/hosts/tvpaint/api/pipeline.py index d636e68cfa..78a0c5270d 100644 --- a/client/ayon_core/hosts/tvpaint/api/pipeline.py +++ b/client/ayon_core/hosts/tvpaint/api/pipeline.py @@ -68,7 +68,7 @@ class TVPaintHost(HostBase, IWorkfileHost, ILoadHost, IPublishHost): log.info("AYON - Installing TVPaint integration") # Create workdir folder if does not exist yet - workdir = os.getenv("AVALON_WORKDIR") + workdir = os.getenv("AYON_WORKDIR") if not os.path.exists(workdir): os.makedirs(workdir) @@ -155,7 +155,7 @@ class TVPaintHost(HostBase, IWorkfileHost, ILoadHost, IPublishHost): return execute_george(george_script) def work_root(self, session): - return session["AVALON_WORKDIR"] + return session["AYON_WORKDIR"] def get_current_workfile(self): return execute_george("tv_GetProjectName") @@ -174,7 +174,7 @@ class TVPaintHost(HostBase, IWorkfileHost, ILoadHost, IPublishHost): # Setup project settings if its the template that's launched. # TODO also check for template creation when it's possible to define # templates - last_workfile = os.environ.get("AVALON_LAST_WORKFILE") + last_workfile = os.environ.get("AYON_LAST_WORKFILE") if not last_workfile or os.path.exists(last_workfile): return diff --git a/client/ayon_core/hosts/tvpaint/plugins/publish/collect_workfile_data.py b/client/ayon_core/hosts/tvpaint/plugins/publish/collect_workfile_data.py index 05ceb143e9..a6b6f05dc9 100644 --- a/client/ayon_core/hosts/tvpaint/plugins/publish/collect_workfile_data.py +++ b/client/ayon_core/hosts/tvpaint/plugins/publish/collect_workfile_data.py @@ -85,8 +85,8 @@ class CollectWorkfileData(pyblish.api.ContextPlugin): if workfile_context: # Change current context with context from workfile key_map = ( - ("AVALON_ASSET", "asset_name"), - ("AVALON_TASK", "task_name") + ("AYON_FOLDER_PATH", "asset_name"), + ("AYON_TASK_NAME", "task_name") ) for env_key, key in key_map: os.environ[env_key] = workfile_context[key] diff --git a/client/ayon_core/hosts/tvpaint/plugins/publish/validate_workfile_project_name.py b/client/ayon_core/hosts/tvpaint/plugins/publish/validate_workfile_project_name.py index be3259bfd8..5b42842717 100644 --- a/client/ayon_core/hosts/tvpaint/plugins/publish/validate_workfile_project_name.py +++ b/client/ayon_core/hosts/tvpaint/plugins/publish/validate_workfile_project_name.py @@ -6,7 +6,7 @@ class ValidateWorkfileProjectName(pyblish.api.ContextPlugin): """Validate project name stored in workfile metadata. It is not possible to publish from different project than is set in - environment variable "AVALON_PROJECT". + environment variable "AYON_PROJECT_NAME". """ label = "Validate Workfile Project Name" diff --git a/client/ayon_core/hosts/unreal/api/rendering.py b/client/ayon_core/hosts/unreal/api/rendering.py index 8717788732..4a15ceb89a 100644 --- a/client/ayon_core/hosts/unreal/api/rendering.py +++ b/client/ayon_core/hosts/unreal/api/rendering.py @@ -60,7 +60,7 @@ def start_rendering(): inst_data.append(data) try: - project = os.environ.get("AVALON_PROJECT") + project = os.environ.get("AYON_PROJECT_NAME") anatomy = Anatomy(project) root = anatomy.roots['renders'] except Exception as e: diff --git a/client/ayon_core/hosts/unreal/hooks/pre_workfile_preparation.py b/client/ayon_core/hosts/unreal/hooks/pre_workfile_preparation.py index 4317844ca5..0eaa1adb84 100644 --- a/client/ayon_core/hosts/unreal/hooks/pre_workfile_preparation.py +++ b/client/ayon_core/hosts/unreal/hooks/pre_workfile_preparation.py @@ -146,7 +146,7 @@ class UnrealPrelaunchHook(PreLaunchHook): def execute(self): """Hook entry method.""" - workdir = self.launch_context.env["AVALON_WORKDIR"] + workdir = self.launch_context.env["AYON_WORKDIR"] executable = str(self.launch_context.executable) engine_version = self.app_name.split("/")[-1].replace("-", ".") try: diff --git a/client/ayon_core/lib/applications.py b/client/ayon_core/lib/applications.py index febdaacdd1..38a29d7991 100644 --- a/client/ayon_core/lib/applications.py +++ b/client/ayon_core/lib/applications.py @@ -1740,15 +1740,15 @@ def prepare_context_environments(data, env_group=None, addons_manager=None): app = data["app"] context_env = { - "AVALON_PROJECT": project_doc["name"], - "AVALON_APP_NAME": app.full_name + "AYON_PROJECT_NAME": project_doc["name"], + "AYON_APP_NAME": app.full_name } if asset_doc: asset_name = get_asset_name_identifier(asset_doc) - context_env["AVALON_ASSET"] = asset_name + context_env["AYON_FOLDER_PATH"] = asset_name if task_name: - context_env["AVALON_TASK"] = task_name + context_env["AYON_TASK_NAME"] = task_name log.debug( "Context environments set:\n{}".format( @@ -1766,7 +1766,7 @@ def prepare_context_environments(data, env_group=None, addons_manager=None): if not app.is_host: return - data["env"]["AVALON_APP"] = app.host_name + data["env"]["AYON_HOST_NAME"] = app.host_name if not asset_doc or not task_name: # QUESTION replace with log.info and skip workfile discovery? @@ -1812,7 +1812,7 @@ def prepare_context_environments(data, env_group=None, addons_manager=None): "Couldn't create workdir because: {}".format(str(exc)) ) - data["env"]["AVALON_WORKDIR"] = workdir + data["env"]["AYON_WORKDIR"] = workdir _prepare_last_workfile(data, workdir, addons_manager) @@ -1929,7 +1929,7 @@ def _prepare_last_workfile(data, workdir, addons_manager): "Setting last workfile path: {}".format(last_workfile_path) ) - data["env"]["AVALON_LAST_WORKFILE"] = last_workfile_path + data["env"]["AYON_LAST_WORKFILE"] = last_workfile_path data["last_workfile_path"] = last_workfile_path diff --git a/client/ayon_core/lib/log.py b/client/ayon_core/lib/log.py index cbb1e41bae..36c39f9d84 100644 --- a/client/ayon_core/lib/log.py +++ b/client/ayon_core/lib/log.py @@ -257,7 +257,7 @@ class Logger: return cls._process_name # Get process name - process_name = os.environ.get("AVALON_APP_NAME") + process_name = os.environ.get("AYON_APP_NAME") if not process_name: try: import psutil diff --git a/client/ayon_core/modules/clockify/launcher_actions/ClockifyStart.py b/client/ayon_core/modules/clockify/launcher_actions/ClockifyStart.py index 19aa2ef195..f7dd1772b0 100644 --- a/client/ayon_core/modules/clockify/launcher_actions/ClockifyStart.py +++ b/client/ayon_core/modules/clockify/launcher_actions/ClockifyStart.py @@ -12,7 +12,7 @@ class ClockifyStart(LauncherAction): def is_compatible(self, session): """Return whether the action is compatible with the session""" - if "AVALON_TASK" in session: + if "AYON_TASK_NAME" in session: return True return False @@ -20,9 +20,9 @@ class ClockifyStart(LauncherAction): self.clockify_api.set_api() user_id = self.clockify_api.user_id workspace_id = self.clockify_api.workspace_id - project_name = session["AVALON_PROJECT"] - asset_name = session["AVALON_ASSET"] - task_name = session["AVALON_TASK"] + project_name = session["AYON_PROJECT_NAME"] + asset_name = session["AYON_FOLDER_PATH"] + task_name = session["AYON_TASK_NAME"] description = asset_name # fetch asset docs diff --git a/client/ayon_core/modules/clockify/launcher_actions/ClockifySync.py b/client/ayon_core/modules/clockify/launcher_actions/ClockifySync.py index 30f5ae698f..5ef9033ffe 100644 --- a/client/ayon_core/modules/clockify/launcher_actions/ClockifySync.py +++ b/client/ayon_core/modules/clockify/launcher_actions/ClockifySync.py @@ -36,7 +36,7 @@ class ClockifySync(LauncherAction): raise ClockifyPermissionsCheckFailed( "Current CLockify user is missing permissions for this action!" ) - project_name = session.get("AVALON_PROJECT") or "" + project_name = session.get("AYON_PROJECT_NAME") or "" projects_to_sync = [] if project_name.strip(): diff --git a/client/ayon_core/modules/deadline/plugins/publish/submit_aftereffects_deadline.py b/client/ayon_core/modules/deadline/plugins/publish/submit_aftereffects_deadline.py index 618b71bbaf..a4eb5b673c 100644 --- a/client/ayon_core/modules/deadline/plugins/publish/submit_aftereffects_deadline.py +++ b/client/ayon_core/modules/deadline/plugins/publish/submit_aftereffects_deadline.py @@ -80,11 +80,11 @@ class AfterEffectsSubmitDeadline( "FTRACK_API_KEY", "FTRACK_API_USER", "FTRACK_SERVER", - "AVALON_PROJECT", - "AVALON_ASSET", - "AVALON_TASK", - "AVALON_WORKDIR", - "AVALON_APP_NAME", + "AYON_PROJECT_NAME", + "AYON_FOLDER_PATH", + "AYON_TASK_NAME", + "AYON_WORKDIR", + "AYON_APP_NAME", "AYON_LOG_NO_COLORS", "IS_TEST" ] diff --git a/client/ayon_core/modules/deadline/plugins/publish/submit_blender_deadline.py b/client/ayon_core/modules/deadline/plugins/publish/submit_blender_deadline.py index af864ace5b..e9e6ef083d 100644 --- a/client/ayon_core/modules/deadline/plugins/publish/submit_blender_deadline.py +++ b/client/ayon_core/modules/deadline/plugins/publish/submit_blender_deadline.py @@ -102,11 +102,11 @@ class BlenderSubmitDeadline(abstract_submit_deadline.AbstractSubmitDeadline, "FTRACK_API_USER", "FTRACK_SERVER", "OPENPYPE_SG_USER", - "AVALON_PROJECT", - "AVALON_ASSET", - "AVALON_TASK", - "AVALON_WORKDIR", - "AVALON_APP_NAME", + "AYON_PROJECT_NAME", + "AYON_FOLDER_PATH", + "AYON_TASK_NAME", + "AYON_WORKDIR", + "AYON_APP_NAME", "IS_TEST" ] diff --git a/client/ayon_core/modules/deadline/plugins/publish/submit_fusion_deadline.py b/client/ayon_core/modules/deadline/plugins/publish/submit_fusion_deadline.py index 7aa8546bb6..9c125db174 100644 --- a/client/ayon_core/modules/deadline/plugins/publish/submit_fusion_deadline.py +++ b/client/ayon_core/modules/deadline/plugins/publish/submit_fusion_deadline.py @@ -220,11 +220,11 @@ class FusionSubmitDeadline( "FTRACK_API_KEY", "FTRACK_API_USER", "FTRACK_SERVER", - "AVALON_PROJECT", - "AVALON_ASSET", - "AVALON_TASK", - "AVALON_WORKDIR", - "AVALON_APP_NAME", + "AYON_PROJECT_NAME", + "AYON_FOLDER_PATH", + "AYON_TASK_NAME", + "AYON_WORKDIR", + "AYON_APP_NAME", "AYON_LOG_NO_COLORS", "IS_TEST", "AYON_BUNDLE_NAME", diff --git a/client/ayon_core/modules/deadline/plugins/publish/submit_harmony_deadline.py b/client/ayon_core/modules/deadline/plugins/publish/submit_harmony_deadline.py index 4d375299fa..d3915ed16d 100644 --- a/client/ayon_core/modules/deadline/plugins/publish/submit_harmony_deadline.py +++ b/client/ayon_core/modules/deadline/plugins/publish/submit_harmony_deadline.py @@ -273,11 +273,11 @@ class HarmonySubmitDeadline( "FTRACK_API_KEY", "FTRACK_API_USER", "FTRACK_SERVER", - "AVALON_PROJECT", - "AVALON_ASSET", - "AVALON_TASK", - "AVALON_WORKDIR", - "AVALON_APP_NAME", + "AYON_PROJECT_NAME", + "AYON_FOLDER_PATH", + "AYON_TASK_NAME", + "AYON_WORKDIR", + "AYON_APP_NAME", "AYON_LOG_NO_COLORS" "IS_TEST" ] diff --git a/client/ayon_core/modules/deadline/plugins/publish/submit_houdini_cache_deadline.py b/client/ayon_core/modules/deadline/plugins/publish/submit_houdini_cache_deadline.py index 96ee80c4d7..f6676da3d6 100644 --- a/client/ayon_core/modules/deadline/plugins/publish/submit_houdini_cache_deadline.py +++ b/client/ayon_core/modules/deadline/plugins/publish/submit_houdini_cache_deadline.py @@ -98,11 +98,11 @@ class HoudiniCacheSubmitDeadline(abstract_submit_deadline.AbstractSubmitDeadline "FTRACK_API_USER", "FTRACK_SERVER", "OPENPYPE_SG_USER", - "AVALON_PROJECT", - "AVALON_ASSET", - "AVALON_TASK", - "AVALON_WORKDIR", - "AVALON_APP_NAME", + "AYON_PROJECT_NAME", + "AYON_FOLDER_PATH", + "AYON_TASK_NAME", + "AYON_WORKDIR", + "AYON_APP_NAME", "AYON_LOG_NO_COLORS", ] diff --git a/client/ayon_core/modules/deadline/plugins/publish/submit_houdini_render_deadline.py b/client/ayon_core/modules/deadline/plugins/publish/submit_houdini_render_deadline.py index d7a062c9a6..436f0d70ad 100644 --- a/client/ayon_core/modules/deadline/plugins/publish/submit_houdini_render_deadline.py +++ b/client/ayon_core/modules/deadline/plugins/publish/submit_houdini_render_deadline.py @@ -204,11 +204,11 @@ class HoudiniSubmitDeadline( "FTRACK_API_USER", "FTRACK_SERVER", "OPENPYPE_SG_USER", - "AVALON_PROJECT", - "AVALON_ASSET", - "AVALON_TASK", - "AVALON_WORKDIR", - "AVALON_APP_NAME", + "AYON_PROJECT_NAME", + "AYON_FOLDER_PATH", + "AYON_TASK_NAME", + "AYON_WORKDIR", + "AYON_APP_NAME", "AYON_LOG_NO_COLORS", ] diff --git a/client/ayon_core/modules/deadline/plugins/publish/submit_max_deadline.py b/client/ayon_core/modules/deadline/plugins/publish/submit_max_deadline.py index 8908283164..4eaaedac34 100644 --- a/client/ayon_core/modules/deadline/plugins/publish/submit_max_deadline.py +++ b/client/ayon_core/modules/deadline/plugins/publish/submit_max_deadline.py @@ -106,11 +106,11 @@ class MaxSubmitDeadline(abstract_submit_deadline.AbstractSubmitDeadline, "FTRACK_API_USER", "FTRACK_SERVER", "OPENPYPE_SG_USER", - "AVALON_PROJECT", - "AVALON_ASSET", - "AVALON_TASK", - "AVALON_WORKDIR", - "AVALON_APP_NAME", + "AYON_PROJECT_NAME", + "AYON_FOLDER_PATH", + "AYON_TASK_NAME", + "AYON_WORKDIR", + "AYON_APP_NAME", "IS_TEST" ] diff --git a/client/ayon_core/modules/deadline/plugins/publish/submit_maya_deadline.py b/client/ayon_core/modules/deadline/plugins/publish/submit_maya_deadline.py index 2b7a7cf698..1b86d74987 100644 --- a/client/ayon_core/modules/deadline/plugins/publish/submit_maya_deadline.py +++ b/client/ayon_core/modules/deadline/plugins/publish/submit_maya_deadline.py @@ -199,11 +199,11 @@ class MayaSubmitDeadline(abstract_submit_deadline.AbstractSubmitDeadline, "FTRACK_API_USER", "FTRACK_SERVER", "OPENPYPE_SG_USER", - "AVALON_PROJECT", - "AVALON_ASSET", - "AVALON_TASK", - "AVALON_WORKDIR", - "AVALON_APP_NAME", + "AYON_PROJECT_NAME", + "AYON_FOLDER_PATH", + "AYON_TASK_NAME", + "AYON_WORKDIR", + "AYON_APP_NAME", "IS_TEST" ] diff --git a/client/ayon_core/modules/deadline/plugins/publish/submit_maya_remote_publish_deadline.py b/client/ayon_core/modules/deadline/plugins/publish/submit_maya_remote_publish_deadline.py index ed360d84ae..08ddbcf661 100644 --- a/client/ayon_core/modules/deadline/plugins/publish/submit_maya_remote_publish_deadline.py +++ b/client/ayon_core/modules/deadline/plugins/publish/submit_maya_remote_publish_deadline.py @@ -104,10 +104,10 @@ class MayaSubmitRemotePublishDeadline( if key in os.environ } - environment["AVALON_PROJECT"] = project_name - environment["AVALON_ASSET"] = instance.context.data["asset"] - environment["AVALON_TASK"] = instance.context.data["task"] - environment["AVALON_APP_NAME"] = os.environ.get("AVALON_APP_NAME") + environment["AYON_PROJECT_NAME"] = project_name + environment["AYON_FOLDER_PATH"] = instance.context.data["asset"] + environment["AYON_TASK_NAME"] = instance.context.data["task"] + environment["AYON_APP_NAME"] = os.environ.get("AYON_APP_NAME") environment["OPENPYPE_PUBLISH_SUBSET"] = instance.data["subset"] environment["AYON_LOG_NO_COLORS"] = "1" environment["AYON_USERNAME"] = instance.context.data["user"] diff --git a/client/ayon_core/modules/deadline/plugins/publish/submit_nuke_deadline.py b/client/ayon_core/modules/deadline/plugins/publish/submit_nuke_deadline.py index 61a334e184..f48f9ba9b7 100644 --- a/client/ayon_core/modules/deadline/plugins/publish/submit_nuke_deadline.py +++ b/client/ayon_core/modules/deadline/plugins/publish/submit_nuke_deadline.py @@ -373,10 +373,10 @@ class NukeSubmitDeadline(pyblish.api.InstancePlugin, keys = [ "PYTHONPATH", "PATH", - "AVALON_PROJECT", - "AVALON_ASSET", - "AVALON_TASK", - "AVALON_APP_NAME", + "AYON_PROJECT_NAME", + "AYON_FOLDER_PATH", + "AYON_TASK_NAME", + "AYON_APP_NAME", "FTRACK_API_KEY", "FTRACK_API_USER", "FTRACK_SERVER", diff --git a/client/ayon_core/modules/deadline/plugins/publish/submit_publish_cache_job.py b/client/ayon_core/modules/deadline/plugins/publish/submit_publish_cache_job.py index 38ea31ab7b..522f19604b 100644 --- a/client/ayon_core/modules/deadline/plugins/publish/submit_publish_cache_job.py +++ b/client/ayon_core/modules/deadline/plugins/publish/submit_publish_cache_job.py @@ -68,7 +68,7 @@ class ProcessSubmittedCacheJobOnFarm(pyblish.api.InstancePlugin, "FTRACK_API_USER", "FTRACK_API_KEY", "FTRACK_SERVER", - "AVALON_APP_NAME", + "AYON_APP_NAME", "AYON_USERNAME", "OPENPYPE_SG_USER", "KITSU_LOGIN", @@ -126,9 +126,9 @@ class ProcessSubmittedCacheJobOnFarm(pyblish.api.InstancePlugin, create_metadata_path(instance, anatomy) environment = { - "AVALON_PROJECT": instance.context.data["projectName"], - "AVALON_ASSET": instance.context.data["asset"], - "AVALON_TASK": instance.context.data["task"], + "AYON_PROJECT_NAME": instance.context.data["projectName"], + "AYON_FOLDER_PATH": instance.context.data["asset"], + "AYON_TASK_NAME": instance.context.data["task"], "AYON_USERNAME": instance.context.data["user"], "AYON_LOG_NO_COLORS": "1", "IS_TEST": str(int(is_in_tests())), diff --git a/client/ayon_core/modules/deadline/plugins/publish/submit_publish_job.py b/client/ayon_core/modules/deadline/plugins/publish/submit_publish_job.py index c4ab6a2932..35b54d40ca 100644 --- a/client/ayon_core/modules/deadline/plugins/publish/submit_publish_job.py +++ b/client/ayon_core/modules/deadline/plugins/publish/submit_publish_job.py @@ -110,7 +110,7 @@ class ProcessSubmittedJobOnFarm(pyblish.api.InstancePlugin, "FTRACK_API_USER", "FTRACK_API_KEY", "FTRACK_SERVER", - "AVALON_APP_NAME", + "AYON_APP_NAME", "AYON_USERNAME", "OPENPYPE_SG_USER", "KITSU_LOGIN", @@ -182,9 +182,9 @@ class ProcessSubmittedJobOnFarm(pyblish.api.InstancePlugin, create_metadata_path(instance, anatomy) environment = { - "AVALON_PROJECT": instance.context.data["projectName"], - "AVALON_ASSET": instance.context.data["asset"], - "AVALON_TASK": instance.context.data["task"], + "AYON_PROJECT_NAME": instance.context.data["projectName"], + "AYON_FOLDER_PATH": instance.context.data["asset"], + "AYON_TASK_NAME": instance.context.data["task"], "AYON_USERNAME": instance.context.data["user"], "AYON_LOG_NO_COLORS": "1", "IS_TEST": str(int(is_in_tests())), diff --git a/client/ayon_core/modules/deadline/repository/custom/plugins/GlobalJobPreLoad.py b/client/ayon_core/modules/deadline/repository/custom/plugins/GlobalJobPreLoad.py index 81aab00b93..8b539931fb 100644 --- a/client/ayon_core/modules/deadline/repository/custom/plugins/GlobalJobPreLoad.py +++ b/client/ayon_core/modules/deadline/repository/custom/plugins/GlobalJobPreLoad.py @@ -471,12 +471,21 @@ def inject_ayon_environment(deadlinePlugin): ] add_kwargs = { - "project": job.GetJobEnvironmentKeyValue("AVALON_PROJECT"), - "asset": job.GetJobEnvironmentKeyValue("AVALON_ASSET"), - "task": job.GetJobEnvironmentKeyValue("AVALON_TASK"), - "app": job.GetJobEnvironmentKeyValue("AVALON_APP_NAME"), "envgroup": "farm", } + # Support backwards compatible keys + for key, env_keys in { + "project": ["AYON_PROJECT_NAME", "AVALON_PROJECT"], + "asset": ["AYON_FOLDER_PATH", "AVALON_ASSET"], + "task": ["AYON_TASK_NAME", "AVALON_TASK"], + "app": ["AYON_APP_NAME", "AVALON_APP_NAME"], + }: + value = "" + for env_key in env_keys: + value = job.GetJobEnvironmentKeyValue(env_key) + if value: + break + add_kwargs[key] = value if job.GetJobEnvironmentKeyValue("IS_TEST"): args.append("--automatic-tests") @@ -486,8 +495,8 @@ def inject_ayon_environment(deadlinePlugin): args.extend(["--{}".format(key), value]) else: raise RuntimeError(( - "Missing required env vars: AVALON_PROJECT, AVALON_ASSET," - " AVALON_TASK, AVALON_APP_NAME" + "Missing required env vars: AYON_PROJECT_NAME," + " AYON_FOLDER_PATH, AYON_TASK_NAME, AYON_APP_NAME" )) environment = { diff --git a/client/ayon_core/modules/royalrender/lib.py b/client/ayon_core/modules/royalrender/lib.py index d985a39d24..2b26ec82e4 100644 --- a/client/ayon_core/modules/royalrender/lib.py +++ b/client/ayon_core/modules/royalrender/lib.py @@ -357,8 +357,8 @@ class BaseCreateRoyalRenderJob(pyblish.api.InstancePlugin, if not all(add_kwargs.values()): raise RuntimeError(( - "Missing required env vars: AVALON_PROJECT, AVALON_ASSET," - " AVALON_TASK, AVALON_APP_NAME" + "Missing required env vars: AYON_PROJECT_NAME, AYON_FOLDER_PATH," + " AYON_TASK_NAME, AYON_APP_NAME" )) for key, value in add_kwargs.items(): diff --git a/client/ayon_core/modules/royalrender/plugins/publish/create_publish_royalrender_job.py b/client/ayon_core/modules/royalrender/plugins/publish/create_publish_royalrender_job.py index abc8d7dccd..910abfcb15 100644 --- a/client/ayon_core/modules/royalrender/plugins/publish/create_publish_royalrender_job.py +++ b/client/ayon_core/modules/royalrender/plugins/publish/create_publish_royalrender_job.py @@ -63,7 +63,7 @@ class CreatePublishRoyalRenderJob(pyblish.api.InstancePlugin, "FTRACK_API_USER", "FTRACK_API_KEY", "FTRACK_SERVER", - "AVALON_APP_NAME", + "AYON_APP_NAME", "AYON_USERNAME", "OPENPYPE_SG_USER", ] @@ -179,9 +179,9 @@ class CreatePublishRoyalRenderJob(pyblish.api.InstancePlugin, anatomy_data = instance.context.data["anatomyData"] environment = RREnvList({ - "AVALON_PROJECT": anatomy_data["project"]["name"], - "AVALON_ASSET": instance.context.data["asset"], - "AVALON_TASK": anatomy_data["task"]["name"], + "AYON_PROJECT_NAME": anatomy_data["project"]["name"], + "AYON_FOLDER_PATH": instance.context.data["asset"], + "AYON_TASK_NAME": anatomy_data["task"]["name"], "AYON_USERNAME": anatomy_data["user"] }) diff --git a/client/ayon_core/modules/royalrender/rr_root/plugins/control_job/perjob/m50__openpype_publish_render.py b/client/ayon_core/modules/royalrender/rr_root/plugins/control_job/perjob/m50__openpype_publish_render.py index 7118c5ebef..cfec2622d9 100644 --- a/client/ayon_core/modules/royalrender/rr_root/plugins/control_job/perjob/m50__openpype_publish_render.py +++ b/client/ayon_core/modules/royalrender/rr_root/plugins/control_job/perjob/m50__openpype_publish_render.py @@ -136,10 +136,10 @@ class OpenPypeContextSelector: def run_publish(self): """Run publish process.""" - env = {"AVALON_PROJECT": str(self.context.get("project")), - "AVALON_ASSET": str(self.context.get("asset")), - "AVALON_TASK": str(self.context.get("task")), - # "AVALON_APP_NAME": str(self.context.get("app_name")) + env = {"AYON_PROJECT_NAME": str(self.context.get("project")), + "AYON_FOLDER_PATH": str(self.context.get("asset")), + "AYON_TASK_NAME": str(self.context.get("task")), + # "AYON_APP_NAME": str(self.context.get("app_name")) } print(">>> setting environment:") @@ -182,10 +182,18 @@ print("running selector") selector = OpenPypeContextSelector() # try to set context from environment -selector.context["project"] = os.getenv("AVALON_PROJECT") -selector.context["asset"] = os.getenv("AVALON_ASSET") -selector.context["task"] = os.getenv("AVALON_TASK") -# selector.context["app_name"] = os.getenv("AVALON_APP_NAME") +for key, env_keys in { + "project": ["AYON_PROJECT_NAME", "AVALON_PROJECT"], + "asset": ["AYON_FOLDER_PATH", "AVALON_ASSET"], + "task": ["AYON_TASK_NAME", "AVALON_TASK"], + # "app_name": ["AYON_APP_NAME", "AVALON_APP_NAME"] +}: + value = "" + for env_key in env_keys: + value = os.getenv(env_key) + if value: + break + selector.context[key] = value # if anything inside is None, scratch the whole thing and # ask user for context. diff --git a/client/ayon_core/pipeline/actions.py b/client/ayon_core/pipeline/actions.py index 1701498d10..8e0ce7e583 100644 --- a/client/ayon_core/pipeline/actions.py +++ b/client/ayon_core/pipeline/actions.py @@ -26,7 +26,7 @@ class LauncherAction(object): Args: session (dict[str, Union[str, None]]): Session data with - AVALON_PROJECT, AVALON_ASSET and AVALON_TASK. + AYON_PROJECT_NAME, AYON_FOLDER_PATH and AYON_TASK_NAME. """ return True diff --git a/client/ayon_core/pipeline/anatomy.py b/client/ayon_core/pipeline/anatomy.py index 86b7d92309..4864822aa1 100644 --- a/client/ayon_core/pipeline/anatomy.py +++ b/client/ayon_core/pipeline/anatomy.py @@ -423,7 +423,7 @@ class Anatomy(BaseAnatomy): def __init__(self, project_name=None, site_name=None): if not project_name: - project_name = os.environ.get("AVALON_PROJECT") + project_name = os.environ.get("AYON_PROJECT_NAME") if not project_name: raise ProjectNotSet(( diff --git a/client/ayon_core/pipeline/context_tools.py b/client/ayon_core/pipeline/context_tools.py index 339ef9187f..5716793354 100644 --- a/client/ayon_core/pipeline/context_tools.py +++ b/client/ayon_core/pipeline/context_tools.py @@ -117,12 +117,12 @@ def install_host(host): addons_manager = _get_addons_manager() - project_name = os.getenv("AVALON_PROJECT") + project_name = os.getenv("AYON_PROJECT_NAME") # WARNING: This might be an issue # - commented out because 'traypublisher' does not have set project # if not project_name: # raise ValueError( - # "AVALON_PROJECT is missing in environment variables." + # "AYON_PROJECT_NAME is missing in environment variables." # ) log.info("Activating {}..".format(project_name)) @@ -152,7 +152,7 @@ def install_host(host): print("Registering pyblish target: automated") pyblish.api.register_target("automated") - host_name = os.environ.get("AVALON_APP") + host_name = os.environ.get("AYON_HOST_NAME") # Give option to handle host installation for addon in addons_manager.get_enabled_addons(): @@ -172,7 +172,7 @@ def install_ayon_plugins(project_name=None, host_name=None): register_inventory_action_path(INVENTORY_PATH) if host_name is None: - host_name = os.environ.get("AVALON_APP") + host_name = os.environ.get("AYON_HOST_NAME") addons_manager = _get_addons_manager() publish_plugin_dirs = addons_manager.collect_publish_plugin_paths( @@ -196,7 +196,7 @@ def install_ayon_plugins(project_name=None, host_name=None): register_inventory_action_path(path) if project_name is None: - project_name = os.environ.get("AVALON_PROJECT") + project_name = os.environ.get("AYON_PROJECT_NAME") # Register studio specific plugins if project_name: @@ -331,7 +331,7 @@ def get_current_host_name(): """Current host name. Function is based on currently registered host integration or environment - variable 'AVALON_APP'. + variable 'AYON_HOST_NAME'. Returns: Union[str, None]: Name of host integration in current process or None. @@ -340,7 +340,7 @@ def get_current_host_name(): host = registered_host() if isinstance(host, HostBase): return host.name - return os.environ.get("AVALON_APP") + return os.environ.get("AYON_HOST_NAME") def get_global_context(): @@ -365,9 +365,9 @@ def get_global_context(): """ return { - "project_name": os.environ.get("AVALON_PROJECT"), - "asset_name": os.environ.get("AVALON_ASSET"), - "task_name": os.environ.get("AVALON_TASK"), + "project_name": os.environ.get("AYON_PROJECT_NAME"), + "asset_name": os.environ.get("AYON_FOLDER_PATH"), + "task_name": os.environ.get("AYON_TASK_NAME"), } @@ -474,10 +474,10 @@ def get_template_data_from_session(session=None, system_settings=None): """ if session is not None: - project_name = session["AVALON_PROJECT"] - asset_name = session["AVALON_ASSET"] - task_name = session["AVALON_TASK"] - host_name = session["AVALON_APP"] + project_name = session["AYON_PROJECT_NAME"] + asset_name = session["AYON_FOLDER_PATH"] + task_name = session["AYON_TASK_NAME"] + host_name = session["AYON_HOST_NAME"] else: context = get_current_context() project_name = context["project_name"] @@ -525,8 +525,8 @@ def get_workdir_from_session(session=None, template_key=None): """ if session is not None: - project_name = session["AVALON_PROJECT"] - host_name = session["AVALON_APP"] + project_name = session["AYON_PROJECT_NAME"] + host_name = session["AYON_HOST_NAME"] else: project_name = get_current_project_name() host_name = get_current_host_name() @@ -566,10 +566,10 @@ def get_custom_workfile_template_from_session( """ if session is not None: - project_name = session["AVALON_PROJECT"] - asset_name = session["AVALON_ASSET"] - task_name = session["AVALON_TASK"] - host_name = session["AVALON_APP"] + project_name = session["AYON_PROJECT_NAME"] + asset_name = session["AYON_FOLDER_PATH"] + task_name = session["AYON_TASK_NAME"] + host_name = session["AYON_HOST_NAME"] else: context = get_current_context() project_name = context["project_name"] @@ -616,10 +616,10 @@ def change_current_context(asset_doc, task_name, template_key=None): folder_path = get_asset_name_identifier(asset_doc) envs = { - "AVALON_PROJECT": project_name, - "AVALON_ASSET": folder_path, - "AVALON_TASK": task_name, - "AVALON_WORKDIR": workdir, + "AYON_PROJECT_NAME": project_name, + "AYON_FOLDER_PATH": folder_path, + "AYON_TASK_NAME": task_name, + "AYON_WORKDIR": workdir, } # Update the Session and environments. Pop from environments all keys with diff --git a/client/ayon_core/pipeline/create/context.py b/client/ayon_core/pipeline/create/context.py index be685ea2cc..b973c45097 100644 --- a/client/ayon_core/pipeline/create/context.py +++ b/client/ayon_core/pipeline/create/context.py @@ -1536,7 +1536,7 @@ class CreateContext: def host_name(self): if hasattr(self.host, "name"): return self.host.name - return os.environ["AVALON_APP"] + return os.environ["AYON_HOST_NAME"] def get_current_project_name(self): """Project name which was used as current context on context reset. diff --git a/client/ayon_core/pipeline/create/legacy_create.py b/client/ayon_core/pipeline/create/legacy_create.py index 08be32eed4..aab6b67e6f 100644 --- a/client/ayon_core/pipeline/create/legacy_create.py +++ b/client/ayon_core/pipeline/create/legacy_create.py @@ -45,7 +45,7 @@ class LegacyCreator(object): def apply_settings(cls, project_settings, system_settings): """Apply OpenPype settings to a plugin class.""" - host_name = os.environ.get("AVALON_APP") + host_name = os.environ.get("AYON_HOST_NAME") plugin_type = "create" plugin_type_settings = ( project_settings diff --git a/client/ayon_core/pipeline/create/subset_name.py b/client/ayon_core/pipeline/create/subset_name.py index 2973b1e54e..93a61b8b8b 100644 --- a/client/ayon_core/pipeline/create/subset_name.py +++ b/client/ayon_core/pipeline/create/subset_name.py @@ -128,13 +128,13 @@ def get_subset_name( return "" if not host_name: - host_name = os.environ.get("AVALON_APP") + host_name = os.environ.get("AYON_HOST_NAME") # Use only last part of class family value split by dot (`.`) family = family.rsplit(".", 1)[-1] if project_name is None: - project_name = os.environ.get("AVALON_PROJECT") + project_name = os.environ.get("AYON_PROJECT_NAME") asset_tasks = asset_doc.get("data", {}).get("tasks") or {} task_info = asset_tasks.get(task_name) or {} diff --git a/client/ayon_core/pipeline/farm/pyblish_functions.py b/client/ayon_core/pipeline/farm/pyblish_functions.py index 9423d8501c..389d3d27ed 100644 --- a/client/ayon_core/pipeline/farm/pyblish_functions.py +++ b/client/ayon_core/pipeline/farm/pyblish_functions.py @@ -321,7 +321,7 @@ def prepare_representations(skeleton_data, exp_files, anatomy, aov_filter, """ representations = [] - host_name = os.environ.get("AVALON_APP", "") + host_name = os.environ.get("AYON_HOST_NAME", "") collections, remainders = clique.assemble(exp_files) log = Logger.get_logger("farm_publishing") @@ -541,7 +541,7 @@ def _create_instances_for_aov(instance, skeleton, aov_filter, additional_data, """ # TODO: this needs to be taking the task from context or instance - task = os.environ["AVALON_TASK"] + task = os.environ["AYON_TASK_NAME"] anatomy = instance.context.data["anatomy"] subset = skeleton["subset"] @@ -611,7 +611,7 @@ def _create_instances_for_aov(instance, skeleton, aov_filter, additional_data, log.info("Creating data for: {}".format(subset_name)) - app = os.environ.get("AVALON_APP", "") + app = os.environ.get("AYON_HOST_NAME", "") if isinstance(col, list): render_file_name = os.path.basename(col[0]) diff --git a/client/ayon_core/pipeline/load/plugins.py b/client/ayon_core/pipeline/load/plugins.py index fc64edf2ae..1d4627689f 100644 --- a/client/ayon_core/pipeline/load/plugins.py +++ b/client/ayon_core/pipeline/load/plugins.py @@ -38,7 +38,7 @@ class LoaderPlugin(list): @classmethod def apply_settings(cls, project_settings, system_settings): - host_name = os.environ.get("AVALON_APP") + host_name = os.environ.get("AYON_HOST_NAME") plugin_type = "load" plugin_type_settings = ( project_settings diff --git a/client/ayon_core/pipeline/publish/lib.py b/client/ayon_core/pipeline/publish/lib.py index 47f4be9e69..a62c2d9c5b 100644 --- a/client/ayon_core/pipeline/publish/lib.py +++ b/client/ayon_core/pipeline/publish/lib.py @@ -437,7 +437,7 @@ def filter_pyblish_plugins(plugins): # - kept becau on farm is probably used host 'shell' which propably # affect how settings are applied there host_name = pyblish.api.current_host() - project_name = os.environ.get("AVALON_PROJECT") + project_name = os.environ.get("AYON_PROJECT_NAME") project_settings = get_project_settings(project_name) system_settings = get_system_settings() diff --git a/client/ayon_core/pipeline/workfile/build_workfile.py b/client/ayon_core/pipeline/workfile/build_workfile.py index c62facaaa9..6b13eeeed6 100644 --- a/client/ayon_core/pipeline/workfile/build_workfile.py +++ b/client/ayon_core/pipeline/workfile/build_workfile.py @@ -229,8 +229,8 @@ class BuildWorkfile: def get_build_presets(self, task_name, asset_doc): """ Returns presets to build workfile for task name. - Presets are loaded for current project set in - io.Session["AVALON_PROJECT"], filtered by registered host + Presets are loaded for current project received by + 'get_current_project_name', filtered by registered host and entered task name. Args: diff --git a/client/ayon_core/pipeline/workfile/path_resolving.py b/client/ayon_core/pipeline/workfile/path_resolving.py index 95a0a03c60..2062705d3c 100644 --- a/client/ayon_core/pipeline/workfile/path_resolving.py +++ b/client/ayon_core/pipeline/workfile/path_resolving.py @@ -157,7 +157,7 @@ def get_workdir( task_name (str): Task name for which are workdir data preapred. host_name (str): Host which is used to workdir. This is required because workdir template may contain `{app}` key. In `Session` - is stored under `AVALON_APP` key. + is stored under `AYON_HOST_NAME` key. anatomy (Anatomy): Optional argument. Anatomy object is created using project name from `project_doc`. It is preferred to pass this argument as initialization of a new Anatomy object may be time diff --git a/client/ayon_core/pipeline/workfile/workfile_template_builder.py b/client/ayon_core/pipeline/workfile/workfile_template_builder.py index 1afe26813f..9778e60d1b 100644 --- a/client/ayon_core/pipeline/workfile/workfile_template_builder.py +++ b/client/ayon_core/pipeline/workfile/workfile_template_builder.py @@ -103,7 +103,7 @@ class AbstractTemplateBuilder(object): if isinstance(host, HostBase): host_name = host.name else: - host_name = os.environ.get("AVALON_APP") + host_name = os.environ.get("AYON_HOST_NAME") self._host = host self._host_name = host_name @@ -129,19 +129,19 @@ class AbstractTemplateBuilder(object): def project_name(self): if isinstance(self._host, HostBase): return self._host.get_current_project_name() - return os.getenv("AVALON_PROJECT") + return os.getenv("AYON_PROJECT_NAME") @property def current_asset_name(self): if isinstance(self._host, HostBase): return self._host.get_current_asset_name() - return os.getenv("AVALON_ASSET") + return os.getenv("AYON_FOLDER_PATH") @property def current_task_name(self): if isinstance(self._host, HostBase): return self._host.get_current_task_name() - return os.getenv("AVALON_TASK") + return os.getenv("AYON_TASK_NAME") def get_current_context(self): if isinstance(self._host, HostBase): @@ -579,7 +579,7 @@ class AbstractTemplateBuilder(object): template_path (str): Fullpath for current task and host's template file. """ - last_workfile_path = os.environ.get("AVALON_LAST_WORKFILE") + last_workfile_path = os.environ.get("AYON_LAST_WORKFILE") self.log.info("__ last_workfile_path: {}".format(last_workfile_path)) if os.path.exists(last_workfile_path): # ignore in case workfile existence diff --git a/client/ayon_core/plugins/actions/open_file_explorer.py b/client/ayon_core/plugins/actions/open_file_explorer.py index b29ed30258..fba3c231a5 100644 --- a/client/ayon_core/plugins/actions/open_file_explorer.py +++ b/client/ayon_core/plugins/actions/open_file_explorer.py @@ -22,14 +22,14 @@ class OpenTaskPath(LauncherAction): def is_compatible(self, session): """Return whether the action is compatible with the session""" - return bool(session.get("AVALON_ASSET")) + return bool(session.get("AYON_FOLDER_PATH")) def process(self, session, **kwargs): from qtpy import QtCore, QtWidgets - project_name = session["AVALON_PROJECT"] - asset_name = session["AVALON_ASSET"] - task_name = session.get("AVALON_TASK", None) + project_name = session["AYON_PROJECT_NAME"] + asset_name = session["AYON_FOLDER_PATH"] + task_name = session.get("AYON_TASK_NAME", None) path = self._get_workdir(project_name, asset_name, task_name) if not path: diff --git a/client/ayon_core/plugins/load/delete_old_versions.py b/client/ayon_core/plugins/load/delete_old_versions.py index 6b3263e2b6..956b232e2b 100644 --- a/client/ayon_core/plugins/load/delete_old_versions.py +++ b/client/ayon_core/plugins/load/delete_old_versions.py @@ -359,7 +359,7 @@ # # if mongo_changes_bulk: # dbcon = AvalonMongoDB() -# dbcon.Session["AVALON_PROJECT"] = project_name +# dbcon.Session["AYON_PROJECT_NAME"] = project_name # dbcon.install() # dbcon.bulk_write(mongo_changes_bulk) # dbcon.uninstall() diff --git a/client/ayon_core/plugins/publish/collect_anatomy_context_data.py b/client/ayon_core/plugins/publish/collect_anatomy_context_data.py index 978ae5e1e1..fbdf26e76c 100644 --- a/client/ayon_core/plugins/publish/collect_anatomy_context_data.py +++ b/client/ayon_core/plugins/publish/collect_anatomy_context_data.py @@ -4,9 +4,9 @@ Requires: context -> anatomy context -> projectEntity context -> assetEntity + context -> task context -> username context -> datetimeData - session -> AVALON_TASK Provides: context -> anatomyData diff --git a/client/ayon_core/plugins/publish/collect_context_entities.py b/client/ayon_core/plugins/publish/collect_context_entities.py index 8480435e21..30bb184ef5 100644 --- a/client/ayon_core/plugins/publish/collect_context_entities.py +++ b/client/ayon_core/plugins/publish/collect_context_entities.py @@ -1,7 +1,6 @@ """Collect Anatomy and global anatomy data. Requires: - session -> AVALON_ASSET context -> projectName context -> asset context -> task diff --git a/client/ayon_core/plugins/publish/collect_from_create_context.py b/client/ayon_core/plugins/publish/collect_from_create_context.py index d8e803a43c..edb5cc1654 100644 --- a/client/ayon_core/plugins/publish/collect_from_create_context.py +++ b/client/ayon_core/plugins/publish/collect_from_create_context.py @@ -57,9 +57,9 @@ class CollectFromCreateContext(pyblish.api.ContextPlugin): asset_name = create_context.get_current_asset_name() task_name = create_context.get_current_task_name() for key, value in ( - ("AVALON_PROJECT", project_name), - ("AVALON_ASSET", asset_name), - ("AVALON_TASK", task_name) + ("AYON_PROJECT_NAME", project_name), + ("AYON_FOLDER_PATH", asset_name), + ("AYON_TASK_NAME", task_name) ): os.environ[key] = value diff --git a/client/ayon_core/plugins/publish/collect_host_name.py b/client/ayon_core/plugins/publish/collect_host_name.py index 89e4e03c1a..e76579bbd2 100644 --- a/client/ayon_core/plugins/publish/collect_host_name.py +++ b/client/ayon_core/plugins/publish/collect_host_name.py @@ -24,13 +24,13 @@ class CollectHostName(pyblish.api.ContextPlugin): if host_name and app_name and app_label: return - # Use AVALON_APP to get host name if available + # Use AYON_HOST_NAME to get host name if available if not host_name: - host_name = os.environ.get("AVALON_APP") + host_name = os.environ.get("AYON_HOST_NAME") - # Use AVALON_APP_NAME to get full app name + # Use AYON_APP_NAME to get full app name if not app_name: - app_name = os.environ.get("AVALON_APP_NAME") + app_name = os.environ.get("AYON_APP_NAME") # Fill missing values based on app full name if (not host_name or not app_label) and app_name: diff --git a/client/ayon_core/plugins/publish/collect_rendered_files.py b/client/ayon_core/plugins/publish/collect_rendered_files.py index a7b6064b7a..9a316b69a4 100644 --- a/client/ayon_core/plugins/publish/collect_rendered_files.py +++ b/client/ayon_core/plugins/publish/collect_rendered_files.py @@ -179,14 +179,14 @@ class CollectRenderedFiles(pyblish.api.ContextPlugin): ) # Remap workdir if it's set - workdir = os.getenv("AVALON_WORKDIR") + workdir = os.getenv("AYON_WORKDIR") remapped_workdir = None if workdir: remapped_workdir = anatomy.roots_obj.path_remapper( - os.getenv("AVALON_WORKDIR") + os.getenv("AYON_WORKDIR") ) if remapped_workdir: - os.environ["AVALON_WORKDIR"] = remapped_workdir + os.environ["AYON_WORKDIR"] = remapped_workdir except Exception as e: self.log.error(e, exc_info=True) raise Exception("Error") from e diff --git a/client/ayon_core/scripts/non_python_host_launch.py b/client/ayon_core/scripts/non_python_host_launch.py index 97632e98ad..4c18fd0ccc 100644 --- a/client/ayon_core/scripts/non_python_host_launch.py +++ b/client/ayon_core/scripts/non_python_host_launch.py @@ -79,7 +79,7 @@ def main(argv): if after_script_idx is not None: launch_args = sys_args[after_script_idx:] - host_name = os.environ["AVALON_APP"].lower() + host_name = os.environ["AYON_HOST_NAME"].lower() if host_name == "photoshop": # TODO refactor launch logic according to AE from ayon_core.hosts.photoshop.api.lib import main @@ -90,7 +90,7 @@ def main(argv): else: title = "Unknown host name" message = ( - "BUG: Environment variable AVALON_APP contains unknown" + "BUG: Environment variable AYON_HOST_NAME contains unknown" " host name \"{}\"" ).format(host_name) show_error_messagebox(title, message) diff --git a/client/ayon_core/settings/lib.py b/client/ayon_core/settings/lib.py index beae376b7c..717d3fba3a 100644 --- a/client/ayon_core/settings/lib.py +++ b/client/ayon_core/settings/lib.py @@ -240,15 +240,15 @@ def get_site_local_overrides(project_name, site_name, local_settings=None): def get_current_project_settings(): """Project settings for current context project. - Project name should be stored in environment variable `AVALON_PROJECT`. + Project name should be stored in environment variable `AYON_PROJECT_NAME`. This function should be used only in host context where environment variable must be set and should not happen that any part of process will change the value of the enviornment variable. """ - project_name = os.environ.get("AVALON_PROJECT") + project_name = os.environ.get("AYON_PROJECT_NAME") if not project_name: raise ValueError( - "Missing context project in environemt variable `AVALON_PROJECT`." + "Missing context project in environemt variable `AYON_PROJECT_NAME`." ) return get_project_settings(project_name) diff --git a/client/ayon_core/tools/experimental_tools/tools_def.py b/client/ayon_core/tools/experimental_tools/tools_def.py index 568c7032d0..be6762b239 100644 --- a/client/ayon_core/tools/experimental_tools/tools_def.py +++ b/client/ayon_core/tools/experimental_tools/tools_def.py @@ -139,7 +139,7 @@ class ExperimentalTools: def get_tools_for_host(self, host_name=None): if not host_name: - host_name = os.environ.get("AVALON_APP") + host_name = os.environ.get("AYON_HOST_NAME") tools = [] for tool in self.tools: if ( diff --git a/client/ayon_core/tools/launcher/models/actions.py b/client/ayon_core/tools/launcher/models/actions.py index 37024b5810..53d2b78dc3 100644 --- a/client/ayon_core/tools/launcher/models/actions.py +++ b/client/ayon_core/tools/launcher/models/actions.py @@ -69,9 +69,9 @@ class ApplicationAction(LauncherAction): _log = None required_session_keys = ( - "AVALON_PROJECT", - "AVALON_ASSET", - "AVALON_TASK" + "AYON_PROJECT_NAME", + "AYON_FOLDER_PATH", + "AYON_TASK_NAME" ) @property @@ -85,7 +85,7 @@ class ApplicationAction(LauncherAction): if not session.get(key): return False - project_name = session["AVALON_PROJECT"] + project_name = session["AYON_PROJECT_NAME"] project_entity = self.project_entities[project_name] apps = project_entity["attrib"].get("applications") if not apps or self.application.full_name not in apps: @@ -119,9 +119,9 @@ class ApplicationAction(LauncherAction): ApplicationLaunchFailed, ) - project_name = session["AVALON_PROJECT"] - asset_name = session["AVALON_ASSET"] - task_name = session["AVALON_TASK"] + project_name = session["AYON_PROJECT_NAME"] + asset_name = session["AYON_FOLDER_PATH"] + task_name = session["AYON_TASK_NAME"] try: self.application.launch( project_name=project_name, @@ -416,6 +416,10 @@ class ActionsModel: task_name = task["name"] return { + "AYON_PROJECT_NAME": project_name, + "AYON_FOLDER_PATH": folder_path, + "AYON_TASK_NAME": task_name, + # Deprecated - kept for backwards compatibility "AVALON_PROJECT": project_name, "AVALON_ASSET": folder_path, "AVALON_TASK": task_name, diff --git a/client/ayon_core/tools/publisher/control.py b/client/ayon_core/tools/publisher/control.py index 988362fee4..5ccd428551 100644 --- a/client/ayon_core/tools/publisher/control.py +++ b/client/ayon_core/tools/publisher/control.py @@ -1807,9 +1807,9 @@ class PublisherController(BasePublisherController): context_title = self._host.get_context_title() if context_title is None: - context_title = os.environ.get("AVALON_APP_NAME") + context_title = os.environ.get("AYON_APP_NAME") if context_title is None: - context_title = os.environ.get("AVALON_APP") + context_title = os.environ.get("AYON_HOST_NAME") return context_title diff --git a/client/ayon_core/tools/texture_copy/app.py b/client/ayon_core/tools/texture_copy/app.py index 9b4406d8e7..eef648eaf9 100644 --- a/client/ayon_core/tools/texture_copy/app.py +++ b/client/ayon_core/tools/texture_copy/app.py @@ -132,8 +132,8 @@ class TextureCopy: def texture_copy(asset, project, path): t.echo("*** Running Texture tool ***") t.echo(">>> Initializing avalon session ...") - os.environ["AVALON_PROJECT"] = project - os.environ["AVALON_ASSET"] = asset + os.environ["AYON_PROJECT_NAME"] = project + os.environ["AYON_FOLDER_PATH"] = asset TextureCopy().process(asset, project, path) diff --git a/client/ayon_core/tools/workfile_template_build/window.py b/client/ayon_core/tools/workfile_template_build/window.py index ae4946d41d..feb11c5e75 100644 --- a/client/ayon_core/tools/workfile_template_build/window.py +++ b/client/ayon_core/tools/workfile_template_build/window.py @@ -27,7 +27,7 @@ class WorkfileBuildPlaceholderDialog(QtWidgets.QDialog): host_name = getattr(self._host, "name", None) if not host_name: - host_name = os.getenv("AVALON_APP") or "NA" + host_name = os.getenv("AYON_HOST_NAME") or "NA" self._host_name = host_name plugins_combo = QtWidgets.QComboBox(self) From 31460538f9b557921bfc18dcfd02f5322ca7a7b2 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Mon, 12 Feb 2024 16:17:51 +0100 Subject: [PATCH 078/185] fix session requirement --- client/ayon_core/hosts/maya/plugins/publish/collect_render.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/client/ayon_core/hosts/maya/plugins/publish/collect_render.py b/client/ayon_core/hosts/maya/plugins/publish/collect_render.py index 7daab19f4a..4ea91ccb0d 100644 --- a/client/ayon_core/hosts/maya/plugins/publish/collect_render.py +++ b/client/ayon_core/hosts/maya/plugins/publish/collect_render.py @@ -8,13 +8,12 @@ publishing on farm. Requires: instance -> families instance -> setMembers + instance -> asset context -> currentFile context -> workspaceDir context -> user - session -> AYON_FOLDER_PATH - Optional: Provides: From 9caab106f782fb2d520da55af995111b77f73496 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Mon, 12 Feb 2024 16:26:10 +0100 Subject: [PATCH 079/185] use AYON prefix in harmony env variables --- client/ayon_core/hosts/harmony/api/README.md | 2 +- client/ayon_core/hosts/harmony/api/TB_sceneOpened.js | 2 +- client/ayon_core/hosts/harmony/api/lib.py | 4 ++-- .../settings/defaults/system_settings/applications.json | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/client/ayon_core/hosts/harmony/api/README.md b/client/ayon_core/hosts/harmony/api/README.md index cdc17b2285..680a88c423 100644 --- a/client/ayon_core/hosts/harmony/api/README.md +++ b/client/ayon_core/hosts/harmony/api/README.md @@ -52,7 +52,7 @@ Because Harmony projects are directories, this integration uses `.zip` as work f ### Show Workfiles on launch -You can show the Workfiles app when Harmony launches by setting environment variable `AVALON_HARMONY_WORKFILES_ON_LAUNCH=1`. +You can show the Workfiles app when Harmony launches by setting environment variable `AYON_HARMONY_WORKFILES_ON_LAUNCH=1`. ## Developing diff --git a/client/ayon_core/hosts/harmony/api/TB_sceneOpened.js b/client/ayon_core/hosts/harmony/api/TB_sceneOpened.js index 1fb0d295e7..cdf60c1aa8 100644 --- a/client/ayon_core/hosts/harmony/api/TB_sceneOpened.js +++ b/client/ayon_core/hosts/harmony/api/TB_sceneOpened.js @@ -349,7 +349,7 @@ function start() { /** hostname or ip of server - should be localhost */ var host = '127.0.0.1'; /** port of the server */ - var port = parseInt(System.getenv('AVALON_HARMONY_PORT')); + var port = parseInt(System.getenv('AYON_HARMONY_PORT')); // Attach the client to the QApplication to preserve. var app = QCoreApplication.instance(); diff --git a/client/ayon_core/hosts/harmony/api/lib.py b/client/ayon_core/hosts/harmony/api/lib.py index 782134c343..bc73e19066 100644 --- a/client/ayon_core/hosts/harmony/api/lib.py +++ b/client/ayon_core/hosts/harmony/api/lib.py @@ -189,14 +189,14 @@ def launch(application_path, *args): install_host(harmony) ProcessContext.port = random.randrange(49152, 65535) - os.environ["AVALON_HARMONY_PORT"] = str(ProcessContext.port) + os.environ["AYON_HARMONY_PORT"] = str(ProcessContext.port) ProcessContext.application_path = application_path # Launch Harmony. setup_startup_scripts() check_libs() - if not os.environ.get("AVALON_HARMONY_WORKFILES_ON_LAUNCH", False): + if not os.environ.get("AYON_HARMONY_WORKFILES_ON_LAUNCH", False): open_empty_workfile() return diff --git a/client/ayon_core/settings/defaults/system_settings/applications.json b/client/ayon_core/settings/defaults/system_settings/applications.json index a5283751e9..2610c15315 100644 --- a/client/ayon_core/settings/defaults/system_settings/applications.json +++ b/client/ayon_core/settings/defaults/system_settings/applications.json @@ -1271,7 +1271,7 @@ "icon": "{}/app_icons/harmony.png", "host_name": "harmony", "environment": { - "AVALON_HARMONY_WORKFILES_ON_LAUNCH": "1" + "AYON_HARMONY_WORKFILES_ON_LAUNCH": "1" }, "variants": { "21": { From f1c70af6ef090e34e9538984deb58014074a4a79 Mon Sep 17 00:00:00 2001 From: Toke Stuart Jepsen Date: Mon, 12 Feb 2024 15:42:27 +0000 Subject: [PATCH 080/185] Add submodule --- client/ayon_core/hosts/unreal/integration | 1 + 1 file changed, 1 insertion(+) create mode 160000 client/ayon_core/hosts/unreal/integration diff --git a/client/ayon_core/hosts/unreal/integration b/client/ayon_core/hosts/unreal/integration new file mode 160000 index 0000000000..6d2793170e --- /dev/null +++ b/client/ayon_core/hosts/unreal/integration @@ -0,0 +1 @@ +Subproject commit 6d2793170ed57187842f683a943593973abcc337 From 28ae27f5b034e782a1532298a5d85656f1fc1f6d Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Mon, 12 Feb 2024 16:47:07 +0100 Subject: [PATCH 081/185] fix kitsu conversion --- client/ayon_core/settings/ayon_settings.py | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/client/ayon_core/settings/ayon_settings.py b/client/ayon_core/settings/ayon_settings.py index 1aa82995b6..35652d5c3c 100644 --- a/client/ayon_core/settings/ayon_settings.py +++ b/client/ayon_core/settings/ayon_settings.py @@ -82,6 +82,20 @@ def _convert_general(ayon_settings, output, default_settings): } +def _convert_kitsu_system_settings( + ayon_settings, output, addon_versions, default_settings +): + if "kitsu" in ayon_settings: + output["kitsu"] = ayon_settings["kitsu"] + + enabled = addon_versions.get("kitsu") is not None + kitsu_settings = default_settings["modules"]["kitsu"] + kitsu_settings["enabled"] = enabled + if enabled: + kitsu_settings["server"] = ayon_settings["kitsu"]["server"] + output["modules"]["kitsu"] = kitsu_settings + + def _convert_timers_manager_system_settings( ayon_settings, output, addon_versions, default_settings ): From f22358e78fcdf93d545774cbc78b7c75a43e4c16 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Mon, 12 Feb 2024 17:42:13 +0100 Subject: [PATCH 082/185] fix default value in 'filter_output_defs' --- client/ayon_core/plugins/publish/extract_review.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/client/ayon_core/plugins/publish/extract_review.py b/client/ayon_core/plugins/publish/extract_review.py index 4e6ece0038..7af0da386b 100644 --- a/client/ayon_core/plugins/publish/extract_review.py +++ b/client/ayon_core/plugins/publish/extract_review.py @@ -1513,11 +1513,11 @@ class ExtractReview(pyblish.api.InstancePlugin): Returns: list: Containg all output definitions matching entered families. """ + filtered_outputs = {} outputs = profile.get("outputs") if not outputs: - return [] + return filtered_outputs - filtered_outputs = {} for output_def in outputs: filename_suffix = output_def["name"] output_filters = output_def.get("filter") From daf8228e9a2db00cbe8cb03b05078850e7cdde8e Mon Sep 17 00:00:00 2001 From: Braden Jennings Date: Tue, 13 Feb 2024 10:00:12 +1300 Subject: [PATCH 083/185] enhancement/OP-7723_hidden_joints_validator --- .../hosts/maya/plugins/publish/validate_rig_joints_hidden.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/client/ayon_core/hosts/maya/plugins/publish/validate_rig_joints_hidden.py b/client/ayon_core/hosts/maya/plugins/publish/validate_rig_joints_hidden.py index c6b9d23574..bb5ec8353e 100644 --- a/client/ayon_core/hosts/maya/plugins/publish/validate_rig_joints_hidden.py +++ b/client/ayon_core/hosts/maya/plugins/publish/validate_rig_joints_hidden.py @@ -7,6 +7,7 @@ from ayon_core.hosts.maya.api import lib from ayon_core.pipeline.publish import ( RepairAction, ValidateContentsOrder, + PublishValidationError ) @@ -38,7 +39,8 @@ class ValidateRigJointsHidden(pyblish.api.InstancePlugin): invalid = self.get_invalid(instance) if invalid: - raise ValueError("Visible joints found: {0}".format(invalid)) + raise PublishValidationError( + "Visible joints found: {0}".format(invalid)) @classmethod def repair(cls, instance): From 6e30f4a6f54c840d4105aedc9b1d3a50ad6f6026 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Mon, 12 Feb 2024 22:35:18 +0100 Subject: [PATCH 084/185] fix env auto fix --- .../repository/custom/plugins/GlobalJobPreLoad.py | 12 ++++++------ .../perjob/m50__openpype_publish_render.py | 12 ++++++------ 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/client/ayon_core/modules/deadline/repository/custom/plugins/GlobalJobPreLoad.py b/client/ayon_core/modules/deadline/repository/custom/plugins/GlobalJobPreLoad.py index 8b539931fb..330bf5b0c9 100644 --- a/client/ayon_core/modules/deadline/repository/custom/plugins/GlobalJobPreLoad.py +++ b/client/ayon_core/modules/deadline/repository/custom/plugins/GlobalJobPreLoad.py @@ -474,12 +474,12 @@ def inject_ayon_environment(deadlinePlugin): "envgroup": "farm", } # Support backwards compatible keys - for key, env_keys in { - "project": ["AYON_PROJECT_NAME", "AVALON_PROJECT"], - "asset": ["AYON_FOLDER_PATH", "AVALON_ASSET"], - "task": ["AYON_TASK_NAME", "AVALON_TASK"], - "app": ["AYON_APP_NAME", "AVALON_APP_NAME"], - }: + for key, env_keys in ( + ("project", ["AYON_PROJECT_NAME", "AVALON_PROJECT"]), + ("asset", ["AYON_FOLDER_PATH", "AVALON_ASSET"], + ("task", ["AYON_TASK_NAME", "AVALON_TASK"]), + ("app", ["AYON_APP_NAME", "AVALON_APP_NAME"]), + ): value = "" for env_key in env_keys: value = job.GetJobEnvironmentKeyValue(env_key) diff --git a/client/ayon_core/modules/royalrender/rr_root/plugins/control_job/perjob/m50__openpype_publish_render.py b/client/ayon_core/modules/royalrender/rr_root/plugins/control_job/perjob/m50__openpype_publish_render.py index cfec2622d9..778052778f 100644 --- a/client/ayon_core/modules/royalrender/rr_root/plugins/control_job/perjob/m50__openpype_publish_render.py +++ b/client/ayon_core/modules/royalrender/rr_root/plugins/control_job/perjob/m50__openpype_publish_render.py @@ -182,12 +182,12 @@ print("running selector") selector = OpenPypeContextSelector() # try to set context from environment -for key, env_keys in { - "project": ["AYON_PROJECT_NAME", "AVALON_PROJECT"], - "asset": ["AYON_FOLDER_PATH", "AVALON_ASSET"], - "task": ["AYON_TASK_NAME", "AVALON_TASK"], - # "app_name": ["AYON_APP_NAME", "AVALON_APP_NAME"] -}: +for key, env_keys in ( + ("project", ["AYON_PROJECT_NAME", "AVALON_PROJECT"]), + ("asset", ["AYON_FOLDER_PATH", "AVALON_ASSET"]), + ("task", ["AYON_TASK_NAME", "AVALON_TASK"]), + # ("app_name", ["AYON_APP_NAME", "AVALON_APP_NAME"]) +): value = "" for env_key in env_keys: value = os.getenv(env_key) From bf82de09d09e1a8704c7a47884d919c16d8000ef Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Mon, 12 Feb 2024 22:38:51 +0100 Subject: [PATCH 085/185] add version that is printed in GlobalJobPreLoad plugin --- .../deadline/repository/custom/plugins/GlobalJobPreLoad.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/client/ayon_core/modules/deadline/repository/custom/plugins/GlobalJobPreLoad.py b/client/ayon_core/modules/deadline/repository/custom/plugins/GlobalJobPreLoad.py index 81aab00b93..459153c957 100644 --- a/client/ayon_core/modules/deadline/repository/custom/plugins/GlobalJobPreLoad.py +++ b/client/ayon_core/modules/deadline/repository/custom/plugins/GlobalJobPreLoad.py @@ -14,7 +14,7 @@ from Deadline.Scripting import ( DirectoryUtils, ProcessUtils, ) - +__version__ = "1.0.0" VERSION_REGEX = re.compile( r"(?P0|[1-9]\d*)" r"\.(?P0|[1-9]\d*)" @@ -593,7 +593,7 @@ def inject_render_job_id(deadlinePlugin): def __main__(deadlinePlugin): - print("*** GlobalJobPreload start ...") + print("*** GlobalJobPreload {} start ...".format(__version__)) print(">>> Getting job ...") job = deadlinePlugin.GetJob() From 2c93caebbff89ce5ae7d9a40a286e972ff733c7c Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Mon, 12 Feb 2024 23:02:52 +0100 Subject: [PATCH 086/185] adding workflow pr-labeler missing config --- .github/pr-glob-labeler.yml | 102 ++++++++++++++++++++++++++++++++++++ 1 file changed, 102 insertions(+) create mode 100644 .github/pr-glob-labeler.yml diff --git a/.github/pr-glob-labeler.yml b/.github/pr-glob-labeler.yml new file mode 100644 index 0000000000..286e7768b5 --- /dev/null +++ b/.github/pr-glob-labeler.yml @@ -0,0 +1,102 @@ +# Add type: unittest label if any changes in tests folders +'type: unittest': +- '*/*tests*/**/*' + +# any changes in documentation structure +'type: documentation': +- '*/**/*website*/**/*' +- '*/**/*docs*/**/*' + +# hosts triage +'host: Nuke': +- '*/**/*nuke*' +- '*/**/*nuke*/**/*' + +'host: Photoshop': +- '*/**/*photoshop*' +- '*/**/*photoshop*/**/*' + +'host: Harmony': +- '*/**/*harmony*' +- '*/**/*harmony*/**/*' + +'host: UE': +- '*/**/*unreal*' +- '*/**/*unreal*/**/*' + +'host: Houdini': +- '*/**/*houdini*' +- '*/**/*houdini*/**/*' + +'host: Maya': +- '*/**/*maya*' +- '*/**/*maya*/**/*' + +'host: Resolve': +- '*/**/*resolve*' +- '*/**/*resolve*/**/*' + +'host: Blender': +- '*/**/*blender*' +- '*/**/*blender*/**/*' + +'host: Hiero': +- '*/**/*hiero*' +- '*/**/*hiero*/**/*' + +'host: Fusion': +- '*/**/*fusion*' +- '*/**/*fusion*/**/*' + +'host: Flame': +- '*/**/*flame*' +- '*/**/*flame*/**/*' + +'host: TrayPublisher': +- '*/**/*traypublisher*' +- '*/**/*traypublisher*/**/*' + +'host: 3dsmax': +- '*/**/*max*' +- '*/**/*max*/**/*' + +'host: TV Paint': +- '*/**/*tvpaint*' +- '*/**/*tvpaint*/**/*' + +'host: CelAction': +- '*/**/*celaction*' +- '*/**/*celaction*/**/*' + +'host: After Effects': +- '*/**/*aftereffects*' +- '*/**/*aftereffects*/**/*' + +'host: Substance Painter': +- '*/**/*substancepainter*' +- '*/**/*substancepainter*/**/*' + +# modules triage +'module: Deadline': +- '*/**/*deadline*' +- '*/**/*deadline*/**/*' + +'module: RoyalRender': +- '*/**/*royalrender*' +- '*/**/*royalrender*/**/*' + +'module: Sitesync': +- '*/**/*sync_server*' +- '*/**/*sync_server*/**/*' + +'module: Ftrack': +- '*/**/*ftrack*' +- '*/**/*ftrack*/**/*' + +'module: Shotgrid': +- '*/**/*shotgrid*' +- '*/**/*shotgrid*/**/*' + +'module: Kitsu': +- '*/**/*kitsu*' +- '*/**/*kitsu*/**/*' From 87d5b3baeced304c02ffdd8c4d44d18907c32e94 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Mon, 12 Feb 2024 23:06:14 +0100 Subject: [PATCH 087/185] fix overscan_color default value --- server/settings/publish_plugins.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/settings/publish_plugins.py b/server/settings/publish_plugins.py index c684ddda40..c01fb92b9c 100644 --- a/server/settings/publish_plugins.py +++ b/server/settings/publish_plugins.py @@ -946,7 +946,7 @@ DEFAULT_PUBLISH_VALUES = { "single_frame_filter": "multi_frame" }, "overscan_crop": "", - "overscan_color": [0, 0, 0, 1.0], + "overscan_color": [0, 0, 0], "width": 0, "height": 0, "scale_pixel_aspect": True, From 1d85cec34c86e771b1339d6c5fd41fe5f877457c Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Tue, 13 Feb 2024 10:08:29 +0100 Subject: [PATCH 088/185] fix return type hint --- client/ayon_core/plugins/publish/extract_review.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/client/ayon_core/plugins/publish/extract_review.py b/client/ayon_core/plugins/publish/extract_review.py index 7af0da386b..2ab70038c6 100644 --- a/client/ayon_core/plugins/publish/extract_review.py +++ b/client/ayon_core/plugins/publish/extract_review.py @@ -1511,7 +1511,8 @@ class ExtractReview(pyblish.api.InstancePlugin): subset_name (str): name of subset Returns: - list: Containg all output definitions matching entered families. + dict[str, Any]: Containg all output definitions matching entered + families. """ filtered_outputs = {} outputs = profile.get("outputs") From 646a40635def59c2c7512ab8ca59c8ab949ed579 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Tue, 13 Feb 2024 10:29:19 +0100 Subject: [PATCH 089/185] add version to AYON plugin --- .../modules/deadline/repository/custom/plugins/Ayon/Ayon.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/client/ayon_core/modules/deadline/repository/custom/plugins/Ayon/Ayon.py b/client/ayon_core/modules/deadline/repository/custom/plugins/Ayon/Ayon.py index a1f752605d..de0a2c6d7a 100644 --- a/client/ayon_core/modules/deadline/repository/custom/plugins/Ayon/Ayon.py +++ b/client/ayon_core/modules/deadline/repository/custom/plugins/Ayon/Ayon.py @@ -15,6 +15,7 @@ import re import os import platform +__version__ = "1.0.0" ###################################################################### # This is the function that Deadline calls to get an instance of the @@ -52,6 +53,9 @@ class AyonDeadlinePlugin(DeadlinePlugin): del self.RenderArgumentCallback def InitializeProcess(self): + self.LogInfo( + "Initializing process with AYON plugin {}".format(__version__) + ) self.PluginType = PluginType.Simple self.StdoutHandling = True From f221dfa4252df76e52a9906887693a43fff6fd9a Mon Sep 17 00:00:00 2001 From: Jakub Trllo <43494761+iLLiCiTiT@users.noreply.github.com> Date: Tue, 13 Feb 2024 10:53:11 +0100 Subject: [PATCH 090/185] Change label back --- .../ayon_core/hosts/photoshop/plugins/publish/collect_review.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/ayon_core/hosts/photoshop/plugins/publish/collect_review.py b/client/ayon_core/hosts/photoshop/plugins/publish/collect_review.py index 3a4b7b5828..1ffbadf022 100644 --- a/client/ayon_core/hosts/photoshop/plugins/publish/collect_review.py +++ b/client/ayon_core/hosts/photoshop/plugins/publish/collect_review.py @@ -13,7 +13,7 @@ class CollectReview(pyblish.api.ContextPlugin): """Adds review to families for instances marked to be reviewable. """ - label = "Collect Review Family" + label = "Collect Review" hosts = ["photoshop"] order = pyblish.api.CollectorOrder + 0.1 From d751fdd798255ca971a2f9ed912f8dbb0ce24b41 Mon Sep 17 00:00:00 2001 From: Jakub Trllo <43494761+iLLiCiTiT@users.noreply.github.com> Date: Tue, 13 Feb 2024 11:00:45 +0100 Subject: [PATCH 091/185] fix return docstring Co-authored-by: Roy Nieterau --- client/ayon_core/plugins/publish/extract_review.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/ayon_core/plugins/publish/extract_review.py b/client/ayon_core/plugins/publish/extract_review.py index 2ab70038c6..b0bc94c317 100644 --- a/client/ayon_core/plugins/publish/extract_review.py +++ b/client/ayon_core/plugins/publish/extract_review.py @@ -1511,7 +1511,7 @@ class ExtractReview(pyblish.api.InstancePlugin): subset_name (str): name of subset Returns: - dict[str, Any]: Containg all output definitions matching entered + dict[str, Any]: Containing all output definitions matching entered families. """ filtered_outputs = {} From b5b4ec2e80ffe2eeafc910bb1c956376de787f56 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Tue, 13 Feb 2024 11:17:48 +0100 Subject: [PATCH 092/185] round loader colors --- server_addon/maya/server/settings/loaders.py | 192 ++++--------------- 1 file changed, 32 insertions(+), 160 deletions(-) diff --git a/server_addon/maya/server/settings/loaders.py b/server_addon/maya/server/settings/loaders.py index df1172ae7d..b8264a56ef 100644 --- a/server_addon/maya/server/settings/loaders.py +++ b/server_addon/maya/server/settings/loaders.py @@ -4,131 +4,67 @@ from ayon_server.types import ColorRGB_float class ColorsSetting(BaseSettingsModel): model: ColorRGB_float = SettingsField( - ( - 0.8196078431372549, - 0.5176470588235295, - 0.11764705882352941 - ), + (0.82, 0.52, 0.12), title="Model:" ) rig: ColorRGB_float = SettingsField( - ( - 0.23137254901960785, - 0.8862745098039215, - 0.9215686274509803 - ), + (0.23, 0.89, 0.92), title="Rig:" ) pointcache: ColorRGB_float = SettingsField( - ( - 0.3686274509803922, - 0.8196078431372549, - 0.11764705882352941 - ), + (0.37, 0.82, 0.12), title="Pointcache:" ) animation: ColorRGB_float = SettingsField( - ( - 0.3686274509803922, - 0.8196078431372549, - 0.11764705882352941 - ), + (0.37, 0.82, 0.12), title="Animation:" ) ass: ColorRGB_float = SettingsField( - ( - 0.9764705882352941, - 0.5294117647058824, - 0.20784313725490197 - ), + (0.98, 0.53, 0.21), title="Arnold StandIn:" ) camera: ColorRGB_float = SettingsField( - ( - 0.5333333333333333, - 0.4470588235294118, - 0.9568627450980393 - ), + (0.53, 0.45, 0.96), title="Camera:" ) fbx: ColorRGB_float = SettingsField( - ( - 0.8431372549019608, - 0.6509803921568628, - 1.0 - ), + (0.84, 0.65, 1.0), title="FBX:" ) mayaAscii: ColorRGB_float = SettingsField( - ( - 0.2627450980392157, - 0.6823529411764706, - 1.0 - ), + (0.26, 0.68, 1.0), title="Maya Ascii:" ) mayaScene: ColorRGB_float = SettingsField( - ( - 0.2627450980392157, - 0.6823529411764706, - 1.0 - ), + (0.26, 0.68, 1.0), title="Maya Scene:" ) setdress: ColorRGB_float = SettingsField( - ( - 1.0, - 0.9803921568627451, - 0.35294117647058826 - ), + (1.0, 0.98, 0.35), title="Set Dress:" ) layout: ColorRGB_float = SettingsField( - ( - 1.0, - 0.9803921568627451, - 0.35294117647058826 - ), + (1.0, 0.98, 0.35), title="Layout:" ) vdbcache: ColorRGB_float = SettingsField( - ( - 0.9764705882352941, - 0.21176470588235294, - 0.0 - ), + (0.98, 0.21, 0.0), title="VDB Cache:" ) vrayproxy: ColorRGB_float = SettingsField( - ( - 1.0, - 0.5882352941176471, - 0.047058823529411764 - ), + (1.0, 0.59, 0.05), title="VRay Proxy:" ) vrayscene_layer: ColorRGB_float = SettingsField( - ( - 1.0, - 0.5882352941176471, - 0.047058823529411764 - ), + (1.0, 0.59, 0.05), title="VRay Scene:" ) yeticache: ColorRGB_float = SettingsField( - ( - 0.38823529411764707, - 0.807843137254902, - 0.8627450980392157 - ), + (0.39, 0.81, 0.86), title="Yeti Cache:" ) yetiRig: ColorRGB_float = SettingsField( - ( - 0.0, - 0.803921568627451, - 0.49019607843137253 - ), + (0.0, 0.80, 0.49), title="Yeti Rig:" ) @@ -163,86 +99,22 @@ class LoadersModel(BaseSettingsModel): DEFAULT_LOADERS_SETTING = { "colors": { - "model": [ - 0.8196078431372549, - 0.5176470588235295, - 0.11764705882352941 - ], - "rig": [ - 0.23137254901960785, - 0.8862745098039215, - 0.9215686274509803 - ], - "pointcache": [ - 0.3686274509803922, - 0.8196078431372549, - 0.11764705882352941 - ], - "animation": [ - 0.3686274509803922, - 0.8196078431372549, - 0.11764705882352941 - ], - "ass": [ - 0.9764705882352941, - 0.5294117647058824, - 0.20784313725490197 - ], - "camera": [ - 0.5333333333333333, - 0.4470588235294118, - 0.9568627450980393 - ], - "fbx": [ - 0.8431372549019608, - 0.6509803921568628, - 1.0 - ], - "mayaAscii": [ - 0.2627450980392157, - 0.6823529411764706, - 1.0 - ], - "mayaScene": [ - 0.2627450980392157, - 0.6823529411764706, - 1.0 - ], - "setdress": [ - 1.0, - 0.9803921568627451, - 0.35294117647058826 - ], - "layout": [ - 1.0, - 0.9803921568627451, - 0.35294117647058826 - ], - "vdbcache": [ - 0.9764705882352941, - 0.21176470588235294, - 0.0 - ], - "vrayproxy": [ - 1.0, - 0.5882352941176471, - 0.047058823529411764 - ], - "vrayscene_layer": [ - 1.0, - 0.5882352941176471, - 0.047058823529411764 - ], - "yeticache": [ - 0.38823529411764707, - 0.807843137254902, - 0.8627450980392157 - ], - "yetiRig": [ - 0.0, - 0.803921568627451, - 0.49019607843137253 - ] + "model": [0.82, 0.52, 0.12], + "rig": [0.23, 0.89, 0.92], + "pointcache": [0.37, 0.82, 0.12], + "animation": [0.37, 0.82, 0.12], + "ass": [0.98, 0.53, 0.21], + "camera":[0.53, 0.45, 0.96], + "fbx": [0.84, 0.65, 1.0], + "mayaAscii": [0.26, 0.68, 1.0], + "mayaScene": [0.26, 0.68, 1.0], + "setdress": [1.0, 0.98, 0.35], + "layout": [1.0, 0.98, 0.35], + "vdbcache": [0.98, 0.21, 0.0], + "vrayproxy": [1.0, 0.59, 0.05], + "vrayscene_layer": [1.0, 0.59, 0.05], + "yeticache": [0.39, 0.81, 0.86], + "yetiRig": [0.0, 0.80, 0.49], }, "reference_loader": { "namespace": "{folder[name]}_{product[name]}_##_", From 0fb5c68ee8940f4ebb6d7dc4e54ea30b103cc8f8 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Tue, 13 Feb 2024 11:31:41 +0100 Subject: [PATCH 093/185] do not force asset and task during publishing --- .../ayon_core/plugins/publish/collect_from_create_context.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/client/ayon_core/plugins/publish/collect_from_create_context.py b/client/ayon_core/plugins/publish/collect_from_create_context.py index d8e803a43c..7adacbc463 100644 --- a/client/ayon_core/plugins/publish/collect_from_create_context.py +++ b/client/ayon_core/plugins/publish/collect_from_create_context.py @@ -61,7 +61,10 @@ class CollectFromCreateContext(pyblish.api.ContextPlugin): ("AVALON_ASSET", asset_name), ("AVALON_TASK", task_name) ): - os.environ[key] = value + if value is None: + os.environ.pop(key, None) + else: + os.environ[key] = value def create_instance( self, From 9ce795dcedbff897f27816f6a63f10bfb4e3fbaf Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Tue, 13 Feb 2024 11:45:02 +0100 Subject: [PATCH 094/185] implement 'is_in_tests' in lib --- client/ayon_core/lib/__init__.py | 2 ++ client/ayon_core/lib/ayon_info.py | 10 ++++++++++ 2 files changed, 12 insertions(+) diff --git a/client/ayon_core/lib/__init__.py b/client/ayon_core/lib/__init__.py index 12a5535a1c..e917467e7c 100644 --- a/client/ayon_core/lib/__init__.py +++ b/client/ayon_core/lib/__init__.py @@ -158,6 +158,7 @@ from .ayon_info import ( is_running_from_build, is_staging_enabled, is_dev_mode_enabled, + is_in_tests, ) @@ -278,6 +279,7 @@ __all__ = [ "is_running_from_build", "is_staging_enabled", "is_dev_mode_enabled", + "is_in_tests", "requests_get", "requests_post" diff --git a/client/ayon_core/lib/ayon_info.py b/client/ayon_core/lib/ayon_info.py index 725e10fa0e..97a35adcc6 100644 --- a/client/ayon_core/lib/ayon_info.py +++ b/client/ayon_core/lib/ayon_info.py @@ -38,6 +38,16 @@ def is_staging_enabled(): return os.getenv("AYON_USE_STAGING") == "1" +def is_in_tests(): + """Process is running in automatic tests mode. + + Returns: + bool: True if running in tests. + + """ + return os.environ.get("AYON_IN_TESTS") == "1" + + def is_dev_mode_enabled(): """Dev mode is enabled in AYON. From 742a39ea9e0034c0397761843c058f0e7901f3c5 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Tue, 13 Feb 2024 11:45:33 +0100 Subject: [PATCH 095/185] use new location of 'is_in_tests' --- client/ayon_core/hosts/aftereffects/api/launch_logic.py | 3 +-- client/ayon_core/hosts/photoshop/api/lib.py | 3 +-- .../hosts/photoshop/plugins/publish/collect_batch_data.py | 2 +- .../plugins/publish/collect_color_coded_instances.py | 3 +-- .../plugins/publish/submit_aftereffects_deadline.py | 2 +- .../deadline/plugins/publish/submit_blender_deadline.py | 2 +- .../deadline/plugins/publish/submit_harmony_deadline.py | 2 +- .../plugins/publish/submit_houdini_cache_deadline.py | 2 +- .../plugins/publish/submit_houdini_render_deadline.py | 2 +- .../deadline/plugins/publish/submit_maya_deadline.py | 4 ++-- .../publish/submit_maya_remote_publish_deadline.py | 2 +- .../deadline/plugins/publish/submit_nuke_deadline.py | 2 +- .../deadline/plugins/publish/submit_publish_cache_job.py | 3 +-- .../deadline/plugins/publish/submit_publish_job.py | 3 +-- client/ayon_core/modules/royalrender/lib.py | 8 ++++++-- client/ayon_core/pipeline/context_tools.py | 2 +- client/ayon_core/plugins/publish/cleanup.py | 2 +- client/ayon_core/plugins/publish/collect_scene_version.py | 3 +-- 18 files changed, 24 insertions(+), 26 deletions(-) diff --git a/client/ayon_core/hosts/aftereffects/api/launch_logic.py b/client/ayon_core/hosts/aftereffects/api/launch_logic.py index 3d09f4d53c..4ffed8cecf 100644 --- a/client/ayon_core/hosts/aftereffects/api/launch_logic.py +++ b/client/ayon_core/hosts/aftereffects/api/launch_logic.py @@ -15,8 +15,7 @@ from wsrpc_aiohttp import ( from qtpy import QtCore -from ayon_core.lib import Logger -from ayon_core.tests.lib import is_in_tests +from ayon_core.lib import Logger, is_in_tests from ayon_core.pipeline import install_host from ayon_core.addon import AddonsManager from ayon_core.tools.utils import host_tools, get_ayon_qt_app diff --git a/client/ayon_core/hosts/photoshop/api/lib.py b/client/ayon_core/hosts/photoshop/api/lib.py index 3111503e40..af14e6d02f 100644 --- a/client/ayon_core/hosts/photoshop/api/lib.py +++ b/client/ayon_core/hosts/photoshop/api/lib.py @@ -3,12 +3,11 @@ import sys import contextlib import traceback -from ayon_core.lib import env_value_to_bool, Logger +from ayon_core.lib import env_value_to_bool, Logger, is_in_tests from ayon_core.addon import AddonsManager from ayon_core.pipeline import install_host from ayon_core.tools.utils import host_tools from ayon_core.tools.utils import get_ayon_qt_app -from ayon_core.tests.lib import is_in_tests from .launch_logic import ProcessLauncher, stub diff --git a/client/ayon_core/hosts/photoshop/plugins/publish/collect_batch_data.py b/client/ayon_core/hosts/photoshop/plugins/publish/collect_batch_data.py index 6639040bd7..2912dbf23d 100644 --- a/client/ayon_core/hosts/photoshop/plugins/publish/collect_batch_data.py +++ b/client/ayon_core/hosts/photoshop/plugins/publish/collect_batch_data.py @@ -21,7 +21,7 @@ from openpype_modules.webpublisher.lib import ( get_batch_asset_task_info, parse_json ) -from ayon_core.tests.lib import is_in_tests +from ayon_core.lib import is_in_tests class CollectBatchData(pyblish.api.ContextPlugin): diff --git a/client/ayon_core/hosts/photoshop/plugins/publish/collect_color_coded_instances.py b/client/ayon_core/hosts/photoshop/plugins/publish/collect_color_coded_instances.py index e309da62ba..d486136f78 100644 --- a/client/ayon_core/hosts/photoshop/plugins/publish/collect_color_coded_instances.py +++ b/client/ayon_core/hosts/photoshop/plugins/publish/collect_color_coded_instances.py @@ -3,10 +3,9 @@ import re import pyblish.api -from ayon_core.lib import prepare_template_data +from ayon_core.lib import prepare_template_data, is_in_tests from ayon_core.hosts.photoshop import api as photoshop from ayon_core.settings import get_project_settings -from ayon_core.tests.lib import is_in_tests class CollectColorCodedInstances(pyblish.api.ContextPlugin): diff --git a/client/ayon_core/modules/deadline/plugins/publish/submit_aftereffects_deadline.py b/client/ayon_core/modules/deadline/plugins/publish/submit_aftereffects_deadline.py index 618b71bbaf..fb75f3a917 100644 --- a/client/ayon_core/modules/deadline/plugins/publish/submit_aftereffects_deadline.py +++ b/client/ayon_core/modules/deadline/plugins/publish/submit_aftereffects_deadline.py @@ -7,10 +7,10 @@ from datetime import datetime from ayon_core.lib import ( env_value_to_bool, collect_frames, + is_in_tests, ) from openpype_modules.deadline import abstract_submit_deadline from openpype_modules.deadline.abstract_submit_deadline import DeadlineJobInfo -from ayon_core.tests.lib import is_in_tests @attr.s diff --git a/client/ayon_core/modules/deadline/plugins/publish/submit_blender_deadline.py b/client/ayon_core/modules/deadline/plugins/publish/submit_blender_deadline.py index af864ace5b..07b9f6e819 100644 --- a/client/ayon_core/modules/deadline/plugins/publish/submit_blender_deadline.py +++ b/client/ayon_core/modules/deadline/plugins/publish/submit_blender_deadline.py @@ -10,10 +10,10 @@ from ayon_core.lib import ( BoolDef, NumberDef, TextDef, + is_in_tests, ) from ayon_core.pipeline.publish import AYONPyblishPluginMixin from ayon_core.pipeline.farm.tools import iter_expected_files -from ayon_core.tests.lib import is_in_tests from openpype_modules.deadline import abstract_submit_deadline from openpype_modules.deadline.abstract_submit_deadline import DeadlineJobInfo diff --git a/client/ayon_core/modules/deadline/plugins/publish/submit_harmony_deadline.py b/client/ayon_core/modules/deadline/plugins/publish/submit_harmony_deadline.py index 4d375299fa..c7047edd67 100644 --- a/client/ayon_core/modules/deadline/plugins/publish/submit_harmony_deadline.py +++ b/client/ayon_core/modules/deadline/plugins/publish/submit_harmony_deadline.py @@ -12,7 +12,7 @@ import pyblish.api from openpype_modules.deadline import abstract_submit_deadline from openpype_modules.deadline.abstract_submit_deadline import DeadlineJobInfo -from ayon_core.tests.lib import is_in_tests +from ayon_core.lib import is_in_tests class _ZipFile(ZipFile): diff --git a/client/ayon_core/modules/deadline/plugins/publish/submit_houdini_cache_deadline.py b/client/ayon_core/modules/deadline/plugins/publish/submit_houdini_cache_deadline.py index 96ee80c4d7..a864e15c76 100644 --- a/client/ayon_core/modules/deadline/plugins/publish/submit_houdini_cache_deadline.py +++ b/client/ayon_core/modules/deadline/plugins/publish/submit_houdini_cache_deadline.py @@ -7,11 +7,11 @@ import pyblish.api from ayon_core.lib import ( TextDef, NumberDef, + is_in_tests, ) from ayon_core.pipeline import ( AYONPyblishPluginMixin ) -from ayon_core.tests.lib import is_in_tests from openpype_modules.deadline import abstract_submit_deadline from openpype_modules.deadline.abstract_submit_deadline import DeadlineJobInfo diff --git a/client/ayon_core/modules/deadline/plugins/publish/submit_houdini_render_deadline.py b/client/ayon_core/modules/deadline/plugins/publish/submit_houdini_render_deadline.py index d7a062c9a6..dbc000a163 100644 --- a/client/ayon_core/modules/deadline/plugins/publish/submit_houdini_render_deadline.py +++ b/client/ayon_core/modules/deadline/plugins/publish/submit_houdini_render_deadline.py @@ -6,10 +6,10 @@ from datetime import datetime import pyblish.api from ayon_core.pipeline import AYONPyblishPluginMixin -from ayon_core.tests.lib import is_in_tests from openpype_modules.deadline import abstract_submit_deadline from openpype_modules.deadline.abstract_submit_deadline import DeadlineJobInfo from ayon_core.lib import ( + is_in_tests, BoolDef, NumberDef ) diff --git a/client/ayon_core/modules/deadline/plugins/publish/submit_maya_deadline.py b/client/ayon_core/modules/deadline/plugins/publish/submit_maya_deadline.py index 2b7a7cf698..79c5c364e0 100644 --- a/client/ayon_core/modules/deadline/plugins/publish/submit_maya_deadline.py +++ b/client/ayon_core/modules/deadline/plugins/publish/submit_maya_deadline.py @@ -35,14 +35,14 @@ from ayon_core.lib import ( BoolDef, NumberDef, TextDef, - EnumDef + EnumDef, + is_in_tests, ) from ayon_core.hosts.maya.api.lib_rendersettings import RenderSettings from ayon_core.hosts.maya.api.lib import get_attr_in_layer from openpype_modules.deadline import abstract_submit_deadline from openpype_modules.deadline.abstract_submit_deadline import DeadlineJobInfo -from ayon_core.tests.lib import is_in_tests from ayon_core.pipeline.farm.tools import iter_expected_files diff --git a/client/ayon_core/modules/deadline/plugins/publish/submit_maya_remote_publish_deadline.py b/client/ayon_core/modules/deadline/plugins/publish/submit_maya_remote_publish_deadline.py index ed360d84ae..c4a7a43ce0 100644 --- a/client/ayon_core/modules/deadline/plugins/publish/submit_maya_remote_publish_deadline.py +++ b/client/ayon_core/modules/deadline/plugins/publish/submit_maya_remote_publish_deadline.py @@ -3,7 +3,7 @@ import attr from datetime import datetime from ayon_core.pipeline import PublishXmlValidationError -from ayon_core.tests.lib import is_in_tests +from ayon_core.lib import is_in_tests from openpype_modules.deadline import abstract_submit_deadline from openpype_modules.deadline.abstract_submit_deadline import DeadlineJobInfo diff --git a/client/ayon_core/modules/deadline/plugins/publish/submit_nuke_deadline.py b/client/ayon_core/modules/deadline/plugins/publish/submit_nuke_deadline.py index 61a334e184..f6fcca4480 100644 --- a/client/ayon_core/modules/deadline/plugins/publish/submit_nuke_deadline.py +++ b/client/ayon_core/modules/deadline/plugins/publish/submit_nuke_deadline.py @@ -10,8 +10,8 @@ import pyblish.api from ayon_core.pipeline.publish import ( AYONPyblishPluginMixin ) -from ayon_core.tests.lib import is_in_tests from ayon_core.lib import ( + is_in_tests, BoolDef, NumberDef ) diff --git a/client/ayon_core/modules/deadline/plugins/publish/submit_publish_cache_job.py b/client/ayon_core/modules/deadline/plugins/publish/submit_publish_cache_job.py index 38ea31ab7b..e6b49d4e58 100644 --- a/client/ayon_core/modules/deadline/plugins/publish/submit_publish_cache_job.py +++ b/client/ayon_core/modules/deadline/plugins/publish/submit_publish_cache_job.py @@ -12,8 +12,7 @@ from ayon_core.client import ( get_last_version_by_subset_name, ) from ayon_core.pipeline import publish -from ayon_core.lib import EnumDef -from ayon_core.tests.lib import is_in_tests +from ayon_core.lib import EnumDef, is_in_tests from ayon_core.pipeline.version_start import get_versioning_start from ayon_core.pipeline.farm.pyblish_functions import ( diff --git a/client/ayon_core/modules/deadline/plugins/publish/submit_publish_job.py b/client/ayon_core/modules/deadline/plugins/publish/submit_publish_job.py index c4ab6a2932..89a50700ba 100644 --- a/client/ayon_core/modules/deadline/plugins/publish/submit_publish_job.py +++ b/client/ayon_core/modules/deadline/plugins/publish/submit_publish_job.py @@ -13,8 +13,7 @@ from ayon_core.client import ( get_last_version_by_subset_name, ) from ayon_core.pipeline import publish -from ayon_core.lib import EnumDef -from ayon_core.tests.lib import is_in_tests +from ayon_core.lib import EnumDef, is_in_tests from ayon_core.pipeline.version_start import get_versioning_start from ayon_core.pipeline.farm.pyblish_functions import ( diff --git a/client/ayon_core/modules/royalrender/lib.py b/client/ayon_core/modules/royalrender/lib.py index d985a39d24..b53c5e6186 100644 --- a/client/ayon_core/modules/royalrender/lib.py +++ b/client/ayon_core/modules/royalrender/lib.py @@ -10,7 +10,12 @@ from datetime import datetime import pyblish.api -from ayon_core.lib import BoolDef, NumberDef, is_running_from_build +from ayon_core.lib import ( + BoolDef, + NumberDef, + is_running_from_build, + is_in_tests, +) from ayon_core.lib.execute import run_ayon_launcher_process from ayon_core.modules.royalrender.api import Api as rrApi from ayon_core.modules.royalrender.rr_job import ( @@ -22,7 +27,6 @@ from ayon_core.modules.royalrender.rr_job import ( from ayon_core.pipeline import AYONPyblishPluginMixin from ayon_core.pipeline.publish import KnownPublishError from ayon_core.pipeline.publish.lib import get_published_workfile_instance -from ayon_core.tests.lib import is_in_tests class BaseCreateRoyalRenderJob(pyblish.api.InstancePlugin, diff --git a/client/ayon_core/pipeline/context_tools.py b/client/ayon_core/pipeline/context_tools.py index 339ef9187f..445e27604d 100644 --- a/client/ayon_core/pipeline/context_tools.py +++ b/client/ayon_core/pipeline/context_tools.py @@ -19,10 +19,10 @@ from ayon_core.client import ( get_asset_name_identifier, get_ayon_server_api_connection, ) +from ayon_core.lib import is_in_tests from ayon_core.lib.events import emit_event from ayon_core.addon import load_addons, AddonsManager from ayon_core.settings import get_project_settings -from ayon_core.tests.lib import is_in_tests from .publish.lib import filter_pyblish_plugins from .anatomy import Anatomy diff --git a/client/ayon_core/plugins/publish/cleanup.py b/client/ayon_core/plugins/publish/cleanup.py index 7bed3269c2..df68af7e57 100644 --- a/client/ayon_core/plugins/publish/cleanup.py +++ b/client/ayon_core/plugins/publish/cleanup.py @@ -5,7 +5,7 @@ import shutil import pyblish.api import re -from ayon_core.tests.lib import is_in_tests +from ayon_core.lib import is_in_tests class CleanUp(pyblish.api.InstancePlugin): diff --git a/client/ayon_core/plugins/publish/collect_scene_version.py b/client/ayon_core/plugins/publish/collect_scene_version.py index 254d3c913d..b04900c74e 100644 --- a/client/ayon_core/plugins/publish/collect_scene_version.py +++ b/client/ayon_core/plugins/publish/collect_scene_version.py @@ -1,8 +1,7 @@ import os import pyblish.api -from ayon_core.lib import get_version_from_path -from ayon_core.tests.lib import is_in_tests +from ayon_core.lib import get_version_from_path, is_in_tests from ayon_core.pipeline import KnownPublishError From 62d76f7b110afa4d931a1cc23ba8119c87dc70cf Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Tue, 13 Feb 2024 11:45:46 +0100 Subject: [PATCH 096/185] add missing items to '__all__' --- client/ayon_core/lib/__init__.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/client/ayon_core/lib/__init__.py b/client/ayon_core/lib/__init__.py index e917467e7c..ab6a604adc 100644 --- a/client/ayon_core/lib/__init__.py +++ b/client/ayon_core/lib/__init__.py @@ -230,6 +230,8 @@ __all__ = [ "IniSettingRegistry", "JSONSettingRegistry", + "AYONSecureRegistry", + "AYONSettingsRegistry", "OpenPypeSecureRegistry", "OpenPypeSettingsRegistry", "get_local_site_id", @@ -272,6 +274,7 @@ __all__ = [ "terminal", "get_datetime_data", + "get_timestamp", "get_formatted_current_time", "Logger", From 20487204ba7c89f7310ef52f7af9b879978a1372 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Tue, 13 Feb 2024 11:57:39 +0100 Subject: [PATCH 097/185] added 3dsmax imageio conversion back --- client/ayon_core/settings/ayon_settings.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/client/ayon_core/settings/ayon_settings.py b/client/ayon_core/settings/ayon_settings.py index 35652d5c3c..cea0158159 100644 --- a/client/ayon_core/settings/ayon_settings.py +++ b/client/ayon_core/settings/ayon_settings.py @@ -294,6 +294,8 @@ def _convert_3dsmax_project_settings(ayon_settings, output): ayon_max = ayon_settings["max"] + _convert_host_imageio(ayon_max) + output["max"] = ayon_max From c932042168d2a87691da6a5f6a0146e4f0116394 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Tue, 13 Feb 2024 12:53:59 +0100 Subject: [PATCH 098/185] make sure old keys are removed --- client/ayon_core/cli_commands.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/client/ayon_core/cli_commands.py b/client/ayon_core/cli_commands.py index 31429c488b..7e652950eb 100644 --- a/client/ayon_core/cli_commands.py +++ b/client/ayon_core/cli_commands.py @@ -84,6 +84,8 @@ class Commands: ): if src_key in os.environ and dst_key not in os.environ: os.environ[dst_key] = os.environ[src_key] + # Remove old keys, so we're sure they're not used + os.environ.pop(src_key, None) log = Logger.get_logger("CLI-publish") From 6bb04dfe08c63aa67d4f115f207c8cc8d1aaa428 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Tue, 13 Feb 2024 13:06:48 +0100 Subject: [PATCH 099/185] fix 'RenderSettings' key usage --- .../plugins/publish/validate_render_image_rule.py | 11 +++++++---- .../maya/plugins/publish/validate_rendersettings.py | 2 +- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/client/ayon_core/hosts/maya/plugins/publish/validate_render_image_rule.py b/client/ayon_core/hosts/maya/plugins/publish/validate_render_image_rule.py index efc622c416..384d99df1a 100644 --- a/client/ayon_core/hosts/maya/plugins/publish/validate_render_image_rule.py +++ b/client/ayon_core/hosts/maya/plugins/publish/validate_render_image_rule.py @@ -60,7 +60,10 @@ class ValidateRenderImageRule(pyblish.api.InstancePlugin): ) return staging_dir - return instance.context.data.get('project_settings')\ - .get('maya') \ - .get('RenderSettings') \ - .get('default_render_image_folder') + return ( + instance.context.data + ["project_settings"] + ["maya"] + ["render_settings"] + ["default_render_image_folder"] + ) diff --git a/client/ayon_core/hosts/maya/plugins/publish/validate_rendersettings.py b/client/ayon_core/hosts/maya/plugins/publish/validate_rendersettings.py index 7f6c0bab1d..78a247b3f2 100644 --- a/client/ayon_core/hosts/maya/plugins/publish/validate_rendersettings.py +++ b/client/ayon_core/hosts/maya/plugins/publish/validate_rendersettings.py @@ -265,7 +265,7 @@ class ValidateRenderSettings(pyblish.api.InstancePlugin): # load validation definitions from settings settings_lights_flag = instance.context.data["project_settings"].get( "maya", {}).get( - "RenderSettings", {}).get( + "render_settings", {}).get( "enable_all_lights", False) instance_lights_flag = instance.data.get("renderSetupIncludeLights") From 0ca94aa3c03acf63d177dde49099d1c99e08ed2d Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Tue, 13 Feb 2024 13:11:03 +0100 Subject: [PATCH 100/185] bump version of global pre load plugin --- .../deadline/repository/custom/plugins/GlobalJobPreLoad.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/ayon_core/modules/deadline/repository/custom/plugins/GlobalJobPreLoad.py b/client/ayon_core/modules/deadline/repository/custom/plugins/GlobalJobPreLoad.py index 0b44c8dce3..818424b5fc 100644 --- a/client/ayon_core/modules/deadline/repository/custom/plugins/GlobalJobPreLoad.py +++ b/client/ayon_core/modules/deadline/repository/custom/plugins/GlobalJobPreLoad.py @@ -14,7 +14,7 @@ from Deadline.Scripting import ( DirectoryUtils, ProcessUtils, ) -__version__ = "1.0.0" +__version__ = "1.0.1" VERSION_REGEX = re.compile( r"(?P0|[1-9]\d*)" r"\.(?P0|[1-9]\d*)" From 4529a5988950bc3cfa5035f0f397c80edda4adbe Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Tue, 13 Feb 2024 14:25:41 +0100 Subject: [PATCH 101/185] fix 'RenderSettings' to 'render_settings' in deadline --- .../modules/deadline/plugins/publish/submit_maya_deadline.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/ayon_core/modules/deadline/plugins/publish/submit_maya_deadline.py b/client/ayon_core/modules/deadline/plugins/publish/submit_maya_deadline.py index b9c858a6a7..a4a5391ce1 100644 --- a/client/ayon_core/modules/deadline/plugins/publish/submit_maya_deadline.py +++ b/client/ayon_core/modules/deadline/plugins/publish/submit_maya_deadline.py @@ -259,7 +259,7 @@ class MayaSubmitDeadline(abstract_submit_deadline.AbstractSubmitDeadline, default_rs_include_lights = ( instance.context.data['project_settings'] ['maya'] - ['RenderSettings'] + ['render_settings'] ['enable_all_lights'] ) From 5a185f4a2ad376c013aa2a5cd8ab8748f9f888bd Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Tue, 13 Feb 2024 15:03:42 +0100 Subject: [PATCH 102/185] move asset icon functions to assets widget --- .../tools/publisher/widgets/assets_widget.py | 2 +- client/ayon_core/tools/utils/__init__.py | 8 --- client/ayon_core/tools/utils/assets_widget.py | 59 ++++++++++++++++++- client/ayon_core/tools/utils/lib.py | 56 ------------------ 4 files changed, 59 insertions(+), 66 deletions(-) diff --git a/client/ayon_core/tools/publisher/widgets/assets_widget.py b/client/ayon_core/tools/publisher/widgets/assets_widget.py index faad37104d..1c5016de99 100644 --- a/client/ayon_core/tools/publisher/widgets/assets_widget.py +++ b/client/ayon_core/tools/publisher/widgets/assets_widget.py @@ -5,13 +5,13 @@ from qtpy import QtWidgets, QtCore, QtGui from ayon_core.tools.utils import ( PlaceholderLineEdit, RecursiveSortFilterProxyModel, - get_asset_icon, ) from ayon_core.tools.utils.assets_widget import ( SingleSelectAssetsWidget, ASSET_ID_ROLE, ASSET_NAME_ROLE, ASSET_PATH_ROLE, + get_asset_icon, ) diff --git a/client/ayon_core/tools/utils/__init__.py b/client/ayon_core/tools/utils/__init__.py index 7be0ea5e9f..445b4d9b97 100644 --- a/client/ayon_core/tools/utils/__init__.py +++ b/client/ayon_core/tools/utils/__init__.py @@ -37,10 +37,6 @@ from .lib import ( get_qt_app, get_ayon_qt_app, get_openpype_qt_app, - get_asset_icon, - get_asset_icon_by_name, - get_asset_icon_name_from_doc, - get_asset_icon_color_from_doc, ) from .models import ( @@ -100,10 +96,6 @@ __all__ = ( "get_qt_app", "get_ayon_qt_app", "get_openpype_qt_app", - "get_asset_icon", - "get_asset_icon_by_name", - "get_asset_icon_name_from_doc", - "get_asset_icon_color_from_doc", "RecursiveSortFilterProxyModel", diff --git a/client/ayon_core/tools/utils/assets_widget.py b/client/ayon_core/tools/utils/assets_widget.py index 7bacf3291d..a97a289737 100644 --- a/client/ayon_core/tools/utils/assets_widget.py +++ b/client/ayon_core/tools/utils/assets_widget.py @@ -10,6 +10,7 @@ from ayon_core.client import ( ) from ayon_core.style import ( get_default_tools_icon_color, + get_default_entity_icon_color, ) from ayon_core.tools.flickcharm import FlickCharm @@ -21,7 +22,7 @@ from .widgets import PlaceholderLineEdit from .models import RecursiveSortFilterProxyModel from .lib import ( DynamicQThread, - get_asset_icon + get_qta_icon_by_name_and_color ) ASSET_ID_ROLE = QtCore.Qt.UserRole + 1 @@ -31,6 +32,62 @@ ASSET_UNDERLINE_COLORS_ROLE = QtCore.Qt.UserRole + 4 ASSET_PATH_ROLE = QtCore.Qt.UserRole + 5 +def get_default_asset_icon_name(has_children): + if has_children: + return "fa.folder" + return "fa.folder-o" + + +def get_asset_icon_color_from_doc(asset_doc): + if asset_doc: + return asset_doc["data"].get("color") + return None + + +def get_asset_icon_name_from_doc(asset_doc): + if asset_doc: + return asset_doc["data"].get("icon") + return None + + +def get_asset_icon_color(asset_doc): + icon_color = get_asset_icon_color_from_doc(asset_doc) + if icon_color: + return icon_color + return get_default_entity_icon_color() + + +def get_asset_icon_by_name(icon_name, icon_color, has_children=False): + if not icon_name: + icon_name = get_default_asset_icon_name(has_children) + + if icon_color: + icon_color = QtGui.QColor(icon_color) + else: + icon_color = get_default_entity_icon_color() + icon = get_qta_icon_by_name_and_color(icon_name, icon_color) + if icon is not None: + return icon + return get_qta_icon_by_name_and_color( + get_default_asset_icon_name(has_children), + icon_color + ) + + +def get_asset_icon_name(asset_doc, has_children=True): + icon_name = get_asset_icon_name_from_doc(asset_doc) + if icon_name: + return icon_name + return get_default_asset_icon_name(has_children) + + +def get_asset_icon(asset_doc, has_children=False): + icon_name = get_asset_icon_name(asset_doc, has_children) + icon_color = get_asset_icon_color(asset_doc) + + return get_qta_icon_by_name_and_color(icon_name, icon_color) + + class _AssetsView(TreeViewSpinner, DeselectableTreeView): """Asset items view. diff --git a/client/ayon_core/tools/utils/lib.py b/client/ayon_core/tools/utils/lib.py index b7edd6be71..e785cec390 100644 --- a/client/ayon_core/tools/utils/lib.py +++ b/client/ayon_core/tools/utils/lib.py @@ -234,62 +234,6 @@ def get_qta_icon_by_name_and_color(icon_name, icon_color): return icon -def get_asset_icon_name(asset_doc, has_children=True): - icon_name = get_asset_icon_name_from_doc(asset_doc) - if icon_name: - return icon_name - return get_default_asset_icon_name(has_children) - - -def get_asset_icon_color(asset_doc): - icon_color = get_asset_icon_color_from_doc(asset_doc) - if icon_color: - return icon_color - return get_default_entity_icon_color() - - -def get_default_asset_icon_name(has_children): - if has_children: - return "fa.folder" - return "fa.folder-o" - - -def get_asset_icon_name_from_doc(asset_doc): - if asset_doc: - return asset_doc["data"].get("icon") - return None - - -def get_asset_icon_color_from_doc(asset_doc): - if asset_doc: - return asset_doc["data"].get("color") - return None - - -def get_asset_icon_by_name(icon_name, icon_color, has_children=False): - if not icon_name: - icon_name = get_default_asset_icon_name(has_children) - - if icon_color: - icon_color = QtGui.QColor(icon_color) - else: - icon_color = get_default_entity_icon_color() - icon = get_qta_icon_by_name_and_color(icon_name, icon_color) - if icon is not None: - return icon - return get_qta_icon_by_name_and_color( - get_default_asset_icon_name(has_children), - icon_color - ) - - -def get_asset_icon(asset_doc, has_children=False): - icon_name = get_asset_icon_name(asset_doc, has_children) - icon_color = get_asset_icon_color(asset_doc) - - return get_qta_icon_by_name_and_color(icon_name, icon_color) - - def get_default_task_icon(color=None): if color is None: color = get_default_entity_icon_color() From 9d7dd0d75a4220f4677403e7e7da9ec75fec1c78 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Tue, 13 Feb 2024 16:41:42 +0100 Subject: [PATCH 103/185] remove settings conversion for timers manager --- client/ayon_core/settings/ayon_settings.py | 33 ++++++---------------- 1 file changed, 8 insertions(+), 25 deletions(-) diff --git a/client/ayon_core/settings/ayon_settings.py b/client/ayon_core/settings/ayon_settings.py index cea0158159..0fe4095a92 100644 --- a/client/ayon_core/settings/ayon_settings.py +++ b/client/ayon_core/settings/ayon_settings.py @@ -96,26 +96,6 @@ def _convert_kitsu_system_settings( output["modules"]["kitsu"] = kitsu_settings -def _convert_timers_manager_system_settings( - ayon_settings, output, addon_versions, default_settings -): - enabled = addon_versions.get("timers_manager") is not None - manager_settings = default_settings["modules"]["timers_manager"] - manager_settings["enabled"] = enabled - if enabled: - ayon_manager = ayon_settings["timers_manager"] - manager_settings.update({ - key: ayon_manager[key] - for key in { - "auto_stop", - "full_time", - "message_time", - "disregard_publishing" - } - }) - output["modules"]["timers_manager"] = manager_settings - - def _convert_clockify_system_settings( ayon_settings, output, addon_versions, default_settings ): @@ -167,21 +147,24 @@ def _convert_modules_system( # TODO add 'enabled' values for func in ( _convert_kitsu_system_settings, - _convert_timers_manager_system_settings, _convert_clockify_system_settings, _convert_deadline_system_settings, _convert_royalrender_system_settings, ): func(ayon_settings, output, addon_versions, default_settings) + for key in { + "timers_manager", + }: + if addon_versions.get(key): + output[key] = ayon_settings + else: + output.pop(key, None) + modules_settings = output["modules"] for module_name in ( "sync_server", - "log_viewer", - "standalonepublish_tool", - "project_manager", "job_queue", - "avalon", "addon_paths", ): settings = default_settings["modules"][module_name] From 221cd01ae2b6759bb6312819b1cd68ff52e02be1 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Tue, 13 Feb 2024 16:42:01 +0100 Subject: [PATCH 104/185] use 'AYONAddon' for times manager addon --- .../modules/timers_manager/timers_manager.py | 38 ++++++++++--------- 1 file changed, 21 insertions(+), 17 deletions(-) diff --git a/client/ayon_core/modules/timers_manager/timers_manager.py b/client/ayon_core/modules/timers_manager/timers_manager.py index daba0cead9..f8f0e4a526 100644 --- a/client/ayon_core/modules/timers_manager/timers_manager.py +++ b/client/ayon_core/modules/timers_manager/timers_manager.py @@ -3,8 +3,8 @@ import platform from ayon_core.client import get_asset_by_name -from ayon_core.modules import ( - OpenPypeModule, +from ayon_core.addon import ( + AYONAddon, ITrayService, IPluginPaths ) @@ -76,7 +76,7 @@ class ExampleTimersManagerConnector: class TimersManager( - OpenPypeModule, + AYONAddon, ITrayService, IPluginPaths ): @@ -99,23 +99,27 @@ class TimersManager( "start_timer" ) - def initialize(self, modules_settings): - timers_settings = modules_settings[self.name] + def initialize(self, studio_settings): + timers_settings = studio_settings.get(self.name) + enabled = timers_settings is not None - self.enabled = timers_settings["enabled"] + auto_stop = False + full_time = 0 + message_time = 0 + if enabled: + # When timer will stop if idle manager is running (minutes) + full_time = int(timers_settings["full_time"] * 60) + # How many minutes before the timer is stopped will popup the message + message_time = int(timers_settings["message_time"] * 60) - # When timer will stop if idle manager is running (minutes) - full_time = int(timers_settings["full_time"] * 60) - # How many minutes before the timer is stopped will popup the message - message_time = int(timers_settings["message_time"] * 60) - - auto_stop = timers_settings["auto_stop"] - platform_name = platform.system().lower() - # Turn of auto stop on MacOs because pynput requires root permissions - # and on linux can cause thread locks on application close - if full_time <= 0 or platform_name in ("darwin", "linux"): - auto_stop = False + auto_stop = timers_settings["auto_stop"] + platform_name = platform.system().lower() + # Turn of auto stop on MacOs because pynput requires root permissions + # and on linux can cause thread locks on application close + if full_time <= 0 or platform_name in ("darwin", "linux"): + auto_stop = False + self.enabled = enabled self.auto_stop = auto_stop self.time_show_message = full_time - message_time self.time_stop_timer = full_time From 40dc41a7a98572d0e3b2ba3dcdb90df85f4ea78c Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Tue, 13 Feb 2024 16:52:51 +0100 Subject: [PATCH 105/185] remove conversion of traypublisher settings --- client/ayon_core/settings/ayon_settings.py | 52 ---------------------- 1 file changed, 52 deletions(-) diff --git a/client/ayon_core/settings/ayon_settings.py b/client/ayon_core/settings/ayon_settings.py index cea0158159..fe54714f75 100644 --- a/client/ayon_core/settings/ayon_settings.py +++ b/client/ayon_core/settings/ayon_settings.py @@ -551,58 +551,6 @@ def _convert_traypublisher_project_settings(ayon_settings, output): _convert_host_imageio(ayon_traypublisher) - ayon_editorial_simple = ( - ayon_traypublisher["editorial_creators"]["editorial_simple"] - ) - # Subset -> Product type conversion - if "product_type_presets" in ayon_editorial_simple: - family_presets = ayon_editorial_simple.pop("product_type_presets") - for item in family_presets: - item["family"] = item.pop("product_type") - ayon_editorial_simple["family_presets"] = family_presets - - if "shot_metadata_creator" in ayon_editorial_simple: - shot_metadata_creator = ayon_editorial_simple.pop( - "shot_metadata_creator" - ) - if isinstance(shot_metadata_creator["clip_name_tokenizer"], dict): - shot_metadata_creator["clip_name_tokenizer"] = [ - {"name": "_sequence_", "regex": "(sc\\d{3})"}, - {"name": "_shot_", "regex": "(sh\\d{3})"}, - ] - ayon_editorial_simple.update(shot_metadata_creator) - - ayon_editorial_simple["clip_name_tokenizer"] = { - item["name"]: item["regex"] - for item in ayon_editorial_simple["clip_name_tokenizer"] - } - - if "shot_subset_creator" in ayon_editorial_simple: - ayon_editorial_simple.update( - ayon_editorial_simple.pop("shot_subset_creator")) - for item in ayon_editorial_simple["shot_hierarchy"]["parents"]: - item["type"] = item.pop("parent_type") - - # Simple creators - ayon_simple_creators = ayon_traypublisher["simple_creators"] - for item in ayon_simple_creators: - if "product_type" not in item: - break - item["family"] = item.pop("product_type") - - shot_add_tasks = ayon_editorial_simple["shot_add_tasks"] - - # TODO: backward compatibility and remove in future - if isinstance(shot_add_tasks, dict): - shot_add_tasks = [] - - # aggregate shot_add_tasks items - new_shot_add_tasks = { - item["name"]: {"type": item["task_type"]} - for item in shot_add_tasks - } - ayon_editorial_simple["shot_add_tasks"] = new_shot_add_tasks - output["traypublisher"] = ayon_traypublisher From 6c158157cc533f386d1255ebb035cee05612ff04 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Tue, 13 Feb 2024 16:53:14 +0100 Subject: [PATCH 106/185] modify SettingsCreator to match new settings --- client/ayon_core/hosts/traypublisher/api/plugin.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/ayon_core/hosts/traypublisher/api/plugin.py b/client/ayon_core/hosts/traypublisher/api/plugin.py index 77a8f23d2e..d3d7f80e89 100644 --- a/client/ayon_core/hosts/traypublisher/api/plugin.py +++ b/client/ayon_core/hosts/traypublisher/api/plugin.py @@ -311,7 +311,7 @@ class SettingsCreator(TrayPublishCreator): @classmethod def from_settings(cls, item_data): identifier = item_data["identifier"] - family = item_data["family"] + family = item_data["product_type"] if not identifier: identifier = "settings_{}".format(family) return type( From 197d3d6786a320289e9765c3ac4152bc36648325 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Tue, 13 Feb 2024 16:55:45 +0100 Subject: [PATCH 107/185] change how setting are applied in editorial creator --- .../hosts/traypublisher/api/editorial.py | 24 +++++++----- .../plugins/create/create_editorial.py | 39 ++++++++----------- 2 files changed, 31 insertions(+), 32 deletions(-) diff --git a/client/ayon_core/hosts/traypublisher/api/editorial.py b/client/ayon_core/hosts/traypublisher/api/editorial.py index d84a7200c8..2c77a66ac7 100644 --- a/client/ayon_core/hosts/traypublisher/api/editorial.py +++ b/client/ayon_core/hosts/traypublisher/api/editorial.py @@ -16,25 +16,31 @@ class ShotMetadataSolver: NO_DECOR_PATERN = re.compile(r"\{([a-z]*?)\}") - # presets - clip_name_tokenizer = None - shot_rename = True - shot_hierarchy = None - shot_add_tasks = None + def __init__(self, logger): + self.clip_name_tokenizer = [] + self.shot_rename = { + "enabled": False, + "shot_rename_template": "", + } + self.shot_hierarchy = { + "enabled": False, + "parents": [], + "parents_path": "", + } + self.shot_add_tasks = [] + self.log = logger - def __init__( + def update_data( self, clip_name_tokenizer, shot_rename, shot_hierarchy, - shot_add_tasks, - logger + shot_add_tasks ): self.clip_name_tokenizer = clip_name_tokenizer self.shot_rename = shot_rename self.shot_hierarchy = shot_hierarchy self.shot_add_tasks = shot_add_tasks - self.log = logger def _rename_template(self, data): """Shot renaming function diff --git a/client/ayon_core/hosts/traypublisher/plugins/create/create_editorial.py b/client/ayon_core/hosts/traypublisher/plugins/create/create_editorial.py index 51a67a871e..791d989070 100644 --- a/client/ayon_core/hosts/traypublisher/plugins/create/create_editorial.py +++ b/client/ayon_core/hosts/traypublisher/plugins/create/create_editorial.py @@ -174,35 +174,28 @@ Supporting publishing new shots to project or updating already created. Publishing will create OTIO file. """ icon = "fa.file" + product_type_presets = [] - def __init__( - self, project_settings, *args, **kwargs - ): - super(EditorialSimpleCreator, self).__init__( - project_settings, *args, **kwargs - ) + def __init__(self, *args, **kwargs): + self._shot_metadata_solver = ShotMetadataSolver(self.log) + super(EditorialSimpleCreator, self).__init__(*args, **kwargs) + + def apply_settings(self, project_settings): editorial_creators = deepcopy( project_settings["traypublisher"]["editorial_creators"] ) - # get this creator settings by identifier - self._creator_settings = editorial_creators.get(self.identifier) + creator_settings = editorial_creators.get(self.identifier) - clip_name_tokenizer = self._creator_settings["clip_name_tokenizer"] - shot_rename = self._creator_settings["shot_rename"] - shot_hierarchy = self._creator_settings["shot_hierarchy"] - shot_add_tasks = self._creator_settings["shot_add_tasks"] - - self._shot_metadata_solver = ShotMetadataSolver( - clip_name_tokenizer, - shot_rename, - shot_hierarchy, - shot_add_tasks, - self.log + self._shot_metadata_solver.update_data( + creator_settings["clip_name_tokenizer"], + creator_settings["shot_rename"], + creator_settings["shot_hierarchy"], + creator_settings["shot_add_tasks"] ) - - # try to set main attributes from settings - if self._creator_settings.get("default_variants"): - self.default_variants = self._creator_settings["default_variants"] + self.product_type_presets = creator_settings["product_type_presets"] + default_variants = creator_settings.get("default_variants") + if default_variants: + self.default_variants = default_variants def create(self, subset_name, instance_data, pre_create_data): allowed_family_presets = self._get_allowed_family_presets( From 0669ef30c8560a6d19a03376cf8f443e3d33db92 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Tue, 13 Feb 2024 16:56:03 +0100 Subject: [PATCH 108/185] use new settings structure in ShotMetadataSolver --- .../hosts/traypublisher/api/editorial.py | 24 ++++++++++--------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/client/ayon_core/hosts/traypublisher/api/editorial.py b/client/ayon_core/hosts/traypublisher/api/editorial.py index 2c77a66ac7..6153bc5752 100644 --- a/client/ayon_core/hosts/traypublisher/api/editorial.py +++ b/client/ayon_core/hosts/traypublisher/api/editorial.py @@ -92,7 +92,9 @@ class ShotMetadataSolver: search_text = parent_name + clip_name - for token_key, pattern in self.clip_name_tokenizer.items(): + for clip_name_item in self.clip_name_tokenizer: + token_key = clip_name_item["name"] + pattern = clip_name_item["regex"] p = re.compile(pattern) match = p.findall(search_text) if not match: @@ -143,11 +145,11 @@ class ShotMetadataSolver: )) _parent_tokens_type = { - parent_token["name"]: parent_token["type"] + parent_token["name"]: parent_token["parent_type"] for parent_token in hierarchy_parents } for _index, _parent in enumerate( - shot_hierarchy["parents_path"].split("/") + shot_hierarchy["parents_path"].split("/") ): # format parent token with value which is formatted try: @@ -268,22 +270,22 @@ class ShotMetadataSolver: """ tasks_to_add = {} - project_tasks = project_doc["config"]["tasks"] - for task_name, task_data in self.shot_add_tasks.items(): - _task_data = deepcopy(task_data) + project_task_types = project_doc["config"]["tasks"] + for task_item in self.shot_add_tasks: + task_name = task_item["name"] + task_type = task_item["task_type"] # check if task type in project task types - if _task_data["type"] in project_tasks.keys(): - tasks_to_add[task_name] = _task_data - else: + if task_type not in project_task_types.keys(): raise KeyError( "Missing task type `{}` for `{}` is not" " existing in `{}``".format( - _task_data["type"], + task_type, task_name, - list(project_tasks.keys()) + list(project_task_types.keys()) ) ) + tasks_to_add[task_name] = {"type": task_type} return tasks_to_add From 551184e3c23662b2b9197b0ebd8f8da528675c12 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Tue, 13 Feb 2024 16:56:18 +0100 Subject: [PATCH 109/185] change variables used during create editorial --- .../plugins/create/create_editorial.py | 62 +++++++++---------- 1 file changed, 31 insertions(+), 31 deletions(-) diff --git a/client/ayon_core/hosts/traypublisher/plugins/create/create_editorial.py b/client/ayon_core/hosts/traypublisher/plugins/create/create_editorial.py index 791d989070..d6501e65a2 100644 --- a/client/ayon_core/hosts/traypublisher/plugins/create/create_editorial.py +++ b/client/ayon_core/hosts/traypublisher/plugins/create/create_editorial.py @@ -198,15 +198,18 @@ or updating already created. Publishing will create OTIO file. self.default_variants = default_variants def create(self, subset_name, instance_data, pre_create_data): - allowed_family_presets = self._get_allowed_family_presets( + allowed_product_type_presets = self._get_allowed_product_type_presets( pre_create_data) + product_types = { + item["product_type"] + for item in self.product_type_presets + } clip_instance_properties = { - k: v for k, v in pre_create_data.items() + k: v + for k, v in pre_create_data.items() if k != "sequence_filepath_data" - if k not in [ - i["family"] for i in self._creator_settings["family_presets"] - ] + if k not in product_types } asset_name = instance_data["folderPath"] @@ -248,7 +251,7 @@ or updating already created. Publishing will create OTIO file. otio_timeline, media_path, clip_instance_properties, - allowed_family_presets, + allowed_product_type_presets, os.path.basename(seq_path), first_otio_timeline ) @@ -348,7 +351,7 @@ or updating already created. Publishing will create OTIO file. otio_timeline, media_path, instance_data, - family_presets, + product_type_presets, sequence_file_name, first_otio_timeline=None ): @@ -358,7 +361,7 @@ or updating already created. Publishing will create OTIO file. otio_timeline (otio.Timeline): otio timeline object media_path (str): media file path string instance_data (dict): clip instance data - family_presets (list): list of dict settings subset presets + product_type_presets (list): list of dict settings subset presets """ tracks = [ @@ -404,17 +407,17 @@ or updating already created. Publishing will create OTIO file. "instance_id": None } - for _fpreset in family_presets: + for product_type_preset in product_type_presets: # exclude audio family if no audio stream if ( - _fpreset["family"] == "audio" + product_type_preset["product_type"] == "audio" and not media_data.get("audio") ): continue instance = self._make_subset_instance( otio_clip, - _fpreset, + product_type_preset, deepcopy(base_instance_data), parenting_data ) @@ -526,7 +529,7 @@ or updating already created. Publishing will create OTIO file. def _make_subset_instance( self, otio_clip, - preset, + product_type_preset, instance_data, parenting_data ): @@ -534,16 +537,16 @@ or updating already created. Publishing will create OTIO file. Args: otio_clip (otio.Clip): otio clip object - preset (dict): single family preset + product_type_preset (dict): single family preset instance_data (dict): instance data parenting_data (dict): shot instance parent data Returns: CreatedInstance: creator instance object """ - family = preset["family"] + family = product_type_preset["product_type"] label = self._make_subset_naming( - preset, + product_type_preset, instance_data ) instance_data["label"] = label @@ -562,11 +565,11 @@ or updating already created. Publishing will create OTIO file. else: # add review family if defined instance_data.update({ - "outputFileType": preset["output_file_type"], + "outputFileType": product_type_preset["output_file_type"], "parent_instance_id": parenting_data["instance_id"], "creator_attributes": { "parent_instance": parenting_data["instance_label"], - "add_review_family": preset.get("review") + "add_review_family": product_type_preset.get("review") } }) @@ -578,15 +581,11 @@ or updating already created. Publishing will create OTIO file. return c_instance - def _make_subset_naming( - self, - preset, - instance_data - ): + def _make_subset_naming(self, product_type_preset, instance_data): """ Subset name maker Args: - preset (dict): single preset item + product_type_preset (dict): single preset item instance_data (dict): instance data Returns: @@ -595,10 +594,10 @@ or updating already created. Publishing will create OTIO file. asset_name = instance_data["creator_attributes"]["folderPath"] variant_name = instance_data["variant"] - family = preset["family"] + family = product_type_preset["product_type"] # get variant name from preset or from inheritance - _variant_name = preset.get("variant") or variant_name + _variant_name = product_type_preset.get("variant") or variant_name # subset name subset_name = "{}{}".format( @@ -756,7 +755,7 @@ or updating already created. Publishing will create OTIO file. "sourceOut": int(source_out) } - def _get_allowed_family_presets(self, pre_create_data): + def _get_allowed_product_type_presets(self, pre_create_data): """ Filter out allowed family presets. Args: @@ -766,10 +765,11 @@ or updating already created. Publishing will create OTIO file. list: lit of dict with preset items """ return [ - {"family": "shot"}, + {"product_type": "shot"}, *[ - preset for preset in self._creator_settings["family_presets"] - if pre_create_data[preset["family"]] + preset + for preset in self.product_type_presets + if pre_create_data[preset["product_type"]] ] ] @@ -846,8 +846,8 @@ or updating already created. Publishing will create OTIO file. ] # add variants swithers attr_defs.extend( - BoolDef(_var["family"], label=_var["family"]) - for _var in self._creator_settings["family_presets"] + BoolDef(item["product_type"], label=item["product_type"]) + for item in self.product_type_presets ) attr_defs.append(UISeparatorDef()) From 8bb4db39d0eed4dac6e56b2281d5bcb2b611376c Mon Sep 17 00:00:00 2001 From: Jakub Trllo <43494761+iLLiCiTiT@users.noreply.github.com> Date: Tue, 13 Feb 2024 17:11:02 +0100 Subject: [PATCH 110/185] fix missing bracket Co-authored-by: Mustafa Taher --- .../deadline/repository/custom/plugins/GlobalJobPreLoad.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/ayon_core/modules/deadline/repository/custom/plugins/GlobalJobPreLoad.py b/client/ayon_core/modules/deadline/repository/custom/plugins/GlobalJobPreLoad.py index 818424b5fc..1565b2c496 100644 --- a/client/ayon_core/modules/deadline/repository/custom/plugins/GlobalJobPreLoad.py +++ b/client/ayon_core/modules/deadline/repository/custom/plugins/GlobalJobPreLoad.py @@ -476,7 +476,7 @@ def inject_ayon_environment(deadlinePlugin): # Support backwards compatible keys for key, env_keys in ( ("project", ["AYON_PROJECT_NAME", "AVALON_PROJECT"]), - ("asset", ["AYON_FOLDER_PATH", "AVALON_ASSET"], + ("asset", ["AYON_FOLDER_PATH", "AVALON_ASSET"]), ("task", ["AYON_TASK_NAME", "AVALON_TASK"]), ("app", ["AYON_APP_NAME", "AVALON_APP_NAME"]), ): From de643a13d837de57d88e8598dcaccd48f23aff74 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Tue, 13 Feb 2024 17:21:41 +0100 Subject: [PATCH 111/185] removed outdated shotgrid conversion --- client/ayon_core/settings/ayon_settings.py | 28 ---------------------- 1 file changed, 28 deletions(-) diff --git a/client/ayon_core/settings/ayon_settings.py b/client/ayon_core/settings/ayon_settings.py index fe54714f75..dd079bec84 100644 --- a/client/ayon_core/settings/ayon_settings.py +++ b/client/ayon_core/settings/ayon_settings.py @@ -600,33 +600,6 @@ def _convert_kitsu_project_settings(ayon_settings, output): output["kitsu"] = ayon_kitsu_settings -def _convert_shotgrid_project_settings(ayon_settings, output): - if "shotgrid" not in ayon_settings: - return - - ayon_shotgrid = ayon_settings["shotgrid"] - # This means that a different variant of addon is used - if "leecher_backend_url" not in ayon_shotgrid: - return - - for key in { - "leecher_backend_url", - "filter_projects_by_login", - "shotgrid_settings", - "leecher_manager_url", - }: - ayon_shotgrid.pop(key) - - asset_field = ayon_shotgrid["fields"]["asset"] - asset_field["type"] = asset_field.pop("asset_type") - - task_field = ayon_shotgrid["fields"]["task"] - if "task" in task_field: - task_field["step"] = task_field.pop("task") - - output["shotgrid"] = ayon_settings["shotgrid"] - - def _convert_slack_project_settings(ayon_settings, output): if "slack" not in ayon_settings: return @@ -848,7 +821,6 @@ def convert_project_settings(ayon_settings, default_settings): _convert_royalrender_project_settings(ayon_settings, output) _convert_kitsu_project_settings(ayon_settings, output) - _convert_shotgrid_project_settings(ayon_settings, output) _convert_slack_project_settings(ayon_settings, output) _convert_global_project_settings(ayon_settings, output, default_settings) From 4e2ee7aaac2c9f00b328204e4463a7d10671b4b8 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Tue, 13 Feb 2024 17:30:39 +0100 Subject: [PATCH 112/185] removed webpublisher settings conversion --- client/ayon_core/settings/ayon_settings.py | 9 --------- 1 file changed, 9 deletions(-) diff --git a/client/ayon_core/settings/ayon_settings.py b/client/ayon_core/settings/ayon_settings.py index dd079bec84..ff97d9726b 100644 --- a/client/ayon_core/settings/ayon_settings.py +++ b/client/ayon_core/settings/ayon_settings.py @@ -560,15 +560,6 @@ def _convert_webpublisher_project_settings(ayon_settings, output): ayon_webpublisher = ayon_settings["webpublisher"] _convert_host_imageio(ayon_webpublisher) - - ayon_publish = ayon_webpublisher["publish"] - - ayon_collect_files = ayon_publish["CollectPublishedFiles"] - ayon_collect_files["task_type_to_family"] = { - item["name"]: item["value"] - for item in ayon_collect_files["task_type_to_family"] - } - output["webpublisher"] = ayon_webpublisher From 342c84784a275b3b2d98a235f5c17811a6e6ec7f Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Tue, 13 Feb 2024 17:33:39 +0100 Subject: [PATCH 113/185] removed kitsu settings conversion --- client/ayon_core/settings/ayon_settings.py | 32 ---------------------- 1 file changed, 32 deletions(-) diff --git a/client/ayon_core/settings/ayon_settings.py b/client/ayon_core/settings/ayon_settings.py index ff97d9726b..2978202b51 100644 --- a/client/ayon_core/settings/ayon_settings.py +++ b/client/ayon_core/settings/ayon_settings.py @@ -82,20 +82,6 @@ def _convert_general(ayon_settings, output, default_settings): } -def _convert_kitsu_system_settings( - ayon_settings, output, addon_versions, default_settings -): - if "kitsu" in ayon_settings: - output["kitsu"] = ayon_settings["kitsu"] - - enabled = addon_versions.get("kitsu") is not None - kitsu_settings = default_settings["modules"]["kitsu"] - kitsu_settings["enabled"] = enabled - if enabled: - kitsu_settings["server"] = ayon_settings["kitsu"]["server"] - output["modules"]["kitsu"] = kitsu_settings - - def _convert_timers_manager_system_settings( ayon_settings, output, addon_versions, default_settings ): @@ -166,7 +152,6 @@ def _convert_modules_system( # TODO add all modules # TODO add 'enabled' values for func in ( - _convert_kitsu_system_settings, _convert_timers_manager_system_settings, _convert_clockify_system_settings, _convert_deadline_system_settings, @@ -575,22 +560,6 @@ def _convert_royalrender_project_settings(ayon_settings, output): } -def _convert_kitsu_project_settings(ayon_settings, output): - if "kitsu" not in ayon_settings: - return - - ayon_kitsu_settings = ayon_settings["kitsu"] - ayon_kitsu_settings.pop("server") - - integrate_note = ayon_kitsu_settings["publish"]["IntegrateKitsuNote"] - status_change_conditions = integrate_note["status_change_conditions"] - if "product_type_requirements" in status_change_conditions: - status_change_conditions["family_requirements"] = ( - status_change_conditions.pop("product_type_requirements")) - - output["kitsu"] = ayon_kitsu_settings - - def _convert_slack_project_settings(ayon_settings, output): if "slack" not in ayon_settings: return @@ -811,7 +780,6 @@ def convert_project_settings(ayon_settings, default_settings): _convert_webpublisher_project_settings(ayon_settings, output) _convert_royalrender_project_settings(ayon_settings, output) - _convert_kitsu_project_settings(ayon_settings, output) _convert_slack_project_settings(ayon_settings, output) _convert_global_project_settings(ayon_settings, output, default_settings) From a1a325002804e4fa6a131bcae3e202c3ed9ec868 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Tue, 13 Feb 2024 17:34:07 +0100 Subject: [PATCH 114/185] removed slack settings conversion --- client/ayon_core/settings/ayon_settings.py | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/client/ayon_core/settings/ayon_settings.py b/client/ayon_core/settings/ayon_settings.py index 2978202b51..19a32520b8 100644 --- a/client/ayon_core/settings/ayon_settings.py +++ b/client/ayon_core/settings/ayon_settings.py @@ -560,19 +560,6 @@ def _convert_royalrender_project_settings(ayon_settings, output): } -def _convert_slack_project_settings(ayon_settings, output): - if "slack" not in ayon_settings: - return - - ayon_slack = ayon_settings["slack"] - ayon_slack.pop("enabled", None) - for profile in ayon_slack["publish"]["CollectSlackFamilies"]["profiles"]: - profile["tasks"] = profile.pop("task_names") - profile["subsets"] = profile.pop("subset_names") - - output["slack"] = ayon_slack - - def _convert_global_project_settings(ayon_settings, output, default_settings): if "core" not in ayon_settings: return @@ -780,7 +767,6 @@ def convert_project_settings(ayon_settings, default_settings): _convert_webpublisher_project_settings(ayon_settings, output) _convert_royalrender_project_settings(ayon_settings, output) - _convert_slack_project_settings(ayon_settings, output) _convert_global_project_settings(ayon_settings, output, default_settings) From ad74bafc4d32476ca38ffe79fb6d8c287fe9197d Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Tue, 13 Feb 2024 17:56:19 +0100 Subject: [PATCH 115/185] removed '_convert_host_imageio' --- client/ayon_core/settings/ayon_settings.py | 38 ---------------------- 1 file changed, 38 deletions(-) diff --git a/client/ayon_core/settings/ayon_settings.py b/client/ayon_core/settings/ayon_settings.py index fe54714f75..27f38fbb5e 100644 --- a/client/ayon_core/settings/ayon_settings.py +++ b/client/ayon_core/settings/ayon_settings.py @@ -52,26 +52,6 @@ def _convert_color(color_value): return color_value -def _convert_host_imageio(host_settings): - if "imageio" not in host_settings: - return - - # --- imageio --- - ayon_imageio = host_settings["imageio"] - # TODO remove when fixed on server - if "ocio_config" in ayon_imageio["ocio_config"]: - ayon_imageio["ocio_config"]["filepath"] = ( - ayon_imageio["ocio_config"].pop("ocio_config") - ) - # Convert file rules - imageio_file_rules = ayon_imageio["file_rules"] - new_rules = {} - for rule in imageio_file_rules["rules"]: - name = rule.pop("name") - new_rules[name] = rule - imageio_file_rules["rules"] = new_rules - - def _convert_general(ayon_settings, output, default_settings): output["core"] = ayon_settings["core"] version_check_interval = ( @@ -242,7 +222,6 @@ def _convert_blender_project_settings(ayon_settings, output): if "blender" not in ayon_settings: return ayon_blender = ayon_settings["blender"] - _convert_host_imageio(ayon_blender) output["blender"] = ayon_blender @@ -252,7 +231,6 @@ def _convert_celaction_project_settings(ayon_settings, output): return ayon_celaction = ayon_settings["celaction"] - _convert_host_imageio(ayon_celaction) output["celaction"] = ayon_celaction @@ -263,7 +241,6 @@ def _convert_flame_project_settings(ayon_settings, output): ayon_flame = ayon_settings["flame"] - _convert_host_imageio(ayon_flame) output["flame"] = ayon_flame @@ -272,7 +249,6 @@ def _convert_fusion_project_settings(ayon_settings, output): return ayon_fusion = ayon_settings["fusion"] - _convert_host_imageio(ayon_fusion) output["fusion"] = ayon_fusion @@ -283,8 +259,6 @@ def _convert_maya_project_settings(ayon_settings, output): ayon_maya = ayon_settings["maya"] - _convert_host_imageio(ayon_maya) - output["maya"] = ayon_maya @@ -294,8 +268,6 @@ def _convert_3dsmax_project_settings(ayon_settings, output): ayon_max = ayon_settings["max"] - _convert_host_imageio(ayon_max) - output["max"] = ayon_max @@ -442,7 +414,6 @@ def _convert_nuke_project_settings(ayon_settings, output): # --- ImageIO --- # NOTE 'monitorOutLut' is maybe not yet in v3 (ut should be) - _convert_host_imageio(ayon_nuke) ayon_imageio = ayon_nuke["imageio"] # workfile @@ -491,7 +462,6 @@ def _convert_hiero_project_settings(ayon_settings, output): return ayon_hiero = ayon_settings["hiero"] - _convert_host_imageio(ayon_hiero) new_gui_filters = {} for item in ayon_hiero.pop("filters", []): @@ -521,7 +491,6 @@ def _convert_photoshop_project_settings(ayon_settings, output): return ayon_photoshop = ayon_settings["photoshop"] - _convert_host_imageio(ayon_photoshop) output["photoshop"] = ayon_photoshop @@ -530,7 +499,6 @@ def _convert_substancepainter_project_settings(ayon_settings, output): return ayon_substance_painter = ayon_settings["substancepainter"] - _convert_host_imageio(ayon_substance_painter) output["substancepainter"] = ayon_substance_painter @@ -539,7 +507,6 @@ def _convert_tvpaint_project_settings(ayon_settings, output): return ayon_tvpaint = ayon_settings["tvpaint"] - _convert_host_imageio(ayon_tvpaint) output["tvpaint"] = ayon_tvpaint @@ -549,8 +516,6 @@ def _convert_traypublisher_project_settings(ayon_settings, output): ayon_traypublisher = ayon_settings["traypublisher"] - _convert_host_imageio(ayon_traypublisher) - output["traypublisher"] = ayon_traypublisher @@ -559,7 +524,6 @@ def _convert_webpublisher_project_settings(ayon_settings, output): return ayon_webpublisher = ayon_settings["webpublisher"] - _convert_host_imageio(ayon_webpublisher) ayon_publish = ayon_webpublisher["publish"] @@ -646,7 +610,6 @@ def _convert_global_project_settings(ayon_settings, output, default_settings): ayon_core = ayon_settings["core"] - _convert_host_imageio(ayon_core) # Publish conversion ayon_publish = ayon_core["publish"] @@ -830,7 +793,6 @@ def convert_project_settings(ayon_settings, default_settings): for key in exact_match: if key in ayon_settings: output[key] = ayon_settings[key] - _convert_host_imageio(output[key]) _convert_blender_project_settings(ayon_settings, output) _convert_celaction_project_settings(ayon_settings, output) From 62a6e6c3afbba1f9953052550b3633cd94922148 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Tue, 13 Feb 2024 17:59:18 +0100 Subject: [PATCH 116/185] modified code to use new imageio structure --- client/ayon_core/pipeline/colorspace.py | 45 +++++++++++++------------ 1 file changed, 23 insertions(+), 22 deletions(-) diff --git a/client/ayon_core/pipeline/colorspace.py b/client/ayon_core/pipeline/colorspace.py index d77f301498..70b7678d0a 100644 --- a/client/ayon_core/pipeline/colorspace.py +++ b/client/ayon_core/pipeline/colorspace.py @@ -254,7 +254,7 @@ def get_imageio_file_rules_colorspace_from_filepath( # match file rule from path colorspace_name = None - for file_rule in file_rules.values(): + for file_rule in file_rules: pattern = file_rule["pattern"] extension = file_rule["ext"] ext_match = re.match( @@ -281,7 +281,7 @@ def get_config_file_rules_colorspace_from_filepath(config_path, filepath): filepath (str): path leading to a file Returns: - Any[str, None]: matching colorspace name + Union[str, None]: matching colorspace name """ if not compatibility_check(): # python environment is not compatible with PyOpenColorIO @@ -837,13 +837,13 @@ def get_imageio_config( if override_global_config: config_data = _get_config_data( - host_ocio_config["filepath"], formatting_data, env + host_ocio_config["ocio_config"], formatting_data, env ) else: # get config path from global config_global = imageio_global["ocio_config"] config_data = _get_config_data( - config_global["filepath"], formatting_data, env + config_global["ocio_config"], formatting_data, env ) if not config_data: @@ -918,28 +918,13 @@ def get_imageio_file_rules(project_name, host_name, project_settings=None): Defaults to None. Returns: - dict: file rules data + list[dict[str, Any]]: file rules data """ project_settings = project_settings or get_project_settings(project_name) imageio_global, imageio_host = _get_imageio_settings( project_settings, host_name) - # get file rules from global and host_name - frules_global = imageio_global["file_rules"] - activate_global_rules = ( - frules_global.get("activate_global_file_rules", False) - # TODO: remove this in future - backward compatibility - or frules_global.get("enabled") - ) - global_rules = frules_global["rules"] - - if not activate_global_rules: - log.info( - "Colorspace global file rules are disabled." - ) - global_rules = {} - # host is optional, some might not have any settings frules_host = imageio_host.get("file_rules", {}) @@ -949,8 +934,24 @@ def get_imageio_file_rules(project_name, host_name, project_settings=None): # TODO: remove this in future - backward compatibility activate_host_rules = frules_host.get("enabled", False) - # return host rules if activated or global rules - return frules_host["rules"] if activate_host_rules else global_rules + if activate_host_rules: + return frules_host["rules"] + + # get file rules from global and host_name + frules_global = imageio_global["file_rules"] + activate_global_rules = ( + frules_global.get("activate_global_file_rules", False) + # TODO: remove this in future - backward compatibility + or frules_global.get("enabled") + ) + + if not activate_global_rules: + log.info( + "Colorspace global file rules are disabled." + ) + return [] + + return frules_global["rules"] def get_remapped_colorspace_to_native( From 85f8392ca8137c4ad002d7963d6e35df53d44af8 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Tue, 13 Feb 2024 18:08:10 +0100 Subject: [PATCH 117/185] fix key used to get ocio config path --- client/ayon_core/pipeline/colorspace.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/client/ayon_core/pipeline/colorspace.py b/client/ayon_core/pipeline/colorspace.py index 70b7678d0a..1b795e1c39 100644 --- a/client/ayon_core/pipeline/colorspace.py +++ b/client/ayon_core/pipeline/colorspace.py @@ -837,13 +837,13 @@ def get_imageio_config( if override_global_config: config_data = _get_config_data( - host_ocio_config["ocio_config"], formatting_data, env + host_ocio_config["filepath"], formatting_data, env ) else: # get config path from global config_global = imageio_global["ocio_config"] config_data = _get_config_data( - config_global["ocio_config"], formatting_data, env + config_global["filepath"], formatting_data, env ) if not config_data: From 2f462dac7aa5475a8b0eb2802ebf4cfbafc5317d Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Tue, 13 Feb 2024 18:42:10 +0100 Subject: [PATCH 118/185] keep only 'get_asset_icon' as public function --- client/ayon_core/tools/utils/assets_widget.py | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/client/ayon_core/tools/utils/assets_widget.py b/client/ayon_core/tools/utils/assets_widget.py index a97a289737..4af932a054 100644 --- a/client/ayon_core/tools/utils/assets_widget.py +++ b/client/ayon_core/tools/utils/assets_widget.py @@ -32,26 +32,26 @@ ASSET_UNDERLINE_COLORS_ROLE = QtCore.Qt.UserRole + 4 ASSET_PATH_ROLE = QtCore.Qt.UserRole + 5 -def get_default_asset_icon_name(has_children): +def _get_default_asset_icon_name(has_children): if has_children: return "fa.folder" return "fa.folder-o" -def get_asset_icon_color_from_doc(asset_doc): +def _get_asset_icon_color_from_doc(asset_doc): if asset_doc: return asset_doc["data"].get("color") return None -def get_asset_icon_name_from_doc(asset_doc): +def _get_asset_icon_name_from_doc(asset_doc): if asset_doc: return asset_doc["data"].get("icon") return None -def get_asset_icon_color(asset_doc): - icon_color = get_asset_icon_color_from_doc(asset_doc) +def _get_asset_icon_color(asset_doc): + icon_color = _get_asset_icon_color_from_doc(asset_doc) if icon_color: return icon_color return get_default_entity_icon_color() @@ -74,16 +74,16 @@ def get_asset_icon_by_name(icon_name, icon_color, has_children=False): ) -def get_asset_icon_name(asset_doc, has_children=True): - icon_name = get_asset_icon_name_from_doc(asset_doc) +def _get_asset_icon_name(asset_doc, has_children=True): + icon_name = _get_asset_icon_name_from_doc(asset_doc) if icon_name: return icon_name - return get_default_asset_icon_name(has_children) + return _get_default_asset_icon_name(has_children) def get_asset_icon(asset_doc, has_children=False): - icon_name = get_asset_icon_name(asset_doc, has_children) - icon_color = get_asset_icon_color(asset_doc) + icon_name = _get_asset_icon_name(asset_doc, has_children) + icon_color = _get_asset_icon_color(asset_doc) return get_qta_icon_by_name_and_color(icon_name, icon_color) From 9156bd08bd5744a06f828425c44ee350903eaba3 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Tue, 13 Feb 2024 18:42:20 +0100 Subject: [PATCH 119/185] removed unused 'get_asset_icon_by_name' --- client/ayon_core/tools/utils/assets_widget.py | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/client/ayon_core/tools/utils/assets_widget.py b/client/ayon_core/tools/utils/assets_widget.py index 4af932a054..694675d877 100644 --- a/client/ayon_core/tools/utils/assets_widget.py +++ b/client/ayon_core/tools/utils/assets_widget.py @@ -57,23 +57,6 @@ def _get_asset_icon_color(asset_doc): return get_default_entity_icon_color() -def get_asset_icon_by_name(icon_name, icon_color, has_children=False): - if not icon_name: - icon_name = get_default_asset_icon_name(has_children) - - if icon_color: - icon_color = QtGui.QColor(icon_color) - else: - icon_color = get_default_entity_icon_color() - icon = get_qta_icon_by_name_and_color(icon_name, icon_color) - if icon is not None: - return icon - return get_qta_icon_by_name_and_color( - get_default_asset_icon_name(has_children), - icon_color - ) - - def _get_asset_icon_name(asset_doc, has_children=True): icon_name = _get_asset_icon_name_from_doc(asset_doc) if icon_name: From e3b0bb98afd21c6ad69fdbd202128461b6949822 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Tue, 13 Feb 2024 18:42:29 +0100 Subject: [PATCH 120/185] added docstring to 'get_asset_icon' --- client/ayon_core/tools/utils/assets_widget.py | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/client/ayon_core/tools/utils/assets_widget.py b/client/ayon_core/tools/utils/assets_widget.py index 694675d877..7c3fd8d97c 100644 --- a/client/ayon_core/tools/utils/assets_widget.py +++ b/client/ayon_core/tools/utils/assets_widget.py @@ -65,6 +65,20 @@ def _get_asset_icon_name(asset_doc, has_children=True): def get_asset_icon(asset_doc, has_children=False): + """Get asset icon. + + Deprecated: + This function will be removed in future releases. Use on your own + risk. + + Args: + asset_doc (dict): Asset document. + has_children (Optional[bool]): Asset has children assets. + + Returns: + QIcon: Asset icon. + + """ icon_name = _get_asset_icon_name(asset_doc, has_children) icon_color = _get_asset_icon_color(asset_doc) From b9e01b254ddca1d402c8a0a4570be2834b43aeda Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Tue, 13 Feb 2024 18:58:25 +0100 Subject: [PATCH 121/185] addons can define their openpype alias name --- client/ayon_core/addon/base.py | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/client/ayon_core/addon/base.py b/client/ayon_core/addon/base.py index a3920c4acb..3b35476aed 100644 --- a/client/ayon_core/addon/base.py +++ b/client/ayon_core/addon/base.py @@ -788,6 +788,7 @@ class AddonsManager: addon_classes.append(modules_item) + aliased_names = [] for addon_cls in addon_classes: name = addon_cls.__name__ if issubclass(addon_cls, OpenPypeModule): @@ -807,6 +808,13 @@ class AddonsManager: self._addons.append(addon) self._addons_by_id[addon.id] = addon self._addons_by_name[addon.name] = addon + # NOTE This will be removed with release 1.0.0 of ayon-core + # please use carefully. + # Gives option to use alias name for addon for cases when + # name in OpenPype was not the same as in AYON. + name_alias = getattr(addon, "openpype_alias", None) + if name_alias: + aliased_names.append((name_alias, addon)) enabled_str = "X" if not addon.enabled: enabled_str = " " @@ -822,6 +830,17 @@ class AddonsManager: exc_info=True ) + for item in aliased_names: + name_alias, addon = item + if name_alias not in self._addons_by_name: + self._addons_by_name[name_alias] = addon + continue + self.log.warning( + "Alias name '{}' of addon '{}' is already assigned.".format( + name_alias, addon.name + ) + ) + if self._report is not None: report[self._report_total_key] = time.time() - time_start self._report["Initialization"] = report From d80ba2bac486711a41d1f889d4e0be3386c463cf Mon Sep 17 00:00:00 2001 From: Sponge96 Date: Wed, 14 Feb 2024 08:50:08 +0000 Subject: [PATCH 122/185] fix: removed artifact syntax Co-authored-by: Kayla Man <64118225+moonyuet@users.noreply.github.com> --- client/ayon_core/hosts/max/plugins/publish/save_scene.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/ayon_core/hosts/max/plugins/publish/save_scene.py b/client/ayon_core/hosts/max/plugins/publish/save_scene.py index 37ff38bc59..7961631b2a 100644 --- a/client/ayon_core/hosts/max/plugins/publish/save_scene.py +++ b/client/ayon_core/hosts/max/plugins/publish/save_scene.py @@ -20,4 +20,4 @@ class SaveCurrentScene(pyblish.api.ContextPlugin): self.log.info(f"Saving current file: {current_file}") host.save_workfile(current_file) else: - self.log.debug("No unsaved changes, skipping file save..")") \ No newline at end of file + self.log.debug("No unsaved changes, skipping file save..") \ No newline at end of file From e43e2344195d57e53a064d2422e547f47a730f67 Mon Sep 17 00:00:00 2001 From: Sponge96 Date: Wed, 14 Feb 2024 08:50:45 +0000 Subject: [PATCH 123/185] refactor: replaced OP imports with ayon-core Co-authored-by: Kayla Man <64118225+moonyuet@users.noreply.github.com> --- client/ayon_core/hosts/max/plugins/publish/save_scene.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/ayon_core/hosts/max/plugins/publish/save_scene.py b/client/ayon_core/hosts/max/plugins/publish/save_scene.py index 7961631b2a..1c59335ceb 100644 --- a/client/ayon_core/hosts/max/plugins/publish/save_scene.py +++ b/client/ayon_core/hosts/max/plugins/publish/save_scene.py @@ -1,5 +1,5 @@ import pyblish.api -from openpype.pipeline import registered_host +from ayon_core.pipeline import registered_host class SaveCurrentScene(pyblish.api.ContextPlugin): From a36bd63da7645d2afe90d27c170de4d66fca574a Mon Sep 17 00:00:00 2001 From: Kayla Man Date: Wed, 14 Feb 2024 17:15:05 +0800 Subject: [PATCH 124/185] some style tweaks on pipeline --- client/ayon_core/hosts/max/api/pipeline.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/client/ayon_core/hosts/max/api/pipeline.py b/client/ayon_core/hosts/max/api/pipeline.py index c9b74cea9e..c26e697429 100644 --- a/client/ayon_core/hosts/max/api/pipeline.py +++ b/client/ayon_core/hosts/max/api/pipeline.py @@ -59,9 +59,9 @@ class MaxHost(HostBase, IWorkfileHost, ILoadHost, IPublishHost): rt.callbacks.addScript(rt.Name('filePostOpen'), lib.check_colorspace) - + rt.callbacks.addScript(rt.Name('postWorkspaceChange'), - self._deferred_menu_creation) + self._deferred_menu_creation) def workfile_has_unsaved_changes(self): return rt.getSaveRequired() From e86555b2cc6eeb799118f9ea7f16fad5ad676c12 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Wed, 14 Feb 2024 11:43:23 +0100 Subject: [PATCH 125/185] use correct dirmap key in nuke --- client/ayon_core/hosts/nuke/api/pipeline.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/ayon_core/hosts/nuke/api/pipeline.py b/client/ayon_core/hosts/nuke/api/pipeline.py index 7483d404ec..735426240e 100644 --- a/client/ayon_core/hosts/nuke/api/pipeline.py +++ b/client/ayon_core/hosts/nuke/api/pipeline.py @@ -179,7 +179,7 @@ def add_nuke_callbacks(): nuke.addOnScriptLoad(WorkfileSettings().set_context_settings) - if nuke_settings["nuke_dirmap"]["enabled"]: + if nuke_settings["dirmap"]["enabled"]: log.info("Added Nuke's dir-mapping callback ...") # Add dirmap for file paths. nuke.addFilenameFilter(dirmap_file_name_filter) From 4d947d7ac77300de276d2819876d423284607221 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Wed, 14 Feb 2024 12:12:29 +0100 Subject: [PATCH 126/185] removed clockify conversion --- client/ayon_core/settings/ayon_settings.py | 15 +-------------- 1 file changed, 1 insertion(+), 14 deletions(-) diff --git a/client/ayon_core/settings/ayon_settings.py b/client/ayon_core/settings/ayon_settings.py index 8795fd0650..2577a3af06 100644 --- a/client/ayon_core/settings/ayon_settings.py +++ b/client/ayon_core/settings/ayon_settings.py @@ -76,19 +76,6 @@ def _convert_kitsu_system_settings( output["modules"]["kitsu"] = kitsu_settings -def _convert_clockify_system_settings( - ayon_settings, output, addon_versions, default_settings -): - enabled = addon_versions.get("clockify") is not None - clockify_settings = default_settings["modules"]["clockify"] - clockify_settings["enabled"] = enabled - if enabled: - clockify_settings["workspace_name"] = ( - ayon_settings["clockify"]["workspace_name"] - ) - output["modules"]["clockify"] = clockify_settings - - def _convert_deadline_system_settings( ayon_settings, output, addon_versions, default_settings ): @@ -127,7 +114,6 @@ def _convert_modules_system( # TODO add 'enabled' values for func in ( _convert_kitsu_system_settings, - _convert_clockify_system_settings, _convert_deadline_system_settings, _convert_royalrender_system_settings, ): @@ -135,6 +121,7 @@ def _convert_modules_system( for key in { "timers_manager", + "clockify", }: if addon_versions.get(key): output[key] = ayon_settings From fa55d1556215fe00b5ed73366db148a1a2b18983 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Wed, 14 Feb 2024 12:13:03 +0100 Subject: [PATCH 127/185] modified clockify addon to use AYON settings --- .../modules/clockify/clockify_module.py | 21 ++++++++++++------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/client/ayon_core/modules/clockify/clockify_module.py b/client/ayon_core/modules/clockify/clockify_module.py index adb7eb66af..58407bfe94 100644 --- a/client/ayon_core/modules/clockify/clockify_module.py +++ b/client/ayon_core/modules/clockify/clockify_module.py @@ -2,22 +2,27 @@ import os import threading import time -from ayon_core.modules import OpenPypeModule, ITrayModule, IPluginPaths +from ayon_core.modules import AYONAddon, ITrayModule, IPluginPaths from ayon_core.client import get_asset_by_name from .constants import CLOCKIFY_FTRACK_USER_PATH, CLOCKIFY_FTRACK_SERVER_PATH -class ClockifyModule(OpenPypeModule, ITrayModule, IPluginPaths): +class ClockifyModule(AYONAddon, ITrayModule, IPluginPaths): name = "clockify" - def initialize(self, modules_settings): - clockify_settings = modules_settings[self.name] - self.enabled = clockify_settings["enabled"] - self.workspace_name = clockify_settings["workspace_name"] + def initialize(self, studio_settings): + enabled = self.name in studio_settings + workspace_name = None + if enabled: + clockify_settings = studio_settings[self.name] + workspace_name = clockify_settings["workspace_name"] - if self.enabled and not self.workspace_name: - raise Exception("Clockify Workspace is not set in settings.") + if enabled and workspace_name: + self.log.warning("Clockify Workspace is not set in settings.") + enabled = False + self.enabled = enabled + self.workspace_name = workspace_name self.timer_manager = None self.MessageWidgetClass = None From 32dde5f02e94fcd8091877eea7ddb003d3b807da Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Wed, 14 Feb 2024 13:30:06 +0100 Subject: [PATCH 128/185] 'get_ayon_settings' is in settings functions --- client/ayon_core/settings/__init__.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/client/ayon_core/settings/__init__.py b/client/ayon_core/settings/__init__.py index ed3aaef7d4..f0e5c95efe 100644 --- a/client/ayon_core/settings/__init__.py +++ b/client/ayon_core/settings/__init__.py @@ -9,6 +9,7 @@ from .lib import ( get_current_project_settings, get_local_settings, ) +from .ayon_settings import get_ayon_settings __all__ = ( @@ -20,4 +21,6 @@ __all__ = ( "get_project_settings", "get_current_project_settings", "get_local_settings", + + "get_ayon_settings", ) From 731a4d7b29f97742ffa2c2647e753d9aa553b908 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Wed, 14 Feb 2024 13:43:04 +0100 Subject: [PATCH 129/185] simplify project settings conversion --- client/ayon_core/settings/ayon_settings.py | 110 --------------------- 1 file changed, 110 deletions(-) diff --git a/client/ayon_core/settings/ayon_settings.py b/client/ayon_core/settings/ayon_settings.py index 2577a3af06..6fdeec574f 100644 --- a/client/ayon_core/settings/ayon_settings.py +++ b/client/ayon_core/settings/ayon_settings.py @@ -188,59 +188,6 @@ def convert_system_settings(ayon_settings, default_settings, addon_versions): # --------- Project settings --------- -def _convert_blender_project_settings(ayon_settings, output): - if "blender" not in ayon_settings: - return - ayon_blender = ayon_settings["blender"] - - output["blender"] = ayon_blender - - -def _convert_celaction_project_settings(ayon_settings, output): - if "celaction" not in ayon_settings: - return - - ayon_celaction = ayon_settings["celaction"] - - output["celaction"] = ayon_celaction - - -def _convert_flame_project_settings(ayon_settings, output): - if "flame" not in ayon_settings: - return - - ayon_flame = ayon_settings["flame"] - - output["flame"] = ayon_flame - - -def _convert_fusion_project_settings(ayon_settings, output): - if "fusion" not in ayon_settings: - return - - ayon_fusion = ayon_settings["fusion"] - - output["fusion"] = ayon_fusion - - -def _convert_maya_project_settings(ayon_settings, output): - if "maya" not in ayon_settings: - return - - ayon_maya = ayon_settings["maya"] - - output["maya"] = ayon_maya - - -def _convert_3dsmax_project_settings(ayon_settings, output): - if "max" not in ayon_settings: - return - - ayon_max = ayon_settings["max"] - - output["max"] = ayon_max - - def _convert_nuke_knobs(knobs): new_knobs = [] for knob in knobs: @@ -456,39 +403,6 @@ def _convert_hiero_project_settings(ayon_settings, output): output["hiero"] = ayon_hiero -def _convert_photoshop_project_settings(ayon_settings, output): - if "photoshop" not in ayon_settings: - return - - ayon_photoshop = ayon_settings["photoshop"] - output["photoshop"] = ayon_photoshop - - -def _convert_substancepainter_project_settings(ayon_settings, output): - if "substancepainter" not in ayon_settings: - return - - ayon_substance_painter = ayon_settings["substancepainter"] - output["substancepainter"] = ayon_substance_painter - - -def _convert_tvpaint_project_settings(ayon_settings, output): - if "tvpaint" not in ayon_settings: - return - - ayon_tvpaint = ayon_settings["tvpaint"] - output["tvpaint"] = ayon_tvpaint - - -def _convert_traypublisher_project_settings(ayon_settings, output): - if "traypublisher" not in ayon_settings: - return - - ayon_traypublisher = ayon_settings["traypublisher"] - - output["traypublisher"] = ayon_traypublisher - - def _convert_webpublisher_project_settings(ayon_settings, output): if "webpublisher" not in ayon_settings: return @@ -747,35 +661,11 @@ def _convert_global_project_settings(ayon_settings, output, default_settings): def convert_project_settings(ayon_settings, default_settings): - # Missing settings - # - standalonepublisher default_settings = copy.deepcopy(default_settings) output = {} - exact_match = { - "aftereffects", - "harmony", - "houdini", - "resolve", - "unreal", - "applications", - "deadline", - } - for key in exact_match: - if key in ayon_settings: - output[key] = ayon_settings[key] - _convert_blender_project_settings(ayon_settings, output) - _convert_celaction_project_settings(ayon_settings, output) - _convert_flame_project_settings(ayon_settings, output) - _convert_fusion_project_settings(ayon_settings, output) - _convert_maya_project_settings(ayon_settings, output) - _convert_3dsmax_project_settings(ayon_settings, output) _convert_nuke_project_settings(ayon_settings, output) _convert_hiero_project_settings(ayon_settings, output) - _convert_photoshop_project_settings(ayon_settings, output) - _convert_substancepainter_project_settings(ayon_settings, output) - _convert_tvpaint_project_settings(ayon_settings, output) - _convert_traypublisher_project_settings(ayon_settings, output) _convert_webpublisher_project_settings(ayon_settings, output) _convert_royalrender_project_settings(ayon_settings, output) From 6b1b4367bbb5f62b9e9d03e22d82f21675d104bf Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Wed, 14 Feb 2024 13:43:19 +0100 Subject: [PATCH 130/185] simplify system settings conversion --- client/ayon_core/settings/ayon_settings.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/client/ayon_core/settings/ayon_settings.py b/client/ayon_core/settings/ayon_settings.py index 6fdeec574f..7e9fad314c 100644 --- a/client/ayon_core/settings/ayon_settings.py +++ b/client/ayon_core/settings/ayon_settings.py @@ -164,9 +164,6 @@ def convert_system_settings(ayon_settings, default_settings, addon_versions): output = { "modules": {} } - if "applications" in ayon_settings: - output["applications"] = ayon_settings["applications"] - if "core" in ayon_settings: _convert_general(ayon_settings, output, default_settings) From 8324b971a8a023dce4f25f9ce2d5196d35ad1f8c Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Wed, 14 Feb 2024 14:01:47 +0100 Subject: [PATCH 131/185] handle additional applications correctly --- client/ayon_core/lib/applications.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/client/ayon_core/lib/applications.py b/client/ayon_core/lib/applications.py index 70aa9811c7..2b0b855c81 100644 --- a/client/ayon_core/lib/applications.py +++ b/client/ayon_core/lib/applications.py @@ -419,7 +419,14 @@ class ApplicationManager: # Prepare known applications app_defs = applications_addon_settings["applications"] additional_apps = app_defs.pop("additional_apps") - app_defs.update(additional_apps) + for additional_app in additional_apps: + app_name = additional_app.pop("name") + if app_name in app_defs: + self.log.warning(( + "Additional application '{}' is already" + " in built-in applications." + ).format(app_name)) + app_defs[app_name] = additional_app for group_name, variant_defs in app_defs.items(): group = ApplicationGroup(group_name, variant_defs, self) From 4113ff7bf0b4dc396aa829352161aca6fdef9eec Mon Sep 17 00:00:00 2001 From: Oscar Domingo Date: Wed, 14 Feb 2024 14:52:18 +0000 Subject: [PATCH 132/185] Add `rez` packages generation for `server_addons` Allow to generate `rez` compatible packages for the `server_addons`, will create a `package.py` which then is also included in the `.zip`. --- server_addon/create_ayon_addons.py | 68 +++++++++++++++++++++++------- 1 file changed, 53 insertions(+), 15 deletions(-) diff --git a/server_addon/create_ayon_addons.py b/server_addon/create_ayon_addons.py index 08443d6588..f9f31dd9b0 100644 --- a/server_addon/create_ayon_addons.py +++ b/server_addon/create_ayon_addons.py @@ -144,11 +144,18 @@ def create_addon_zip( output_dir: Path, addon_name: str, addon_version: str, - keep_source: bool + keep_source: bool, + rez_package: bool, ): zip_filepath = output_dir / f"{addon_name}-{addon_version}.zip" + + if rez_package: + zip_filepath = output_dir / f"{addon_name}-{addon_version}-rez.zip" + addon_output_dir = output_dir / addon_name / addon_version with ZipFileLongPaths(zip_filepath, "w", zipfile.ZIP_DEFLATED) as zipf: + # TODO: Decide if we want to keep this for first pass checking without + # executing any python. Otherwiseh we can be removed zipf.writestr( "manifest.json", json.dumps({ @@ -168,8 +175,14 @@ def create_addon_zip( src_path = os.path.join(root, filename) if rel_root: dst_path = os.path.join("addon", rel_root, filename) + if rez_package: + dst_path = os.path.join(rel_root, filename) else: dst_path = os.path.join("addon", filename) + + if rez_package: + dst_path = filename + zipf.write(src_path, dst_path) if not keep_source: @@ -180,7 +193,8 @@ def create_addon_package( addon_dir: Path, output_dir: Path, create_zip: bool, - keep_source: bool + keep_source: bool, + rez_package: bool, ): server_dir = addon_dir / "server" addon_version = get_addon_version(addon_dir) @@ -191,22 +205,37 @@ def create_addon_package( addon_output_dir.mkdir(parents=True) # Copy server content - src_root = os.path.normpath(str(server_dir.absolute())) - src_root_offset = len(src_root) + 1 - for root, _, filenames in os.walk(str(server_dir)): - dst_root = addon_output_dir - if root != src_root: - rel_root = root[src_root_offset:] - dst_root = dst_root / rel_root + if not rez_package: + src_root = os.path.normpath(str(server_dir.absolute())) + src_root_offset = len(src_root) + 1 + for root, _, filenames in os.walk(str(server_dir)): + dst_root = addon_output_dir + if root != src_root: + rel_root = root[src_root_offset:] + dst_root = dst_root / rel_root - dst_root.mkdir(parents=True, exist_ok=True) - for filename in filenames: - src_path = os.path.join(root, filename) - shutil.copy(src_path, str(dst_root)) + dst_root.mkdir(parents=True, exist_ok=True) + for filename in filenames: + src_path = os.path.join(root, filename) + shutil.copy(src_path, str(dst_root)) + else: + package_py = addon_output_dir / "package.py" + + with open(package_py, "w+") as pkg_py: + pkg_py.write( + f"""name = "{addon_dir.name}" +version = "{addon_version}" +plugin_for = ["ayon_server"] +build_command = "python {{root}}/rezbuild.py" +""" + ) + shutil.copytree( + server_dir, addon_output_dir / "server", dirs_exist_ok=True + ) if create_zip: create_addon_zip( - output_dir, addon_dir.name, addon_version, keep_source + output_dir, addon_dir.name, addon_version, keep_source, rez_package ) @@ -216,6 +245,7 @@ def main( keep_source=False, clear_output_dir=False, addons=None, + rez_package=False, ): current_dir = Path(os.path.dirname(os.path.abspath(__file__))) root_dir = current_dir.parent @@ -250,7 +280,7 @@ def main( continue create_addon_package( - addon_dir, output_dir, create_zip, keep_source + addon_dir, output_dir, create_zip, keep_source, rez_package ) print(f"- package '{addon_dir.name}' created") @@ -300,6 +330,13 @@ if __name__ == "__main__": action="append", help="Limit addon creation to given addon name", ) + parser.add_argument( + "-r", + "--rez", + dest="rez_package", + action="store_true", + help="Make it a Rez-compatible package", + ) args = parser.parse_args(sys.argv[1:]) main( @@ -308,4 +345,5 @@ if __name__ == "__main__": args.keep_sources, args.clear_output_dir, args.addons, + args.rez_package, ) From 0744c27c91d8eac2d9742827f6dd1a687f1189bf Mon Sep 17 00:00:00 2001 From: Oscar Domingo Date: Wed, 14 Feb 2024 14:56:52 +0000 Subject: [PATCH 133/185] `package.py` Ensure we require the correct `ayon_server` version For more info on `rez` package requests syntax check: https://rez.readthedocs.io/en/latest/basic_concepts.html#package-requests-concept --- package.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/package.py b/package.py index d7266d852b..3b451e0078 100644 --- a/package.py +++ b/package.py @@ -5,4 +5,7 @@ version = "0.2.1-dev.1" client_dir = "ayon_core" plugin_for = ["ayon_server"] -ayon_version = ">=1.0.3,<2.0.0" +requires = [ + "~ayon_server-1.0.3+<2.0.0", +] + From 4c0651f593213838e2a2b21a34ccebba81bea732 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Wed, 14 Feb 2024 18:18:02 +0100 Subject: [PATCH 134/185] create only rez packages --- server_addon/create_ayon_addons.py | 77 ++++++++---------------------- 1 file changed, 19 insertions(+), 58 deletions(-) diff --git a/server_addon/create_ayon_addons.py b/server_addon/create_ayon_addons.py index f9f31dd9b0..5e06d8ee8a 100644 --- a/server_addon/create_ayon_addons.py +++ b/server_addon/create_ayon_addons.py @@ -40,6 +40,11 @@ IGNORED_HOSTS = [ IGNORED_MODULES = [] +PACKAGE_PY_TEMPLATE = """name = "{addon_name}" +version = "{addon_version}" +plugin_for = ["ayon_server"] +""" + class ZipFileLongPaths(zipfile.ZipFile): """Allows longer paths in zip files. @@ -145,24 +150,11 @@ def create_addon_zip( addon_name: str, addon_version: str, keep_source: bool, - rez_package: bool, ): zip_filepath = output_dir / f"{addon_name}-{addon_version}.zip" - if rez_package: - zip_filepath = output_dir / f"{addon_name}-{addon_version}-rez.zip" - addon_output_dir = output_dir / addon_name / addon_version with ZipFileLongPaths(zip_filepath, "w", zipfile.ZIP_DEFLATED) as zipf: - # TODO: Decide if we want to keep this for first pass checking without - # executing any python. Otherwiseh we can be removed - zipf.writestr( - "manifest.json", - json.dumps({ - "addon_name": addon_name, - "addon_version": addon_version - }) - ) # Add client code content to zip src_root = os.path.normpath(str(addon_output_dir.absolute())) src_root_offset = len(src_root) + 1 @@ -174,14 +166,9 @@ def create_addon_zip( for filename in filenames: src_path = os.path.join(root, filename) if rel_root: - dst_path = os.path.join("addon", rel_root, filename) - if rez_package: - dst_path = os.path.join(rel_root, filename) + dst_path = os.path.join(rel_root, filename) else: - dst_path = os.path.join("addon", filename) - - if rez_package: - dst_path = filename + dst_path = filename zipf.write(src_path, dst_path) @@ -194,9 +181,7 @@ def create_addon_package( output_dir: Path, create_zip: bool, keep_source: bool, - rez_package: bool, ): - server_dir = addon_dir / "server" addon_version = get_addon_version(addon_dir) addon_output_dir = output_dir / addon_dir.name / addon_version @@ -205,37 +190,22 @@ def create_addon_package( addon_output_dir.mkdir(parents=True) # Copy server content - if not rez_package: - src_root = os.path.normpath(str(server_dir.absolute())) - src_root_offset = len(src_root) + 1 - for root, _, filenames in os.walk(str(server_dir)): - dst_root = addon_output_dir - if root != src_root: - rel_root = root[src_root_offset:] - dst_root = dst_root / rel_root + package_py = addon_output_dir / "package.py" + package_py_content = PACKAGE_PY_TEMPLATE.format( + addon_name=addon_dir.name, addon_version=addon_version + ) - dst_root.mkdir(parents=True, exist_ok=True) - for filename in filenames: - src_path = os.path.join(root, filename) - shutil.copy(src_path, str(dst_root)) - else: - package_py = addon_output_dir / "package.py" + with open(package_py, "w+") as pkg_py: + pkg_py.write(package_py_content) - with open(package_py, "w+") as pkg_py: - pkg_py.write( - f"""name = "{addon_dir.name}" -version = "{addon_version}" -plugin_for = ["ayon_server"] -build_command = "python {{root}}/rezbuild.py" -""" - ) - shutil.copytree( - server_dir, addon_output_dir / "server", dirs_exist_ok=True - ) + server_dir = addon_dir / "server" + shutil.copytree( + server_dir, addon_output_dir / "server", dirs_exist_ok=True + ) if create_zip: create_addon_zip( - output_dir, addon_dir.name, addon_version, keep_source, rez_package + output_dir, addon_dir.name, addon_version, keep_source ) @@ -245,7 +215,6 @@ def main( keep_source=False, clear_output_dir=False, addons=None, - rez_package=False, ): current_dir = Path(os.path.dirname(os.path.abspath(__file__))) root_dir = current_dir.parent @@ -280,7 +249,7 @@ def main( continue create_addon_package( - addon_dir, output_dir, create_zip, keep_source, rez_package + addon_dir, output_dir, create_zip, keep_source ) print(f"- package '{addon_dir.name}' created") @@ -330,13 +299,6 @@ if __name__ == "__main__": action="append", help="Limit addon creation to given addon name", ) - parser.add_argument( - "-r", - "--rez", - dest="rez_package", - action="store_true", - help="Make it a Rez-compatible package", - ) args = parser.parse_args(sys.argv[1:]) main( @@ -345,5 +307,4 @@ if __name__ == "__main__": args.keep_sources, args.clear_output_dir, args.addons, - args.rez_package, ) From 40a9788536fd06a40d54f351e9a55f8c5d96a580 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Wed, 14 Feb 2024 18:32:09 +0100 Subject: [PATCH 135/185] fix applications settings --- server_addon/applications/server/__init__.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/server_addon/applications/server/__init__.py b/server_addon/applications/server/__init__.py index e782e8a591..d5c2de3df3 100644 --- a/server_addon/applications/server/__init__.py +++ b/server_addon/applications/server/__init__.py @@ -92,8 +92,9 @@ class ApplicationsAddon(BaseServerAddon): settings_model = ApplicationsAddonSettings async def get_default_settings(self): - applications_path = os.path.join(self.addon_dir, "applications.json") - tools_path = os.path.join(self.addon_dir, "tools.json") + server_dir = os.path.join(self.addon_dir, "server") + applications_path = os.path.join(server_dir, "applications.json") + tools_path = os.path.join(server_dir, "tools.json") default_values = copy.deepcopy(DEFAULT_VALUES) with open(applications_path, "r") as stream: default_values.update(json.load(stream)) From 1d72cd102356bb5d0b4ae0f8555dec46433311cd Mon Sep 17 00:00:00 2001 From: Kayla Man Date: Thu, 15 Feb 2024 16:47:05 +0800 Subject: [PATCH 136/185] bug fix remove items not working in scene inventory manager --- client/ayon_core/hosts/max/api/pipeline.py | 17 +++++++++++++++++ .../hosts/max/plugins/load/load_camera_fbx.py | 8 ++++---- .../hosts/max/plugins/load/load_max_scene.py | 9 +++++---- .../hosts/max/plugins/load/load_model.py | 8 +++++--- .../hosts/max/plugins/load/load_model_fbx.py | 9 +++++---- .../hosts/max/plugins/load/load_model_obj.py | 6 +++--- .../hosts/max/plugins/load/load_model_usd.py | 5 +++-- .../hosts/max/plugins/load/load_pointcache.py | 5 +++-- .../plugins/load/load_pointcache_ornatrix.py | 5 +++-- .../hosts/max/plugins/load/load_pointcloud.py | 6 +++--- .../max/plugins/load/load_redshift_proxy.py | 6 +++--- .../hosts/max/plugins/load/load_tycache.py | 9 ++++----- 12 files changed, 58 insertions(+), 35 deletions(-) diff --git a/client/ayon_core/hosts/max/api/pipeline.py b/client/ayon_core/hosts/max/api/pipeline.py index c26e697429..106c29fd26 100644 --- a/client/ayon_core/hosts/max/api/pipeline.py +++ b/client/ayon_core/hosts/max/api/pipeline.py @@ -242,3 +242,20 @@ def get_previous_loaded_object(container: str): if str(obj) in sel_list: node_list.append(obj) return node_list + + +def remove_container_data(container: str): + """Function to remove container data after updating, switching or deleting it. + + Args: + container (str): container + """ + if container.modifiers[0].name == "OP Data": + all_set_members_names = [ + member.node for member + in container.modifiers[0].openPypeData.all_handles] + for current_set_member in all_set_members_names: + rt.Delete(current_set_member) + rt.deleteModifier(container, container.modifiers[0]) + + rt.Delete(container) diff --git a/client/ayon_core/hosts/max/plugins/load/load_camera_fbx.py b/client/ayon_core/hosts/max/plugins/load/load_camera_fbx.py index 34b120c179..d7eebdbc3a 100644 --- a/client/ayon_core/hosts/max/plugins/load/load_camera_fbx.py +++ b/client/ayon_core/hosts/max/plugins/load/load_camera_fbx.py @@ -1,6 +1,6 @@ import os -from ayon_core.hosts.max.api import lib, maintained_selection +from ayon_core.hosts.max.api import lib from ayon_core.hosts.max.api.lib import ( unique_namespace, get_namespace, @@ -9,7 +9,8 @@ from ayon_core.hosts.max.api.lib import ( from ayon_core.hosts.max.api.pipeline import ( containerise, get_previous_loaded_object, - update_custom_attribute_data + update_custom_attribute_data, + remove_container_data ) from ayon_core.pipeline import get_representation_path, load @@ -94,6 +95,5 @@ class FbxLoader(load.LoaderPlugin): def remove(self, container): from pymxs import runtime as rt - node = rt.GetNodeByName(container["instance_node"]) - rt.Delete(node) + remove_container_data(node) diff --git a/client/ayon_core/hosts/max/plugins/load/load_max_scene.py b/client/ayon_core/hosts/max/plugins/load/load_max_scene.py index 7267d7a59e..81f3af089f 100644 --- a/client/ayon_core/hosts/max/plugins/load/load_max_scene.py +++ b/client/ayon_core/hosts/max/plugins/load/load_max_scene.py @@ -7,8 +7,10 @@ from ayon_core.hosts.max.api.lib import ( object_transform_set ) from ayon_core.hosts.max.api.pipeline import ( - containerise, get_previous_loaded_object, - update_custom_attribute_data + containerise, + get_previous_loaded_object, + update_custom_attribute_data, + remove_container_data ) from ayon_core.pipeline import get_representation_path, load @@ -93,6 +95,5 @@ class MaxSceneLoader(load.LoaderPlugin): def remove(self, container): from pymxs import runtime as rt - node = rt.GetNodeByName(container["instance_node"]) - rt.Delete(node) + remove_container_data(node) diff --git a/client/ayon_core/hosts/max/plugins/load/load_model.py b/client/ayon_core/hosts/max/plugins/load/load_model.py index 796e1b80ad..28ec7be01f 100644 --- a/client/ayon_core/hosts/max/plugins/load/load_model.py +++ b/client/ayon_core/hosts/max/plugins/load/load_model.py @@ -2,11 +2,13 @@ import os from ayon_core.pipeline import load, get_representation_path from ayon_core.hosts.max.api.pipeline import ( containerise, - get_previous_loaded_object + get_previous_loaded_object, + remove_container_data ) from ayon_core.hosts.max.api import lib from ayon_core.hosts.max.api.lib import ( - maintained_selection, unique_namespace + maintained_selection, + unique_namespace ) @@ -99,7 +101,7 @@ class ModelAbcLoader(load.LoaderPlugin): from pymxs import runtime as rt node = rt.GetNodeByName(container["instance_node"]) - rt.Delete(node) + remove_container_data(node) @staticmethod def get_container_children(parent, type_name): diff --git a/client/ayon_core/hosts/max/plugins/load/load_model_fbx.py b/client/ayon_core/hosts/max/plugins/load/load_model_fbx.py index 827cf63b39..81ad84546a 100644 --- a/client/ayon_core/hosts/max/plugins/load/load_model_fbx.py +++ b/client/ayon_core/hosts/max/plugins/load/load_model_fbx.py @@ -1,8 +1,10 @@ import os from ayon_core.pipeline import load, get_representation_path from ayon_core.hosts.max.api.pipeline import ( - containerise, get_previous_loaded_object, - update_custom_attribute_data + containerise, + get_previous_loaded_object, + update_custom_attribute_data, + remove_container_data ) from ayon_core.hosts.max.api import lib from ayon_core.hosts.max.api.lib import ( @@ -92,6 +94,5 @@ class FbxModelLoader(load.LoaderPlugin): def remove(self, container): from pymxs import runtime as rt - node = rt.GetNodeByName(container["instance_node"]) - rt.Delete(node) + remove_container_data(node) diff --git a/client/ayon_core/hosts/max/plugins/load/load_model_obj.py b/client/ayon_core/hosts/max/plugins/load/load_model_obj.py index 22d3d4b58a..1023b67f0c 100644 --- a/client/ayon_core/hosts/max/plugins/load/load_model_obj.py +++ b/client/ayon_core/hosts/max/plugins/load/load_model_obj.py @@ -11,7 +11,8 @@ from ayon_core.hosts.max.api.lib import maintained_selection from ayon_core.hosts.max.api.pipeline import ( containerise, get_previous_loaded_object, - update_custom_attribute_data + update_custom_attribute_data, + remove_container_data ) from ayon_core.pipeline import get_representation_path, load @@ -84,6 +85,5 @@ class ObjLoader(load.LoaderPlugin): def remove(self, container): from pymxs import runtime as rt - node = rt.GetNodeByName(container["instance_node"]) - rt.Delete(node) + remove_container_data(node) diff --git a/client/ayon_core/hosts/max/plugins/load/load_model_usd.py b/client/ayon_core/hosts/max/plugins/load/load_model_usd.py index 8d42219217..6a08bebf5a 100644 --- a/client/ayon_core/hosts/max/plugins/load/load_model_usd.py +++ b/client/ayon_core/hosts/max/plugins/load/load_model_usd.py @@ -13,7 +13,8 @@ from ayon_core.hosts.max.api.lib import maintained_selection from ayon_core.hosts.max.api.pipeline import ( containerise, get_previous_loaded_object, - update_custom_attribute_data + update_custom_attribute_data, + remove_container_data ) from ayon_core.pipeline import get_representation_path, load @@ -114,4 +115,4 @@ class ModelUSDLoader(load.LoaderPlugin): def remove(self, container): node = rt.GetNodeByName(container["instance_node"]) - rt.Delete(node) + remove_container_data(node) diff --git a/client/ayon_core/hosts/max/plugins/load/load_pointcache.py b/client/ayon_core/hosts/max/plugins/load/load_pointcache.py index a92fa66757..d7267afb7d 100644 --- a/client/ayon_core/hosts/max/plugins/load/load_pointcache.py +++ b/client/ayon_core/hosts/max/plugins/load/load_pointcache.py @@ -10,7 +10,8 @@ from ayon_core.hosts.max.api import lib, maintained_selection from ayon_core.hosts.max.api.lib import unique_namespace from ayon_core.hosts.max.api.pipeline import ( containerise, - get_previous_loaded_object + get_previous_loaded_object, + remove_container_data ) @@ -105,7 +106,7 @@ class AbcLoader(load.LoaderPlugin): from pymxs import runtime as rt node = rt.GetNodeByName(container["instance_node"]) - rt.Delete(node) + remove_container_data(node) @staticmethod def get_container_children(parent, type_name): diff --git a/client/ayon_core/hosts/max/plugins/load/load_pointcache_ornatrix.py b/client/ayon_core/hosts/max/plugins/load/load_pointcache_ornatrix.py index 27b2e271d2..5b48e5d189 100644 --- a/client/ayon_core/hosts/max/plugins/load/load_pointcache_ornatrix.py +++ b/client/ayon_core/hosts/max/plugins/load/load_pointcache_ornatrix.py @@ -4,7 +4,8 @@ from ayon_core.pipeline.load import LoadError from ayon_core.hosts.max.api.pipeline import ( containerise, get_previous_loaded_object, - update_custom_attribute_data + update_custom_attribute_data, + remove_container_data ) from ayon_core.hosts.max.api.lib import ( @@ -105,4 +106,4 @@ class OxAbcLoader(load.LoaderPlugin): def remove(self, container): node = rt.GetNodeByName(container["instance_node"]) - rt.Delete(node) + remove_container_data(node) \ No newline at end of file diff --git a/client/ayon_core/hosts/max/plugins/load/load_pointcloud.py b/client/ayon_core/hosts/max/plugins/load/load_pointcloud.py index 45e3da5621..7f4fba50b3 100644 --- a/client/ayon_core/hosts/max/plugins/load/load_pointcloud.py +++ b/client/ayon_core/hosts/max/plugins/load/load_pointcloud.py @@ -8,7 +8,8 @@ from ayon_core.hosts.max.api.lib import ( from ayon_core.hosts.max.api.pipeline import ( containerise, get_previous_loaded_object, - update_custom_attribute_data + update_custom_attribute_data, + remove_container_data ) from ayon_core.pipeline import get_representation_path, load @@ -63,6 +64,5 @@ class PointCloudLoader(load.LoaderPlugin): def remove(self, container): """remove the container""" from pymxs import runtime as rt - node = rt.GetNodeByName(container["instance_node"]) - rt.Delete(node) + remove_container_data(node) diff --git a/client/ayon_core/hosts/max/plugins/load/load_redshift_proxy.py b/client/ayon_core/hosts/max/plugins/load/load_redshift_proxy.py index 3f73210c24..3ccc5cc5e1 100644 --- a/client/ayon_core/hosts/max/plugins/load/load_redshift_proxy.py +++ b/client/ayon_core/hosts/max/plugins/load/load_redshift_proxy.py @@ -9,7 +9,8 @@ from ayon_core.pipeline.load import LoadError from ayon_core.hosts.max.api.pipeline import ( containerise, update_custom_attribute_data, - get_previous_loaded_object + get_previous_loaded_object, + remove_container_data ) from ayon_core.hosts.max.api import lib from ayon_core.hosts.max.api.lib import ( @@ -72,6 +73,5 @@ class RedshiftProxyLoader(load.LoaderPlugin): def remove(self, container): from pymxs import runtime as rt - node = rt.getNodeByName(container["instance_node"]) - rt.delete(node) + remove_container_data(node) diff --git a/client/ayon_core/hosts/max/plugins/load/load_tycache.py b/client/ayon_core/hosts/max/plugins/load/load_tycache.py index 48fb5c447a..97f41026b4 100644 --- a/client/ayon_core/hosts/max/plugins/load/load_tycache.py +++ b/client/ayon_core/hosts/max/plugins/load/load_tycache.py @@ -1,13 +1,13 @@ import os from ayon_core.hosts.max.api import lib, maintained_selection from ayon_core.hosts.max.api.lib import ( - unique_namespace, - + unique_namespace ) from ayon_core.hosts.max.api.pipeline import ( containerise, get_previous_loaded_object, - update_custom_attribute_data + update_custom_attribute_data, + remove_container_data ) from ayon_core.pipeline import get_representation_path, load @@ -59,6 +59,5 @@ class TyCacheLoader(load.LoaderPlugin): def remove(self, container): """remove the container""" from pymxs import runtime as rt - node = rt.GetNodeByName(container["instance_node"]) - rt.Delete(node) + remove_container_data(node) From 8e9fd531d0935aa56d20efaacd3b91088a01c4a5 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Thu, 15 Feb 2024 10:23:56 +0100 Subject: [PATCH 137/185] change color types back to their previous type --- .../plugins/publish/extract_sequence.py | 2 +- server/settings/publish_plugins.py | 18 +- server_addon/maya/server/settings/loaders.py | 192 ++++++++++-------- .../maya/server/settings/publish_playblast.py | 44 ++-- .../server/settings/publish_plugins.py | 13 +- 5 files changed, 157 insertions(+), 112 deletions(-) diff --git a/client/ayon_core/hosts/tvpaint/plugins/publish/extract_sequence.py b/client/ayon_core/hosts/tvpaint/plugins/publish/extract_sequence.py index 6d54d8ec32..0ab9fbd038 100644 --- a/client/ayon_core/hosts/tvpaint/plugins/publish/extract_sequence.py +++ b/client/ayon_core/hosts/tvpaint/plugins/publish/extract_sequence.py @@ -31,7 +31,7 @@ class ExtractSequence(pyblish.api.Extractor): families = ["review", "render"] # Modifiable with settings - review_bg = [255, 255, 255, 255] + review_bg = [255, 255, 255, 1.0] def process(self, instance): self.log.info( diff --git a/server/settings/publish_plugins.py b/server/settings/publish_plugins.py index c01fb92b9c..9b5f3ae571 100644 --- a/server/settings/publish_plugins.py +++ b/server/settings/publish_plugins.py @@ -387,14 +387,22 @@ class ExtractReviewOutputDefModel(BaseSettingsModel): "Crop input overscan. See the documentation for more information." ) ) - overscan_color: ColorRGB_uint8 = SettingsField( - (0, 0, 0), + overscan_color: ColorRGBA_uint8 = SettingsField( + (0, 0, 0, 0.0), title="Overscan color", description=( "Overscan color is used when input aspect ratio is not" " same as output aspect ratio." ) ) + # overscan_color: ColorRGB_uint8 = SettingsField( + # (0, 0, 0), + # title="Overscan color", + # description=( + # "Overscan color is used when input aspect ratio is not" + # " same as output aspect ratio." + # ) + # ) width: int = SettingsField( 0, ge=0, @@ -901,7 +909,8 @@ DEFAULT_PUBLISH_VALUES = { "single_frame_filter": "single_frame" }, "overscan_crop": "", - "overscan_color": [0, 0, 0], + # "overscan_color": [0, 0, 0], + "overscan_color": [0, 0, 0, 0.0], "width": 1920, "height": 1080, "scale_pixel_aspect": True, @@ -946,7 +955,8 @@ DEFAULT_PUBLISH_VALUES = { "single_frame_filter": "multi_frame" }, "overscan_crop": "", - "overscan_color": [0, 0, 0], + # "overscan_color": [0, 0, 0], + "overscan_color": [0, 0, 0, 0.0], "width": 0, "height": 0, "scale_pixel_aspect": True, diff --git a/server_addon/maya/server/settings/loaders.py b/server_addon/maya/server/settings/loaders.py index b8264a56ef..3e8d368a6b 100644 --- a/server_addon/maya/server/settings/loaders.py +++ b/server_addon/maya/server/settings/loaders.py @@ -3,70 +3,86 @@ from ayon_server.types import ColorRGB_float class ColorsSetting(BaseSettingsModel): - model: ColorRGB_float = SettingsField( - (0.82, 0.52, 0.12), - title="Model:" - ) - rig: ColorRGB_float = SettingsField( - (0.23, 0.89, 0.92), - title="Rig:" - ) - pointcache: ColorRGB_float = SettingsField( - (0.37, 0.82, 0.12), - title="Pointcache:" - ) - animation: ColorRGB_float = SettingsField( - (0.37, 0.82, 0.12), - title="Animation:" - ) - ass: ColorRGB_float = SettingsField( - (0.98, 0.53, 0.21), - title="Arnold StandIn:" - ) - camera: ColorRGB_float = SettingsField( - (0.53, 0.45, 0.96), - title="Camera:" - ) - fbx: ColorRGB_float = SettingsField( - (0.84, 0.65, 1.0), - title="FBX:" - ) - mayaAscii: ColorRGB_float = SettingsField( - (0.26, 0.68, 1.0), - title="Maya Ascii:" - ) - mayaScene: ColorRGB_float = SettingsField( - (0.26, 0.68, 1.0), - title="Maya Scene:" - ) - setdress: ColorRGB_float = SettingsField( - (1.0, 0.98, 0.35), - title="Set Dress:" - ) - layout: ColorRGB_float = SettingsField( - (1.0, 0.98, 0.35), - title="Layout:" - ) - vdbcache: ColorRGB_float = SettingsField( - (0.98, 0.21, 0.0), - title="VDB Cache:" - ) - vrayproxy: ColorRGB_float = SettingsField( - (1.0, 0.59, 0.05), - title="VRay Proxy:" - ) - vrayscene_layer: ColorRGB_float = SettingsField( - (1.0, 0.59, 0.05), - title="VRay Scene:" - ) - yeticache: ColorRGB_float = SettingsField( - (0.39, 0.81, 0.86), - title="Yeti Cache:" - ) - yetiRig: ColorRGB_float = SettingsField( - (0.0, 0.80, 0.49), - title="Yeti Rig:" - ) + model: ColorRGBA_uint8 = SettingsField( + (209, 132, 30, 1.0), title="Model:") + rig: ColorRGBA_uint8 = SettingsField( + (59, 226, 235, 1.0), title="Rig:") + pointcache: ColorRGBA_uint8 = SettingsField( + (94, 209, 30, 1.0), title="Pointcache:") + animation: ColorRGBA_uint8 = SettingsField( + (94, 209, 30, 1.0), title="Animation:") + ass: ColorRGBA_uint8 = SettingsField( + (249, 135, 53, 1.0), title="Arnold StandIn:") + camera: ColorRGBA_uint8 = SettingsField( + (136, 114, 244, 1.0), title="Camera:") + fbx: ColorRGBA_uint8 = SettingsField( + (215, 166, 255, 1.0), title="FBX:") + mayaAscii: ColorRGBA_uint8 = SettingsField( + (67, 174, 255, 1.0), title="Maya Ascii:") + mayaScene: ColorRGBA_uint8 = SettingsField( + (67, 174, 255, 1.0), title="Maya Scene:") + setdress: ColorRGBA_uint8 = SettingsField( + (255, 250, 90, 1.0), title="Set Dress:") + layout: ColorRGBA_uint8 = SettingsField(( + 255, 250, 90, 1.0), title="Layout:") + vdbcache: ColorRGBA_uint8 = SettingsField( + (249, 54, 0, 1.0), title="VDB Cache:") + vrayproxy: ColorRGBA_uint8 = SettingsField( + (255, 150, 12, 1.0), title="VRay Proxy:") + vrayscene_layer: ColorRGBA_uint8 = SettingsField( + (255, 150, 12, 1.0), title="VRay Scene:") + yeticache: ColorRGBA_uint8 = SettingsField( + (99, 206, 220, 1.0), title="Yeti Cache:") + yetiRig: ColorRGBA_uint8 = SettingsField( + (0, 205, 125, 1.0), title="Yeti Rig:") + # model: ColorRGB_float = SettingsField( + # (0.82, 0.52, 0.12), title="Model:" + # ) + # rig: ColorRGB_float = SettingsField( + # (0.23, 0.89, 0.92), title="Rig:" + # ) + # pointcache: ColorRGB_float = SettingsField( + # (0.37, 0.82, 0.12), title="Pointcache:" + # ) + # animation: ColorRGB_float = SettingsField( + # (0.37, 0.82, 0.12), title="Animation:" + # ) + # ass: ColorRGB_float = SettingsField( + # (0.98, 0.53, 0.21), title="Arnold StandIn:" + # ) + # camera: ColorRGB_float = SettingsField( + # (0.53, 0.45, 0.96), title="Camera:" + # ) + # fbx: ColorRGB_float = SettingsField( + # (0.84, 0.65, 1.0), title="FBX:" + # ) + # mayaAscii: ColorRGB_float = SettingsField( + # (0.26, 0.68, 1.0), title="Maya Ascii:" + # ) + # mayaScene: ColorRGB_float = SettingsField( + # (0.26, 0.68, 1.0), title="Maya Scene:" + # ) + # setdress: ColorRGB_float = SettingsField( + # (1.0, 0.98, 0.35), title="Set Dress:" + # ) + # layout: ColorRGB_float = SettingsField( + # (1.0, 0.98, 0.35), title="Layout:" + # ) + # vdbcache: ColorRGB_float = SettingsField( + # (0.98, 0.21, 0.0), title="VDB Cache:" + # ) + # vrayproxy: ColorRGB_float = SettingsField( + # (1.0, 0.59, 0.05), title="VRay Proxy:" + # ) + # vrayscene_layer: ColorRGB_float = SettingsField( + # (1.0, 0.59, 0.05), title="VRay Scene:" + # ) + # yeticache: ColorRGB_float = SettingsField( + # (0.39, 0.81, 0.86), title="Yeti Cache:" + # ) + # yetiRig: ColorRGB_float = SettingsField( + # (0.0, 0.80, 0.49), title="Yeti Rig:" + # ) class ReferenceLoaderModel(BaseSettingsModel): @@ -99,22 +115,38 @@ class LoadersModel(BaseSettingsModel): DEFAULT_LOADERS_SETTING = { "colors": { - "model": [0.82, 0.52, 0.12], - "rig": [0.23, 0.89, 0.92], - "pointcache": [0.37, 0.82, 0.12], - "animation": [0.37, 0.82, 0.12], - "ass": [0.98, 0.53, 0.21], - "camera":[0.53, 0.45, 0.96], - "fbx": [0.84, 0.65, 1.0], - "mayaAscii": [0.26, 0.68, 1.0], - "mayaScene": [0.26, 0.68, 1.0], - "setdress": [1.0, 0.98, 0.35], - "layout": [1.0, 0.98, 0.35], - "vdbcache": [0.98, 0.21, 0.0], - "vrayproxy": [1.0, 0.59, 0.05], - "vrayscene_layer": [1.0, 0.59, 0.05], - "yeticache": [0.39, 0.81, 0.86], - "yetiRig": [0.0, 0.80, 0.49], + "model": [209, 132, 30, 1.0], + "rig": [59, 226, 235, 1.0], + "pointcache": [94, 209, 30, 1.0], + "animation": [94, 209, 30, 1.0], + "ass": [249, 135, 53, 1.0], + "camera": [136, 114, 244, 1.0], + "fbx": [215, 166, 255, 1.0], + "mayaAscii": [67, 174, 255, 1.0], + "mayaScene": [67, 174, 255, 1.0], + "setdress": [255, 250, 90, 1.0], + "layout": [255, 250, 90, 1.0], + "vdbcache": [249, 54, 0, 1.0], + "vrayproxy": [255, 150, 12, 1.0], + "vrayscene_layer": [255, 150, 12, 1.0], + "yeticache": [99, 206, 220, 1.0], + "yetiRig": [0, 205, 125, 1.0] + # "model": [0.82, 0.52, 0.12], + # "rig": [0.23, 0.89, 0.92], + # "pointcache": [0.37, 0.82, 0.12], + # "animation": [0.37, 0.82, 0.12], + # "ass": [0.98, 0.53, 0.21], + # "camera":[0.53, 0.45, 0.96], + # "fbx": [0.84, 0.65, 1.0], + # "mayaAscii": [0.26, 0.68, 1.0], + # "mayaScene": [0.26, 0.68, 1.0], + # "setdress": [1.0, 0.98, 0.35], + # "layout": [1.0, 0.98, 0.35], + # "vdbcache": [0.98, 0.21, 0.0], + # "vrayproxy": [1.0, 0.59, 0.05], + # "vrayscene_layer": [1.0, 0.59, 0.05], + # "yeticache": [0.39, 0.81, 0.86], + # "yetiRig": [0.0, 0.80, 0.49], }, "reference_loader": { "namespace": "{folder[name]}_{product[name]}_##_", diff --git a/server_addon/maya/server/settings/publish_playblast.py b/server_addon/maya/server/settings/publish_playblast.py index dcedf3ccc9..39f48bacbe 100644 --- a/server_addon/maya/server/settings/publish_playblast.py +++ b/server_addon/maya/server/settings/publish_playblast.py @@ -6,7 +6,7 @@ from ayon_server.settings import ( ensure_unique_names, task_types_enum, ) -from ayon_server.types import ColorRGB_float +from ayon_server.types import ColorRGBA_uint8, ColorRGB_float def hardware_falloff_enum(): @@ -54,18 +54,27 @@ class DisplayOptionsSetting(BaseSettingsModel): override_display: bool = SettingsField( True, title="Override display options" ) - background: ColorRGB_float = SettingsField( - (0.5, 0.5, 0.5), title="Background Color" + background: ColorRGBA_uint8 = SettingsField( + (125, 125, 125, 1.0), title="Background Color" ) + # background: ColorRGB_float = SettingsField( + # (0.5, 0.5, 0.5), title="Background Color" + # ) displayGradient: bool = SettingsField( True, title="Display background gradient" ) - backgroundTop: ColorRGB_float = SettingsField( - (0.5, 0.5, 0.5), title="Background Top" + backgroundTop: ColorRGBA_uint8 = SettingsField( + (125, 125, 125, 1.0), title="Background Top" ) - backgroundBottom: ColorRGB_float = SettingsField( - (0.5, 0.5, 0.5), title="Background Bottom" + backgroundBottom: ColorRGBA_uint8 = SettingsField( + (125, 125, 125, 1.0), title="Background Bottom" ) + # backgroundTop: ColorRGB_float = SettingsField( + # (0.5, 0.5, 0.5), title="Background Top" + # ) + # backgroundBottom: ColorRGB_float = SettingsField( + # (0.5, 0.5, 0.5), title="Background Bottom" + # ) class GenericSetting(BaseSettingsModel): @@ -282,21 +291,12 @@ DEFAULT_PLAYBLAST_SETTING = { }, "DisplayOptions": { "override_display": True, - "background": [ - 0.5, - 0.5, - 0.5 - ], - "backgroundBottom": [ - 0.5, - 0.5, - 0.5 - ], - "backgroundTop": [ - 0.5, - 0.5, - 0.5 - ], + "background": [125, 125, 125, 1.0], + "backgroundBottom": [125, 125, 125, 1.0], + "backgroundTop": [125, 125, 125, 1.0], + # "background": [0.5, 0.5, 0.5], + # "backgroundBottom": [0.5, 0.5, 0.5], + # "backgroundTop": [0.5, 0.5, 0.5], "displayGradient": True }, "Generic": { diff --git a/server_addon/tvpaint/server/settings/publish_plugins.py b/server_addon/tvpaint/server/settings/publish_plugins.py index 37ad3e0e70..0d978e5714 100644 --- a/server_addon/tvpaint/server/settings/publish_plugins.py +++ b/server_addon/tvpaint/server/settings/publish_plugins.py @@ -1,5 +1,5 @@ from ayon_server.settings import BaseSettingsModel, SettingsField -from ayon_server.types import ColorRGB_uint8 +from ayon_server.types import ColorRGBA_uint8, ColorRGB_uint8 class CollectRenderInstancesModel(BaseSettingsModel): @@ -10,10 +10,12 @@ class CollectRenderInstancesModel(BaseSettingsModel): class ExtractSequenceModel(BaseSettingsModel): """Review BG color is used for whole scene review and for thumbnails.""" - # TODO Use alpha color - review_bg: ColorRGB_uint8 = SettingsField( - (255, 255, 255), + review_bg: ColorRGBA_uint8 = SettingsField( + (255, 255, 255, 1.0), title="Review BG color") + # review_bg: ColorRGB_uint8 = SettingsField( + # (255, 255, 255), + # title="Review BG color") class ValidatePluginModel(BaseSettingsModel): @@ -100,7 +102,8 @@ DEFAULT_PUBLISH_SETTINGS = { "ignore_render_pass_transparency": False }, "ExtractSequence": { - "review_bg": [255, 255, 255] + # "review_bg": [255, 255, 255] + "review_bg": [255, 255, 255, 1.0] }, "ValidateProjectSettings": { "enabled": True, From a811ef9a0ce9c79b99a1a41bd9f5730d35e4a93c Mon Sep 17 00:00:00 2001 From: Kayla Man Date: Thu, 15 Feb 2024 17:58:05 +0800 Subject: [PATCH 138/185] remove unrelated code --- client/ayon_core/hosts/max/api/pipeline.py | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/client/ayon_core/hosts/max/api/pipeline.py b/client/ayon_core/hosts/max/api/pipeline.py index 106c29fd26..c26e697429 100644 --- a/client/ayon_core/hosts/max/api/pipeline.py +++ b/client/ayon_core/hosts/max/api/pipeline.py @@ -242,20 +242,3 @@ def get_previous_loaded_object(container: str): if str(obj) in sel_list: node_list.append(obj) return node_list - - -def remove_container_data(container: str): - """Function to remove container data after updating, switching or deleting it. - - Args: - container (str): container - """ - if container.modifiers[0].name == "OP Data": - all_set_members_names = [ - member.node for member - in container.modifiers[0].openPypeData.all_handles] - for current_set_member in all_set_members_names: - rt.Delete(current_set_member) - rt.deleteModifier(container, container.modifiers[0]) - - rt.Delete(container) From 87df73da2242ac3ba32378f681d979ab6a011ed2 Mon Sep 17 00:00:00 2001 From: Kayla Man Date: Thu, 15 Feb 2024 18:12:32 +0800 Subject: [PATCH 139/185] restored unrelated code --- client/ayon_core/hosts/max/api/pipeline.py | 17 ----------------- .../hosts/max/plugins/load/load_camera_fbx.py | 8 ++++---- .../hosts/max/plugins/load/load_max_scene.py | 9 ++++----- .../hosts/max/plugins/load/load_model.py | 8 +++----- .../hosts/max/plugins/load/load_model_fbx.py | 9 ++++----- .../hosts/max/plugins/load/load_model_obj.py | 6 +++--- .../hosts/max/plugins/load/load_model_usd.py | 5 ++--- .../hosts/max/plugins/load/load_pointcache.py | 5 ++--- .../plugins/load/load_pointcache_ornatrix.py | 5 ++--- .../hosts/max/plugins/load/load_pointcloud.py | 6 +++--- .../max/plugins/load/load_redshift_proxy.py | 6 +++--- .../hosts/max/plugins/load/load_tycache.py | 9 +++++---- 12 files changed, 35 insertions(+), 58 deletions(-) diff --git a/client/ayon_core/hosts/max/api/pipeline.py b/client/ayon_core/hosts/max/api/pipeline.py index 106c29fd26..c26e697429 100644 --- a/client/ayon_core/hosts/max/api/pipeline.py +++ b/client/ayon_core/hosts/max/api/pipeline.py @@ -242,20 +242,3 @@ def get_previous_loaded_object(container: str): if str(obj) in sel_list: node_list.append(obj) return node_list - - -def remove_container_data(container: str): - """Function to remove container data after updating, switching or deleting it. - - Args: - container (str): container - """ - if container.modifiers[0].name == "OP Data": - all_set_members_names = [ - member.node for member - in container.modifiers[0].openPypeData.all_handles] - for current_set_member in all_set_members_names: - rt.Delete(current_set_member) - rt.deleteModifier(container, container.modifiers[0]) - - rt.Delete(container) diff --git a/client/ayon_core/hosts/max/plugins/load/load_camera_fbx.py b/client/ayon_core/hosts/max/plugins/load/load_camera_fbx.py index d7eebdbc3a..34b120c179 100644 --- a/client/ayon_core/hosts/max/plugins/load/load_camera_fbx.py +++ b/client/ayon_core/hosts/max/plugins/load/load_camera_fbx.py @@ -1,6 +1,6 @@ import os -from ayon_core.hosts.max.api import lib +from ayon_core.hosts.max.api import lib, maintained_selection from ayon_core.hosts.max.api.lib import ( unique_namespace, get_namespace, @@ -9,8 +9,7 @@ from ayon_core.hosts.max.api.lib import ( from ayon_core.hosts.max.api.pipeline import ( containerise, get_previous_loaded_object, - update_custom_attribute_data, - remove_container_data + update_custom_attribute_data ) from ayon_core.pipeline import get_representation_path, load @@ -95,5 +94,6 @@ class FbxLoader(load.LoaderPlugin): def remove(self, container): from pymxs import runtime as rt + node = rt.GetNodeByName(container["instance_node"]) - remove_container_data(node) + rt.Delete(node) diff --git a/client/ayon_core/hosts/max/plugins/load/load_max_scene.py b/client/ayon_core/hosts/max/plugins/load/load_max_scene.py index 81f3af089f..7267d7a59e 100644 --- a/client/ayon_core/hosts/max/plugins/load/load_max_scene.py +++ b/client/ayon_core/hosts/max/plugins/load/load_max_scene.py @@ -7,10 +7,8 @@ from ayon_core.hosts.max.api.lib import ( object_transform_set ) from ayon_core.hosts.max.api.pipeline import ( - containerise, - get_previous_loaded_object, - update_custom_attribute_data, - remove_container_data + containerise, get_previous_loaded_object, + update_custom_attribute_data ) from ayon_core.pipeline import get_representation_path, load @@ -95,5 +93,6 @@ class MaxSceneLoader(load.LoaderPlugin): def remove(self, container): from pymxs import runtime as rt + node = rt.GetNodeByName(container["instance_node"]) - remove_container_data(node) + rt.Delete(node) diff --git a/client/ayon_core/hosts/max/plugins/load/load_model.py b/client/ayon_core/hosts/max/plugins/load/load_model.py index 28ec7be01f..796e1b80ad 100644 --- a/client/ayon_core/hosts/max/plugins/load/load_model.py +++ b/client/ayon_core/hosts/max/plugins/load/load_model.py @@ -2,13 +2,11 @@ import os from ayon_core.pipeline import load, get_representation_path from ayon_core.hosts.max.api.pipeline import ( containerise, - get_previous_loaded_object, - remove_container_data + get_previous_loaded_object ) from ayon_core.hosts.max.api import lib from ayon_core.hosts.max.api.lib import ( - maintained_selection, - unique_namespace + maintained_selection, unique_namespace ) @@ -101,7 +99,7 @@ class ModelAbcLoader(load.LoaderPlugin): from pymxs import runtime as rt node = rt.GetNodeByName(container["instance_node"]) - remove_container_data(node) + rt.Delete(node) @staticmethod def get_container_children(parent, type_name): diff --git a/client/ayon_core/hosts/max/plugins/load/load_model_fbx.py b/client/ayon_core/hosts/max/plugins/load/load_model_fbx.py index 81ad84546a..827cf63b39 100644 --- a/client/ayon_core/hosts/max/plugins/load/load_model_fbx.py +++ b/client/ayon_core/hosts/max/plugins/load/load_model_fbx.py @@ -1,10 +1,8 @@ import os from ayon_core.pipeline import load, get_representation_path from ayon_core.hosts.max.api.pipeline import ( - containerise, - get_previous_loaded_object, - update_custom_attribute_data, - remove_container_data + containerise, get_previous_loaded_object, + update_custom_attribute_data ) from ayon_core.hosts.max.api import lib from ayon_core.hosts.max.api.lib import ( @@ -94,5 +92,6 @@ class FbxModelLoader(load.LoaderPlugin): def remove(self, container): from pymxs import runtime as rt + node = rt.GetNodeByName(container["instance_node"]) - remove_container_data(node) + rt.Delete(node) diff --git a/client/ayon_core/hosts/max/plugins/load/load_model_obj.py b/client/ayon_core/hosts/max/plugins/load/load_model_obj.py index 1023b67f0c..22d3d4b58a 100644 --- a/client/ayon_core/hosts/max/plugins/load/load_model_obj.py +++ b/client/ayon_core/hosts/max/plugins/load/load_model_obj.py @@ -11,8 +11,7 @@ from ayon_core.hosts.max.api.lib import maintained_selection from ayon_core.hosts.max.api.pipeline import ( containerise, get_previous_loaded_object, - update_custom_attribute_data, - remove_container_data + update_custom_attribute_data ) from ayon_core.pipeline import get_representation_path, load @@ -85,5 +84,6 @@ class ObjLoader(load.LoaderPlugin): def remove(self, container): from pymxs import runtime as rt + node = rt.GetNodeByName(container["instance_node"]) - remove_container_data(node) + rt.Delete(node) diff --git a/client/ayon_core/hosts/max/plugins/load/load_model_usd.py b/client/ayon_core/hosts/max/plugins/load/load_model_usd.py index 6a08bebf5a..8d42219217 100644 --- a/client/ayon_core/hosts/max/plugins/load/load_model_usd.py +++ b/client/ayon_core/hosts/max/plugins/load/load_model_usd.py @@ -13,8 +13,7 @@ from ayon_core.hosts.max.api.lib import maintained_selection from ayon_core.hosts.max.api.pipeline import ( containerise, get_previous_loaded_object, - update_custom_attribute_data, - remove_container_data + update_custom_attribute_data ) from ayon_core.pipeline import get_representation_path, load @@ -115,4 +114,4 @@ class ModelUSDLoader(load.LoaderPlugin): def remove(self, container): node = rt.GetNodeByName(container["instance_node"]) - remove_container_data(node) + rt.Delete(node) diff --git a/client/ayon_core/hosts/max/plugins/load/load_pointcache.py b/client/ayon_core/hosts/max/plugins/load/load_pointcache.py index d7267afb7d..a92fa66757 100644 --- a/client/ayon_core/hosts/max/plugins/load/load_pointcache.py +++ b/client/ayon_core/hosts/max/plugins/load/load_pointcache.py @@ -10,8 +10,7 @@ from ayon_core.hosts.max.api import lib, maintained_selection from ayon_core.hosts.max.api.lib import unique_namespace from ayon_core.hosts.max.api.pipeline import ( containerise, - get_previous_loaded_object, - remove_container_data + get_previous_loaded_object ) @@ -106,7 +105,7 @@ class AbcLoader(load.LoaderPlugin): from pymxs import runtime as rt node = rt.GetNodeByName(container["instance_node"]) - remove_container_data(node) + rt.Delete(node) @staticmethod def get_container_children(parent, type_name): diff --git a/client/ayon_core/hosts/max/plugins/load/load_pointcache_ornatrix.py b/client/ayon_core/hosts/max/plugins/load/load_pointcache_ornatrix.py index 5b48e5d189..27b2e271d2 100644 --- a/client/ayon_core/hosts/max/plugins/load/load_pointcache_ornatrix.py +++ b/client/ayon_core/hosts/max/plugins/load/load_pointcache_ornatrix.py @@ -4,8 +4,7 @@ from ayon_core.pipeline.load import LoadError from ayon_core.hosts.max.api.pipeline import ( containerise, get_previous_loaded_object, - update_custom_attribute_data, - remove_container_data + update_custom_attribute_data ) from ayon_core.hosts.max.api.lib import ( @@ -106,4 +105,4 @@ class OxAbcLoader(load.LoaderPlugin): def remove(self, container): node = rt.GetNodeByName(container["instance_node"]) - remove_container_data(node) \ No newline at end of file + rt.Delete(node) diff --git a/client/ayon_core/hosts/max/plugins/load/load_pointcloud.py b/client/ayon_core/hosts/max/plugins/load/load_pointcloud.py index 7f4fba50b3..45e3da5621 100644 --- a/client/ayon_core/hosts/max/plugins/load/load_pointcloud.py +++ b/client/ayon_core/hosts/max/plugins/load/load_pointcloud.py @@ -8,8 +8,7 @@ from ayon_core.hosts.max.api.lib import ( from ayon_core.hosts.max.api.pipeline import ( containerise, get_previous_loaded_object, - update_custom_attribute_data, - remove_container_data + update_custom_attribute_data ) from ayon_core.pipeline import get_representation_path, load @@ -64,5 +63,6 @@ class PointCloudLoader(load.LoaderPlugin): def remove(self, container): """remove the container""" from pymxs import runtime as rt + node = rt.GetNodeByName(container["instance_node"]) - remove_container_data(node) + rt.Delete(node) diff --git a/client/ayon_core/hosts/max/plugins/load/load_redshift_proxy.py b/client/ayon_core/hosts/max/plugins/load/load_redshift_proxy.py index 3ccc5cc5e1..3f73210c24 100644 --- a/client/ayon_core/hosts/max/plugins/load/load_redshift_proxy.py +++ b/client/ayon_core/hosts/max/plugins/load/load_redshift_proxy.py @@ -9,8 +9,7 @@ from ayon_core.pipeline.load import LoadError from ayon_core.hosts.max.api.pipeline import ( containerise, update_custom_attribute_data, - get_previous_loaded_object, - remove_container_data + get_previous_loaded_object ) from ayon_core.hosts.max.api import lib from ayon_core.hosts.max.api.lib import ( @@ -73,5 +72,6 @@ class RedshiftProxyLoader(load.LoaderPlugin): def remove(self, container): from pymxs import runtime as rt + node = rt.getNodeByName(container["instance_node"]) - remove_container_data(node) + rt.delete(node) diff --git a/client/ayon_core/hosts/max/plugins/load/load_tycache.py b/client/ayon_core/hosts/max/plugins/load/load_tycache.py index 97f41026b4..48fb5c447a 100644 --- a/client/ayon_core/hosts/max/plugins/load/load_tycache.py +++ b/client/ayon_core/hosts/max/plugins/load/load_tycache.py @@ -1,13 +1,13 @@ import os from ayon_core.hosts.max.api import lib, maintained_selection from ayon_core.hosts.max.api.lib import ( - unique_namespace + unique_namespace, + ) from ayon_core.hosts.max.api.pipeline import ( containerise, get_previous_loaded_object, - update_custom_attribute_data, - remove_container_data + update_custom_attribute_data ) from ayon_core.pipeline import get_representation_path, load @@ -59,5 +59,6 @@ class TyCacheLoader(load.LoaderPlugin): def remove(self, container): """remove the container""" from pymxs import runtime as rt + node = rt.GetNodeByName(container["instance_node"]) - remove_container_data(node) + rt.Delete(node) From 3c726393fc64789ea4988009fda701d6e0969eb8 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Thu, 15 Feb 2024 14:27:48 +0100 Subject: [PATCH 140/185] bump version to 0.2.1 --- client/ayon_core/version.py | 2 +- package.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/client/ayon_core/version.py b/client/ayon_core/version.py index 914e415b8c..46dc6c6876 100644 --- a/client/ayon_core/version.py +++ b/client/ayon_core/version.py @@ -1,3 +1,3 @@ # -*- coding: utf-8 -*- """Package declaring AYON core addon version.""" -__version__ = "0.2.1-dev.1" +__version__ = "0.2.1" diff --git a/package.py b/package.py index 3b451e0078..5a1376c209 100644 --- a/package.py +++ b/package.py @@ -1,6 +1,6 @@ name = "core" title = "Core" -version = "0.2.1-dev.1" +version = "0.2.1" client_dir = "ayon_core" From 6baba8633f80698639ee0fa8e0493924830e8d3a Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Thu, 15 Feb 2024 14:33:59 +0100 Subject: [PATCH 141/185] bump version to '0.3.0-dev.1' --- client/ayon_core/version.py | 2 +- package.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/client/ayon_core/version.py b/client/ayon_core/version.py index 46dc6c6876..f3ad9713d5 100644 --- a/client/ayon_core/version.py +++ b/client/ayon_core/version.py @@ -1,3 +1,3 @@ # -*- coding: utf-8 -*- """Package declaring AYON core addon version.""" -__version__ = "0.2.1" +__version__ = "0.3.0-dev.1" diff --git a/package.py b/package.py index 5a1376c209..470bbf256b 100644 --- a/package.py +++ b/package.py @@ -1,6 +1,6 @@ name = "core" title = "Core" -version = "0.2.1" +version = "0.3.0-dev.1" client_dir = "ayon_core" From 32094aa148629f98799992302cf06de43f4c2d91 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Thu, 15 Feb 2024 17:15:28 +0100 Subject: [PATCH 142/185] fix missing import in maya addon --- server_addon/maya/server/settings/loaders.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server_addon/maya/server/settings/loaders.py b/server_addon/maya/server/settings/loaders.py index 3e8d368a6b..418a7046ae 100644 --- a/server_addon/maya/server/settings/loaders.py +++ b/server_addon/maya/server/settings/loaders.py @@ -1,5 +1,5 @@ from ayon_server.settings import BaseSettingsModel, SettingsField -from ayon_server.types import ColorRGB_float +from ayon_server.types import ColorRGB_float, ColorRGBA_uint8 class ColorsSetting(BaseSettingsModel): From 33d6f54c2d0d169f0820a8340673622c5e052258 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Thu, 15 Feb 2024 17:24:55 +0100 Subject: [PATCH 143/185] ExtractBurnin are using AYON settings --- .../plugins/publish/extract_burnin.py | 89 +++++++++++-------- client/ayon_core/settings/ayon_settings.py | 40 --------- 2 files changed, 51 insertions(+), 78 deletions(-) diff --git a/client/ayon_core/plugins/publish/extract_burnin.py b/client/ayon_core/plugins/publish/extract_burnin.py index 2b76527d5f..4da158343e 100644 --- a/client/ayon_core/plugins/publish/extract_burnin.py +++ b/client/ayon_core/plugins/publish/extract_burnin.py @@ -65,8 +65,8 @@ class ExtractBurnin(publish.Extractor): # Default options for burnins for cases that are not set in presets. default_options = { "font_size": 42, - "font_color": [255, 255, 255, 255], - "bg_color": [0, 0, 0, 127], + "font_color": [255, 255, 255, 1.0], + "bg_color": [0, 0, 0, 0.5], "bg_padding": 5, "x_offset": 5, "y_offset": 5 @@ -96,7 +96,9 @@ class ExtractBurnin(publish.Extractor): instance.data["representations"].remove(repre) def _get_burnins_per_representations(self, instance, src_burnin_defs): - self.log.debug("Filtering of representations and their burnins starts") + self.log.debug( + "Filtering of representations and their burnins starts" + ) filtered_repres = [] repres = instance.data.get("representations") or [] @@ -116,11 +118,11 @@ class ExtractBurnin(publish.Extractor): ) # Filter output definition by `burnin` represetation key - repre_linked_burnins = { - name: output - for name, output in burnin_defs.items() - if name in repre_burnin_links - } + repre_linked_burnins = [ + burnin_def + for burnin_def in burnin_defs.items() + if burnin_def["name"] in repre_burnin_links + ] self.log.debug( "repre_linked_burnins: {}".format(repre_linked_burnins) ) @@ -154,19 +156,21 @@ class ExtractBurnin(publish.Extractor): filtering_criteria = { "hosts": host_name, - "families": family, + "product_types": family, + "product_names": subset, "task_names": task_name, "task_types": task_type, - "subset": subset } - profile = filter_profiles(self.profiles, filtering_criteria, - logger=self.log) - + profile = filter_profiles( + self.profiles, + filtering_criteria, + logger=self.log + ) if not profile: self.log.debug(( "Skipped instance. None of profiles in presets are for" - " Host: \"{}\" | Families: \"{}\" | Task \"{}\"" - " | Task type \"{}\" | Subset \"{}\" " + " Host: \"{}\" | Product type: \"{}\" | Task name \"{}\"" + " | Task type \"{}\" | Product name \"{}\" " ).format(host_name, family, task_name, task_type, subset)) return @@ -175,7 +179,7 @@ class ExtractBurnin(publish.Extractor): if not burnin_defs: self.log.debug(( "Skipped instance. Burnin definitions are not set for profile" - " Host: \"{}\" | Families: \"{}\" | Task \"{}\"" + " Host: \"{}\" | Product type: \"{}\" | Task name \"{}\"" " | Profile \"{}\"" ).format(host_name, family, task_name, profile)) return @@ -275,7 +279,8 @@ class ExtractBurnin(publish.Extractor): # it in review? # burnin_data["fps"] = fps - for filename_suffix, burnin_def in repre_burnin_defs.items(): + for burnin_def in repre_burnin_defs: + filename_suffix = burnin_def["name"] new_repre = copy.deepcopy(repre) new_repre["stagingDir"] = src_repre_staging_dir @@ -288,16 +293,28 @@ class ExtractBurnin(publish.Extractor): burnin_values = {} for key in self.positions: value = burnin_def.get(key) - if value: - burnin_values[key] = value.replace( - "{task}", "{task[name]}" - ) + if not value: + continue + # TODO remove replacements + burnin_values[key] = ( + value + .replace("{task}", "{task[name]}") + .replace("{product[name]}", "{subset}") + .replace("{Product[name]}", "{Subset}") + .replace("{PRODUCT[NAME]}", "{SUBSET}") + .replace("{product[type]}", "{family}") + .replace("{Product[type]}", "{Family}") + .replace("{PRODUCT[TYPE]}", "{FAMILY}") + .replace("{folder[name]}", "{asset}") + .replace("{Folder[name]}", "{Asset}") + .replace("{FOLDER[NAME]}", "{ASSET}") + ) # Remove "delete" tag from new representation if "delete" in new_repre["tags"]: new_repre["tags"].remove("delete") - if len(repre_burnin_defs.keys()) > 1: + if len(repre_burnin_defs) > 1: # Update name and outputName to be # able have multiple outputs in case of more burnin presets # Join previous "outputName" with filename suffix @@ -401,8 +418,7 @@ class ExtractBurnin(publish.Extractor): bg_color_hex = "#{0:0>2X}{1:0>2X}{2:0>2X}".format( bg_red, bg_green, bg_blue ) - bg_color_alpha = float(bg_alpha) / 255 - burnin_options["bg_opacity"] = bg_color_alpha + burnin_options["bg_opacity"] = bg_alpha burnin_options["bg_color"] = bg_color_hex # FG Color @@ -412,8 +428,7 @@ class ExtractBurnin(publish.Extractor): fg_color_hex = "#{0:0>2X}{1:0>2X}{2:0>2X}".format( fg_red, fg_green, fg_blue ) - fg_color_alpha = float(fg_alpha) / 255 - burnin_options["opacity"] = fg_color_alpha + burnin_options["opacity"] = fg_alpha burnin_options["font_color"] = fg_color_hex # Define font filepath @@ -543,15 +558,16 @@ class ExtractBurnin(publish.Extractor): Burnin definitions without tags filter are marked as valid. Args: - outputs (list): Contain list of burnin definitions from presets. + burnin_defs (list): Burnin definitions. tags (list): Tags of processed representation. Returns: list: Containg all burnin definitions matching entered tags. + """ - filtered_burnins = {} + filtered_burnins = [] repre_tags_low = set(tag.lower() for tag in tags) - for filename_suffix, burnin_def in burnin_defs.items(): + for burnin_def in burnin_defs: valid = True tag_filters = burnin_def["filter"]["tags"] if tag_filters: @@ -561,8 +577,7 @@ class ExtractBurnin(publish.Extractor): valid = bool(repre_tags_low & tag_filters_low) if valid: - filtered_burnins[filename_suffix] = burnin_def - + filtered_burnins.append(burnin_def) return filtered_burnins def input_output_paths( @@ -724,7 +739,7 @@ class ExtractBurnin(publish.Extractor): Returns: list: Containg all valid output definitions. """ - filtered_burnin_defs = {} + filtered_burnin_defs = [] burnin_defs = profile.get("burnins") if not burnin_defs: @@ -732,13 +747,11 @@ class ExtractBurnin(publish.Extractor): families = self.families_from_instance(instance) - for filename_suffix, orig_burnin_def in burnin_defs.items(): + for orig_burnin_def in burnin_defs: burnin_def = copy.deepcopy(orig_burnin_def) - def_filter = burnin_def.get("filter", None) or {} - for key in ("families", "tags"): - if key not in def_filter: - def_filter[key] = [] + filename_suffix = burnin_def["name"] + def_filter = burnin_def["filter"] families_filters = def_filter["families"] if not self.families_filter_validation( families, families_filters @@ -769,7 +782,7 @@ class ExtractBurnin(publish.Extractor): burnin_values["filter"] = def_filter - filtered_burnin_defs[filename_suffix] = burnin_values + filtered_burnin_defs.append(burnin_values) self.log.debug(( "Burnin definition \"{}\" passed first filtering." diff --git a/client/ayon_core/settings/ayon_settings.py b/client/ayon_core/settings/ayon_settings.py index 190970b908..f74e6129db 100644 --- a/client/ayon_core/settings/ayon_settings.py +++ b/client/ayon_core/settings/ayon_settings.py @@ -449,46 +449,6 @@ def _convert_global_project_settings(ayon_settings, output, default_settings): new_outputs[name] = profile_output profile["outputs"] = new_outputs - # Extract Burnin plugin - extract_burnin = ayon_publish["ExtractBurnin"] - extract_burnin_options = extract_burnin["options"] - for color_key in ("font_color", "bg_color"): - extract_burnin_options[color_key] = _convert_color( - extract_burnin_options[color_key] - ) - - for profile in extract_burnin["profiles"]: - extract_burnin_defs = profile["burnins"] - if "product_names" in profile: - profile["subsets"] = profile.pop("product_names") - profile["families"] = profile.pop("product_types") - - for burnin_def in extract_burnin_defs: - for key in ( - "TOP_LEFT", - "TOP_CENTERED", - "TOP_RIGHT", - "BOTTOM_LEFT", - "BOTTOM_CENTERED", - "BOTTOM_RIGHT", - ): - burnin_def[key] = ( - burnin_def[key] - .replace("{product[name]}", "{subset}") - .replace("{Product[name]}", "{Subset}") - .replace("{PRODUCT[NAME]}", "{SUBSET}") - .replace("{product[type]}", "{family}") - .replace("{Product[type]}", "{Family}") - .replace("{PRODUCT[TYPE]}", "{FAMILY}") - .replace("{folder[name]}", "{asset}") - .replace("{Folder[name]}", "{Asset}") - .replace("{FOLDER[NAME]}", "{ASSET}") - ) - profile["burnins"] = { - extract_burnin_def.pop("name"): extract_burnin_def - for extract_burnin_def in extract_burnin_defs - } - if "IntegrateProductGroup" in ayon_publish: subset_group = ayon_publish.pop("IntegrateProductGroup") subset_group_profiles = subset_group.pop("product_grouping_profiles") From 7669e8ff2b3b17fef8498afc47925ff5a33893d4 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Thu, 15 Feb 2024 17:30:37 +0100 Subject: [PATCH 144/185] 'ExtractOIIOTranscode is using AYON settings --- .../publish/extract_color_transcode.py | 12 ++++++---- client/ayon_core/settings/ayon_settings.py | 23 ------------------- 2 files changed, 7 insertions(+), 28 deletions(-) diff --git a/client/ayon_core/plugins/publish/extract_color_transcode.py b/client/ayon_core/plugins/publish/extract_color_transcode.py index 66ba8ad2be..77c4673bca 100644 --- a/client/ayon_core/plugins/publish/extract_color_transcode.py +++ b/client/ayon_core/plugins/publish/extract_color_transcode.py @@ -81,6 +81,7 @@ class ExtractOIIOTranscode(publish.Extractor): if not profile: return + profile_output_defs = profile["outputs"] new_representations = [] repres = instance.data["representations"] for idx, repre in enumerate(list(repres)): @@ -98,7 +99,8 @@ class ExtractOIIOTranscode(publish.Extractor): self.log.warning("Config file doesn't exist, skipping") continue - for output_name, output_def in profile.get("outputs", {}).items(): + for output_def in profile_output_defs: + output_name = output_def["name"] new_repre = copy.deepcopy(repre) original_staging_dir = new_repre["stagingDir"] @@ -318,10 +320,10 @@ class ExtractOIIOTranscode(publish.Extractor): subset = instance.data["subset"] filtering_criteria = { "hosts": host_name, - "families": family, + "product_types": family, + "product_names": subset, "task_names": task_name, "task_types": task_type, - "subsets": subset } profile = filter_profiles(self.profiles, filtering_criteria, logger=self.log) @@ -329,8 +331,8 @@ class ExtractOIIOTranscode(publish.Extractor): if not profile: self.log.debug(( "Skipped instance. None of profiles in presets are for" - " Host: \"{}\" | Families: \"{}\" | Task \"{}\"" - " | Task type \"{}\" | Subset \"{}\" " + " Host: \"{}\" | Product types: \"{}\" | Task \"{}\"" + " | Task type \"{}\" | Product names: \"{}\" " ).format(host_name, family, task_name, task_type, subset)) return profile diff --git a/client/ayon_core/settings/ayon_settings.py b/client/ayon_core/settings/ayon_settings.py index f74e6129db..81a0fde844 100644 --- a/client/ayon_core/settings/ayon_settings.py +++ b/client/ayon_core/settings/ayon_settings.py @@ -426,29 +426,6 @@ def _convert_global_project_settings(ayon_settings, output, default_settings): ayon_extract_thumbnail["background_color"] ) - # ExtractOIIOTranscode plugin - extract_oiio_transcode = ayon_publish["ExtractOIIOTranscode"] - extract_oiio_transcode_profiles = extract_oiio_transcode["profiles"] - for profile in extract_oiio_transcode_profiles: - new_outputs = {} - name_counter = {} - if "product_names" in profile: - profile["subsets"] = profile.pop("product_names") - for profile_output in profile["outputs"]: - if "name" in profile_output: - name = profile_output.pop("name") - else: - # Backwards compatibility for setting without 'name' in model - name = profile_output["extension"] - if name in new_outputs: - name_counter[name] += 1 - name = "{}_{}".format(name, name_counter[name]) - else: - name_counter[name] = 0 - - new_outputs[name] = profile_output - profile["outputs"] = new_outputs - if "IntegrateProductGroup" in ayon_publish: subset_group = ayon_publish.pop("IntegrateProductGroup") subset_group_profiles = subset_group.pop("product_grouping_profiles") From 266eb53769e7fbc5ac54661652e3676777f80a86 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Thu, 15 Feb 2024 17:32:45 +0100 Subject: [PATCH 145/185] IntegrateProductGroup is using AYON settings --- ...ubset_group.py => integrate_product_group.py} | 16 ++++++++-------- client/ayon_core/settings/ayon_settings.py | 8 -------- 2 files changed, 8 insertions(+), 16 deletions(-) rename client/ayon_core/plugins/publish/{integrate_subset_group.py => integrate_product_group.py} (87%) diff --git a/client/ayon_core/plugins/publish/integrate_subset_group.py b/client/ayon_core/plugins/publish/integrate_product_group.py similarity index 87% rename from client/ayon_core/plugins/publish/integrate_subset_group.py rename to client/ayon_core/plugins/publish/integrate_product_group.py index c2f1eac9e3..f7c96893ca 100644 --- a/client/ayon_core/plugins/publish/integrate_subset_group.py +++ b/client/ayon_core/plugins/publish/integrate_product_group.py @@ -17,24 +17,24 @@ from ayon_core.lib import ( ) -class IntegrateSubsetGroup(pyblish.api.InstancePlugin): +class IntegrateProductGroup(pyblish.api.InstancePlugin): """Integrate Subset Group for publish.""" # Run after CollectAnatomyInstanceData order = pyblish.api.IntegratorOrder - 0.1 - label = "Subset Group" + label = "Product Group" # Attributes set by settings - subset_grouping_profiles = None + product_grouping_profiles = None def process(self, instance): """Look into subset group profiles set by settings. - Attribute 'subset_grouping_profiles' is defined by settings. + Attribute 'product_grouping_profiles' is defined by settings. """ - # Skip if 'subset_grouping_profiles' is empty - if not self.subset_grouping_profiles: + # Skip if 'product_grouping_profiles' is empty + if not self.product_grouping_profiles: return if instance.data.get("subsetGroup"): @@ -47,7 +47,7 @@ class IntegrateSubsetGroup(pyblish.api.InstancePlugin): # Skip if there is no matching profile filter_criteria = self.get_profile_filter_criteria(instance) profile = filter_profiles( - self.subset_grouping_profiles, + self.product_grouping_profiles, filter_criteria, logger=self.log ) @@ -91,7 +91,7 @@ class IntegrateSubsetGroup(pyblish.api.InstancePlugin): # Return filter criteria return { - "families": anatomy_data["family"], + "product_types": anatomy_data["family"], "tasks": task.get("name"), "hosts": instance.context.data["hostName"], "task_types": task.get("type") diff --git a/client/ayon_core/settings/ayon_settings.py b/client/ayon_core/settings/ayon_settings.py index 81a0fde844..9c8deecab0 100644 --- a/client/ayon_core/settings/ayon_settings.py +++ b/client/ayon_core/settings/ayon_settings.py @@ -426,14 +426,6 @@ def _convert_global_project_settings(ayon_settings, output, default_settings): ayon_extract_thumbnail["background_color"] ) - if "IntegrateProductGroup" in ayon_publish: - subset_group = ayon_publish.pop("IntegrateProductGroup") - subset_group_profiles = subset_group.pop("product_grouping_profiles") - for profile in subset_group_profiles: - profile["families"] = profile.pop("product_types") - subset_group["subset_grouping_profiles"] = subset_group_profiles - ayon_publish["IntegrateSubsetGroup"] = subset_group - # Cleanup plugin ayon_cleanup = ayon_publish["CleanUp"] if "patterns" in ayon_cleanup: From 508997c7f472d7560ed74a08e8a469738eb3daed Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Thu, 15 Feb 2024 17:38:32 +0100 Subject: [PATCH 146/185] get_subset_name is using AYON settings --- .../plugins/create/create_render.py | 6 ++--- .../photoshop/plugins/create/create_image.py | 4 ++-- .../ayon_core/pipeline/create/subset_name.py | 24 ++++++++++++++----- client/ayon_core/settings/ayon_settings.py | 19 --------------- 4 files changed, 23 insertions(+), 30 deletions(-) diff --git a/client/ayon_core/hosts/aftereffects/plugins/create/create_render.py b/client/ayon_core/hosts/aftereffects/plugins/create/create_render.py index 78aa49a562..bd005f5d4f 100644 --- a/client/ayon_core/hosts/aftereffects/plugins/create/create_render.py +++ b/client/ayon_core/hosts/aftereffects/plugins/create/create_render.py @@ -194,13 +194,13 @@ class RenderCreator(Creator): name into created subset name. Position of composition name could be set in - `project_settings/global/tools/creator/subset_name_profiles` with some - form of '{composition}' placeholder. + `project_settings/global/tools/creator/product_name_profiles` with + some form of '{composition}' placeholder. Composition name will be used implicitly if multiple composition should be handled at same time. - If {composition} placeholder is not us 'subset_name_profiles' + If {composition} placeholder is not us 'product_name_profiles' composition name will be capitalized and set at the end of subset name if necessary. diff --git a/client/ayon_core/hosts/photoshop/plugins/create/create_image.py b/client/ayon_core/hosts/photoshop/plugins/create/create_image.py index a28872bba1..2ef746fc94 100644 --- a/client/ayon_core/hosts/photoshop/plugins/create/create_image.py +++ b/client/ayon_core/hosts/photoshop/plugins/create/create_image.py @@ -209,8 +209,8 @@ class ImageCreator(Creator): 'Use layer name in subset' will explicitly add layer name into subset name. Position of this name is configurable in - `project_settings/global/tools/creator/subset_name_profiles`. - If layer placeholder ({layer}) is not used in `subset_name_profiles` + `project_settings/global/tools/creator/product_name_profiles`. + If layer placeholder ({layer}) is not used in `product_name_profiles` but layer name should be used (set explicitly in UI or implicitly if multiple images should be created), it is added in capitalized form as a suffix to subset name. diff --git a/client/ayon_core/pipeline/create/subset_name.py b/client/ayon_core/pipeline/create/subset_name.py index 93a61b8b8b..81967ffd99 100644 --- a/client/ayon_core/pipeline/create/subset_name.py +++ b/client/ayon_core/pipeline/create/subset_name.py @@ -48,9 +48,9 @@ def get_subset_name_template( if project_settings is None: project_settings = get_project_settings(project_name) tools_settings = project_settings["global"]["tools"] - profiles = tools_settings["creator"]["subset_name_profiles"] + profiles = tools_settings["creator"]["product_name_profiles"] filtering_criteria = { - "families": family, + "product_types": family, "hosts": host_name, "tasks": task_name, "task_types": task_type @@ -59,7 +59,19 @@ def get_subset_name_template( matching_profile = filter_profiles(profiles, filtering_criteria) template = None if matching_profile: - template = matching_profile["template"] + # TODO remove formatting keys replacement + template = ( + matching_profile["template"] + .replace("{task[name]}", "{task}") + .replace("{Task[name]}", "{Task}") + .replace("{TASK[NAME]}", "{TASK}") + .replace("{product[type]}", "{family}") + .replace("{Product[type]}", "{Family}") + .replace("{PRODUCT[TYPE]}", "{FAMILY}") + .replace("{folder[name]}", "{asset}") + .replace("{Folder[name]}", "{Asset}") + .replace("{FOLDER[NAME]}", "{ASSET}") + ) # Make sure template is set (matching may have empty string) if not template: @@ -82,9 +94,9 @@ def get_subset_name( """Calculate subset name based on passed context and OpenPype settings. Subst name templates are defined in `project_settings/global/tools/creator - /subset_name_profiles` where are profiles with host name, family, task name - and task type filters. If context does not match any profile then - `DEFAULT_SUBSET_TEMPLATE` is used as default template. + /product_name_profiles` where are profiles with host name, family, + task name and task type filters. If context does not match any profile + then `DEFAULT_SUBSET_TEMPLATE` is used as default template. That's main reason why so many arguments are required to calculate subset name. diff --git a/client/ayon_core/settings/ayon_settings.py b/client/ayon_core/settings/ayon_settings.py index 9c8deecab0..43bf8ca471 100644 --- a/client/ayon_core/settings/ayon_settings.py +++ b/client/ayon_core/settings/ayon_settings.py @@ -442,26 +442,7 @@ def _convert_global_project_settings(ayon_settings, output, default_settings): # Tools settings ayon_tools = ayon_core["tools"] ayon_create_tool = ayon_tools["creator"] - if "product_name_profiles" in ayon_create_tool: - product_name_profiles = ayon_create_tool.pop("product_name_profiles") - for profile in product_name_profiles: - profile["families"] = profile.pop("product_types") - ayon_create_tool["subset_name_profiles"] = product_name_profiles - for profile in ayon_create_tool["subset_name_profiles"]: - template = profile["template"] - profile["template"] = ( - template - .replace("{task[name]}", "{task}") - .replace("{Task[name]}", "{Task}") - .replace("{TASK[NAME]}", "{TASK}") - .replace("{product[type]}", "{family}") - .replace("{Product[type]}", "{Family}") - .replace("{PRODUCT[TYPE]}", "{FAMILY}") - .replace("{folder[name]}", "{asset}") - .replace("{Folder[name]}", "{Asset}") - .replace("{FOLDER[NAME]}", "{ASSET}") - ) product_smart_select_key = "families_smart_select" if "product_types_smart_select" in ayon_create_tool: From 7beef914f768010e8f00e1e94ccede97add31d1f Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Thu, 15 Feb 2024 17:39:00 +0100 Subject: [PATCH 147/185] smart family select is using AYON settings --- client/ayon_core/settings/ayon_settings.py | 8 -------- client/ayon_core/tools/creator/window.py | 12 +++++++----- 2 files changed, 7 insertions(+), 13 deletions(-) diff --git a/client/ayon_core/settings/ayon_settings.py b/client/ayon_core/settings/ayon_settings.py index 43bf8ca471..8943debba5 100644 --- a/client/ayon_core/settings/ayon_settings.py +++ b/client/ayon_core/settings/ayon_settings.py @@ -444,15 +444,7 @@ def _convert_global_project_settings(ayon_settings, output, default_settings): ayon_create_tool = ayon_tools["creator"] - product_smart_select_key = "families_smart_select" - if "product_types_smart_select" in ayon_create_tool: - product_smart_select_key = "product_types_smart_select" - new_smart_select_families = { - item["name"]: item["task_names"] - for item in ayon_create_tool.pop(product_smart_select_key) - } - ayon_create_tool["families_smart_select"] = new_smart_select_families ayon_loader_tool = ayon_tools["loader"] if "product_type_filter_profiles" in ayon_loader_tool: diff --git a/client/ayon_core/tools/creator/window.py b/client/ayon_core/tools/creator/window.py index 676e1c3959..5862725076 100644 --- a/client/ayon_core/tools/creator/window.py +++ b/client/ayon_core/tools/creator/window.py @@ -377,23 +377,25 @@ class CreatorWindow(QtWidgets.QDialog): self._creators_model.reset() - pype_project_setting = ( + product_types_smart_select = ( get_current_project_settings() ["global"] ["tools"] ["creator"] - ["families_smart_select"] + ["product_types_smart_select"] ) current_index = None family = None task_name = get_current_task_name() or None lowered_task_name = task_name.lower() if task_name: - for _family, _task_names in pype_project_setting.items(): - _low_task_names = {name.lower() for name in _task_names} + for smart_item in product_types_smart_select: + _low_task_names = { + name.lower() for name in smart_item["task_names"] + } for _task_name in _low_task_names: if _task_name in lowered_task_name: - family = _family + family = smart_item["name"] break if family: break From eecabc7c89becb1f9c6f4ac6b0199aa0116373eb Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Thu, 15 Feb 2024 17:42:33 +0100 Subject: [PATCH 148/185] template name profiles are using AYON settings --- client/ayon_core/pipeline/publish/lib.py | 2 +- client/ayon_core/settings/ayon_settings.py | 9 --------- 2 files changed, 1 insertion(+), 10 deletions(-) diff --git a/client/ayon_core/pipeline/publish/lib.py b/client/ayon_core/pipeline/publish/lib.py index a62c2d9c5b..a14651551f 100644 --- a/client/ayon_core/pipeline/publish/lib.py +++ b/client/ayon_core/pipeline/publish/lib.py @@ -138,7 +138,7 @@ def get_publish_template_name( template = None filter_criteria = { "hosts": host_name, - "families": family, + "product_types": family, "task_names": task_name, "task_types": task_type, } diff --git a/client/ayon_core/settings/ayon_settings.py b/client/ayon_core/settings/ayon_settings.py index 8943debba5..1c173e438f 100644 --- a/client/ayon_core/settings/ayon_settings.py +++ b/client/ayon_core/settings/ayon_settings.py @@ -456,15 +456,6 @@ def _convert_global_project_settings(ayon_settings, output, default_settings): ayon_loader_tool["family_filter_profiles"] = ( product_type_filter_profiles) - ayon_publish_tool = ayon_tools["publish"] - for profile in ayon_publish_tool["hero_template_name_profiles"]: - if "product_types" in profile: - profile["families"] = profile.pop("product_types") - - for profile in ayon_publish_tool["template_name_profiles"]: - if "product_types" in profile: - profile["families"] = profile.pop("product_types") - ayon_core["sync_server"] = ( default_settings["global"]["sync_server"] ) From 698e60f2d57ddbbc6fc528d11931d6e5bdc281b3 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Thu, 15 Feb 2024 17:42:45 +0100 Subject: [PATCH 149/185] removed conversion of unused settings --- client/ayon_core/settings/ayon_settings.py | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/client/ayon_core/settings/ayon_settings.py b/client/ayon_core/settings/ayon_settings.py index 1c173e438f..3362fd2c3e 100644 --- a/client/ayon_core/settings/ayon_settings.py +++ b/client/ayon_core/settings/ayon_settings.py @@ -440,22 +440,6 @@ def _convert_global_project_settings(ayon_settings, output, default_settings): )) # Tools settings - ayon_tools = ayon_core["tools"] - ayon_create_tool = ayon_tools["creator"] - - - - - ayon_loader_tool = ayon_tools["loader"] - if "product_type_filter_profiles" in ayon_loader_tool: - product_type_filter_profiles = ( - ayon_loader_tool.pop("product_type_filter_profiles")) - for profile in product_type_filter_profiles: - profile["filter_families"] = profile.pop("filter_product_types") - - ayon_loader_tool["family_filter_profiles"] = ( - product_type_filter_profiles) - ayon_core["sync_server"] = ( default_settings["global"]["sync_server"] ) From b390a7f3b5da5658d418d7642d3db7c6e8894146 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Thu, 15 Feb 2024 17:44:11 +0100 Subject: [PATCH 150/185] CleanUp plugin is using AYON settings --- client/ayon_core/plugins/publish/cleanup.py | 20 ++++++++++---------- client/ayon_core/settings/ayon_settings.py | 5 ----- 2 files changed, 10 insertions(+), 15 deletions(-) diff --git a/client/ayon_core/plugins/publish/cleanup.py b/client/ayon_core/plugins/publish/cleanup.py index df68af7e57..db73d28e7a 100644 --- a/client/ayon_core/plugins/publish/cleanup.py +++ b/client/ayon_core/plugins/publish/cleanup.py @@ -40,7 +40,7 @@ class CleanUp(pyblish.api.InstancePlugin): active = True # Presets - paterns = None # list of regex paterns + patterns = None # list of regex patterns remove_temp_renders = True def process(self, instance): @@ -115,10 +115,10 @@ class CleanUp(pyblish.api.InstancePlugin): src = os.path.normpath(src) dest = os.path.normpath(dest) - # add src dir into clearing dir paths (regex paterns) + # add src dir into clearing dir paths (regex patterns) transfers_dirs.append(os.path.dirname(src)) - # add dest dir into clearing dir paths (regex paterns) + # add dest dir into clearing dir paths (regex patterns) transfers_dirs.append(os.path.dirname(dest)) if src in skip_cleanup_filepaths: @@ -141,13 +141,13 @@ class CleanUp(pyblish.api.InstancePlugin): # add dir for cleanup dirnames.append(os.path.dirname(src)) - # clean by regex paterns + # clean by regex patterns # make unique set transfers_dirs = set(transfers_dirs) self.log.debug("__ transfers_dirs: `{}`".format(transfers_dirs)) - self.log.debug("__ self.paterns: `{}`".format(self.paterns)) - if self.paterns: + self.log.debug("__ self.patterns: `{}`".format(self.patterns)) + if self.patterns: files = list() # get list of all available content of dirs for _dir in transfers_dirs: @@ -159,14 +159,14 @@ class CleanUp(pyblish.api.InstancePlugin): self.log.debug("__ files: `{}`".format(files)) - # remove all files which match regex patern + # remove all files which match regex pattern for f in files: if os.path.normpath(f) in skip_cleanup_filepaths: continue - for p in self.paterns: - patern = re.compile(p) - if not patern.findall(f): + for p in self.patterns: + pattern = re.compile(p) + if not pattern.findall(f): continue if not os.path.exists(f): continue diff --git a/client/ayon_core/settings/ayon_settings.py b/client/ayon_core/settings/ayon_settings.py index 3362fd2c3e..5c4813f3aa 100644 --- a/client/ayon_core/settings/ayon_settings.py +++ b/client/ayon_core/settings/ayon_settings.py @@ -426,11 +426,6 @@ def _convert_global_project_settings(ayon_settings, output, default_settings): ayon_extract_thumbnail["background_color"] ) - # Cleanup plugin - ayon_cleanup = ayon_publish["CleanUp"] - if "patterns" in ayon_cleanup: - ayon_cleanup["paterns"] = ayon_cleanup.pop("patterns") - # Project root settings - json string to dict ayon_core["project_environments"] = json.loads( ayon_core["project_environments"] From 6566900f805f19825b000023c395b358625e55ab Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Thu, 15 Feb 2024 18:09:17 +0100 Subject: [PATCH 151/185] fix addon name in package.py for royal render --- server_addon/create_ayon_addons.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/server_addon/create_ayon_addons.py b/server_addon/create_ayon_addons.py index 5e06d8ee8a..9553980f5d 100644 --- a/server_addon/create_ayon_addons.py +++ b/server_addon/create_ayon_addons.py @@ -191,8 +191,11 @@ def create_addon_package( # Copy server content package_py = addon_output_dir / "package.py" + addon_name = addon_dir.name + if addon_name == "royal_render": + addon_name = "royalrender" package_py_content = PACKAGE_PY_TEMPLATE.format( - addon_name=addon_dir.name, addon_version=addon_version + addon_name=addon_name, addon_version=addon_version ) with open(package_py, "w+") as pkg_py: From 6499962cb42e868cb92d39cbe8862cff0c60cb60 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Thu, 15 Feb 2024 18:21:50 +0100 Subject: [PATCH 152/185] implemented simple folders widget as possible replacement of AssetsWidget --- .../tools/ayon_utils/widgets/__init__.py | 2 + .../ayon_utils/widgets/folders_widget.py | 112 ++++++++++++++++++ 2 files changed, 114 insertions(+) diff --git a/client/ayon_core/tools/ayon_utils/widgets/__init__.py b/client/ayon_core/tools/ayon_utils/widgets/__init__.py index f58de17c4a..b1b7dd7527 100644 --- a/client/ayon_core/tools/ayon_utils/widgets/__init__.py +++ b/client/ayon_core/tools/ayon_utils/widgets/__init__.py @@ -9,6 +9,7 @@ from .folders_widget import ( FoldersWidget, FoldersQtModel, FOLDERS_MODEL_SENDER_NAME, + SimpleFoldersWidget, ) from .tasks_widget import ( @@ -31,6 +32,7 @@ __all__ = ( "FoldersWidget", "FoldersQtModel", "FOLDERS_MODEL_SENDER_NAME", + "SimpleFoldersWidget", "TasksWidget", "TasksQtModel", diff --git a/client/ayon_core/tools/ayon_utils/widgets/folders_widget.py b/client/ayon_core/tools/ayon_utils/widgets/folders_widget.py index 1e395b0368..6ca5264a8d 100644 --- a/client/ayon_core/tools/ayon_utils/widgets/folders_widget.py +++ b/client/ayon_core/tools/ayon_utils/widgets/folders_widget.py @@ -2,6 +2,11 @@ import collections from qtpy import QtWidgets, QtGui, QtCore +from ayon_core.lib.events import QueuedEventSystem +from ayon_core.tools.ayon_utils.models import ( + HierarchyModel, + HierarchyExpectedSelection, +) from ayon_core.tools.utils import ( RecursiveSortFilterProxyModel, TreeView, @@ -514,3 +519,110 @@ class FoldersWidget(QtWidgets.QWidget): if folder_id is not None: self.set_selected_folder(folder_id) self._controller.expected_folder_selected(folder_id) + + +class SimpleSelectionModel(object): + """Model handling selection changes. + + Triggering events: + - "selection.project.changed" + - "selection.folder.changed" + """ + + event_source = "selection.model" + + def __init__(self, controller): + self._controller = controller + + self._project_name = None + self._folder_id = None + self._task_id = None + self._task_name = None + + def get_selected_project_name(self): + return self._project_name + + def set_selected_project(self, project_name): + self._project_name = project_name + self._controller.emit_event( + "selection.project.changed", + {"project_name": project_name}, + self.event_source + ) + + def get_selected_folder_id(self): + return self._folder_id + + def set_selected_folder(self, folder_id): + if folder_id == self._folder_id: + return + self._folder_id = folder_id + self._controller.emit_event( + "selection.folder.changed", + { + "project_name": self._project_name, + "folder_id": folder_id, + }, + self.event_source + ) + + +class SimpleFoldersController(object): + def __init__(self): + self._event_system = self._create_event_system() + self._hierarchy_model = HierarchyModel(self) + self._selection_model = SimpleSelectionModel(self) + self._expected_selection = HierarchyExpectedSelection( + self, handle_project=False, handle_folder=True, handle_task=False + ) + + def emit_event(self, topic, data=None, source=None): + """Use implemented event system to trigger event.""" + + if data is None: + data = {} + self._event_system.emit(topic, data, source) + + def register_event_callback(self, topic, callback): + self._event_system.add_callback(topic, callback) + + # Model functions + def get_folder_items(self, project_name, sender=None): + return self._hierarchy_model.get_folder_items(project_name, sender) + + def set_selected_project(self, project_name): + self._selection_model.set_selected_project(project_name) + + def set_selected_folder(self, folder_id): + self._selection_model.set_selected_folder(folder_id) + + def get_expected_selection_data(self): + self._expected_selection.get_expected_selection_data() + + def expected_folder_selected(self, folder_id): + self._expected_selection.expected_folder_selected(folder_id) + + def _create_event_system(self): + return QueuedEventSystem() + + +class SimpleFoldersWidget(FoldersWidget): + def __init__(self, controller=None, *args, **kwargs): + if controller is None: + controller = SimpleFoldersController() + super(SimpleFoldersWidget, self).__init__(controller, *args, **kwargs) + + def set_project_name(self, project_name): + self._controller.set_selected_project(project_name) + super(SimpleFoldersWidget, self).set_project_name(project_name) + + def _on_project_selection_change(self, event): + """Ignore project selection change from controller. + + Only who can trigger project change is this widget with + 'set_project_name' which already cares about project change. + + Args: + event (Event): Triggered event. + """ + pass From 4744ff329ed90d010400c6a3f1943e248e376eb8 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Thu, 15 Feb 2024 18:28:27 +0100 Subject: [PATCH 153/185] added 'get_selected_folder_path' --- .../tools/ayon_utils/widgets/folders_widget.py | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/client/ayon_core/tools/ayon_utils/widgets/folders_widget.py b/client/ayon_core/tools/ayon_utils/widgets/folders_widget.py index 6ca5264a8d..cf81d1c8ff 100644 --- a/client/ayon_core/tools/ayon_utils/widgets/folders_widget.py +++ b/client/ayon_core/tools/ayon_utils/widgets/folders_widget.py @@ -395,6 +395,15 @@ class FoldersWidget(QtWidgets.QWidget): return self._get_selected_item_id() + def get_selected_folder_path(self): + """Get selected folder id. + + Returns: + Union[str, None]: Folder path which is selected. + """ + + return self._get_selected_item_value(FOLDER_PATH_ROLE) + def get_selected_folder_label(self): """Selected folder label. @@ -478,9 +487,12 @@ class FoldersWidget(QtWidgets.QWidget): self.refreshed.emit() def _get_selected_item_id(self): + return self._get_selected_item_value(FOLDER_ID_ROLE) + + def _get_selected_item_value(self, role): selection_model = self._folders_view.selectionModel() for index in selection_model.selectedIndexes(): - item_id = index.data(FOLDER_ID_ROLE) + item_id = index.data(role) if item_id is not None: return item_id return None From 8331c90fcfe3e66dea703af0023ee0cefa81563b Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Thu, 15 Feb 2024 18:52:05 +0100 Subject: [PATCH 154/185] ExtractThumbnail uses AYON settings --- client/ayon_core/lib/transcoding.py | 9 +++-- .../plugins/publish/extract_thumbnail.py | 39 ++++++++++++------- client/ayon_core/settings/ayon_settings.py | 20 ---------- 3 files changed, 32 insertions(+), 36 deletions(-) diff --git a/client/ayon_core/lib/transcoding.py b/client/ayon_core/lib/transcoding.py index 6c6837dcf9..08e0bc9237 100644 --- a/client/ayon_core/lib/transcoding.py +++ b/client/ayon_core/lib/transcoding.py @@ -1385,23 +1385,26 @@ def _get_image_dimensions(application, input_path, log): def convert_color_values(application, color_value): """Get color mapping for ffmpeg and oiiotool. + Args: application (str): Application for which command should be created. - color_value (list[int]): List of 8bit int values for RGBA. + color_value (tuple[int, int, int, float]): List of 8bit int values + for RGBA. + Returns: str: ffmpeg returns hex string, oiiotool is string with floats. + """ red, green, blue, alpha = color_value if application == "ffmpeg": return "{0:0>2X}{1:0>2X}{2:0>2X}@{3}".format( - red, green, blue, (alpha / 255.0) + red, green, blue, alpha ) elif application == "oiiotool": red = float(red / 255) green = float(green / 255) blue = float(blue / 255) - alpha = float(alpha / 255) return "{0:.3f},{1:.3f},{2:.3f},{3:.3f}".format( red, green, blue, alpha) diff --git a/client/ayon_core/plugins/publish/extract_thumbnail.py b/client/ayon_core/plugins/publish/extract_thumbnail.py index 3874ddc13c..e392ce630a 100644 --- a/client/ayon_core/plugins/publish/extract_thumbnail.py +++ b/client/ayon_core/plugins/publish/extract_thumbnail.py @@ -42,15 +42,27 @@ class ExtractThumbnail(pyblish.api.InstancePlugin): integrate_thumbnail = False target_size = { - "type": "resize", - "width": 1920, - "height": 1080 + "type": "source", + "resize": { + "width": 1920, + "height": 1080 + } } - background_color = None + background_color = (0, 0, 0, 0.0) duration_split = 0.5 # attribute presets from settings - oiiotool_defaults = None - ffmpeg_args = None + oiiotool_defaults = { + "type": "colorspace", + "colorspace": "color_picking", + "display_and_view": { + "display": "default", + "view": "sRGB" + } + } + ffmpeg_args = { + "input": [], + "output": [] + } product_names = [] def process(self, instance): @@ -369,7 +381,6 @@ class ExtractThumbnail(pyblish.api.InstancePlugin): repre_display = colorspace_data.get("display") repre_view = colorspace_data.get("view") - oiio_default_type = None oiio_default_display = None oiio_default_view = None oiio_default_colorspace = None @@ -387,11 +398,12 @@ class ExtractThumbnail(pyblish.api.InstancePlugin): # oiiotool_defaults elif self.oiiotool_defaults: oiio_default_type = self.oiiotool_defaults["type"] - if "colorspace" in oiio_default_type: + if "colorspace" == oiio_default_type: oiio_default_colorspace = self.oiiotool_defaults["colorspace"] else: - oiio_default_display = self.oiiotool_defaults["display"] - oiio_default_view = self.oiiotool_defaults["view"] + display_and_view = self.oiiotool_defaults["display_and_view"] + oiio_default_display = display_and_view["display"] + oiio_default_view = display_and_view["view"] try: convert_colorspace( @@ -507,11 +519,12 @@ class ExtractThumbnail(pyblish.api.InstancePlugin): input_path, ): # get settings - if self.target_size.get("type") == "source": + if self.target_size["type"] == "source": return [] - target_width = self.target_size["width"] - target_height = self.target_size["height"] + resize = self.target_size["resize"] + target_width = resize["width"] + target_height = resize["height"] # form arg string per application return get_rescaled_command_arguments( diff --git a/client/ayon_core/settings/ayon_settings.py b/client/ayon_core/settings/ayon_settings.py index 5c4813f3aa..12d4833469 100644 --- a/client/ayon_core/settings/ayon_settings.py +++ b/client/ayon_core/settings/ayon_settings.py @@ -406,26 +406,6 @@ def _convert_global_project_settings(ayon_settings, output, default_settings): # Publish conversion ayon_publish = ayon_core["publish"] - # ExtractThumbnail plugin - ayon_extract_thumbnail = ayon_publish["ExtractThumbnail"] - # fix display and view at oiio defaults - ayon_default_oiio = copy.deepcopy( - ayon_extract_thumbnail["oiiotool_defaults"]) - display_and_view = ayon_default_oiio.pop("display_and_view") - ayon_default_oiio["display"] = display_and_view["display"] - ayon_default_oiio["view"] = display_and_view["view"] - ayon_extract_thumbnail["oiiotool_defaults"] = ayon_default_oiio - # fix target size - ayon_default_resize = copy.deepcopy(ayon_extract_thumbnail["target_size"]) - resize = ayon_default_resize.pop("resize") - ayon_default_resize["width"] = resize["width"] - ayon_default_resize["height"] = resize["height"] - ayon_extract_thumbnail["target_size"] = ayon_default_resize - # fix background color - ayon_extract_thumbnail["background_color"] = _convert_color( - ayon_extract_thumbnail["background_color"] - ) - # Project root settings - json string to dict ayon_core["project_environments"] = json.loads( ayon_core["project_environments"] From c8ec6ad2b83ba32a9467f31ccb4bcf1ed4969c52 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Thu, 15 Feb 2024 18:58:39 +0100 Subject: [PATCH 155/185] 'project_environments' are loaded correctly --- client/ayon_core/lib/applications.py | 1 + client/ayon_core/settings/ayon_settings.py | 8 -------- 2 files changed, 1 insertion(+), 8 deletions(-) diff --git a/client/ayon_core/lib/applications.py b/client/ayon_core/lib/applications.py index 60ef2a6708..d79f18a707 100644 --- a/client/ayon_core/lib/applications.py +++ b/client/ayon_core/lib/applications.py @@ -1658,6 +1658,7 @@ def apply_project_environments_value( env_value = project_settings["global"]["project_environments"] if env_value: + env_value = json.loads(env_value) parsed_value = parse_environments(env_value, env_group) env.update(acre.compute( _merge_env(parsed_value, env), diff --git a/client/ayon_core/settings/ayon_settings.py b/client/ayon_core/settings/ayon_settings.py index 12d4833469..6d2163ee6e 100644 --- a/client/ayon_core/settings/ayon_settings.py +++ b/client/ayon_core/settings/ayon_settings.py @@ -406,14 +406,6 @@ def _convert_global_project_settings(ayon_settings, output, default_settings): # Publish conversion ayon_publish = ayon_core["publish"] - # Project root settings - json string to dict - ayon_core["project_environments"] = json.loads( - ayon_core["project_environments"] - ) - ayon_core["project_folder_structure"] = json.dumps(json.loads( - ayon_core["project_folder_structure"] - )) - # Tools settings ayon_core["sync_server"] = ( default_settings["global"]["sync_server"] From ad6472e9bf55ffea5e00d91e169a991f16089d35 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Thu, 15 Feb 2024 18:59:20 +0100 Subject: [PATCH 156/185] removed core settings conversion --- client/ayon_core/hosts/nuke/api/plugin.py | 2 +- client/ayon_core/lib/applications.py | 6 +++--- client/ayon_core/pipeline/colorspace.py | 2 +- client/ayon_core/pipeline/context_tools.py | 4 ++-- .../ayon_core/pipeline/create/legacy_create.py | 2 +- .../ayon_core/pipeline/create/subset_name.py | 2 +- client/ayon_core/pipeline/load/plugins.py | 2 +- client/ayon_core/pipeline/project_folders.py | 2 +- client/ayon_core/pipeline/publish/lib.py | 8 ++++---- client/ayon_core/pipeline/version_start.py | 2 +- .../pipeline/workfile/lock_workfile.py | 2 +- .../pipeline/workfile/path_resolving.py | 4 ++-- .../plugins/publish/collect_comment.py | 2 +- client/ayon_core/settings/ayon_settings.py | 18 ------------------ client/ayon_core/tools/pyblish_pype/control.py | 2 +- 15 files changed, 21 insertions(+), 39 deletions(-) diff --git a/client/ayon_core/hosts/nuke/api/plugin.py b/client/ayon_core/hosts/nuke/api/plugin.py index 4b8ddac167..d9be3fad17 100644 --- a/client/ayon_core/hosts/nuke/api/plugin.py +++ b/client/ayon_core/hosts/nuke/api/plugin.py @@ -493,7 +493,7 @@ def get_colorspace_from_node(node): def get_review_presets_config(): settings = get_current_project_settings() review_profiles = ( - settings["global"] + settings["core"] ["publish"] ["ExtractReview"] ["profiles"] diff --git a/client/ayon_core/lib/applications.py b/client/ayon_core/lib/applications.py index d79f18a707..a4e2d9c89d 100644 --- a/client/ayon_core/lib/applications.py +++ b/client/ayon_core/lib/applications.py @@ -1656,7 +1656,7 @@ def apply_project_environments_value( if project_settings is None: project_settings = get_project_settings(project_name) - env_value = project_settings["global"]["project_environments"] + env_value = project_settings["core"]["project_environments"] if env_value: env_value = json.loads(env_value) parsed_value = parse_environments(env_value, env_group) @@ -1917,7 +1917,7 @@ def should_start_last_workfile( project_settings = get_project_settings(project_name) profiles = ( project_settings - ["global"] + ["core"] ["tools"] ["Workfiles"] ["last_workfile_on_startup"] @@ -1967,7 +1967,7 @@ def should_workfile_tool_start( project_settings = get_project_settings(project_name) profiles = ( project_settings - ["global"] + ["core"] ["tools"] ["Workfiles"] ["open_workfile_tool_on_startup"] diff --git a/client/ayon_core/pipeline/colorspace.py b/client/ayon_core/pipeline/colorspace.py index 1b795e1c39..7100984217 100644 --- a/client/ayon_core/pipeline/colorspace.py +++ b/client/ayon_core/pipeline/colorspace.py @@ -1018,7 +1018,7 @@ def _get_imageio_settings(project_settings, host_name): tuple[dict, dict]: image io settings for global and host """ # get image io from global and host_name - imageio_global = project_settings["global"]["imageio"] + imageio_global = project_settings["core"]["imageio"] # host is optional, some might not have any settings imageio_host = project_settings.get(host_name, {}).get("imageio", {}) diff --git a/client/ayon_core/pipeline/context_tools.py b/client/ayon_core/pipeline/context_tools.py index 730852ff4a..7c0db0be27 100644 --- a/client/ayon_core/pipeline/context_tools.py +++ b/client/ayon_core/pipeline/context_tools.py @@ -208,8 +208,8 @@ def install_ayon_plugins(project_name=None, host_name=None): platform_name = platform.system().lower() project_plugins = ( project_settings - .get("global", {}) - .get("project_plugins", {}) + ["core"] + ["project_plugins"] .get(platform_name) ) or [] for path in project_plugins: diff --git a/client/ayon_core/pipeline/create/legacy_create.py b/client/ayon_core/pipeline/create/legacy_create.py index aab6b67e6f..2ab8b8e3e5 100644 --- a/client/ayon_core/pipeline/create/legacy_create.py +++ b/client/ayon_core/pipeline/create/legacy_create.py @@ -54,7 +54,7 @@ class LegacyCreator(object): ) global_type_settings = ( project_settings - .get("global", {}) + .get("core", {}) .get(plugin_type, {}) ) if not global_type_settings and not plugin_type_settings: diff --git a/client/ayon_core/pipeline/create/subset_name.py b/client/ayon_core/pipeline/create/subset_name.py index 81967ffd99..5925ec0f2b 100644 --- a/client/ayon_core/pipeline/create/subset_name.py +++ b/client/ayon_core/pipeline/create/subset_name.py @@ -47,7 +47,7 @@ def get_subset_name_template( if project_settings is None: project_settings = get_project_settings(project_name) - tools_settings = project_settings["global"]["tools"] + tools_settings = project_settings["core"]["tools"] profiles = tools_settings["creator"]["product_name_profiles"] filtering_criteria = { "product_types": family, diff --git a/client/ayon_core/pipeline/load/plugins.py b/client/ayon_core/pipeline/load/plugins.py index 1d4627689f..962417c6f2 100644 --- a/client/ayon_core/pipeline/load/plugins.py +++ b/client/ayon_core/pipeline/load/plugins.py @@ -47,7 +47,7 @@ class LoaderPlugin(list): ) global_type_settings = ( project_settings - .get("global", {}) + .get("core", {}) .get(plugin_type, {}) ) if not global_type_settings and not plugin_type_settings: diff --git a/client/ayon_core/pipeline/project_folders.py b/client/ayon_core/pipeline/project_folders.py index ad205522a6..811a98ce4b 100644 --- a/client/ayon_core/pipeline/project_folders.py +++ b/client/ayon_core/pipeline/project_folders.py @@ -104,7 +104,7 @@ def _list_path_items(folder_structure): def get_project_basic_paths(project_name): project_settings = get_project_settings(project_name) folder_structure = ( - project_settings["global"]["project_folder_structure"] + project_settings["core"]["project_folder_structure"] ) if not folder_structure: return [] diff --git a/client/ayon_core/pipeline/publish/lib.py b/client/ayon_core/pipeline/publish/lib.py index a14651551f..90725e6d79 100644 --- a/client/ayon_core/pipeline/publish/lib.py +++ b/client/ayon_core/pipeline/publish/lib.py @@ -60,7 +60,7 @@ def get_template_name_profiles( return copy.deepcopy( project_settings - ["global"] + ["core"] ["tools"] ["publish"] ["template_name_profiles"] @@ -95,7 +95,7 @@ def get_hero_template_name_profiles( return copy.deepcopy( project_settings - ["global"] + ["core"] ["tools"] ["publish"] ["hero_template_name_profiles"] @@ -383,7 +383,7 @@ def get_plugin_settings(plugin, project_settings, log, category=None): # TODO: change after all plugins are moved one level up if category_from_file in ("ayon_core", "openpype"): - category_from_file = "global" + category_from_file = "core" try: return ( @@ -744,7 +744,7 @@ def get_custom_staging_dir_info(project_name, host_name, family, task_name, ValueError - if misconfigured template should be used """ settings = project_settings or get_project_settings(project_name) - custom_staging_dir_profiles = (settings["global"] + custom_staging_dir_profiles = (settings["core"] ["tools"] ["publish"] ["custom_staging_dir_profiles"]) diff --git a/client/ayon_core/pipeline/version_start.py b/client/ayon_core/pipeline/version_start.py index bd7d800335..4813910bf3 100644 --- a/client/ayon_core/pipeline/version_start.py +++ b/client/ayon_core/pipeline/version_start.py @@ -16,7 +16,7 @@ def get_versioning_start( project_settings = get_project_settings(project_name) version_start = 1 - settings = project_settings["global"] + settings = project_settings["core"] profiles = settings.get("version_start_category", {}).get("profiles", []) if not profiles: diff --git a/client/ayon_core/pipeline/workfile/lock_workfile.py b/client/ayon_core/pipeline/workfile/lock_workfile.py index a6d4348966..7eab3f36dc 100644 --- a/client/ayon_core/pipeline/workfile/lock_workfile.py +++ b/client/ayon_core/pipeline/workfile/lock_workfile.py @@ -64,7 +64,7 @@ def is_workfile_lock_enabled(host_name, project_name, project_setting=None): project_setting = get_project_settings(project_name) workfile_lock_profiles = ( project_setting - ["global"] + ["core"] ["tools"] ["Workfiles"] ["workfile_lock_profiles"]) diff --git a/client/ayon_core/pipeline/workfile/path_resolving.py b/client/ayon_core/pipeline/workfile/path_resolving.py index 2062705d3c..168e775475 100644 --- a/client/ayon_core/pipeline/workfile/path_resolving.py +++ b/client/ayon_core/pipeline/workfile/path_resolving.py @@ -72,7 +72,7 @@ def get_workfile_template_key( try: profiles = ( project_settings - ["global"] + ["core"] ["tools"] ["Workfiles"] ["workfile_template_profiles"] @@ -507,7 +507,7 @@ def create_workdir_extra_folders( # Load extra folders profiles extra_folders_profiles = ( - project_settings["global"]["tools"]["Workfiles"]["extra_folders"] + project_settings["core"]["tools"]["Workfiles"]["extra_folders"] ) # Skip if are empty if not extra_folders_profiles: diff --git a/client/ayon_core/plugins/publish/collect_comment.py b/client/ayon_core/plugins/publish/collect_comment.py index dadb7b9e8d..458c0a5658 100644 --- a/client/ayon_core/plugins/publish/collect_comment.py +++ b/client/ayon_core/plugins/publish/collect_comment.py @@ -43,7 +43,7 @@ class CollectInstanceCommentDef( @classmethod def apply_settings(cls, project_setting, _): - plugin_settings = project_setting["global"]["publish"].get( + plugin_settings = project_setting["core"]["publish"].get( "collect_comment_per_instance" ) if not plugin_settings: diff --git a/client/ayon_core/settings/ayon_settings.py b/client/ayon_core/settings/ayon_settings.py index 6d2163ee6e..4d45f8cca8 100644 --- a/client/ayon_core/settings/ayon_settings.py +++ b/client/ayon_core/settings/ayon_settings.py @@ -397,22 +397,6 @@ def _convert_royalrender_project_settings(ayon_settings, output): } -def _convert_global_project_settings(ayon_settings, output, default_settings): - if "core" not in ayon_settings: - return - - ayon_core = ayon_settings["core"] - - # Publish conversion - ayon_publish = ayon_core["publish"] - - # Tools settings - ayon_core["sync_server"] = ( - default_settings["global"]["sync_server"] - ) - output["global"] = ayon_core - - def convert_project_settings(ayon_settings, default_settings): default_settings = copy.deepcopy(default_settings) output = {} @@ -422,8 +406,6 @@ def convert_project_settings(ayon_settings, default_settings): _convert_royalrender_project_settings(ayon_settings, output) - _convert_global_project_settings(ayon_settings, output, default_settings) - for key, value in ayon_settings.items(): if key not in output: output[key] = value diff --git a/client/ayon_core/tools/pyblish_pype/control.py b/client/ayon_core/tools/pyblish_pype/control.py index 1a3e7a15f0..0e25fa9e27 100644 --- a/client/ayon_core/tools/pyblish_pype/control.py +++ b/client/ayon_core/tools/pyblish_pype/control.py @@ -208,7 +208,7 @@ class Controller(QtCore.QObject): if not presets: return {} - result = presets.get("global", {}).get("filters", {}) + result = presets.get("core", {}).get("filters", {}) hosts = pyblish.api.registered_hosts() for host in hosts: host_presets = presets.get(host, {}).get("filters") From 47d9af00eab4da6b5cc244a718a6bf9a759883c3 Mon Sep 17 00:00:00 2001 From: Jakub Trllo <43494761+iLLiCiTiT@users.noreply.github.com> Date: Thu, 15 Feb 2024 23:14:06 +0100 Subject: [PATCH 157/185] fix burnins def loop --- client/ayon_core/plugins/publish/extract_burnin.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/ayon_core/plugins/publish/extract_burnin.py b/client/ayon_core/plugins/publish/extract_burnin.py index 4da158343e..499a72bd4f 100644 --- a/client/ayon_core/plugins/publish/extract_burnin.py +++ b/client/ayon_core/plugins/publish/extract_burnin.py @@ -120,7 +120,7 @@ class ExtractBurnin(publish.Extractor): # Filter output definition by `burnin` represetation key repre_linked_burnins = [ burnin_def - for burnin_def in burnin_defs.items() + for burnin_def in burnin_defs if burnin_def["name"] in repre_burnin_links ] self.log.debug( From bc83a61365330b2c19dda4c523c14d20377fdaec Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Thu, 15 Feb 2024 23:28:35 +0100 Subject: [PATCH 158/185] fix type check --- client/ayon_core/hosts/maya/api/plugin.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/ayon_core/hosts/maya/api/plugin.py b/client/ayon_core/hosts/maya/api/plugin.py index aba5fd8903..42c0c7051e 100644 --- a/client/ayon_core/hosts/maya/api/plugin.py +++ b/client/ayon_core/hosts/maya/api/plugin.py @@ -612,7 +612,7 @@ def get_load_color_for_family(family, settings=None): else: raise ValueError("Invalid color definition {}".format(str(color))) - if type(red, int): + if isinstance(red, int): red = red / 255.0 green = green / 255.0 blue = blue / 255.0 From fe2909f2d8a8bc339c6ae12ac676ded79ae3ebdc Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Fri, 16 Feb 2024 10:22:51 +0100 Subject: [PATCH 159/185] removed deadline conversion --- client/ayon_core/settings/ayon_settings.py | 18 +----------------- 1 file changed, 1 insertion(+), 17 deletions(-) diff --git a/client/ayon_core/settings/ayon_settings.py b/client/ayon_core/settings/ayon_settings.py index 190970b908..830cbd5e10 100644 --- a/client/ayon_core/settings/ayon_settings.py +++ b/client/ayon_core/settings/ayon_settings.py @@ -62,22 +62,6 @@ def _convert_general(ayon_settings, output, default_settings): } -def _convert_deadline_system_settings( - ayon_settings, output, addon_versions, default_settings -): - enabled = addon_versions.get("deadline") is not None - deadline_settings = default_settings["modules"]["deadline"] - deadline_settings["enabled"] = enabled - if enabled: - ayon_deadline = ayon_settings["deadline"] - deadline_settings["deadline_urls"] = { - item["name"]: item["value"] - for item in ayon_deadline["deadline_urls"] - } - - output["modules"]["deadline"] = deadline_settings - - def _convert_royalrender_system_settings( ayon_settings, output, addon_versions, default_settings ): @@ -99,7 +83,6 @@ def _convert_modules_system( # TODO add all modules # TODO add 'enabled' values for func in ( - _convert_deadline_system_settings, _convert_royalrender_system_settings, ): func(ayon_settings, output, addon_versions, default_settings) @@ -107,6 +90,7 @@ def _convert_modules_system( for key in { "timers_manager", "clockify", + "deadline", }: if addon_versions.get(key): output[key] = ayon_settings From b41109559b5e3d3cad29cd3a238d2f6605ac3a5e Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Fri, 16 Feb 2024 10:28:29 +0100 Subject: [PATCH 160/185] modified deadline addon to use AYON settings --- .../modules/deadline/deadline_module.py | 38 +++++++++---------- .../collect_deadline_server_from_instance.py | 7 +++- 2 files changed, 24 insertions(+), 21 deletions(-) diff --git a/client/ayon_core/modules/deadline/deadline_module.py b/client/ayon_core/modules/deadline/deadline_module.py index c98d04759e..97d346c287 100644 --- a/client/ayon_core/modules/deadline/deadline_module.py +++ b/client/ayon_core/modules/deadline/deadline_module.py @@ -4,7 +4,7 @@ import six import sys from ayon_core.lib import requests_get, Logger -from ayon_core.modules import OpenPypeModule, IPluginPaths +from ayon_core.modules import AYONAddon, IPluginPaths class DeadlineWebserviceError(Exception): @@ -13,28 +13,28 @@ class DeadlineWebserviceError(Exception): """ -class DeadlineModule(OpenPypeModule, IPluginPaths): +class DeadlineModule(AYONAddon, IPluginPaths): name = "deadline" - def __init__(self, manager, settings): - self.deadline_urls = {} - super(DeadlineModule, self).__init__(manager, settings) - - def initialize(self, modules_settings): + def initialize(self, studio_settings): # This module is always enabled - deadline_settings = modules_settings[self.name] - self.enabled = deadline_settings["enabled"] - deadline_url = deadline_settings.get("DEADLINE_REST_URL") - if deadline_url: - self.deadline_urls = {"default": deadline_url} - else: - self.deadline_urls = deadline_settings.get("deadline_urls") # noqa: E501 + deadline_urls = {} + enabled = self.name in studio_settings + if enabled: + deadline_settings = studio_settings[self.name] + deadline_urls = { + url_item["name"]: url_item["value"] + for url_item in deadline_settings["deadline_urls"] + } - if not self.deadline_urls: - self.enabled = False - self.log.warning(("default Deadline Webservice URL " - "not specified. Disabling module.")) - return + if enabled and not deadline_urls: + enabled = False + self.log.warning(( + "Deadline Webservice URLs are not specified. Disabling addon." + )) + + self.enabled = enabled + self.deadline_urls = deadline_urls def get_plugin_paths(self): """Deadline plugin paths.""" diff --git a/client/ayon_core/modules/deadline/plugins/publish/collect_deadline_server_from_instance.py b/client/ayon_core/modules/deadline/plugins/publish/collect_deadline_server_from_instance.py index 0cfe7c9b39..445971f2b0 100644 --- a/client/ayon_core/modules/deadline/plugins/publish/collect_deadline_server_from_instance.py +++ b/client/ayon_core/modules/deadline/plugins/publish/collect_deadline_server_from_instance.py @@ -47,11 +47,11 @@ class CollectDeadlineServerFromInstance(pyblish.api.InstancePlugin): deadline_settings = ( render_instance.context.data ["system_settings"] - ["modules"] ["deadline"] ) default_server = render_instance.context.data["defaultDeadline"] + # QUESTION How and where is this is set? Should be removed? instance_server = render_instance.data.get("deadlineServers") if not instance_server: self.log.debug("Using default server.") @@ -64,7 +64,10 @@ class CollectDeadlineServerFromInstance(pyblish.api.InstancePlugin): asString=True ) - default_servers = deadline_settings["deadline_urls"] + default_servers = { + url_item["name"]: url_item["value"] + for url_item in deadline_settings["deadline_urls"] + } project_servers = ( render_instance.context.data ["project_settings"] From a8041e55f9daafb50a0229f70393eeb286741a39 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Fri, 16 Feb 2024 15:58:18 +0100 Subject: [PATCH 161/185] moved 'usdlib.py' to pipeline --- .../houdini/plugins/publish/collect_instances_usd_layered.py | 2 +- .../hosts/houdini/plugins/publish/collect_usd_bootstrap.py | 2 +- client/ayon_core/{lib => pipeline}/usdlib.py | 0 3 files changed, 2 insertions(+), 2 deletions(-) rename client/ayon_core/{lib => pipeline}/usdlib.py (100%) diff --git a/client/ayon_core/hosts/houdini/plugins/publish/collect_instances_usd_layered.py b/client/ayon_core/hosts/houdini/plugins/publish/collect_instances_usd_layered.py index 800d6fb883..ee259fb70d 100644 --- a/client/ayon_core/hosts/houdini/plugins/publish/collect_instances_usd_layered.py +++ b/client/ayon_core/hosts/houdini/plugins/publish/collect_instances_usd_layered.py @@ -2,7 +2,7 @@ import hou import pyblish.api from ayon_core.hosts.houdini.api import lib import ayon_core.hosts.houdini.api.usd as hou_usdlib -import ayon_core.lib.usdlib as usdlib +from ayon_core.pipeline import usdlib class CollectInstancesUsdLayered(pyblish.api.ContextPlugin): diff --git a/client/ayon_core/hosts/houdini/plugins/publish/collect_usd_bootstrap.py b/client/ayon_core/hosts/houdini/plugins/publish/collect_usd_bootstrap.py index ed54ad8bc1..7342c8f621 100644 --- a/client/ayon_core/hosts/houdini/plugins/publish/collect_usd_bootstrap.py +++ b/client/ayon_core/hosts/houdini/plugins/publish/collect_usd_bootstrap.py @@ -5,7 +5,7 @@ from ayon_core.client import ( get_asset_by_name, get_asset_name_identifier, ) -import ayon_core.lib.usdlib as usdlib +from ayon_core.pipeline import usdlib class CollectUsdBootstrap(pyblish.api.InstancePlugin): diff --git a/client/ayon_core/lib/usdlib.py b/client/ayon_core/pipeline/usdlib.py similarity index 100% rename from client/ayon_core/lib/usdlib.py rename to client/ayon_core/pipeline/usdlib.py From d250405dd672d75af23b349d1226156e1c20fa59 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Fri, 16 Feb 2024 16:29:20 +0100 Subject: [PATCH 162/185] don't use 'get_local_settings' in experimental tools --- client/ayon_core/tools/experimental_tools/tools_def.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/client/ayon_core/tools/experimental_tools/tools_def.py b/client/ayon_core/tools/experimental_tools/tools_def.py index be6762b239..305060978d 100644 --- a/client/ayon_core/tools/experimental_tools/tools_def.py +++ b/client/ayon_core/tools/experimental_tools/tools_def.py @@ -1,5 +1,4 @@ import os -from ayon_core.settings import get_local_settings # Constant key under which local settings are stored LOCAL_EXPERIMENTAL_KEY = "experimental_tools" @@ -151,7 +150,10 @@ class ExperimentalTools: def refresh_availability(self): """Reload local settings and check if any tool changed ability.""" - local_settings = get_local_settings() + + # NOTE AYON does not have implemented settings for experimental + # tools. + local_settings = {} experimental_settings = ( local_settings.get(LOCAL_EXPERIMENTAL_KEY) ) or {} From 21989f88dd6a1adeb3841e0f44ca33e3c855f35d Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Fri, 16 Feb 2024 16:29:39 +0100 Subject: [PATCH 163/185] don't use local settings in applications logic --- client/ayon_core/lib/applications.py | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/client/ayon_core/lib/applications.py b/client/ayon_core/lib/applications.py index 60ef2a6708..69da56a0da 100644 --- a/client/ayon_core/lib/applications.py +++ b/client/ayon_core/lib/applications.py @@ -16,7 +16,6 @@ from ayon_core.client import get_asset_name_identifier from ayon_core.settings import ( get_system_settings, get_project_settings, - get_local_settings ) from ayon_core.settings.constants import ( METADATA_KEYS, @@ -1528,16 +1527,17 @@ def prepare_app_environments( # Use environments from local settings filtered_local_envs = {} - system_settings = data["system_settings"] - whitelist_envs = system_settings["general"].get("local_env_white_list") - if whitelist_envs: - local_settings = get_local_settings() - local_envs = local_settings.get("environments") or {} - filtered_local_envs = { - key: value - for key, value in local_envs.items() - if key in whitelist_envs - } + # NOTE Overrides for environment variables are not implemented in AYON. + # system_settings = data["system_settings"] + # whitelist_envs = system_settings["general"].get("local_env_white_list") + # if whitelist_envs: + # local_settings = get_local_settings() + # local_envs = local_settings.get("environments") or {} + # filtered_local_envs = { + # key: value + # for key, value in local_envs.items() + # if key in whitelist_envs + # } # Apply local environment variables for already existing values for key, value in filtered_local_envs.items(): From f7790f14af0395f496d193796966ffa6cb6b2c72 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Fri, 16 Feb 2024 16:30:01 +0100 Subject: [PATCH 164/185] do not add local settings to 'get_all_current_info' --- client/ayon_core/lib/ayon_info.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/client/ayon_core/lib/ayon_info.py b/client/ayon_core/lib/ayon_info.py index 97a35adcc6..ec37d735d8 100644 --- a/client/ayon_core/lib/ayon_info.py +++ b/client/ayon_core/lib/ayon_info.py @@ -5,7 +5,6 @@ import platform import getpass import socket -from ayon_core.settings.lib import get_local_settings from .execute import get_ayon_launcher_args from .local_settings import get_local_site_id @@ -96,7 +95,6 @@ def get_all_current_info(): return { "workstation": get_workstation_info(), "env": os.environ.copy(), - "local_settings": get_local_settings(), "ayon": get_ayon_info(), } From 02ecdb0ad19a399f6ee68f158c92ecce1c02757a Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Fri, 16 Feb 2024 16:31:20 +0100 Subject: [PATCH 165/185] don't use local settings in anatomy --- client/ayon_core/pipeline/anatomy.py | 20 ++++---------------- 1 file changed, 4 insertions(+), 16 deletions(-) diff --git a/client/ayon_core/pipeline/anatomy.py b/client/ayon_core/pipeline/anatomy.py index 4864822aa1..e7833a9a15 100644 --- a/client/ayon_core/pipeline/anatomy.py +++ b/client/ayon_core/pipeline/anatomy.py @@ -8,9 +8,6 @@ import numbers import six import time -from ayon_core.settings.lib import ( - get_local_settings, -) from ayon_core.client import get_project, get_ayon_server_api_connection from ayon_core.lib import Logger, get_local_site_id from ayon_core.lib.path_templates import ( @@ -453,7 +450,7 @@ class Anatomy(BaseAnatomy): return cls._sync_server_addon_cache.data @classmethod - def _get_studio_roots_overrides(cls, project_name, local_settings=None): + def _get_studio_roots_overrides(cls, project_name): """This would return 'studio' site override by local settings. Notes: @@ -465,7 +462,6 @@ class Anatomy(BaseAnatomy): Args: project_name (str): Name of project. - local_settings (Optional[dict[str, Any]]): Prepared local settings. Returns: Union[Dict[str, str], None]): Local root overrides. @@ -488,11 +484,6 @@ class Anatomy(BaseAnatomy): should be returned. """ - # Local settings may be used more than once or may not be used at all - # - to avoid slowdowns 'get_local_settings' is not called until it's - # really needed - local_settings = None - # First check if sync server is available and enabled sync_server = cls.get_sync_server_addon() if sync_server is None or not sync_server.enabled: @@ -503,11 +494,8 @@ class Anatomy(BaseAnatomy): # Use sync server to receive active site name project_cache = cls._default_site_id_cache[project_name] if project_cache.is_outdated: - local_settings = get_local_settings() project_cache.update_data( - sync_server.get_active_site_type( - project_name, local_settings - ) + sync_server.get_active_site_type(project_name) ) site_name = project_cache.data @@ -517,12 +505,12 @@ class Anatomy(BaseAnatomy): # Handle studio root overrides without sync server # - studio root overrides can be done even without sync server roots_overrides = cls._get_studio_roots_overrides( - project_name, local_settings + project_name ) else: # Ask sync server to get roots overrides roots_overrides = sync_server.get_site_root_overrides( - project_name, site_name, local_settings + project_name, site_name ) site_cache.update_data(roots_overrides) return site_cache.data From 5224125b3af8310b212926fb0de98258633989f9 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Fri, 16 Feb 2024 16:32:15 +0100 Subject: [PATCH 166/185] removed 'get_local_settings' function --- client/ayon_core/settings/__init__.py | 2 -- client/ayon_core/settings/lib.py | 5 ----- 2 files changed, 7 deletions(-) diff --git a/client/ayon_core/settings/__init__.py b/client/ayon_core/settings/__init__.py index f0e5c95efe..074dbf8d03 100644 --- a/client/ayon_core/settings/__init__.py +++ b/client/ayon_core/settings/__init__.py @@ -7,7 +7,6 @@ from .lib import ( get_system_settings, get_project_settings, get_current_project_settings, - get_local_settings, ) from .ayon_settings import get_ayon_settings @@ -20,7 +19,6 @@ __all__ = ( "get_system_settings", "get_project_settings", "get_current_project_settings", - "get_local_settings", "get_ayon_settings", ) diff --git a/client/ayon_core/settings/lib.py b/client/ayon_core/settings/lib.py index 4dff7768f7..1508516c71 100644 --- a/client/ayon_core/settings/lib.py +++ b/client/ayon_core/settings/lib.py @@ -48,11 +48,6 @@ def clear_metadata_from_settings(values): clear_metadata_from_settings(item) -def get_local_settings(): - # TODO implement ayon implementation - return {} - - def load_openpype_default_settings(): """Load openpype default settings.""" return load_jsons_from_dir(DEFAULTS_DIR) From 4c1ac5a4f022fe1f5fd89c6f1e9402b4639e5668 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Fri, 16 Feb 2024 16:32:28 +0100 Subject: [PATCH 167/185] cleared 'get_site_local_overrides' and added warning --- client/ayon_core/settings/lib.py | 30 ++++-------------------------- 1 file changed, 4 insertions(+), 26 deletions(-) diff --git a/client/ayon_core/settings/lib.py b/client/ayon_core/settings/lib.py index 1508516c71..8e358396c4 100644 --- a/client/ayon_core/settings/lib.py +++ b/client/ayon_core/settings/lib.py @@ -198,39 +198,17 @@ def merge_overrides(source_dict, override_dict): def get_site_local_overrides(project_name, site_name, local_settings=None): """Site overrides from local settings for passet project and site name. + Warning: + This function is not implemented for AYON. + Args: project_name (str): For which project are overrides. site_name (str): For which site are overrides needed. local_settings (dict): Preloaded local settings. They are loaded automatically if not passed. """ - # Check if local settings were passed - if local_settings is None: - local_settings = get_local_settings() - output = {} - - # Skip if local settings are empty - if not local_settings: - return output - - local_project_settings = local_settings.get("projects") or {} - - # Prepare overrides for entered project and for default project - project_locals = None - if project_name: - project_locals = local_project_settings.get(project_name) - default_project_locals = local_project_settings.get(DEFAULT_PROJECT_KEY) - - # First load and use local settings from default project - if default_project_locals and site_name in default_project_locals: - output.update(default_project_locals[site_name]) - - # Apply project specific local settings if there are any - if project_locals and site_name in project_locals: - output.update(project_locals[site_name]) - - return output + return {} def get_current_project_settings(): From eb07f945a56440a5e3b5d402a56a0ee9745fe5bd Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Fri, 16 Feb 2024 16:34:33 +0100 Subject: [PATCH 168/185] added comment to dirmap implementation --- client/ayon_core/host/dirmap.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/client/ayon_core/host/dirmap.py b/client/ayon_core/host/dirmap.py index 9756657386..effafb6261 100644 --- a/client/ayon_core/host/dirmap.py +++ b/client/ayon_core/host/dirmap.py @@ -181,6 +181,10 @@ class HostDirmap(object): exclude_locals=False, cached=False) + # TODO implement + # Dirmap is dependent on 'get_site_local_overrides' which + # is not implemented in AYON. The mapping should be received + # from sitesync addon. active_overrides = get_site_local_overrides( project_name, active_site) remote_overrides = get_site_local_overrides( From d10d860623c7c15f3c403016382f7e52c4d2fd56 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Fri, 16 Feb 2024 16:44:30 +0100 Subject: [PATCH 169/185] reduced filtering hosts for publisher as experimental tool --- client/ayon_core/tools/experimental_tools/tools_def.py | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/client/ayon_core/tools/experimental_tools/tools_def.py b/client/ayon_core/tools/experimental_tools/tools_def.py index be6762b239..716a45c3a0 100644 --- a/client/ayon_core/tools/experimental_tools/tools_def.py +++ b/client/ayon_core/tools/experimental_tools/tools_def.py @@ -89,9 +89,13 @@ class ExperimentalTools: "New publisher", "Combined creation and publishing into one tool.", self._show_publisher, - hosts_filter=["blender", "maya", "nuke", "celaction", "flame", - "fusion", "harmony", "hiero", "resolve", - "tvpaint", "unreal"] + hosts_filter=[ + "celaction", + "flame", + "harmony", + "hiero", + "resolve", + ] ) ] From cd9a240296205699e1911f0049516c9d3562f910 Mon Sep 17 00:00:00 2001 From: Toke Stuart Jepsen Date: Fri, 16 Feb 2024 16:07:16 +0000 Subject: [PATCH 170/185] Remove redundant code --- .../plugins/publish/submit_publish_job.py | 145 ------------------ 1 file changed, 145 deletions(-) diff --git a/client/ayon_core/modules/deadline/plugins/publish/submit_publish_job.py b/client/ayon_core/modules/deadline/plugins/publish/submit_publish_job.py index d4d04f79f6..4023846817 100644 --- a/client/ayon_core/modules/deadline/plugins/publish/submit_publish_job.py +++ b/client/ayon_core/modules/deadline/plugins/publish/submit_publish_job.py @@ -330,151 +330,6 @@ class ProcessSubmittedJobOnFarm(pyblish.api.InstancePlugin, self.log.debug("Skipping local instance.") return - data = instance.data.copy() - context = instance.context - self.context = context - self.anatomy = instance.context.data["anatomy"] - - asset = data.get("asset") or context.data["asset"] - subset = data.get("subset") - - start = instance.data.get("frameStart") - if start is None: - start = context.data["frameStart"] - - end = instance.data.get("frameEnd") - if end is None: - end = context.data["frameEnd"] - - handle_start = instance.data.get("handleStart") - if handle_start is None: - handle_start = context.data["handleStart"] - - handle_end = instance.data.get("handleEnd") - if handle_end is None: - handle_end = context.data["handleEnd"] - - fps = instance.data.get("fps") - if fps is None: - fps = context.data["fps"] - - if data.get("extendFrames", False): - start, end = self._extend_frames( - asset, - subset, - start, - end, - data["overrideExistingFrame"]) - - try: - source = data["source"] - except KeyError: - source = context.data["currentFile"] - - success, rootless_path = ( - self.anatomy.find_root_template_from_path(source) - ) - if success: - source = rootless_path - - else: - # `rootless_path` is not set to `source` if none of roots match - self.log.warning(( - "Could not find root path for remapping \"{}\"." - " This may cause issues." - ).format(source)) - - family = "render" - if ("prerender" in instance.data["families"] or - "prerender.farm" in instance.data["families"]): - family = "prerender" - families = [family] - - # pass review to families if marked as review - do_not_add_review = False - if data.get("review"): - families.append("review") - elif data.get("review") is False: - self.log.debug("Instance has review explicitly disabled.") - do_not_add_review = True - - instance_skeleton_data = { - "family": family, - "subset": subset, - "families": families, - "asset": asset, - "frameStart": start, - "frameEnd": end, - "handleStart": handle_start, - "handleEnd": handle_end, - "frameStartHandle": start - handle_start, - "frameEndHandle": end + handle_end, - "comment": instance.data["comment"], - "fps": fps, - "source": source, - "extendFrames": data.get("extendFrames"), - "overrideExistingFrame": data.get("overrideExistingFrame"), - "pixelAspect": data.get("pixelAspect", 1), - "resolutionWidth": data.get("resolutionWidth", 1920), - "resolutionHeight": data.get("resolutionHeight", 1080), - "multipartExr": data.get("multipartExr", False), - "jobBatchName": data.get("jobBatchName", ""), - "useSequenceForReview": data.get("useSequenceForReview", True), - # map inputVersions `ObjectId` -> `str` so json supports it - "inputVersions": list(map(str, data.get("inputVersions", []))), - "colorspace": instance.data.get("colorspace"), - "stagingDir_persistent": instance.data.get( - "stagingDir_persistent", False - ) - } - - # skip locking version if we are creating v01 - instance_version = instance.data.get("version") # take this if exists - if instance_version != 1: - instance_skeleton_data["version"] = instance_version - - # transfer specific families from original instance to new render - for item in self.families_transfer: - if item in instance.data.get("families", []): - instance_skeleton_data["families"] += [item] - - # transfer specific properties from original instance based on - # mapping dictionary `instance_transfer` - for key, values in self.instance_transfer.items(): - if key in instance.data.get("families", []): - for v in values: - instance_skeleton_data[v] = instance.data.get(v) - - # look into instance data if representations are not having any - # which are having tag `publish_on_farm` and include them - for repre in instance.data.get("representations", []): - staging_dir = repre.get("stagingDir") - if staging_dir: - success, rootless_staging_dir = ( - self.anatomy.find_root_template_from_path( - staging_dir - ) - ) - if success: - repre["stagingDir"] = rootless_staging_dir - else: - self.log.warning(( - "Could not find root path for remapping \"{}\"." - " This may cause issues on farm." - ).format(staging_dir)) - repre["stagingDir"] = staging_dir - - if "publish_on_farm" in repre.get("tags"): - # create representations attribute of not there - if "representations" not in instance_skeleton_data.keys(): - instance_skeleton_data["representations"] = [] - - instance_skeleton_data["representations"].append(repre) - - instances = None - assert data.get("expectedFiles"), ("Submission from old Pype version" - " - missing expectedFiles") - anatomy = instance.context.data["anatomy"] instance_skeleton_data = create_skeleton_instance( From f9a70bc7699dce3e92c609cc0453e12af55fe57c Mon Sep 17 00:00:00 2001 From: Toke Stuart Jepsen Date: Mon, 19 Feb 2024 09:09:16 +0000 Subject: [PATCH 171/185] Fix exposed knobs validator --- .../hosts/nuke/plugins/publish/validate_exposed_knobs.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/ayon_core/hosts/nuke/plugins/publish/validate_exposed_knobs.py b/client/ayon_core/hosts/nuke/plugins/publish/validate_exposed_knobs.py index 9111bcdc2c..c047347481 100644 --- a/client/ayon_core/hosts/nuke/plugins/publish/validate_exposed_knobs.py +++ b/client/ayon_core/hosts/nuke/plugins/publish/validate_exposed_knobs.py @@ -65,7 +65,7 @@ class ValidateExposedKnobs( group_node = instance.data["transientData"]["node"] nuke_settings = instance.context.data["project_settings"]["nuke"] create_settings = nuke_settings["create"][plugin] - exposed_knobs = create_settings["exposed_knobs"] + exposed_knobs = create_settings.get("exposed_knobs", []) unexposed_knobs = [] for knob in exposed_knobs: if knob not in group_node.knobs(): From 25ead9ee87ad2b7e1ec32192441aef96054a5965 Mon Sep 17 00:00:00 2001 From: Toke Stuart Jepsen Date: Mon, 19 Feb 2024 09:11:59 +0000 Subject: [PATCH 172/185] Fix exposed write knobs --- client/ayon_core/hosts/nuke/api/plugin.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/client/ayon_core/hosts/nuke/api/plugin.py b/client/ayon_core/hosts/nuke/api/plugin.py index 4b8ddac167..af7b6d5b2f 100644 --- a/client/ayon_core/hosts/nuke/api/plugin.py +++ b/client/ayon_core/hosts/nuke/api/plugin.py @@ -1348,7 +1348,9 @@ def _remove_old_knobs(node): def exposed_write_knobs(settings, plugin_name, instance_node): - exposed_knobs = settings["nuke"]["create"][plugin_name]["exposed_knobs"] + exposed_knobs = settings["nuke"]["create"][plugin_name].get( + "exposed_knobs", [] + ) if exposed_knobs: instance_node.addKnob(nuke.Text_Knob('', 'Write Knobs')) write_node = nuke.allNodes(group=instance_node, filter="Write")[0] From 4f09e30e204d639032b869c2722e1b22af3c8f57 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Mon, 19 Feb 2024 10:42:20 +0100 Subject: [PATCH 173/185] removed debug log --- client/ayon_core/plugins/publish/extract_burnin.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/client/ayon_core/plugins/publish/extract_burnin.py b/client/ayon_core/plugins/publish/extract_burnin.py index 499a72bd4f..d189e36a99 100644 --- a/client/ayon_core/plugins/publish/extract_burnin.py +++ b/client/ayon_core/plugins/publish/extract_burnin.py @@ -113,9 +113,6 @@ class ExtractBurnin(publish.Extractor): ) burnin_defs = copy.deepcopy(src_burnin_defs) - self.log.debug( - "burnin_defs.keys(): {}".format(burnin_defs.keys()) - ) # Filter output definition by `burnin` represetation key repre_linked_burnins = [ From c45a4245361f7e6ff72fea57d792e04470a0a9d5 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Mon, 19 Feb 2024 10:58:35 +0100 Subject: [PATCH 174/185] add docstring --- client/ayon_core/plugins/publish/extract_burnin.py | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/client/ayon_core/plugins/publish/extract_burnin.py b/client/ayon_core/plugins/publish/extract_burnin.py index d189e36a99..88670928f2 100644 --- a/client/ayon_core/plugins/publish/extract_burnin.py +++ b/client/ayon_core/plugins/publish/extract_burnin.py @@ -96,6 +96,17 @@ class ExtractBurnin(publish.Extractor): instance.data["representations"].remove(repre) def _get_burnins_per_representations(self, instance, src_burnin_defs): + """ + + Args: + instance (pyblish.api.Instance): Pyblish instance. + src_burnin_defs (list): Burnin definitions. + + Returns: + list[tuple[dict, list]]: List of tuples containing representation + and its burnin definitions. + + """ self.log.debug( "Filtering of representations and their burnins starts" ) From 17e9a0a4a62eb57111163ada47bae20c7c3195dc Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Mon, 19 Feb 2024 13:49:31 +0100 Subject: [PATCH 175/185] remove 'ObjectId' usage --- .../publish/collect_input_representations_to_versions.py | 2 -- client/ayon_core/plugins/publish/integrate.py | 2 -- client/ayon_core/tools/push_to_project/models/integrate.py | 3 --- 3 files changed, 7 deletions(-) diff --git a/client/ayon_core/plugins/publish/collect_input_representations_to_versions.py b/client/ayon_core/plugins/publish/collect_input_representations_to_versions.py index b5c9872e74..6caee1be6a 100644 --- a/client/ayon_core/plugins/publish/collect_input_representations_to_versions.py +++ b/client/ayon_core/plugins/publish/collect_input_representations_to_versions.py @@ -1,7 +1,5 @@ import pyblish.api -from bson.objectid import ObjectId - from ayon_core.client import get_representations diff --git a/client/ayon_core/plugins/publish/integrate.py b/client/ayon_core/plugins/publish/integrate.py index a67c837daf..a502031595 100644 --- a/client/ayon_core/plugins/publish/integrate.py +++ b/client/ayon_core/plugins/publish/integrate.py @@ -6,7 +6,6 @@ import datetime import clique import six -from bson.objectid import ObjectId import pyblish.api from ayon_core.client.operations import ( @@ -988,7 +987,6 @@ class IntegrateAsset(pyblish.api.InstancePlugin): """ return { - "_id": ObjectId(), "path": self.get_rootless_path(anatomy, path), "size": os.path.getsize(path), "hash": source_hash(path), diff --git a/client/ayon_core/tools/push_to_project/models/integrate.py b/client/ayon_core/tools/push_to_project/models/integrate.py index 175716cf10..3de1beb2d2 100644 --- a/client/ayon_core/tools/push_to_project/models/integrate.py +++ b/client/ayon_core/tools/push_to_project/models/integrate.py @@ -8,8 +8,6 @@ import sys import traceback import uuid -from bson.objectid import ObjectId - from ayon_core.client import ( get_project, get_assets, @@ -1080,7 +1078,6 @@ class ProjectPushItemProcess: new_repre_files = [] for (path, rootless_path) in repre_filepaths: new_repre_files.append({ - "_id": ObjectId(), "path": rootless_path, "size": os.path.getsize(path), "hash": source_hash(path), From b5cecb728cc4fcacb49b419c03f295aa69d95980 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Mon, 19 Feb 2024 15:37:31 +0100 Subject: [PATCH 176/185] fix burnin defs --- client/ayon_core/plugins/publish/extract_burnin.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/client/ayon_core/plugins/publish/extract_burnin.py b/client/ayon_core/plugins/publish/extract_burnin.py index 88670928f2..edba7d6d8a 100644 --- a/client/ayon_core/plugins/publish/extract_burnin.py +++ b/client/ayon_core/plugins/publish/extract_burnin.py @@ -773,10 +773,13 @@ class ExtractBurnin(publish.Extractor): continue # Burnin values + new_burnin_def = {} burnin_values = {} for key, value in tuple(burnin_def.items()): key_low = key.lower() - if key_low in self.positions and value: + if key_low not in self.positions: + new_burnin_def[key] = value + elif value: burnin_values[key_low] = value # Skip processing if burnin values are not set @@ -788,9 +791,9 @@ class ExtractBurnin(publish.Extractor): ).format(filename_suffix, str(orig_burnin_def))) continue - burnin_values["filter"] = def_filter + new_burnin_def.update(burnin_values) - filtered_burnin_defs.append(burnin_values) + filtered_burnin_defs.append(new_burnin_def) self.log.debug(( "Burnin definition \"{}\" passed first filtering." From afb0a966a2539a14ca1e13db9b242ba04f578671 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Mon, 19 Feb 2024 16:33:23 +0100 Subject: [PATCH 177/185] fix integrate product group --- client/ayon_core/plugins/publish/integrate_product_group.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/ayon_core/plugins/publish/integrate_product_group.py b/client/ayon_core/plugins/publish/integrate_product_group.py index f7c96893ca..82646ed733 100644 --- a/client/ayon_core/plugins/publish/integrate_product_group.py +++ b/client/ayon_core/plugins/publish/integrate_product_group.py @@ -58,7 +58,7 @@ class IntegrateProductGroup(pyblish.api.InstancePlugin): template = profile["template"] fill_pairs = prepare_template_data({ - "family": filter_criteria["families"], + "family": filter_criteria["product_types"], "task": filter_criteria["tasks"], "host": filter_criteria["hosts"], "subset": instance.data["subset"], From 76ffe5742b7792d01c6d6b54c1444464c5322617 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Mon, 19 Feb 2024 16:58:32 +0100 Subject: [PATCH 178/185] fix extract review --- client/ayon_core/plugins/publish/extract_review.py | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/client/ayon_core/plugins/publish/extract_review.py b/client/ayon_core/plugins/publish/extract_review.py index b0bc94c317..927c8a3538 100644 --- a/client/ayon_core/plugins/publish/extract_review.py +++ b/client/ayon_core/plugins/publish/extract_review.py @@ -1280,14 +1280,11 @@ class ExtractReview(pyblish.api.InstancePlugin): "FFprobe couldn't read resolution from input file: \"{}\"" ).format(full_input_path_single_file)) - # NOTE Setting only one of `width` or `heigth` is not allowed + # NOTE Setting only one of `width` or `height` is not allowed # - settings value can't have None but has value of 0 - output_width = ( - output_def.get("output_width") or output_width or None - ) - output_height = ( - output_def.get("output_height") or output_height or None - ) + output_width = output_def["width"] or output_width or None + output_height = output_def["height"] or output_height or None + # Force to use input resolution if output resolution was not defined # in settings. Resolution from instance is not used when # 'use_input_res' is set to 'True'. From 940e8a4cc7794ad079b6ae336149d06e689e597a Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Mon, 19 Feb 2024 17:46:30 +0100 Subject: [PATCH 179/185] Change warning to deprecation and modify message --- client/ayon_core/settings/lib.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/client/ayon_core/settings/lib.py b/client/ayon_core/settings/lib.py index 8e358396c4..4dde488d6c 100644 --- a/client/ayon_core/settings/lib.py +++ b/client/ayon_core/settings/lib.py @@ -198,8 +198,8 @@ def merge_overrides(source_dict, override_dict): def get_site_local_overrides(project_name, site_name, local_settings=None): """Site overrides from local settings for passet project and site name. - Warning: - This function is not implemented for AYON. + Deprecated: + This function is not implemented for AYON and will be removed. Args: project_name (str): For which project are overrides. From e382bb101d9e30acfbcfb9f5db228d1b9d8d7d46 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Mon, 19 Feb 2024 17:55:29 +0100 Subject: [PATCH 180/185] removed shader definition editor --- .../maya/api/shader_definition_editor.py | 176 ------------------ 1 file changed, 176 deletions(-) delete mode 100644 client/ayon_core/hosts/maya/api/shader_definition_editor.py diff --git a/client/ayon_core/hosts/maya/api/shader_definition_editor.py b/client/ayon_core/hosts/maya/api/shader_definition_editor.py deleted file mode 100644 index bfa531eb87..0000000000 --- a/client/ayon_core/hosts/maya/api/shader_definition_editor.py +++ /dev/null @@ -1,176 +0,0 @@ -# -*- coding: utf-8 -*- -"""Editor for shader definitions. - -Shader names are stored as simple text file over GridFS in mongodb. - -""" -import os -from qtpy import QtWidgets, QtCore, QtGui -from ayon_core.client.mongo import OpenPypeMongoConnection -from ayon_core import resources -import gridfs - - -DEFINITION_FILENAME = "{}/maya/shader_definition.txt".format( - os.getenv("AYON_PROJECT_NAME")) - - -class ShaderDefinitionsEditor(QtWidgets.QWidget): - """Widget serving as simple editor for shader name definitions.""" - - # name of the file used to store definitions - - def __init__(self, parent=None): - super(ShaderDefinitionsEditor, self).__init__(parent) - self._mongo = OpenPypeMongoConnection.get_mongo_client() - self._gridfs = gridfs.GridFS( - self._mongo[os.getenv("OPENPYPE_DATABASE_NAME")]) - self._editor = None - - self._original_content = self._read_definition_file() - - self.setObjectName("shaderDefinitionEditor") - self.setWindowTitle("OpenPype shader name definition editor") - icon = QtGui.QIcon(resources.get_ayon_icon_filepath()) - self.setWindowIcon(icon) - self.setWindowFlags(QtCore.Qt.Window) - self.setParent(parent) - self.setAttribute(QtCore.Qt.WA_DeleteOnClose) - self.resize(750, 500) - - self._setup_ui() - self._reload() - - def _setup_ui(self): - """Setup UI of Widget.""" - layout = QtWidgets.QVBoxLayout(self) - label = QtWidgets.QLabel() - label.setText("Put shader names here - one name per line:") - layout.addWidget(label) - self._editor = QtWidgets.QPlainTextEdit() - self._editor.setStyleSheet("border: none;") - layout.addWidget(self._editor) - - btn_layout = QtWidgets.QHBoxLayout() - save_btn = QtWidgets.QPushButton("Save") - save_btn.clicked.connect(self._save) - - reload_btn = QtWidgets.QPushButton("Reload") - reload_btn.clicked.connect(self._reload) - - exit_btn = QtWidgets.QPushButton("Exit") - exit_btn.clicked.connect(self._close) - - btn_layout.addWidget(reload_btn) - btn_layout.addWidget(save_btn) - btn_layout.addWidget(exit_btn) - - layout.addLayout(btn_layout) - - def _read_definition_file(self, file=None): - """Read definition file from database. - - Args: - file (gridfs.grid_file.GridOut, Optional): File to read. If not - set, new query will be issued to find it. - - Returns: - str: Content of the file or empty string if file doesn't exist. - - """ - content = "" - if not file: - file = self._gridfs.find_one( - {"filename": DEFINITION_FILENAME}) - if not file: - print(">>> [SNDE]: nothing in database yet") - return content - content = file.read() - file.close() - return content - - def _write_definition_file(self, content, force=False): - """Write content as definition to file in database. - - Before file is written, check is made if its content has not - changed. If is changed, warning is issued to user if he wants - it to overwrite. Note: GridFs doesn't allow changing file content. - You need to delete existing file and create new one. - - Args: - content (str): Content to write. - - Raises: - ContentException: If file is changed in database while - editor is running. - """ - file = self._gridfs.find_one( - {"filename": DEFINITION_FILENAME}) - if file: - content_check = self._read_definition_file(file) - if content == content_check: - print(">>> [SNDE]: content not changed") - return - if self._original_content != content_check: - if not force: - raise ContentException("Content changed") - print(">>> [SNDE]: overwriting data") - file.close() - self._gridfs.delete(file._id) - - file = self._gridfs.new_file( - filename=DEFINITION_FILENAME, - content_type='text/plain', - encoding='utf-8') - file.write(content) - file.close() - QtCore.QTimer.singleShot(200, self._reset_style) - self._editor.setStyleSheet("border: 1px solid #33AF65;") - self._original_content = content - - def _reset_style(self): - """Reset editor style back. - - Used to visually indicate save. - - """ - self._editor.setStyleSheet("border: none;") - - def _close(self): - self.hide() - - def closeEvent(self, event): - event.ignore() - self.hide() - - def _reload(self): - print(">>> [SNDE]: reloading") - self._set_content(self._read_definition_file()) - - def _save(self): - try: - self._write_definition_file(content=self._editor.toPlainText()) - except ContentException: - # content has changed meanwhile - print(">>> [SNDE]: content has changed") - self._show_overwrite_warning() - - def _set_content(self, content): - self._editor.setPlainText(content) - - def _show_overwrite_warning(self): - reply = QtWidgets.QMessageBox.question( - self, - "Warning", - ("Content you are editing was changed meanwhile in database.\n" - "Please, reload and solve the conflict."), - QtWidgets.QMessageBox.OK) - - if reply == QtWidgets.QMessageBox.OK: - # do nothing - pass - - -class ContentException(Exception): - """This is risen during save if file is changed in database.""" - pass From 0a9acb834ff1b445c5bc46e8fbf9749cfd332993 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Mon, 19 Feb 2024 17:56:59 +0100 Subject: [PATCH 181/185] modified ValidateModelName plugin --- .../plugins/publish/validate_model_name.py | 44 ++++++++----------- 1 file changed, 18 insertions(+), 26 deletions(-) diff --git a/client/ayon_core/hosts/maya/plugins/publish/validate_model_name.py b/client/ayon_core/hosts/maya/plugins/publish/validate_model_name.py index cf2bbcd77c..0d27965971 100644 --- a/client/ayon_core/hosts/maya/plugins/publish/validate_model_name.py +++ b/client/ayon_core/hosts/maya/plugins/publish/validate_model_name.py @@ -4,16 +4,15 @@ import os import platform import re -import gridfs import pyblish.api from maya import cmds import ayon_core.hosts.maya.api.action -from ayon_core.client.mongo import OpenPypeMongoConnection -from ayon_core.hosts.maya.api.shader_definition_editor import ( - DEFINITION_FILENAME) from ayon_core.pipeline.publish import ( - OptionalPyblishPluginMixin, PublishValidationError, ValidateContentsOrder) + OptionalPyblishPluginMixin, + PublishValidationError, + ValidateContentsOrder, +) class ValidateModelName(pyblish.api.InstancePlugin, @@ -31,13 +30,16 @@ class ValidateModelName(pyblish.api.InstancePlugin, families = ["model"] label = "Model Name" actions = [ayon_core.hosts.maya.api.action.SelectInvalidAction] - material_file = None - database_file = DEFINITION_FILENAME + + material_file = { + "windows": None, + "darwin": None, + "linux": None, + } @classmethod def get_invalid(cls, instance): """Get invalid nodes.""" - use_db = cls.database def is_group(group_name): """Find out if supplied transform is group or not.""" @@ -98,25 +100,15 @@ class ValidateModelName(pyblish.api.InstancePlugin, # load shader list file as utf-8 shaders = [] - if not use_db: - material_file = cls.material_file[platform.system().lower()] - if material_file: - if os.path.isfile(material_file): - shader_file = open(material_file, "r") - shaders = shader_file.readlines() - shader_file.close() - else: - cls.log.error("Missing shader name definition file.") - return True + material_file = cls.material_file[platform.system().lower()] + if material_file: + if os.path.isfile(material_file): + shader_file = open(material_file, "r") + shaders = shader_file.readlines() + shader_file.close() else: - client = OpenPypeMongoConnection.get_mongo_client() - fs = gridfs.GridFS(client[os.getenv("OPENPYPE_DATABASE_NAME")]) - shader_file = fs.find_one({"filename": cls.database_file}) - if not shader_file: - cls.log.error("Missing shader name definition in database.") - return True - shaders = shader_file.read().splitlines() - shader_file.close() + cls.log.error("Missing shader name definition file.") + return True # strip line endings from list shaders = [s.rstrip() for s in shaders if s.rstrip()] From f53b12605e34ee1ca2cd91a707932eb44a95a7a0 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Mon, 19 Feb 2024 17:57:12 +0100 Subject: [PATCH 182/185] removed unused function 'edit_shader_definitions' --- client/ayon_core/hosts/maya/api/commands.py | 19 ------------------- 1 file changed, 19 deletions(-) diff --git a/client/ayon_core/hosts/maya/api/commands.py b/client/ayon_core/hosts/maya/api/commands.py index b52d5e6c2d..f69dca97a8 100644 --- a/client/ayon_core/hosts/maya/api/commands.py +++ b/client/ayon_core/hosts/maya/api/commands.py @@ -38,25 +38,6 @@ class ToolWindows: cls._windows[tool] = window -def edit_shader_definitions(): - from qtpy import QtWidgets - from ayon_core.hosts.maya.api.shader_definition_editor import ( - ShaderDefinitionsEditor - ) - from ayon_core.tools.utils import qt_app_context - - top_level_widgets = QtWidgets.QApplication.topLevelWidgets() - main_window = next(widget for widget in top_level_widgets - if widget.objectName() == "MayaWindow") - - with qt_app_context(): - window = ToolWindows.get_window("shader_definition_editor") - if not window: - window = ShaderDefinitionsEditor(parent=main_window) - ToolWindows.set_window("shader_definition_editor", window) - window.show() - - def _resolution_from_document(doc): if not doc or "data" not in doc: print("Entered document is not valid. \"{}\"".format(str(doc))) From 73637ae363583fb2ae343982bf589d56c1339178 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Mon, 19 Feb 2024 18:06:00 +0100 Subject: [PATCH 183/185] removed plugins and script related to maya remote publish --- .../publish/collect_publishable_instances.py | 39 ------ .../submit_maya_remote_publish_deadline.py | 131 ------------------ client/ayon_core/scripts/remote_publish.py | 12 -- 3 files changed, 182 deletions(-) delete mode 100644 client/ayon_core/modules/deadline/plugins/publish/collect_publishable_instances.py delete mode 100644 client/ayon_core/modules/deadline/plugins/publish/submit_maya_remote_publish_deadline.py delete mode 100644 client/ayon_core/scripts/remote_publish.py diff --git a/client/ayon_core/modules/deadline/plugins/publish/collect_publishable_instances.py b/client/ayon_core/modules/deadline/plugins/publish/collect_publishable_instances.py deleted file mode 100644 index 347da86360..0000000000 --- a/client/ayon_core/modules/deadline/plugins/publish/collect_publishable_instances.py +++ /dev/null @@ -1,39 +0,0 @@ -# -*- coding: utf-8 -*- -"""Collect instances that should be processed and published on DL. - -""" -import os - -import pyblish.api -from ayon_core.pipeline import PublishValidationError - - -class CollectDeadlinePublishableInstances(pyblish.api.InstancePlugin): - """Collect instances that should be processed and published on DL. - - Some long running publishes (not just renders) could be offloaded to DL, - this plugin compares theirs name against env variable, marks only - publishable by farm. - - Triggered only when running only in headless mode, eg on a farm. - """ - - order = pyblish.api.CollectorOrder + 0.499 - label = "Collect Deadline Publishable Instance" - targets = ["remote"] - - def process(self, instance): - self.log.debug("CollectDeadlinePublishableInstances") - publish_inst = os.environ.get("OPENPYPE_PUBLISH_SUBSET", '') - if not publish_inst: - raise PublishValidationError("OPENPYPE_PUBLISH_SUBSET env var " - "required for remote publishing") - - subset_name = instance.data["subset"] - if subset_name == publish_inst: - self.log.debug("Publish {}".format(subset_name)) - instance.data["publish"] = True - instance.data["farm"] = False - else: - self.log.debug("Skipping {}".format(subset_name)) - instance.data["publish"] = False diff --git a/client/ayon_core/modules/deadline/plugins/publish/submit_maya_remote_publish_deadline.py b/client/ayon_core/modules/deadline/plugins/publish/submit_maya_remote_publish_deadline.py deleted file mode 100644 index 1042c44c33..0000000000 --- a/client/ayon_core/modules/deadline/plugins/publish/submit_maya_remote_publish_deadline.py +++ /dev/null @@ -1,131 +0,0 @@ -import os -import attr -from datetime import datetime - -from ayon_core.pipeline import PublishXmlValidationError -from ayon_core.lib import is_in_tests -from openpype_modules.deadline import abstract_submit_deadline -from openpype_modules.deadline.abstract_submit_deadline import DeadlineJobInfo - -import pyblish.api - - -@attr.s -class MayaPluginInfo(object): - Build = attr.ib(default=None) # Don't force build - StrictErrorChecking = attr.ib(default=True) - - SceneFile = attr.ib(default=None) # Input scene - Version = attr.ib(default=None) # Mandatory for Deadline - ProjectPath = attr.ib(default=None) - - ScriptJob = attr.ib(default=True) - ScriptFilename = attr.ib(default=None) - - -class MayaSubmitRemotePublishDeadline( - abstract_submit_deadline.AbstractSubmitDeadline): - """Submit Maya scene to perform a local publish in Deadline. - - Publishing in Deadline can be helpful for scenes that publish very slow. - This way it can process in the background on another machine without the - Artist having to wait for the publish to finish on their local machine. - - Submission is done through the Deadline Web Service. DL then triggers - `openpype/scripts/remote_publish.py`. - - Each publishable instance creates its own full publish job. - - Different from `ProcessSubmittedJobOnFarm` which creates publish job - depending on metadata json containing context and instance data of - rendered files. - """ - - label = "Submit Scene to Deadline" - order = pyblish.api.IntegratorOrder - hosts = ["maya"] - families = ["publish.farm"] - targets = ["local"] - - def process(self, instance): - - # Ensure no errors so far - if not (all(result["success"] - for result in instance.context.data["results"])): - raise PublishXmlValidationError("Publish process has errors") - - if not instance.data["publish"]: - self.log.warning("No active instances found. " - "Skipping submission..") - return - - super(MayaSubmitRemotePublishDeadline, self).process(instance) - - def get_job_info(self): - instance = self._instance - context = instance.context - - project_name = instance.context.data["projectName"] - scene = instance.context.data["currentFile"] - scenename = os.path.basename(scene) - - job_name = "{scene} [PUBLISH]".format(scene=scenename) - batch_name = "{code} - {scene}".format(code=project_name, - scene=scenename) - - if is_in_tests(): - batch_name += datetime.now().strftime("%d%m%Y%H%M%S") - - job_info = DeadlineJobInfo(Plugin="MayaBatch") - job_info.BatchName = batch_name - job_info.Name = job_name - job_info.UserName = context.data.get("user") - job_info.Comment = context.data.get("comment", "") - - # use setting for publish job on farm, no reason to have it separately - project_settings = context.data["project_settings"] - deadline_publish_job_sett = project_settings["deadline"]["publish"]["ProcessSubmittedJobOnFarm"] # noqa - job_info.Department = deadline_publish_job_sett["deadline_department"] - job_info.ChunkSize = deadline_publish_job_sett["deadline_chunk_size"] - job_info.Priority = deadline_publish_job_sett["deadline_priority"] - job_info.Group = deadline_publish_job_sett["deadline_group"] - job_info.Pool = deadline_publish_job_sett["deadline_pool"] - - # Include critical environment variables with submission + Session - keys = [ - "FTRACK_API_USER", - "FTRACK_API_KEY", - "FTRACK_SERVER" - ] - - environment = { - key: os.environ[key] - for key in keys - if key in os.environ - } - - environment["AYON_PROJECT_NAME"] = project_name - environment["AYON_FOLDER_PATH"] = instance.context.data["asset"] - environment["AYON_TASK_NAME"] = instance.context.data["task"] - environment["AYON_APP_NAME"] = os.environ.get("AYON_APP_NAME") - environment["OPENPYPE_PUBLISH_SUBSET"] = instance.data["subset"] - environment["AYON_LOG_NO_COLORS"] = "1" - environment["AYON_USERNAME"] = instance.context.data["user"] - environment["AYON_REMOTE_PUBLISH"] = "1" - - for key, value in environment.items(): - job_info.EnvironmentKeyValue[key] = value - - def get_plugin_info(self): - # Not all hosts can import this module. - from maya import cmds - scene = self._instance.context.data["currentFile"] - - plugin_info = MayaPluginInfo() - plugin_info.SceneFile = scene - plugin_info.ScriptFilename = "{OPENPYPE_REPOS_ROOT}/openpype/scripts/remote_publish.py" # noqa - plugin_info.Version = cmds.about(version=True) - plugin_info.ProjectPath = cmds.workspace(query=True, - rootDirectory=True) - - return attr.asdict(plugin_info) diff --git a/client/ayon_core/scripts/remote_publish.py b/client/ayon_core/scripts/remote_publish.py deleted file mode 100644 index 7e7bf2493b..0000000000 --- a/client/ayon_core/scripts/remote_publish.py +++ /dev/null @@ -1,12 +0,0 @@ -try: - from ayon_core.lib import Logger - from ayon_core.pipeline.publish.lib import remote_publish -except ImportError as exc: - # Ensure Deadline fails by output an error that contains "Fatal Error:" - raise ImportError("Fatal Error: %s" % exc) - - -if __name__ == "__main__": - # Perform remote publish with thorough error checking - log = Logger.get_logger(__name__) - remote_publish(log) From 5bb00e43717c1d736875a94aad668efb183c3cfd Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Mon, 19 Feb 2024 18:06:16 +0100 Subject: [PATCH 184/185] removed 'remote_publish' function from publish lib --- client/ayon_core/pipeline/publish/lib.py | 20 -------------------- 1 file changed, 20 deletions(-) diff --git a/client/ayon_core/pipeline/publish/lib.py b/client/ayon_core/pipeline/publish/lib.py index 90725e6d79..7d980b4bbe 100644 --- a/client/ayon_core/pipeline/publish/lib.py +++ b/client/ayon_core/pipeline/publish/lib.py @@ -485,26 +485,6 @@ def filter_pyblish_plugins(plugins): plugins.remove(plugin) -def remote_publish(log): - """Loops through all plugins, logs to console. Used for tests. - - Args: - log (Logger) - """ - - # Error exit as soon as any error occurs. - error_format = "Failed {plugin.__name__}: {error}\n{error.traceback}" - - for result in pyblish.util.publish_iter(): - if not result["error"]: - continue - - error_message = error_format.format(**result) - log.error(error_message) - # 'Fatal Error: ' is because of Deadline - raise RuntimeError("Fatal Error: {}".format(error_message)) - - def get_errored_instances_from_context(context, plugin=None): """Collect failed instances from pyblish context. From b938fe4220a4cd878342183309ff0fff16afdae8 Mon Sep 17 00:00:00 2001 From: Toke Stuart Jepsen Date: Tue, 20 Feb 2024 10:45:44 +0000 Subject: [PATCH 185/185] Remove validate model plugin --- .../plugins/publish/validate_model_name.py | 153 ------------------ 1 file changed, 153 deletions(-) delete mode 100644 client/ayon_core/hosts/maya/plugins/publish/validate_model_name.py diff --git a/client/ayon_core/hosts/maya/plugins/publish/validate_model_name.py b/client/ayon_core/hosts/maya/plugins/publish/validate_model_name.py deleted file mode 100644 index 0d27965971..0000000000 --- a/client/ayon_core/hosts/maya/plugins/publish/validate_model_name.py +++ /dev/null @@ -1,153 +0,0 @@ -# -*- coding: utf-8 -*- -"""Validate model nodes names.""" -import os -import platform -import re - -import pyblish.api -from maya import cmds - -import ayon_core.hosts.maya.api.action -from ayon_core.pipeline.publish import ( - OptionalPyblishPluginMixin, - PublishValidationError, - ValidateContentsOrder, -) - - -class ValidateModelName(pyblish.api.InstancePlugin, - OptionalPyblishPluginMixin): - """Validate name of model - - starts with (somename)_###_(materialID)_GEO - materialID must be present in list - padding number doesn't have limit - - """ - optional = True - order = ValidateContentsOrder - hosts = ["maya"] - families = ["model"] - label = "Model Name" - actions = [ayon_core.hosts.maya.api.action.SelectInvalidAction] - - material_file = { - "windows": None, - "darwin": None, - "linux": None, - } - - @classmethod - def get_invalid(cls, instance): - """Get invalid nodes.""" - - def is_group(group_name): - """Find out if supplied transform is group or not.""" - try: - children = cmds.listRelatives(group_name, children=True) - for child in children: - if not cmds.ls(child, transforms=True): - return False - return True - except Exception: - return False - - invalid = [] - content_instance = instance.data.get("setMembers", None) - if not content_instance: - cls.log.error("Instance has no nodes!") - return True - pass - - # validate top level group name - assemblies = cmds.ls(content_instance, assemblies=True, long=True) - if len(assemblies) != 1: - cls.log.error("Must have exactly one top group") - return assemblies or True - top_group = assemblies[0] - regex = cls.top_level_regex - r = re.compile(regex) - m = r.match(top_group) - project_name = instance.context.data["projectName"] - current_asset_name = instance.context.data["asset"] - if m is None: - cls.log.error("invalid name on: {}".format(top_group)) - cls.log.error("name doesn't match regex {}".format(regex)) - invalid.append(top_group) - else: - if "asset" in r.groupindex: - if m.group("asset") != current_asset_name: - cls.log.error("Invalid asset name in top level group.") - return top_group - if "subset" in r.groupindex: - if m.group("subset") != instance.data.get("subset"): - cls.log.error("Invalid subset name in top level group.") - return top_group - if "project" in r.groupindex: - if m.group("project") != project_name: - cls.log.error("Invalid project name in top level group.") - return top_group - - descendants = cmds.listRelatives(content_instance, - allDescendents=True, - fullPath=True) or [] - - descendants = cmds.ls(descendants, noIntermediate=True, long=True) - trns = cmds.ls(descendants, long=False, type='transform') - - # filter out groups - filtered = [node for node in trns if not is_group(node)] - - # load shader list file as utf-8 - shaders = [] - material_file = cls.material_file[platform.system().lower()] - if material_file: - if os.path.isfile(material_file): - shader_file = open(material_file, "r") - shaders = shader_file.readlines() - shader_file.close() - else: - cls.log.error("Missing shader name definition file.") - return True - - # strip line endings from list - shaders = [s.rstrip() for s in shaders if s.rstrip()] - - # compile regex for testing names - regex = cls.regex - r = re.compile(regex) - - for obj in filtered: - cls.log.debug("testing: {}".format(obj)) - m = r.match(obj) - if m is None: - cls.log.error("invalid name on: {}".format(obj)) - invalid.append(obj) - else: - # if we have shader files and shader named group is in - # regex, test this group against names in shader file - if "shader" in r.groupindex and shaders: - try: - if not m.group('shader') in shaders: - cls.log.error( - "invalid materialID on: {0} ({1})".format( - obj, m.group('shader'))) - invalid.append(obj) - except IndexError: - # shader named group doesn't match - cls.log.error( - "shader group doesn't match: {}".format(obj)) - invalid.append(obj) - - return invalid - - def process(self, instance): - """Plugin entry point.""" - if not self.is_active(instance.data): - return - - invalid = self.get_invalid(instance) - - if invalid: - raise PublishValidationError( - "Model naming is invalid. See the log.")