mirror of
https://github.com/ynput/ayon-core.git
synced 2025-12-24 21:04:40 +01:00
Merge branch 'develop' into feature/new-context-env-variables
This commit is contained in:
commit
e24f138f47
43 changed files with 227 additions and 689 deletions
102
.github/pr-glob-labeler.yml
vendored
Normal file
102
.github/pr-glob-labeler.yml
vendored
Normal file
|
|
@ -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*/**/*'
|
||||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
||||
|
|
|
|||
|
|
@ -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):
|
||||
|
|
|
|||
|
|
@ -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.")
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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):
|
||||
|
|
|
|||
|
|
@ -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):
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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):
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
)
|
||||
|
|
|
|||
|
|
@ -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 (
|
||||
|
|
|
|||
|
|
@ -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 (
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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):
|
||||
"""
|
||||
|
|
|
|||
|
|
@ -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):
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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": {
|
||||
|
|
|
|||
|
|
@ -1,4 +0,0 @@
|
|||
Tests for Pype
|
||||
--------------
|
||||
Trigger by:
|
||||
`pype test --pype`
|
||||
|
|
@ -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'
|
||||
|
|
@ -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)
|
||||
|
|
@ -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"
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -1,5 +1,8 @@
|
|||
from .window import WorkfileBuildPlaceholderDialog
|
||||
from .lib import open_template_ui
|
||||
|
||||
__all__ = (
|
||||
"WorkfileBuildPlaceholderDialog",
|
||||
|
||||
"open_template_ui"
|
||||
)
|
||||
|
|
|
|||
28
client/ayon_core/tools/workfile_template_build/lib.py
Normal file
28
client/ayon_core/tools/workfile_template_build/lib.py
Normal file
|
|
@ -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"
|
||||
)
|
||||
|
|
@ -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"
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue