diff --git a/openpype/cli.py b/openpype/cli.py index f0fe550a1f..8caa139765 100644 --- a/openpype/cli.py +++ b/openpype/cli.py @@ -296,12 +296,15 @@ def run(script): @click.option("--mongo_url", help="MongoDB for testing.", default=None) +@click.option("--dump_databases", + help="Dump all databases to data folder.", + default=None) def runtests(folder, mark, pyargs, test_data_folder, persist, app_variant, - timeout, setup_only, mongo_url, app_group): + timeout, setup_only, mongo_url, app_group, dump_databases): """Run all automatic tests after proper initialization via start.py""" PypeCommands().run_tests(folder, mark, pyargs, test_data_folder, persist, app_variant, timeout, setup_only, - mongo_url, app_group) + mongo_url, app_group, dump_databases) @main.command(help="DEPRECATED - run sync server") diff --git a/openpype/hosts/aftereffects/api/README.md b/openpype/hosts/aftereffects/api/README.md index 9c4bad3689..790c9f859a 100644 --- a/openpype/hosts/aftereffects/api/README.md +++ b/openpype/hosts/aftereffects/api/README.md @@ -1,6 +1,6 @@ # AfterEffects Integration -Requirements: This extension requires use of Javascript engine, which is +Requirements: This extension requires use of Javascript engine, which is available since CC 16.0. Please check your File>Project Settings>Expressions>Expressions Engine @@ -13,28 +13,26 @@ The After Effects integration requires two components to work; `extension` and ` To install the extension download [Extension Manager Command Line tool (ExManCmd)](https://github.com/Adobe-CEP/Getting-Started-guides/tree/master/Package%20Distribute%20Install#option-2---exmancmd). ``` -ExManCmd /install {path to addon}/api/extension.zxp +ExManCmd /install {path to avalon-core}\avalon\photoshop\extension.zxp ``` OR download [Anastasiy’s Extension Manager](https://install.anastasiy.com/) -`{path to addon}` will be most likely in your AppData (on Windows, in your user data folder in Linux and MacOS.) - ### Server The easiest way to get the server and After Effects launch is with: ``` -python -c ^"import openpype.hosts.photoshop;openpype.hosts..aftereffects.launch(""c:\Program Files\Adobe\Adobe After Effects 2020\Support Files\AfterFX.exe"")^" +python -c ^"import avalon.photoshop;avalon.aftereffects.launch(""c:\Program Files\Adobe\Adobe After Effects 2020\Support Files\AfterFX.exe"")^" ``` `avalon.aftereffects.launch` launches the application and server, and also closes the server when After Effects exists. ## Usage -The After Effects extension can be found under `Window > Extensions > AYON`. Once launched you should be presented with a panel like this: +The After Effects extension can be found under `Window > Extensions > OpenPype`. Once launched you should be presented with a panel like this: -![Ayon Panel](panel.png "Ayon Panel") +![Avalon Panel](panel.PNG "Avalon Panel") ## Developing @@ -45,8 +43,8 @@ When developing the extension you can load it [unsigned](https://github.com/Adob When signing the extension you can use this [guide](https://github.com/Adobe-CEP/Getting-Started-guides/tree/master/Package%20Distribute%20Install#package-distribute-install-guide). ``` -ZXPSignCmd -selfSignedCert NA NA Ayon Avalon-After-Effects Ayon extension.p12 -ZXPSignCmd -sign {path to addon}/api/extension {path to addon}/api/extension.zxp extension.p12 Ayon +ZXPSignCmd -selfSignedCert NA NA Avalon Avalon-After-Effects avalon extension.p12 +ZXPSignCmd -sign {path to avalon-core}\avalon\aftereffects\extension {path to avalon-core}\avalon\aftereffects\extension.zxp extension.p12 avalon ``` ### Plugin Examples @@ -54,14 +52,14 @@ ZXPSignCmd -sign {path to addon}/api/extension {path to addon}/api/extension.zxp These plugins were made with the [polly config](https://github.com/mindbender-studio/config). To fully integrate and load, you will have to use this config and add `image` to the [integration plugin](https://github.com/mindbender-studio/config/blob/master/polly/plugins/publish/integrate_asset.py). Expected deployed extension location on default Windows: -`c:\Program Files (x86)\Common Files\Adobe\CEP\extensions\io.ynput.AE.panel` +`c:\Program Files (x86)\Common Files\Adobe\CEP\extensions\com.openpype.AE.panel` For easier debugging of Javascript: https://community.adobe.com/t5/download-install/adobe-extension-debuger-problem/td-p/10911704?page=1 Add (optional) --enable-blink-features=ShadowDOMV0,CustomElementsV0 when starting Chrome then localhost:8092 -Or use Visual Studio Code https://medium.com/adobetech/extendscript-debugger-for-visual-studio-code-public-release-a2ff6161fa01 +Or use Visual Studio Code https://medium.com/adobetech/extendscript-debugger-for-visual-studio-code-public-release-a2ff6161fa01 ## Resources - https://javascript-tools-guide.readthedocs.io/introduction/index.html - https://github.com/Adobe-CEP/Getting-Started-guides diff --git a/openpype/hosts/aftereffects/api/extension.zxp b/openpype/hosts/aftereffects/api/extension.zxp index 104a5c9e99..933dc7dc6c 100644 Binary files a/openpype/hosts/aftereffects/api/extension.zxp and b/openpype/hosts/aftereffects/api/extension.zxp differ diff --git a/openpype/hosts/aftereffects/api/extension/.debug b/openpype/hosts/aftereffects/api/extension/.debug index 20a6713ab2..b06ec515dd 100644 --- a/openpype/hosts/aftereffects/api/extension/.debug +++ b/openpype/hosts/aftereffects/api/extension/.debug @@ -1,31 +1,32 @@ - + - + - + - + - + - + - + - + - + - + + \ No newline at end of file diff --git a/openpype/hosts/aftereffects/api/extension/CSXS/manifest.xml b/openpype/hosts/aftereffects/api/extension/CSXS/manifest.xml index cf6ba67f44..7329a9e723 100644 --- a/openpype/hosts/aftereffects/api/extension/CSXS/manifest.xml +++ b/openpype/hosts/aftereffects/api/extension/CSXS/manifest.xml @@ -1,8 +1,8 @@ - + - + @@ -38,7 +38,7 @@ - + ./index.html @@ -49,7 +49,7 @@ Panel - AYON + OpenPype 200 @@ -66,7 +66,7 @@ - ./icons/ayon_logo.png + ./icons/iconNormal.png ./icons/iconRollover.png ./icons/iconDisabled.png ./icons/iconDarkNormal.png diff --git a/openpype/hosts/aftereffects/api/extension/icons/ayon_logo.png b/openpype/hosts/aftereffects/api/extension/icons/ayon_logo.png deleted file mode 100644 index 3a96f8e2b4..0000000000 Binary files a/openpype/hosts/aftereffects/api/extension/icons/ayon_logo.png and /dev/null differ diff --git a/openpype/hosts/photoshop/api/panel.png b/openpype/hosts/aftereffects/api/panel.PNG similarity index 100% rename from openpype/hosts/photoshop/api/panel.png rename to openpype/hosts/aftereffects/api/panel.PNG diff --git a/openpype/hosts/aftereffects/api/panel.png b/openpype/hosts/aftereffects/api/panel.png deleted file mode 100644 index d05ed35428..0000000000 Binary files a/openpype/hosts/aftereffects/api/panel.png and /dev/null differ diff --git a/openpype/hosts/aftereffects/api/panel_failure.PNG b/openpype/hosts/aftereffects/api/panel_failure.PNG new file mode 100644 index 0000000000..67afc4e212 Binary files /dev/null and b/openpype/hosts/aftereffects/api/panel_failure.PNG differ diff --git a/openpype/hosts/aftereffects/api/panel_failure.png b/openpype/hosts/aftereffects/api/panel_failure.png deleted file mode 100644 index 6e52a77d22..0000000000 Binary files a/openpype/hosts/aftereffects/api/panel_failure.png and /dev/null differ diff --git a/openpype/hosts/houdini/startup/python2.7libs/pythonrc.py b/openpype/hosts/houdini/startup/python2.7libs/pythonrc.py index 683ea6721c..0b92fc2706 100644 --- a/openpype/hosts/houdini/startup/python2.7libs/pythonrc.py +++ b/openpype/hosts/houdini/startup/python2.7libs/pythonrc.py @@ -2,10 +2,12 @@ """OpenPype startup script.""" from openpype.pipeline import install_host from openpype.hosts.houdini.api import HoudiniHost +from openpype import AYON_SERVER_ENABLED def main(): - print("Installing OpenPype ...") + print("Installing {} ...".format( + "AYON" if AYON_SERVER_ENABLED else "OpenPype")) install_host(HoudiniHost()) diff --git a/openpype/hosts/houdini/startup/python3.10libs/pythonrc.py b/openpype/hosts/houdini/startup/python3.10libs/pythonrc.py index 683ea6721c..0b92fc2706 100644 --- a/openpype/hosts/houdini/startup/python3.10libs/pythonrc.py +++ b/openpype/hosts/houdini/startup/python3.10libs/pythonrc.py @@ -2,10 +2,12 @@ """OpenPype startup script.""" from openpype.pipeline import install_host from openpype.hosts.houdini.api import HoudiniHost +from openpype import AYON_SERVER_ENABLED def main(): - print("Installing OpenPype ...") + print("Installing {} ...".format( + "AYON" if AYON_SERVER_ENABLED else "OpenPype")) install_host(HoudiniHost()) diff --git a/openpype/hosts/houdini/startup/python3.7libs/pythonrc.py b/openpype/hosts/houdini/startup/python3.7libs/pythonrc.py index 683ea6721c..0b92fc2706 100644 --- a/openpype/hosts/houdini/startup/python3.7libs/pythonrc.py +++ b/openpype/hosts/houdini/startup/python3.7libs/pythonrc.py @@ -2,10 +2,12 @@ """OpenPype startup script.""" from openpype.pipeline import install_host from openpype.hosts.houdini.api import HoudiniHost +from openpype import AYON_SERVER_ENABLED def main(): - print("Installing OpenPype ...") + print("Installing {} ...".format( + "AYON" if AYON_SERVER_ENABLED else "OpenPype")) install_host(HoudiniHost()) diff --git a/openpype/hosts/houdini/startup/python3.9libs/pythonrc.py b/openpype/hosts/houdini/startup/python3.9libs/pythonrc.py index 683ea6721c..0b92fc2706 100644 --- a/openpype/hosts/houdini/startup/python3.9libs/pythonrc.py +++ b/openpype/hosts/houdini/startup/python3.9libs/pythonrc.py @@ -2,10 +2,12 @@ """OpenPype startup script.""" from openpype.pipeline import install_host from openpype.hosts.houdini.api import HoudiniHost +from openpype import AYON_SERVER_ENABLED def main(): - print("Installing OpenPype ...") + print("Installing {} ...".format( + "AYON" if AYON_SERVER_ENABLED else "OpenPype")) install_host(HoudiniHost()) diff --git a/openpype/hosts/maya/plugins/load/load_image.py b/openpype/hosts/maya/plugins/load/load_image.py index 3b1f5442ce..27c9ec7118 100644 --- a/openpype/hosts/maya/plugins/load/load_image.py +++ b/openpype/hosts/maya/plugins/load/load_image.py @@ -9,7 +9,7 @@ from openpype.pipeline import ( ) from openpype.pipeline.load.utils import get_representation_path_from_context from openpype.pipeline.colorspace import ( - get_imageio_colorspace_from_filepath, + get_imageio_file_rules_colorspace_from_filepath, get_imageio_config, get_imageio_file_rules ) @@ -285,10 +285,10 @@ class FileNodeLoader(load.LoaderPlugin): ) path = get_representation_path_from_context(context) - colorspace = get_imageio_colorspace_from_filepath( - path=path, - host_name=host_name, - project_name=project_name, + colorspace = get_imageio_file_rules_colorspace_from_filepath( + path, + host_name, + project_name, config_data=config_data, file_rules=file_rules, project_settings=project_settings diff --git a/openpype/hosts/maya/plugins/publish/validate_rendersettings.py b/openpype/hosts/maya/plugins/publish/validate_rendersettings.py index 3409b4ec91..f2a98eab32 100644 --- a/openpype/hosts/maya/plugins/publish/validate_rendersettings.py +++ b/openpype/hosts/maya/plugins/publish/validate_rendersettings.py @@ -371,7 +371,6 @@ class ValidateRenderSettings(pyblish.api.InstancePlugin): continue for node in data["nodes"]: lib.set_attribute(data["attribute"], data["values"][0], node) - with lib.renderlayer(layer_node): # Repair animation must be enabled @@ -392,13 +391,11 @@ class ValidateRenderSettings(pyblish.api.InstancePlugin): if renderer != "renderman": prefix_attr = RenderSettings.get_image_prefix_attr(renderer) fname_prefix = default_prefix - cmds.setAttr("{}.{}".format(node, prefix_attr), - fname_prefix, type="string") + cmds.setAttr(prefix_attr, fname_prefix, type="string") # Repair padding padding_attr = RenderSettings.get_padding_attr(renderer) - cmds.setAttr("{}.{}".format(node, padding_attr), - cls.DEFAULT_PADDING) + cmds.setAttr(padding_attr, cls.DEFAULT_PADDING) else: # renderman handles stuff differently cmds.setAttr("rmanGlobals.imageFileFormat", diff --git a/openpype/hosts/photoshop/api/README.md b/openpype/hosts/photoshop/api/README.md index a207d21f2f..7bd2bcb1bf 100644 --- a/openpype/hosts/photoshop/api/README.md +++ b/openpype/hosts/photoshop/api/README.md @@ -9,7 +9,7 @@ The Photoshop integration requires two components to work; `extension` and `serv To install the extension download [Extension Manager Command Line tool (ExManCmd)](https://github.com/Adobe-CEP/Getting-Started-guides/tree/master/Package%20Distribute%20Install#option-2---exmancmd). ``` -ExManCmd /install {path to addon}/api/extension.zxp +ExManCmd /install {path to avalon-core}\avalon\photoshop\extension.zxp ``` ### Server @@ -17,16 +17,16 @@ ExManCmd /install {path to addon}/api/extension.zxp The easiest way to get the server and Photoshop launch is with: ``` -python -c ^"import openpype.hosts.photoshop;openpype.hosts.photoshop.launch(""C:\Program Files\Adobe\Adobe Photoshop 2020\Photoshop.exe"")^" +python -c ^"import avalon.photoshop;avalon.photoshop.launch(""C:\Program Files\Adobe\Adobe Photoshop 2020\Photoshop.exe"")^" ``` `avalon.photoshop.launch` launches the application and server, and also closes the server when Photoshop exists. ## Usage -The Photoshop extension can be found under `Window > Extensions > Ayon`. Once launched you should be presented with a panel like this: +The Photoshop extension can be found under `Window > Extensions > Avalon`. Once launched you should be presented with a panel like this: -![Ayon Panel](panel.png "AYON Panel") +![Avalon Panel](panel.PNG "Avalon Panel") ## Developing @@ -37,7 +37,7 @@ When developing the extension you can load it [unsigned](https://github.com/Adob When signing the extension you can use this [guide](https://github.com/Adobe-CEP/Getting-Started-guides/tree/master/Package%20Distribute%20Install#package-distribute-install-guide). ``` -ZXPSignCmd -selfSignedCert NA NA Ayon Ayon-Photoshop Ayon extension.p12 +ZXPSignCmd -selfSignedCert NA NA Avalon Avalon-Photoshop avalon extension.p12 ZXPSignCmd -sign {path to avalon-core}\avalon\photoshop\extension {path to avalon-core}\avalon\photoshop\extension.zxp extension.p12 avalon ``` diff --git a/openpype/hosts/photoshop/api/extension.zxp b/openpype/hosts/photoshop/api/extension.zxp index 26a73a37fd..39b766cd0d 100644 Binary files a/openpype/hosts/photoshop/api/extension.zxp and b/openpype/hosts/photoshop/api/extension.zxp differ diff --git a/openpype/hosts/photoshop/api/extension/.debug b/openpype/hosts/photoshop/api/extension/.debug index 4cea03cb41..a0e2f3c9e0 100644 --- a/openpype/hosts/photoshop/api/extension/.debug +++ b/openpype/hosts/photoshop/api/extension/.debug @@ -1,9 +1,9 @@ - + - + \ No newline at end of file diff --git a/openpype/hosts/photoshop/api/extension/CSXS/manifest.xml b/openpype/hosts/photoshop/api/extension/CSXS/manifest.xml index 16d85be9b4..2089d06da1 100644 --- a/openpype/hosts/photoshop/api/extension/CSXS/manifest.xml +++ b/openpype/hosts/photoshop/api/extension/CSXS/manifest.xml @@ -1,7 +1,7 @@ - + - + @@ -16,7 +16,7 @@ - + ./index.html @@ -32,7 +32,7 @@ Panel - AYON + OpenPype 300 @@ -44,7 +44,7 @@ - ./icons/ayon_logo.png + ./icons/avalon-logo-48.png diff --git a/openpype/hosts/photoshop/api/extension/icons/avalon-logo-48.png b/openpype/hosts/photoshop/api/extension/icons/avalon-logo-48.png new file mode 100644 index 0000000000..33fe2a606b Binary files /dev/null and b/openpype/hosts/photoshop/api/extension/icons/avalon-logo-48.png differ diff --git a/openpype/hosts/photoshop/api/extension/icons/ayon_logo.png b/openpype/hosts/photoshop/api/extension/icons/ayon_logo.png deleted file mode 100644 index 3a96f8e2b4..0000000000 Binary files a/openpype/hosts/photoshop/api/extension/icons/ayon_logo.png and /dev/null differ diff --git a/openpype/hosts/photoshop/api/panel.PNG b/openpype/hosts/photoshop/api/panel.PNG new file mode 100644 index 0000000000..be5db3b8df Binary files /dev/null and b/openpype/hosts/photoshop/api/panel.PNG differ diff --git a/openpype/hosts/photoshop/api/panel_failure.PNG b/openpype/hosts/photoshop/api/panel_failure.PNG new file mode 100644 index 0000000000..67afc4e212 Binary files /dev/null and b/openpype/hosts/photoshop/api/panel_failure.PNG differ diff --git a/openpype/hosts/photoshop/api/panel_failure.png b/openpype/hosts/photoshop/api/panel_failure.png deleted file mode 100644 index 6e52a77d22..0000000000 Binary files a/openpype/hosts/photoshop/api/panel_failure.png and /dev/null differ diff --git a/openpype/hosts/standalonepublisher/plugins/publish/collect_original_basename.py b/openpype/hosts/standalonepublisher/plugins/publish/collect_original_basename.py deleted file mode 100644 index b83a924d33..0000000000 --- a/openpype/hosts/standalonepublisher/plugins/publish/collect_original_basename.py +++ /dev/null @@ -1,18 +0,0 @@ -# -*- coding: utf-8 -*- -"""Collect original base name for use in templates.""" -from pathlib import Path - -import pyblish.api - - -class CollectOriginalBasename(pyblish.api.InstancePlugin): - """Collect original file base name.""" - - order = pyblish.api.CollectorOrder + 0.498 - label = "Collect Base Name" - hosts = ["standalonepublisher"] - families = ["simpleUnrealTexture"] - - def process(self, instance): - file_name = Path(instance.data["representations"][0]["files"]) - instance.data["originalBasename"] = file_name.stem diff --git a/openpype/hosts/standalonepublisher/plugins/publish/validate_simple_unreal_texture_naming.py b/openpype/hosts/standalonepublisher/plugins/publish/validate_simple_unreal_texture_naming.py deleted file mode 100644 index c123bef4f8..0000000000 --- a/openpype/hosts/standalonepublisher/plugins/publish/validate_simple_unreal_texture_naming.py +++ /dev/null @@ -1,29 +0,0 @@ -# -*- coding: utf-8 -*- -"""Validator for correct file naming.""" -import re -import pyblish.api - -from openpype.pipeline.publish import ( - ValidateContentsOrder, - PublishXmlValidationError, -) - - -class ValidateSimpleUnrealTextureNaming(pyblish.api.InstancePlugin): - label = "Validate Unreal Texture Names" - hosts = ["standalonepublisher"] - families = ["simpleUnrealTexture"] - order = ValidateContentsOrder - regex = "^T_{asset}.*" - - def process(self, instance): - file_name = instance.data.get("originalBasename") - self.log.info(file_name) - pattern = self.regex.format(asset=instance.data.get("asset")) - if not re.match(pattern, file_name): - msg = f"Invalid file name {file_name}" - raise PublishXmlValidationError( - self, msg, formatting_data={ - "invalid_file": file_name, - "asset": instance.data.get("asset") - }) diff --git a/openpype/hosts/tvpaint/plugins/publish/collect_render_instances.py b/openpype/hosts/tvpaint/plugins/publish/collect_render_instances.py index e89fbf7882..577e6e30e2 100644 --- a/openpype/hosts/tvpaint/plugins/publish/collect_render_instances.py +++ b/openpype/hosts/tvpaint/plugins/publish/collect_render_instances.py @@ -73,7 +73,7 @@ class CollectRenderInstances(pyblish.api.InstancePlugin): render_layer_id = creator_attributes["render_layer_instance_id"] for in_data in instance.context.data["workfileInstances"]: if ( - in_data["creator_identifier"] == "render.layer" + in_data.get("creator_identifier") == "render.layer" and in_data["instance_id"] == render_layer_id ): render_layer_data = in_data diff --git a/openpype/modules/deadline/abstract_submit_deadline.py b/openpype/modules/deadline/abstract_submit_deadline.py index 9b31b6402b..187feb9b1a 100644 --- a/openpype/modules/deadline/abstract_submit_deadline.py +++ b/openpype/modules/deadline/abstract_submit_deadline.py @@ -464,8 +464,7 @@ class AbstractSubmitDeadline(pyblish.api.InstancePlugin, self.log.info("Submitted job to Deadline: {}.".format(job_id)) # TODO: Find a way that's more generic and not render type specific - export_job = instance.data["exportJob"] - if export_job: + if "exportJob" in instance.data: self.log.info("Splitting export and render in two jobs") self.log.info("Export job id: %s", job_id) render_job_info = self.get_job_info(dependency_job_ids=[job_id]) diff --git a/openpype/modules/deadline/plugins/publish/collect_default_deadline_server.py b/openpype/modules/deadline/plugins/publish/collect_default_deadline_server.py index 58721efad3..cd4cde2519 100644 --- a/openpype/modules/deadline/plugins/publish/collect_default_deadline_server.py +++ b/openpype/modules/deadline/plugins/publish/collect_default_deadline_server.py @@ -2,6 +2,8 @@ """Collect default Deadline server.""" import pyblish.api +from openpype import AYON_SERVER_ENABLED + class CollectDefaultDeadlineServer(pyblish.api.ContextPlugin): """Collect default Deadline Webservice URL. @@ -30,24 +32,26 @@ class CollectDefaultDeadlineServer(pyblish.api.ContextPlugin): self.log.error("Cannot get OpenPype Deadline module.") raise AssertionError("OpenPype Deadline module not found.") - # get default deadline webservice url from deadline module - self.log.debug(deadline_module.deadline_urls) - context.data["defaultDeadline"] = deadline_module.deadline_urls["default"] # noqa: E501 + deadline_settings = context.data["project_settings"]["deadline"] + deadline_server_name = None + if AYON_SERVER_ENABLED: + deadline_server_name = deadline_settings["deadline_server"] + else: + deadline_servers = deadline_settings["deadline_servers"] + if deadline_servers: + deadline_server_name = deadline_servers[0] - context.data["deadlinePassMongoUrl"] = self.pass_mongo_url + context.data["deadlinePassMongoUrl"] = self.pass_mongo_url - deadline_servers = (context.data - ["project_settings"] - ["deadline"] - ["deadline_servers"]) - if deadline_servers: - deadline_server_name = deadline_servers[0] + deadline_webservice = None + if deadline_server_name: deadline_webservice = deadline_module.deadline_urls.get( deadline_server_name) - if deadline_webservice: - context.data["defaultDeadline"] = deadline_webservice - self.log.debug("Overriding from project settings with {}".format( # noqa: E501 - deadline_webservice)) - context.data["defaultDeadline"] = \ - context.data["defaultDeadline"].strip().rstrip("/") + default_deadline_webservice = deadline_module.deadline_urls["default"] + deadline_webservice = ( + deadline_webservice + or default_deadline_webservice + ) + + context.data["defaultDeadline"] = deadline_webservice.strip().rstrip("/") # noqa diff --git a/openpype/plugins/publish/integrate.py b/openpype/plugins/publish/integrate.py index 5bb51a3049..581c0c012f 100644 --- a/openpype/plugins/publish/integrate.py +++ b/openpype/plugins/publish/integrate.py @@ -137,7 +137,6 @@ class IntegrateAsset(pyblish.api.InstancePlugin): "mvUsd", "mvUsdComposition", "mvUsdOverride", - "simpleUnrealTexture", "online", "uasset", "blendScene", diff --git a/openpype/pype_commands.py b/openpype/pype_commands.py index b6535e0835..f744337c67 100644 --- a/openpype/pype_commands.py +++ b/openpype/pype_commands.py @@ -185,8 +185,7 @@ class PypeCommands: task, app, env_group=env_group, - launch_type=LaunchTypes.farm_render, - env={} + launch_type=LaunchTypes.farm_render ) else: env = os.environ.copy() @@ -215,7 +214,7 @@ class PypeCommands: def run_tests(self, folder, mark, pyargs, test_data_folder, persist, app_variant, timeout, setup_only, - mongo_url, app_group): + mongo_url, app_group, dump_databases): """ Runs tests from 'folder' @@ -276,6 +275,13 @@ class PypeCommands: if mongo_url: args.extend(["--mongo_url", mongo_url]) + if dump_databases: + msg = "dump_databases format is not recognized: {}".format( + dump_databases + ) + assert dump_databases in ["bson", "json"], msg + args.extend(["--dump_databases", dump_databases]) + print("run_tests args: {}".format(args)) import pytest pytest.main(args) diff --git a/openpype/settings/defaults/project_anatomy/templates.json b/openpype/settings/defaults/project_anatomy/templates.json index 5766a09100..6c3e038d27 100644 --- a/openpype/settings/defaults/project_anatomy/templates.json +++ b/openpype/settings/defaults/project_anatomy/templates.json @@ -38,16 +38,6 @@ "file": "{subset}_{@version}<_{output}><.{@frame}>.{ext}", "path": "{@folder}/{@file}" }, - "simpleUnrealTextureHero": { - "folder": "{root[work]}/{project[name]}/{hierarchy}/{asset}/publish/{family}/hero", - "file": "{originalBasename}.{ext}", - "path": "{@folder}/{@file}" - }, - "simpleUnrealTexture": { - "folder": "{root[work]}/{project[name]}/{hierarchy}/{asset}/publish/{family}/{@version}", - "file": "{originalBasename}_{@version}.{ext}", - "path": "{@folder}/{@file}" - }, "online": { "folder": "{root[work]}/{project[name]}/{hierarchy}/{asset}/publish/{family}/{subset}/{@version}", "file": "{originalBasename}<.{@frame}><_{udim}>.{ext}", @@ -68,8 +58,6 @@ }, "__dynamic_keys_labels__": { "maya2unreal": "Maya to Unreal", - "simpleUnrealTextureHero": "Simple Unreal Texture - Hero", - "simpleUnrealTexture": "Simple Unreal Texture", "online": "online", "tycache": "tycache", "source": "source", diff --git a/openpype/settings/defaults/project_settings/global.json b/openpype/settings/defaults/project_settings/global.json index 959faf14fa..885e8638f9 100644 --- a/openpype/settings/defaults/project_settings/global.json +++ b/openpype/settings/defaults/project_settings/global.json @@ -322,22 +322,9 @@ "animation", "setdress", "layout", - "mayaScene", - "simpleUnrealTexture" + "mayaScene" ], - "template_name_profiles": [ - { - "families": [ - "simpleUnrealTexture" - ], - "hosts": [ - "standalonepublisher" - ], - "task_types": [], - "task_names": [], - "template_name": "simpleUnrealTextureHero" - } - ] + "template_name_profiles": [] }, "CleanUp": { "paterns": [], @@ -519,17 +506,6 @@ "task_names": [], "template_name": "render" }, - { - "families": [ - "simpleUnrealTexture" - ], - "hosts": [ - "standalonepublisher" - ], - "task_types": [], - "task_names": [], - "template_name": "simpleUnrealTexture" - }, { "families": [ "staticMesh", @@ -565,19 +541,7 @@ "template_name": "tycache" } ], - "hero_template_name_profiles": [ - { - "families": [ - "simpleUnrealTexture" - ], - "hosts": [ - "standalonepublisher" - ], - "task_types": [], - "task_names": [], - "template_name": "simpleUnrealTextureHero" - } - ], + "hero_template_name_profiles": [], "custom_staging_dir_profiles": [] } }, diff --git a/openpype/settings/defaults/project_settings/standalonepublisher.json b/openpype/settings/defaults/project_settings/standalonepublisher.json index d923b4db43..44982133eb 100644 --- a/openpype/settings/defaults/project_settings/standalonepublisher.json +++ b/openpype/settings/defaults/project_settings/standalonepublisher.json @@ -133,14 +133,6 @@ ], "help": "Texture files with UDIM together with worfile" }, - "create_simple_unreal_texture": { - "name": "simple_unreal_texture", - "label": "Simple Unreal Texture", - "family": "simpleUnrealTexture", - "icon": "Image", - "defaults": [], - "help": "Texture files with Unreal naming convention" - }, "create_vdb": { "name": "vdb", "label": "VDB Volumetric Data", diff --git a/openpype/settings/defaults/project_settings/traypublisher.json b/openpype/settings/defaults/project_settings/traypublisher.json index e13de11414..7d2f358cb2 100644 --- a/openpype/settings/defaults/project_settings/traypublisher.json +++ b/openpype/settings/defaults/project_settings/traypublisher.json @@ -244,19 +244,6 @@ ".hda" ] }, - { - "family": "simpleUnrealTexture", - "identifier": "", - "label": "Simple UE texture", - "icon": "fa.image", - "default_variants": [], - "description": "Simple Unreal Engine texture", - "detailed_description": "Texture files with Unreal Engine naming conventions", - "allow_sequences": false, - "allow_multiple_items": true, - "allow_version_control": false, - "extensions": [] - }, { "family": "audio", "identifier": "", diff --git a/openpype/tools/tray/pype_tray.py b/openpype/tools/tray/pype_tray.py index a5876ca721..db391b469a 100644 --- a/openpype/tools/tray/pype_tray.py +++ b/openpype/tools/tray/pype_tray.py @@ -632,6 +632,14 @@ class TrayManager: self.exit() elif result.restart or result.token_changed: + # Remove environment variables from current connection + # - keep develop, staging, headless values + for key in { + "AYON_SERVER_URL", + "AYON_API_KEY", + "AYON_BUNDLE_NAME", + }: + os.environ.pop(key, None) self.restart() def _on_restart_action(self): diff --git a/server_addon/deadline/server/settings/main.py b/server_addon/deadline/server/settings/main.py index f158b7464d..f766ef9db8 100644 --- a/server_addon/deadline/server/settings/main.py +++ b/server_addon/deadline/server/settings/main.py @@ -14,15 +14,35 @@ class ServerListSubmodel(BaseSettingsModel): value: str = Field(title="Value") +async def defined_deadline_ws_name_enum_resolver( + addon: "BaseServerAddon", + settings_variant: str = "production", + project_name: str | None = None, +) -> list[str]: + """Provides list of names of configured Deadline webservice urls.""" + if addon is None: + return [] + + settings = await addon.get_studio_settings(variant=settings_variant) + + ws_urls = [] + for deadline_url_item in settings.deadline_urls: + ws_urls.append(deadline_url_item.name) + + return ws_urls + + class DeadlineSettings(BaseSettingsModel): deadline_urls: list[ServerListSubmodel] = Field( default_factory=list, title="System Deadline Webservice URLs", scope=["studio"], ) - deadline_servers: list[str] = Field( - title="Project deadline servers", + deadline_server: str = Field( + title="Project deadline server", section="---", + scope=["project"], + enum_resolver=defined_deadline_ws_name_enum_resolver ) publish: PublishPluginsModel = Field( default_factory=PublishPluginsModel, @@ -42,7 +62,6 @@ DEFAULT_VALUES = { "value": "http://127.0.0.1:8082" } ], - # TODO: this needs to be dynamic from "deadline_urls" - "deadline_servers": [], + "deadline_server": "default", "publish": DEFAULT_DEADLINE_PLUGINS_SETTINGS } diff --git a/server_addon/deadline/server/settings/publish_plugins.py b/server_addon/deadline/server/settings/publish_plugins.py index 0781902fe5..a989f3ad9d 100644 --- a/server_addon/deadline/server/settings/publish_plugins.py +++ b/server_addon/deadline/server/settings/publish_plugins.py @@ -3,12 +3,6 @@ from pydantic import Field, validator from ayon_server.settings import BaseSettingsModel, ensure_unique_names -class CollectDefaultDeadlineServerModel(BaseSettingsModel): - """Settings for event handlers running in ftrack service.""" - - pass_mongo_url: bool = Field(title="Pass Mongo url to job") - - class CollectDeadlinePoolsModel(BaseSettingsModel): """Settings Deadline default pools.""" @@ -286,12 +280,6 @@ class ProcessSubmittedJobOnFarmModel(BaseSettingsModel): class PublishPluginsModel(BaseSettingsModel): - CollectDefaultDeadlineServer: CollectDefaultDeadlineServerModel = Field( - default_factory=CollectDefaultDeadlineServerModel, - title="Default Deadline Webservice") - CollectDefaultDeadlineServer: CollectDefaultDeadlineServerModel = Field( - default_factory=CollectDefaultDeadlineServerModel, - title="Default Deadline Webservice") CollectDeadlinePools: CollectDeadlinePoolsModel = Field( default_factory=CollectDeadlinePoolsModel, title="Default Pools") @@ -332,9 +320,6 @@ class PublishPluginsModel(BaseSettingsModel): DEFAULT_DEADLINE_PLUGINS_SETTINGS = { - "CollectDefaultDeadlineServer": { - "pass_mongo_url": True - }, "CollectDeadlinePools": { "primary_pool": "", "secondary_pool": "" diff --git a/tests/conftest.py b/tests/conftest.py index 028c19bc5f..cb4806998a 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -39,6 +39,11 @@ def pytest_addoption(parser): help="Provide url of the Mongo database." ) + parser.addoption( + "--dump_databases", action="store", default=None, + help="Dump databases to data folder." + ) + @pytest.fixture(scope="module") def test_data_folder(request): @@ -75,6 +80,11 @@ def mongo_url(request): return request.config.getoption("--mongo_url") +@pytest.fixture(scope="module") +def dump_databases(request): + return request.config.getoption("--dump_databases") + + @pytest.hookimpl(tryfirst=True, hookwrapper=True) def pytest_runtest_makereport(item, call): # execute all other hooks to obtain the report object diff --git a/tests/integration/README.md b/tests/integration/README.md index 7b9b7cd706..1e45b55ed5 100644 --- a/tests/integration/README.md +++ b/tests/integration/README.md @@ -29,7 +29,7 @@ Command line arguments - "--timeout" - "Provide specific timeout value for test case", - "--setup_only" - "Only create dbs, do not run tests", - "--mongo_url" - "MongoDB for testing.", - + - "--dump_databases" - ("json"|"bson") export database in expected format after successful test (to output folder in temp location - which is made persistent by this, must be cleared manually) Run Tray for test ----------------- In case of failed test you might want to run it manually and visually debug what happened. diff --git a/tests/lib/db_handler.py b/tests/lib/db_handler.py index 82e741cc3b..d9a52be5b4 100644 --- a/tests/lib/db_handler.py +++ b/tests/lib/db_handler.py @@ -2,7 +2,7 @@ Helper class for automatic testing, provides dump and restore via command line utilities. - Expect mongodump, mongoimport and mongorestore present at PATH + Expect mongodump, mongoexport, mongoimport and mongorestore present at PATH """ import os import pymongo @@ -148,7 +148,7 @@ class DBHandler: self.client.drop_database(db_name) def backup_to_dump(self, db_name, dump_dir, overwrite=False, - collection=None): + collection=None, format="bson"): """ Helper method for running mongodump for specific 'db_name' """ @@ -160,15 +160,24 @@ class DBHandler: raise RuntimeError("Backup already exists, " "run with overwrite=True") - query = self._dump_query(self.uri, dump_dir, - db_name=db_name, collection=collection) - print("Mongodump query:: {}".format(query)) - subprocess.run(query) + collections = [collection] + if format == "json" and collection is None: + collections = self.client[db_name].list_collection_names() + + for collection in collections: + query = self._dump_query(self.uri, dump_dir, + db_name=db_name, collection=collection, + format=format) + print("Mongodump query:: {}".format(query)) + process = subprocess.run(query) + assert process.returncode == 0, "Mongo dump failed." def _db_exists(self, db_name): return db_name in self.client.list_database_names() - def _dump_query(self, uri, output_path, db_name=None, collection=None): + def _dump_query( + self, uri, output_path, db_name=None, collection=None, format="bson" + ): """Prepares dump query based on 'db_name' or 'collection'.""" db_part = coll_part = "" if db_name: @@ -177,11 +186,22 @@ class DBHandler: if not db_name: raise ValueError("db_name must be present") coll_part = "--collection={}".format(collection) - query = "\"{}\" --uri=\"{}\" --out={} {} {}".format( - "mongodump", uri, output_path, db_part, coll_part - ) - return query + tool = "mongodump" + query = "{} --uri=\"{}\"" + + if format == "json": + assert collection, "Collection is needed for json export." + + query += " --jsonArray --pretty" + tool = "mongoexport" + output_path = os.path.join( + output_path, "{}.{}.json".format(db_name, collection) + ) + + query += " --out={} {} {}" + + return query.format(tool, uri, output_path, db_part, coll_part) def _restore_query(self, uri, dump_dir, db_name=None, db_name_out=None, diff --git a/tests/lib/testing_classes.py b/tests/lib/testing_classes.py index 7700381aa6..7a90f76662 100644 --- a/tests/lib/testing_classes.py +++ b/tests/lib/testing_classes.py @@ -70,7 +70,9 @@ class ModuleUnitTest(BaseTest): ) @pytest.fixture(scope="module") - def download_test_data(self, test_data_folder, persist, request): + def download_test_data( + self, test_data_folder, persist, request, dump_databases + ): test_data_folder = test_data_folder or self.TEST_DATA_FOLDER if test_data_folder: print("Using existing folder {}".format(test_data_folder)) @@ -100,13 +102,13 @@ class ModuleUnitTest(BaseTest): if ext and ext.lstrip('.') in handler_class.IMPLEMENTED_ZIP_FORMATS: # noqa: E501 handler_class.unzip(os.path.join(tmpdir, file_name)) - yield tmpdir + yield tmpdir - persist = (persist or self.PERSIST or - self.is_test_failed(request)) - if not persist: - print("Removing {}".format(tmpdir)) - shutil.rmtree(tmpdir) + persist = (persist or self.PERSIST or + self.is_test_failed(request) or dump_databases) + if not persist: + print("Removing {}".format(tmpdir)) + shutil.rmtree(tmpdir) @pytest.fixture(scope="module") def output_folder_url(self, download_test_data): @@ -163,7 +165,7 @@ class ModuleUnitTest(BaseTest): @pytest.fixture(scope="module") def db_setup(self, download_test_data, env_var, monkeypatch_session, - request, mongo_url): + request, mongo_url, dump_databases, persist): """Restore prepared MongoDB dumps into selected DB.""" backup_dir = os.path.join(download_test_data, "input", "dumps") uri = os.environ.get("OPENPYPE_MONGO") @@ -178,7 +180,17 @@ class ModuleUnitTest(BaseTest): yield db_handler - persist = self.PERSIST or self.is_test_failed(request) + if dump_databases: + print("Dumping databases to {}".format(download_test_data)) + output_dir = os.path.join(download_test_data, "output", "dumps") + db_handler.backup_to_dump( + self.TEST_DB_NAME, output_dir, format=dump_databases + ) + db_handler.backup_to_dump( + self.TEST_OPENPYPE_NAME, output_dir, format=dump_databases + ) + + persist = persist or self.PERSIST or self.is_test_failed(request) if not persist: db_handler.teardown(self.TEST_DB_NAME) db_handler.teardown(self.TEST_OPENPYPE_NAME)