From 7c705eded6c715d478dfccbc796c107fdeb0fa9b Mon Sep 17 00:00:00 2001 From: "clement.hector" Date: Tue, 9 May 2023 15:53:38 +0200 Subject: [PATCH 01/30] 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 02/30] 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 03/30] 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 04/30] 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 05/30] 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 06/30] 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 07/30] 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 08/30] 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 09/30] 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 10/30] 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 11/30] 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 12/30] 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 13/30] 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 14/30] 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 15/30] 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 16/30] 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 b58917fefa0940ce3500446d2b25d84c85433bd8 Mon Sep 17 00:00:00 2001 From: Toke Jepsen Date: Mon, 5 Feb 2024 08:17:25 +0000 Subject: [PATCH 17/30] 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 4e76c9f5dc9282fa65c97faeaf3598f5b9f5e07b Mon Sep 17 00:00:00 2001 From: Toke Stuart Jepsen Date: Fri, 9 Feb 2024 08:16:23 +0000 Subject: [PATCH 18/30] 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 6538f5b75d96545d0e0089663f2a6c7454b9e2b1 Mon Sep 17 00:00:00 2001 From: Toke Jepsen Date: Fri, 9 Feb 2024 09:05:31 +0000 Subject: [PATCH 19/30] 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 20/30] 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 0057e4509f4e476a459e3ffd9f9ed1b9acb095e7 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Mon, 12 Feb 2024 15:25:05 +0100 Subject: [PATCH 21/30] 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 22/30] 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 9caab106f782fb2d520da55af995111b77f73496 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Mon, 12 Feb 2024 16:26:10 +0100 Subject: [PATCH 23/30] 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 24/30] 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 daf8228e9a2db00cbe8cb03b05078850e7cdde8e Mon Sep 17 00:00:00 2001 From: Braden Jennings Date: Tue, 13 Feb 2024 10:00:12 +1300 Subject: [PATCH 25/30] 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 2c93caebbff89ce5ae7d9a40a286e972ff733c7c Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Mon, 12 Feb 2024 23:02:52 +0100 Subject: [PATCH 26/30] 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 0fb5c68ee8940f4ebb6d7dc4e54ea30b103cc8f8 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Tue, 13 Feb 2024 11:31:41 +0100 Subject: [PATCH 27/30] 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 28/30] 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 29/30] 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 30/30] 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",