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*/**/*' diff --git a/client/ayon_core/hosts/aftereffects/api/launch_logic.py b/client/ayon_core/hosts/aftereffects/api/launch_logic.py index 8c54908fe5..0d1a6cf585 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/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/hosts/maya/api/lib.py b/client/ayon_core/hosts/maya/api/lib.py index 7b791c3d51..324ef28ab5 100644 --- a/client/ayon_core/hosts/maya/api/lib.py +++ b/client/ayon_core/hosts/maya/api/lib.py @@ -3140,119 +3140,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 update_content_on_context_change(): """ This will update scene content to match new asset on context change diff --git a/client/ayon_core/hosts/maya/api/menu.py b/client/ayon_core/hosts/maya/api/menu.py index 7478739496..70347e91b6 100644 --- a/client/ayon_core/hosts/maya/api/menu.py +++ b/client/ayon_core/hosts/maya/api/menu.py @@ -9,7 +9,8 @@ import maya.cmds as cmds from ayon_core.pipeline import ( get_current_asset_name, - get_current_task_name + get_current_task_name, + registered_host ) from ayon_core.pipeline.workfile import BuildWorkfile from ayon_core.tools.utils import host_tools @@ -21,8 +22,10 @@ from .workfile_template_builder import ( create_placeholder, update_placeholder, build_workfile_template, - update_workfile_template, + update_workfile_template ) +from ayon_core.tools.workfile_template_build import open_template_ui +from .workfile_template_builder import MayaTemplateBuilder log = logging.getLogger(__name__) @@ -167,16 +170,6 @@ def install(project_settings): 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, @@ -187,6 +180,27 @@ def install(project_settings): parent=builder_menu, command=update_workfile_template ) + cmds.menuItem( + divider=True, + parent=builder_menu + ) + cmds.menuItem( + "Open Template", + parent=builder_menu, + command=lambda *args: open_template_ui( + MayaTemplateBuilder(registered_host()), get_main_window() + ), + ) + 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/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): diff --git a/client/ayon_core/hosts/maya/startup/userSetup.py b/client/ayon_core/hosts/maya/startup/userSetup.py index 22b776915c..adbbfe4f44 100644 --- a/client/ayon_core/hosts/maya/startup/userSetup.py +++ b/client/ayon_core/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.") diff --git a/client/ayon_core/hosts/nuke/api/pipeline.py b/client/ayon_core/hosts/nuke/api/pipeline.py index bdba0757b6..92b44428a0 100644 --- a/client/ayon_core/hosts/nuke/api/pipeline.py +++ b/client/ayon_core/hosts/nuke/api/pipeline.py @@ -21,10 +21,12 @@ from ayon_core.pipeline import ( AVALON_CONTAINER_ID, get_current_asset_name, get_current_task_name, + registered_host, ) from ayon_core.pipeline.workfile import BuildWorkfile from ayon_core.tools.utils import host_tools from ayon_core.hosts.nuke import NUKE_ROOT_DIR +from ayon_core.tools.workfile_template_build import open_template_ui from .command import viewer_update_and_undo_stop from .lib import ( @@ -55,6 +57,7 @@ from .workfile_template_builder import ( build_workfile_template, create_placeholder, update_placeholder, + NukeTemplateBuilder, ) from .workio import ( open_file, @@ -313,7 +316,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() @@ -321,6 +324,12 @@ def _install_menu(): if not ASSIST: menu_template.addSeparator() + menu_template.addCommand( + "Open template", + lambda: open_template_ui( + NukeTemplateBuilder(registered_host()), get_main_window() + ) + ) menu_template.addCommand( "Create Place Holder", lambda: create_placeholder() diff --git a/client/ayon_core/hosts/nuke/api/workfile_template_builder.py b/client/ayon_core/hosts/nuke/api/workfile_template_builder.py index 4c15da983e..218ba97dd5 100644 --- a/client/ayon_core/hosts/nuke/api/workfile_template_builder.py +++ b/client/ayon_core/hosts/nuke/api/workfile_template_builder.py @@ -7,7 +7,7 @@ from ayon_core.pipeline.workfile.workfile_template_builder import ( LoadPlaceholderItem, CreatePlaceholderItem, PlaceholderLoadMixin, - PlaceholderCreateMixin + PlaceholderCreateMixin, ) from ayon_core.tools.workfile_template_build import ( WorkfileBuildPlaceholderDialog, 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 0ed891c8cf..464b6e3999 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/lib/__init__.py b/client/ayon_core/lib/__init__.py index 12a5535a1c..ab6a604adc 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, ) @@ -229,6 +230,8 @@ __all__ = [ "IniSettingRegistry", "JSONSettingRegistry", + "AYONSecureRegistry", + "AYONSettingsRegistry", "OpenPypeSecureRegistry", "OpenPypeSettingsRegistry", "get_local_site_id", @@ -271,6 +274,7 @@ __all__ = [ "terminal", "get_datetime_data", + "get_timestamp", "get_formatted_current_time", "Logger", @@ -278,6 +282,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. 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 a4eb5b673c..3537c3099d 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 e9e6ef083d..ae19e63a37 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 d3915ed16d..beb8afc3a3 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 f6676da3d6..94e0947952 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 436f0d70ad..45209d00f6 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 1b86d74987..d01c344321 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 08ddbcf661..1042c44c33 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 f48f9ba9b7..26606cadfd 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 522f19604b..54d4fb47fc 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 35b54d40ca..299babdc0e 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 2b26ec82e4..5343a5f06f 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 5716793354..730852ff4a 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/pipeline/workfile/workfile_template_builder.py b/client/ayon_core/pipeline/workfile/workfile_template_builder.py index 9778e60d1b..3004e55861 100644 --- a/client/ayon_core/pipeline/workfile/workfile_template_builder.py +++ b/client/ayon_core/pipeline/workfile/workfile_template_builder.py @@ -553,6 +553,12 @@ class AbstractTemplateBuilder(object): self.clear_shared_populate_data() + def open_template(self): + """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/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_from_create_context.py b/client/ayon_core/plugins/publish/collect_from_create_context.py index edb5cc1654..66ca5745b2 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): ("AYON_FOLDER_PATH", asset_name), ("AYON_TASK_NAME", task_name) ): - os.environ[key] = value + if value is None: + os.environ.pop(key, None) + else: + os.environ[key] = value def create_instance( self, 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 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": { 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 diff --git a/client/ayon_core/tools/workfile_template_build/__init__.py b/client/ayon_core/tools/workfile_template_build/__init__.py index 82a22aea50..ad94ebcf79 100644 --- a/client/ayon_core/tools/workfile_template_build/__init__.py +++ b/client/ayon_core/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/client/ayon_core/tools/workfile_template_build/lib.py b/client/ayon_core/tools/workfile_template_build/lib.py new file mode 100644 index 0000000000..de3a0d0084 --- /dev/null +++ b/client/ayon_core/tools/workfile_template_build/lib.py @@ -0,0 +1,28 @@ +import traceback + +from qtpy import QtWidgets + +from ayon_core.tools.utils.dialogs import show_message_dialog + + +def open_template_ui(builder, main_window): + """Open template from `builder` + + Asks user about overwriting current scene and feedsback exceptions. + """ + 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 == QtWidgets.QMessageBox.Yes: + try: + builder.open_template() + except Exception: + show_message_dialog( + title="Template Load Failed", + message="".join(traceback.format_exc()), + parent=main_window, + level="critical" + ) 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"