mirror of
https://github.com/ynput/ayon-core.git
synced 2025-12-24 21:04:40 +01:00
Merge branch 'develop' into feature/modules_using_keyring
This commit is contained in:
commit
91faeb5492
50 changed files with 733 additions and 685 deletions
17
README.md
17
README.md
|
|
@ -166,14 +166,23 @@ sudo yum install qt5-qtbase-devel
|
|||
<details>
|
||||
<summary>Use pyenv to install Python version for OpenPype build</summary>
|
||||
|
||||
You will need **bzip2**, **readline** and **sqlite3** libraries.
|
||||
You will need **bzip2**, **readline**, **sqlite3** and other libraries.
|
||||
|
||||
**Ubuntu:**
|
||||
For more details about Python build environments see:
|
||||
|
||||
https://github.com/pyenv/pyenv/wiki#suggested-build-environment
|
||||
|
||||
**For Ubuntu:**
|
||||
```sh
|
||||
sudo apt install libbz2-dev libreadline-dev libsqlite3-dev
|
||||
sudo apt-get update; sudo apt-get install --no-install-recommends make build-essential libssl-dev zlib1g-dev libbz2-dev libreadline-dev libsqlite3-dev wget curl llvm libncurses5-dev xz-utils tk-dev libxml2-dev libxmlsec1-dev libffi-dev liblzma-dev
|
||||
```
|
||||
|
||||
1) install **pyenv**
|
||||
**For Centos:**
|
||||
```sh
|
||||
yum install gcc zlib-devel bzip2 bzip2-devel readline-devel sqlite sqlite-devel openssl-devel tk-devel libffi-devel
|
||||
```
|
||||
|
||||
**install pyenv**
|
||||
```sh
|
||||
curl https://pyenv.run | bash
|
||||
|
||||
|
|
|
|||
|
|
@ -14,7 +14,10 @@ from zipfile import ZipFile, BadZipFile
|
|||
from appdirs import user_data_dir
|
||||
from speedcopy import copyfile
|
||||
|
||||
from .user_settings import OpenPypeSettingsRegistry
|
||||
from .user_settings import (
|
||||
OpenPypeSecureRegistry,
|
||||
OpenPypeSettingsRegistry
|
||||
)
|
||||
from .tools import get_openpype_path_from_db
|
||||
|
||||
|
||||
|
|
@ -239,6 +242,7 @@ class BootstrapRepos:
|
|||
self._app = "openpype"
|
||||
self._log = log.getLogger(str(__class__))
|
||||
self.data_dir = Path(user_data_dir(self._app, self._vendor))
|
||||
self.secure_registry = OpenPypeSecureRegistry("mongodb")
|
||||
self.registry = OpenPypeSettingsRegistry()
|
||||
self.zip_filter = [".pyc", "__pycache__"]
|
||||
self.openpype_filter = [
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ from .tools import (
|
|||
validate_mongo_connection,
|
||||
get_openpype_path_from_db
|
||||
)
|
||||
from .user_settings import OpenPypeSettingsRegistry
|
||||
from .user_settings import OpenPypeSecureRegistry
|
||||
from .version import __version__
|
||||
|
||||
|
||||
|
|
@ -42,13 +42,13 @@ class InstallDialog(QtWidgets.QDialog):
|
|||
|
||||
def __init__(self, parent=None):
|
||||
super(InstallDialog, self).__init__(parent)
|
||||
self.registry = OpenPypeSettingsRegistry()
|
||||
self.secure_registry = OpenPypeSecureRegistry("mongodb")
|
||||
|
||||
self.mongo_url = ""
|
||||
try:
|
||||
self.mongo_url = (
|
||||
os.getenv("OPENPYPE_MONGO", "")
|
||||
or self.registry.get_secure_item("openPypeMongo")
|
||||
or self.secure_registry.get_item("openPypeMongo")
|
||||
)
|
||||
except ValueError:
|
||||
pass
|
||||
|
|
|
|||
|
|
@ -71,7 +71,7 @@ class InstallThread(QThread):
|
|||
if not os.getenv("OPENPYPE_MONGO"):
|
||||
# try to get it from settings registry
|
||||
try:
|
||||
self._mongo = bs.registry.get_secure_item(
|
||||
self._mongo = bs.secure_registry.get_item(
|
||||
"openPypeMongo")
|
||||
except ValueError:
|
||||
self.message.emit(
|
||||
|
|
@ -82,7 +82,7 @@ class InstallThread(QThread):
|
|||
self._mongo = os.getenv("OPENPYPE_MONGO")
|
||||
else:
|
||||
self.message.emit("Saving mongo connection string ...", False)
|
||||
bs.registry.set_secure_item("openPypeMongo", self._mongo)
|
||||
bs.secure_registry.set_item("openPypeMongo", self._mongo)
|
||||
|
||||
os.environ["OPENPYPE_MONGO"] = self._mongo
|
||||
|
||||
|
|
@ -169,7 +169,7 @@ class InstallThread(QThread):
|
|||
f"!!! invalid mongo url {self._mongo}", True)
|
||||
self.finished.emit(InstallResult(-1))
|
||||
return
|
||||
bs.registry.set_secure_item("openPypeMongo", self._mongo)
|
||||
bs.secure_registry.set_item("openPypeMongo", self._mongo)
|
||||
os.environ["OPENPYPE_MONGO"] = self._mongo
|
||||
|
||||
self.message.emit(f"processing {self._path}", True)
|
||||
|
|
|
|||
|
|
@ -25,8 +25,112 @@ except ImportError:
|
|||
|
||||
import platform
|
||||
|
||||
import appdirs
|
||||
import six
|
||||
import appdirs
|
||||
|
||||
_PLACEHOLDER = object()
|
||||
|
||||
|
||||
class OpenPypeSecureRegistry:
|
||||
"""Store information using keyring.
|
||||
|
||||
Registry should be used for private data that should be available only for
|
||||
user.
|
||||
|
||||
All passed registry names will have added prefix `OpenPype/` to easier
|
||||
identify which data were created by OpenPype.
|
||||
|
||||
Args:
|
||||
name(str): Name of registry used as identifier for data.
|
||||
"""
|
||||
def __init__(self, name):
|
||||
try:
|
||||
import keyring
|
||||
|
||||
except Exception:
|
||||
raise NotImplementedError(
|
||||
"Python module `keyring` is not available."
|
||||
)
|
||||
|
||||
# hack for cx_freeze and Windows keyring backend
|
||||
if platform.system().lower() == "windows":
|
||||
from keyring.backends import Windows
|
||||
|
||||
keyring.set_keyring(Windows.WinVaultKeyring())
|
||||
|
||||
# Force "OpenPype" prefix
|
||||
self._name = "/".join(("OpenPype", name))
|
||||
|
||||
def set_item(self, name, value):
|
||||
# type: (str, str) -> None
|
||||
"""Set sensitive item into system's keyring.
|
||||
|
||||
This uses `Keyring module`_ to save sensitive stuff into system's
|
||||
keyring.
|
||||
|
||||
Args:
|
||||
name (str): Name of the item.
|
||||
value (str): Value of the item.
|
||||
|
||||
.. _Keyring module:
|
||||
https://github.com/jaraco/keyring
|
||||
|
||||
"""
|
||||
import keyring
|
||||
|
||||
keyring.set_password(self._name, name, value)
|
||||
|
||||
@lru_cache(maxsize=32)
|
||||
def get_item(self, name, default=_PLACEHOLDER):
|
||||
"""Get value of sensitive item from system's keyring.
|
||||
|
||||
See also `Keyring module`_
|
||||
|
||||
Args:
|
||||
name (str): Name of the item.
|
||||
default (Any): Default value if item is not available.
|
||||
|
||||
Returns:
|
||||
value (str): Value of the item.
|
||||
|
||||
Raises:
|
||||
ValueError: If item doesn't exist and default is not defined.
|
||||
|
||||
.. _Keyring module:
|
||||
https://github.com/jaraco/keyring
|
||||
|
||||
"""
|
||||
import keyring
|
||||
|
||||
value = keyring.get_password(self._name, name)
|
||||
if value:
|
||||
return value
|
||||
|
||||
if default is not _PLACEHOLDER:
|
||||
return default
|
||||
|
||||
# NOTE Should raise `KeyError`
|
||||
raise ValueError(
|
||||
"Item {}:{} does not exist in keyring.".format(self._name, name)
|
||||
)
|
||||
|
||||
def delete_item(self, name):
|
||||
# type: (str) -> None
|
||||
"""Delete value stored in system's keyring.
|
||||
|
||||
See also `Keyring module`_
|
||||
|
||||
Args:
|
||||
name (str): Name of the item to be deleted.
|
||||
|
||||
.. _Keyring module:
|
||||
https://github.com/jaraco/keyring
|
||||
|
||||
"""
|
||||
import keyring
|
||||
|
||||
self.get_item.cache_clear()
|
||||
keyring.delete_password(self._name, name)
|
||||
|
||||
|
||||
@six.add_metaclass(ABCMeta)
|
||||
|
|
@ -46,13 +150,6 @@ class ASettingRegistry():
|
|||
# type: (str) -> ASettingRegistry
|
||||
super(ASettingRegistry, self).__init__()
|
||||
|
||||
if six.PY3:
|
||||
import keyring
|
||||
# hack for cx_freeze and Windows keyring backend
|
||||
if platform.system() == "Windows":
|
||||
from keyring.backends import Windows
|
||||
keyring.set_keyring(Windows.WinVaultKeyring())
|
||||
|
||||
self._name = name
|
||||
self._items = {}
|
||||
|
||||
|
|
@ -127,78 +224,6 @@ class ASettingRegistry():
|
|||
del self._items[name]
|
||||
self._delete_item(name)
|
||||
|
||||
def set_secure_item(self, name, value):
|
||||
# type: (str, str) -> None
|
||||
"""Set sensitive item into system's keyring.
|
||||
|
||||
This uses `Keyring module`_ to save sensitive stuff into system's
|
||||
keyring.
|
||||
|
||||
Args:
|
||||
name (str): Name of the item.
|
||||
value (str): Value of the item.
|
||||
|
||||
.. _Keyring module:
|
||||
https://github.com/jaraco/keyring
|
||||
|
||||
"""
|
||||
if six.PY2:
|
||||
raise NotImplementedError(
|
||||
"Keyring not available on Python 2 hosts")
|
||||
import keyring
|
||||
keyring.set_password(self._name, name, value)
|
||||
|
||||
@lru_cache(maxsize=32)
|
||||
def get_secure_item(self, name):
|
||||
# type: (str) -> str
|
||||
"""Get value of sensitive item from system's keyring.
|
||||
|
||||
See also `Keyring module`_
|
||||
|
||||
Args:
|
||||
name (str): Name of the item.
|
||||
|
||||
Returns:
|
||||
value (str): Value of the item.
|
||||
|
||||
Raises:
|
||||
ValueError: If item doesn't exist.
|
||||
|
||||
.. _Keyring module:
|
||||
https://github.com/jaraco/keyring
|
||||
|
||||
"""
|
||||
if six.PY2:
|
||||
raise NotImplementedError(
|
||||
"Keyring not available on Python 2 hosts")
|
||||
import keyring
|
||||
value = keyring.get_password(self._name, name)
|
||||
if not value:
|
||||
raise ValueError(
|
||||
"Item {}:{} does not exist in keyring.".format(
|
||||
self._name, name))
|
||||
return value
|
||||
|
||||
def delete_secure_item(self, name):
|
||||
# type: (str) -> None
|
||||
"""Delete value stored in system's keyring.
|
||||
|
||||
See also `Keyring module`_
|
||||
|
||||
Args:
|
||||
name (str): Name of the item to be deleted.
|
||||
|
||||
.. _Keyring module:
|
||||
https://github.com/jaraco/keyring
|
||||
|
||||
"""
|
||||
if six.PY2:
|
||||
raise NotImplementedError(
|
||||
"Keyring not available on Python 2 hosts")
|
||||
import keyring
|
||||
self.get_secure_item.cache_clear()
|
||||
keyring.delete_password(self._name, name)
|
||||
|
||||
|
||||
class IniSettingRegistry(ASettingRegistry):
|
||||
"""Class using :mod:`configparser`.
|
||||
|
|
@ -459,9 +484,10 @@ class OpenPypeSettingsRegistry(JSONSettingRegistry):
|
|||
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
def __init__(self, name=None):
|
||||
self.vendor = "pypeclub"
|
||||
self.product = "openpype"
|
||||
if not name:
|
||||
name = "openpype_settings"
|
||||
path = appdirs.user_data_dir(self.product, self.vendor)
|
||||
super(OpenPypeSettingsRegistry, self).__init__(
|
||||
"openpype_settings", path)
|
||||
super(OpenPypeSettingsRegistry, self).__init__(name, path)
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
import os
|
||||
import subprocess
|
||||
from openpype.lib import PreLaunchHook
|
||||
|
||||
|
||||
|
|
@ -10,15 +11,32 @@ class LaunchWithWindowsShell(PreLaunchHook):
|
|||
instead.
|
||||
"""
|
||||
|
||||
order = 10
|
||||
app_groups = ["resolve", "nuke", "nukex", "hiero", "nukestudio"]
|
||||
# Should be as last hook becuase must change launch arguments to string
|
||||
order = 1000
|
||||
app_groups = ["nuke", "nukex", "hiero", "nukestudio"]
|
||||
platforms = ["windows"]
|
||||
|
||||
def execute(self):
|
||||
# Get comspec which is cmd.exe in most cases.
|
||||
comspec = os.environ.get("COMSPEC", "cmd.exe")
|
||||
# Add comspec to arguments list and add "/k"
|
||||
new_args = [comspec, "/c"]
|
||||
new_args.extend(self.launch_context.launch_args)
|
||||
new_args = [
|
||||
# Get comspec which is cmd.exe in most cases.
|
||||
os.environ.get("COMSPEC", "cmd.exe"),
|
||||
# NOTE change to "/k" if want to keep console opened
|
||||
"/c",
|
||||
# Convert arguments to command line arguments (as string)
|
||||
"\"{}\"".format(
|
||||
subprocess.list2cmdline(self.launch_context.launch_args)
|
||||
)
|
||||
]
|
||||
# Convert list to string
|
||||
# WARNING this only works if is used as string
|
||||
args_string = " ".join(new_args)
|
||||
self.log.info((
|
||||
"Modified launch arguments to be launched with shell \"{}\"."
|
||||
).format(args_string))
|
||||
|
||||
# Replace launch args with new one
|
||||
self.launch_context.launch_args = new_args
|
||||
self.launch_context.launch_args = args_string
|
||||
# Change `creationflags` to CREATE_NEW_CONSOLE
|
||||
self.launch_context.kwargs["creationflags"] = (
|
||||
subprocess.CREATE_NEW_CONSOLE
|
||||
)
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ import pyblish.api as pyblish
|
|||
import openpype.hosts.aftereffects
|
||||
|
||||
|
||||
log = logging.getLogger("pype.hosts.aftereffects")
|
||||
log = logging.getLogger("openpype.hosts.aftereffects")
|
||||
|
||||
|
||||
HOST_DIR = os.path.dirname(os.path.abspath(openpype.hosts.aftereffects.__file__))
|
||||
|
|
|
|||
|
|
@ -46,6 +46,12 @@ class CollectAERender(abstract_collect_render.AbstractCollectRender):
|
|||
"Please recreate instance.")
|
||||
item_id = inst["members"][0]
|
||||
work_area_info = self.stub.get_work_area(int(item_id))
|
||||
|
||||
if not work_area_info:
|
||||
self.log.warning("Orphaned instance, deleting metadata")
|
||||
self.stub.remove_instance(int(item_id))
|
||||
continue
|
||||
|
||||
frameStart = work_area_info.workAreaStart
|
||||
|
||||
frameEnd = round(work_area_info.workAreaStart +
|
||||
|
|
|
|||
|
|
@ -21,3 +21,4 @@ class RemovePublishHighlight(openpype.api.Extractor):
|
|||
item = instance.data
|
||||
comp_name = item["comp_name"].replace(stub.PUBLISH_ICON, '')
|
||||
stub.rename_item(item["comp_id"], comp_name)
|
||||
instance.data["comp_name"] = comp_name
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@ def install():
|
|||
avalon.data["familiesStateDefault"] = False
|
||||
avalon.data["familiesStateToggled"] = family_states
|
||||
|
||||
log.info("pype.hosts.fusion installed")
|
||||
log.info("openpype.hosts.fusion installed")
|
||||
|
||||
pyblish.register_host("fusion")
|
||||
pyblish.register_plugin_path(PUBLISH_PATH)
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ class CollectFusionRenderMode(pyblish.api.InstancePlugin):
|
|||
available tool does not visualize which render mode is set for the
|
||||
current comp, please run the following line in the console (Py2)
|
||||
|
||||
comp.GetData("pype.rendermode")
|
||||
comp.GetData("openpype.rendermode")
|
||||
|
||||
This will return the name of the current render mode as seen above under
|
||||
Options.
|
||||
|
|
@ -34,7 +34,7 @@ class CollectFusionRenderMode(pyblish.api.InstancePlugin):
|
|||
raise RuntimeError("No comp previously collected, unable to "
|
||||
"retrieve Fusion version.")
|
||||
|
||||
rendermode = comp.GetData("pype.rendermode") or "local"
|
||||
rendermode = comp.GetData("openpype.rendermode") or "local"
|
||||
assert rendermode in options, "Must be supported render mode"
|
||||
|
||||
self.log.info("Render mode: {0}".format(rendermode))
|
||||
|
|
|
|||
|
|
@ -96,11 +96,11 @@ class SetRenderMode(QtWidgets.QWidget):
|
|||
return self._comp.GetAttrs("COMPS_Name")
|
||||
|
||||
def _get_comp_rendermode(self):
|
||||
return self._comp.GetData("pype.rendermode") or "local"
|
||||
return self._comp.GetData("openpype.rendermode") or "local"
|
||||
|
||||
def _set_comp_rendermode(self):
|
||||
rendermode = self.mode_options.currentText()
|
||||
self._comp.SetData("pype.rendermode", rendermode)
|
||||
self._comp.SetData("openpype.rendermode", rendermode)
|
||||
|
||||
self._comp.Print("Updated render mode to '%s'\n" % rendermode)
|
||||
self.hide()
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ import openpype.hosts.hiero.api as phiero
|
|||
avalon.api.install(phiero)
|
||||
|
||||
try:
|
||||
__import__("pype.hosts.hiero.api")
|
||||
__import__("openpype.hosts.hiero.api")
|
||||
__import__("pyblish")
|
||||
|
||||
except ImportError as e:
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ from openpype import lib
|
|||
from pyblish import api as pyblish
|
||||
import openpype.hosts.photoshop
|
||||
|
||||
log = logging.getLogger("pype.hosts.photoshop")
|
||||
log = logging.getLogger("openpype.hosts.photoshop")
|
||||
|
||||
HOST_DIR = os.path.dirname(os.path.abspath(openpype.hosts.photoshop.__file__))
|
||||
PLUGINS_DIR = os.path.join(HOST_DIR, "plugins")
|
||||
|
|
|
|||
|
|
@ -47,7 +47,7 @@ def install():
|
|||
avalon.data["familiesStateDefault"] = False
|
||||
avalon.data["familiesStateToggled"] = family_states
|
||||
|
||||
log.info("pype.hosts.resolve installed")
|
||||
log.info("openpype.hosts.resolve installed")
|
||||
|
||||
pyblish.register_host("resolve")
|
||||
pyblish.register_plugin_path(PUBLISH_PATH)
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@ class ResolvePrelaunch(PreLaunchHook):
|
|||
self.launch_context.env["PRE_PYTHON_SCRIPT"] = pre_py_sc
|
||||
self.log.debug(f"-- pre_py_sc: `{pre_py_sc}`...")
|
||||
try:
|
||||
__import__("pype.hosts.resolve")
|
||||
__import__("openpype.hosts.resolve")
|
||||
__import__("pyblish")
|
||||
|
||||
except ImportError:
|
||||
|
|
|
|||
|
|
@ -104,7 +104,8 @@ from .plugin_tools import (
|
|||
from .local_settings import (
|
||||
IniSettingRegistry,
|
||||
JSONSettingRegistry,
|
||||
PypeSettingsRegistry,
|
||||
OpenPypeSecureRegistry,
|
||||
OpenPypeSettingsRegistry,
|
||||
get_local_site_id,
|
||||
change_openpype_mongo_url
|
||||
)
|
||||
|
|
@ -217,7 +218,8 @@ __all__ = [
|
|||
|
||||
"IniSettingRegistry",
|
||||
"JSONSettingRegistry",
|
||||
"PypeSettingsRegistry",
|
||||
"OpenPypeSecureRegistry",
|
||||
"OpenPypeSettingsRegistry",
|
||||
"get_local_site_id",
|
||||
"change_openpype_mongo_url",
|
||||
|
||||
|
|
|
|||
|
|
@ -216,7 +216,7 @@ class Anatomy:
|
|||
"""Returns value of root key from template."""
|
||||
root_templates = []
|
||||
for group in re.findall(self.root_key_regex, template):
|
||||
root_templates.append(group)
|
||||
root_templates.append("{" + group + "}")
|
||||
|
||||
if not root_templates:
|
||||
return None
|
||||
|
|
|
|||
|
|
@ -17,6 +17,10 @@ from openpype.settings import (
|
|||
get_project_settings,
|
||||
get_environments
|
||||
)
|
||||
from openpype.settings.constants import (
|
||||
METADATA_KEYS,
|
||||
M_DYNAMIC_KEY_LABEL
|
||||
)
|
||||
from . import (
|
||||
PypeLogger,
|
||||
Anatomy
|
||||
|
|
@ -123,7 +127,16 @@ class ApplicationGroup:
|
|||
self.host_name = host_name
|
||||
|
||||
variants = data.get("variants") or {}
|
||||
key_label_mapping = variants.pop(M_DYNAMIC_KEY_LABEL, {})
|
||||
for variant_name, variant_data in variants.items():
|
||||
if variant_name in METADATA_KEYS:
|
||||
continue
|
||||
|
||||
if "variant_label" not in variant_data:
|
||||
variant_label = key_label_mapping.get(variant_name)
|
||||
if variant_label:
|
||||
variant_data["variant_label"] = variant_label
|
||||
|
||||
variants[variant_name] = Application(
|
||||
variant_name, variant_data, self
|
||||
)
|
||||
|
|
@ -165,7 +178,7 @@ class Application:
|
|||
enabled = False
|
||||
if group.enabled:
|
||||
enabled = data.get("enabled", True)
|
||||
self.enabled = enabled
|
||||
self.enabled = enabled
|
||||
|
||||
self.label = data.get("variant_label") or name
|
||||
self.full_name = "/".join((group.name, name))
|
||||
|
|
@ -265,22 +278,31 @@ class ApplicationManager:
|
|||
self.tool_groups.clear()
|
||||
self.tools.clear()
|
||||
|
||||
settings = get_system_settings()
|
||||
settings = get_system_settings(
|
||||
clear_metadata=False, exclude_locals=False
|
||||
)
|
||||
|
||||
app_defs = settings["applications"]
|
||||
for group_name, variant_defs in app_defs.items():
|
||||
if group_name in METADATA_KEYS:
|
||||
continue
|
||||
|
||||
group = ApplicationGroup(group_name, variant_defs, self)
|
||||
self.app_groups[group_name] = group
|
||||
for app in group:
|
||||
# TODO This should be replaced with `full_name` in future
|
||||
self.applications[app.full_name] = app
|
||||
|
||||
tools_definitions = settings["tools"]["tool_groups"]
|
||||
tool_label_mapping = tools_definitions.pop(M_DYNAMIC_KEY_LABEL, {})
|
||||
for tool_group_name, tool_group_data in tools_definitions.items():
|
||||
if not tool_group_name:
|
||||
if not tool_group_name or tool_group_name in METADATA_KEYS:
|
||||
continue
|
||||
|
||||
tool_group_label = (
|
||||
tool_label_mapping.get(tool_group_name) or tool_group_name
|
||||
)
|
||||
group = EnvironmentToolGroup(
|
||||
tool_group_name, tool_group_data, self
|
||||
tool_group_name, tool_group_label, tool_group_data, self
|
||||
)
|
||||
self.tool_groups[tool_group_name] = group
|
||||
for tool in group:
|
||||
|
|
@ -336,16 +358,24 @@ class EnvironmentToolGroup:
|
|||
manager (ApplicationManager): Manager that creates the group.
|
||||
"""
|
||||
|
||||
def __init__(self, name, data, manager):
|
||||
def __init__(self, name, label, data, manager):
|
||||
self.name = name
|
||||
self.label = label
|
||||
self._data = data
|
||||
self.manager = manager
|
||||
self._environment = data["environment"]
|
||||
|
||||
variants = data.get("variants") or {}
|
||||
label_by_key = variants.pop(M_DYNAMIC_KEY_LABEL, {})
|
||||
variants_by_name = {}
|
||||
for variant_name, variant_env in variants.items():
|
||||
tool = EnvironmentTool(variant_name, variant_env, self)
|
||||
if variant_name in METADATA_KEYS:
|
||||
continue
|
||||
|
||||
variant_label = label_by_key.get(variant_name) or variant_name
|
||||
tool = EnvironmentTool(
|
||||
variant_name, variant_label, variant_env, self
|
||||
)
|
||||
variants_by_name[variant_name] = tool
|
||||
self.variants = variants_by_name
|
||||
|
||||
|
|
@ -372,8 +402,10 @@ class EnvironmentTool:
|
|||
group (str): Name of group which wraps tool.
|
||||
"""
|
||||
|
||||
def __init__(self, name, environment, group):
|
||||
def __init__(self, name, label, environment, group):
|
||||
self.name = name
|
||||
self.variant_label = label
|
||||
self.label = " ".join((group.label, label))
|
||||
self.group = group
|
||||
self._environment = environment
|
||||
self.full_name = "/".join((group.name, name))
|
||||
|
|
@ -804,10 +836,15 @@ class ApplicationLaunchContext:
|
|||
self.log.debug("All prelaunch hook executed. Starting new process.")
|
||||
|
||||
# Prepare subprocess args
|
||||
args = self.clear_launch_args(self.launch_args)
|
||||
self.log.debug(
|
||||
"Launching \"{}\" with args ({}): {}".format(
|
||||
self.app_name, len(args), args
|
||||
args_len_str = ""
|
||||
if isinstance(self.launch_args, str):
|
||||
args = self.launch_args
|
||||
else:
|
||||
args = self.clear_launch_args(self.launch_args)
|
||||
args_len_str = " ({})".format(len(args))
|
||||
self.log.info(
|
||||
"Launching \"{}\" with args{}: {}".format(
|
||||
self.app_name, args_len_str, args
|
||||
)
|
||||
)
|
||||
# Run process
|
||||
|
|
@ -853,7 +890,10 @@ class ApplicationLaunchContext:
|
|||
Return:
|
||||
list: Unpacked arguments.
|
||||
"""
|
||||
while True:
|
||||
if isinstance(args, str):
|
||||
return args
|
||||
all_cleared = False
|
||||
while not all_cleared:
|
||||
all_cleared = True
|
||||
new_args = []
|
||||
for arg in args:
|
||||
|
|
@ -865,8 +905,6 @@ class ApplicationLaunchContext:
|
|||
new_args.append(arg)
|
||||
args = new_args
|
||||
|
||||
if all_cleared:
|
||||
break
|
||||
return args
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ from datetime import datetime
|
|||
from abc import ABCMeta, abstractmethod
|
||||
import json
|
||||
|
||||
# TODO Use pype igniter logic instead of using duplicated code
|
||||
# disable lru cache in Python 2
|
||||
try:
|
||||
from functools import lru_cache
|
||||
|
|
@ -25,11 +26,115 @@ except ImportError:
|
|||
|
||||
import platform
|
||||
|
||||
import appdirs
|
||||
import six
|
||||
import appdirs
|
||||
|
||||
from .import validate_mongo_connection
|
||||
|
||||
_PLACEHOLDER = object()
|
||||
|
||||
|
||||
class OpenPypeSecureRegistry:
|
||||
"""Store information using keyring.
|
||||
|
||||
Registry should be used for private data that should be available only for
|
||||
user.
|
||||
|
||||
All passed registry names will have added prefix `OpenPype/` to easier
|
||||
identify which data were created by OpenPype.
|
||||
|
||||
Args:
|
||||
name(str): Name of registry used as identifier for data.
|
||||
"""
|
||||
def __init__(self, name):
|
||||
try:
|
||||
import keyring
|
||||
|
||||
except Exception:
|
||||
raise NotImplementedError(
|
||||
"Python module `keyring` is not available."
|
||||
)
|
||||
|
||||
# hack for cx_freeze and Windows keyring backend
|
||||
if platform.system().lower() == "windows":
|
||||
from keyring.backends import Windows
|
||||
|
||||
keyring.set_keyring(Windows.WinVaultKeyring())
|
||||
|
||||
# Force "OpenPype" prefix
|
||||
self._name = "/".join(("OpenPype", name))
|
||||
|
||||
def set_item(self, name, value):
|
||||
# type: (str, str) -> None
|
||||
"""Set sensitive item into system's keyring.
|
||||
|
||||
This uses `Keyring module`_ to save sensitive stuff into system's
|
||||
keyring.
|
||||
|
||||
Args:
|
||||
name (str): Name of the item.
|
||||
value (str): Value of the item.
|
||||
|
||||
.. _Keyring module:
|
||||
https://github.com/jaraco/keyring
|
||||
|
||||
"""
|
||||
import keyring
|
||||
|
||||
keyring.set_password(self._name, name, value)
|
||||
|
||||
@lru_cache(maxsize=32)
|
||||
def get_item(self, name, default=_PLACEHOLDER):
|
||||
"""Get value of sensitive item from system's keyring.
|
||||
|
||||
See also `Keyring module`_
|
||||
|
||||
Args:
|
||||
name (str): Name of the item.
|
||||
default (Any): Default value if item is not available.
|
||||
|
||||
Returns:
|
||||
value (str): Value of the item.
|
||||
|
||||
Raises:
|
||||
ValueError: If item doesn't exist and default is not defined.
|
||||
|
||||
.. _Keyring module:
|
||||
https://github.com/jaraco/keyring
|
||||
|
||||
"""
|
||||
import keyring
|
||||
|
||||
value = keyring.get_password(self._name, name)
|
||||
if value is not None:
|
||||
return value
|
||||
|
||||
if default is not _PLACEHOLDER:
|
||||
return default
|
||||
|
||||
# NOTE Should raise `KeyError`
|
||||
raise ValueError(
|
||||
"Item {}:{} does not exist in keyring.".format(self._name, name)
|
||||
)
|
||||
|
||||
def delete_item(self, name):
|
||||
# type: (str) -> None
|
||||
"""Delete value stored in system's keyring.
|
||||
|
||||
See also `Keyring module`_
|
||||
|
||||
Args:
|
||||
name (str): Name of the item to be deleted.
|
||||
|
||||
.. _Keyring module:
|
||||
https://github.com/jaraco/keyring
|
||||
|
||||
"""
|
||||
import keyring
|
||||
|
||||
self.get_item.cache_clear()
|
||||
keyring.delete_password(self._name, name)
|
||||
|
||||
|
||||
@six.add_metaclass(ABCMeta)
|
||||
class ASettingRegistry():
|
||||
|
|
@ -48,13 +153,6 @@ class ASettingRegistry():
|
|||
# type: (str) -> ASettingRegistry
|
||||
super(ASettingRegistry, self).__init__()
|
||||
|
||||
if six.PY3:
|
||||
import keyring
|
||||
# hack for cx_freeze and Windows keyring backend
|
||||
if platform.system() == "Windows":
|
||||
from keyring.backends import Windows
|
||||
keyring.set_keyring(Windows.WinVaultKeyring())
|
||||
|
||||
self._name = name
|
||||
self._items = {}
|
||||
|
||||
|
|
@ -120,7 +218,7 @@ class ASettingRegistry():
|
|||
"""Delete item from settings.
|
||||
|
||||
Note:
|
||||
see :meth:`pype.lib.local_settings.ARegistrySettings.delete_item`
|
||||
see :meth:`openpype.lib.user_settings.ARegistrySettings.delete_item`
|
||||
|
||||
"""
|
||||
pass
|
||||
|
|
@ -129,78 +227,6 @@ class ASettingRegistry():
|
|||
del self._items[name]
|
||||
self._delete_item(name)
|
||||
|
||||
def set_secure_item(self, name, value):
|
||||
# type: (str, str) -> None
|
||||
"""Set sensitive item into system's keyring.
|
||||
|
||||
This uses `Keyring module`_ to save sensitive stuff into system's
|
||||
keyring.
|
||||
|
||||
Args:
|
||||
name (str): Name of the item.
|
||||
value (str): Value of the item.
|
||||
|
||||
.. _Keyring module:
|
||||
https://github.com/jaraco/keyring
|
||||
|
||||
"""
|
||||
if six.PY2:
|
||||
raise NotImplementedError(
|
||||
"Keyring not available on Python 2 hosts")
|
||||
import keyring
|
||||
keyring.set_password(self._name, name, value)
|
||||
|
||||
@lru_cache(maxsize=32)
|
||||
def get_secure_item(self, name):
|
||||
# type: (str) -> str
|
||||
"""Get value of sensitive item from system's keyring.
|
||||
|
||||
See also `Keyring module`_
|
||||
|
||||
Args:
|
||||
name (str): Name of the item.
|
||||
|
||||
Returns:
|
||||
value (str): Value of the item.
|
||||
|
||||
Raises:
|
||||
ValueError: If item doesn't exist.
|
||||
|
||||
.. _Keyring module:
|
||||
https://github.com/jaraco/keyring
|
||||
|
||||
"""
|
||||
if six.PY2:
|
||||
raise NotImplementedError(
|
||||
"Keyring not available on Python 2 hosts")
|
||||
import keyring
|
||||
value = keyring.get_password(self._name, name)
|
||||
if not value:
|
||||
raise ValueError(
|
||||
"Item {}:{} does not exist in keyring.".format(
|
||||
self._name, name))
|
||||
return value
|
||||
|
||||
def delete_secure_item(self, name):
|
||||
# type: (str) -> None
|
||||
"""Delete value stored in system's keyring.
|
||||
|
||||
See also `Keyring module`_
|
||||
|
||||
Args:
|
||||
name (str): Name of the item to be deleted.
|
||||
|
||||
.. _Keyring module:
|
||||
https://github.com/jaraco/keyring
|
||||
|
||||
"""
|
||||
if six.PY2:
|
||||
raise NotImplementedError(
|
||||
"Keyring not available on Python 2 hosts")
|
||||
import keyring
|
||||
self.get_secure_item.cache_clear()
|
||||
keyring.delete_password(self._name, name)
|
||||
|
||||
|
||||
class IniSettingRegistry(ASettingRegistry):
|
||||
"""Class using :mod:`configparser`.
|
||||
|
|
@ -218,7 +244,7 @@ class IniSettingRegistry(ASettingRegistry):
|
|||
if not os.path.exists(self._registry_file):
|
||||
with open(self._registry_file, mode="w") as cfg:
|
||||
print("# Settings registry", cfg)
|
||||
print("# Generated by Pype {}".format(version), cfg)
|
||||
print("# Generated by OpenPype {}".format(version), cfg)
|
||||
now = datetime.now().strftime("%d/%m/%Y %H:%M:%S")
|
||||
print("# {}".format(now), cfg)
|
||||
|
||||
|
|
@ -352,7 +378,7 @@ class IniSettingRegistry(ASettingRegistry):
|
|||
"""Delete item from default section.
|
||||
|
||||
Note:
|
||||
See :meth:`~pype.lib.IniSettingsRegistry.delete_item_from_section`
|
||||
See :meth:`~openpype.lib.IniSettingsRegistry.delete_item_from_section`
|
||||
|
||||
"""
|
||||
self.delete_item_from_section("MAIN", name)
|
||||
|
|
@ -369,7 +395,7 @@ class JSONSettingRegistry(ASettingRegistry):
|
|||
now = datetime.now().strftime("%d/%m/%Y %H:%M:%S")
|
||||
header = {
|
||||
"__metadata__": {
|
||||
"pype-version": os.getenv("OPENPYPE_VERSION", "N/A"),
|
||||
"openpype-version": os.getenv("OPENPYPE_VERSION", "N/A"),
|
||||
"generated": now
|
||||
},
|
||||
"registry": {}
|
||||
|
|
@ -387,7 +413,7 @@ class JSONSettingRegistry(ASettingRegistry):
|
|||
"""Get item value from registry json.
|
||||
|
||||
Note:
|
||||
See :meth:`pype.lib.JSONSettingRegistry.get_item`
|
||||
See :meth:`openpype.lib.JSONSettingRegistry.get_item`
|
||||
|
||||
"""
|
||||
with open(self._registry_file, mode="r") as cfg:
|
||||
|
|
@ -420,7 +446,7 @@ class JSONSettingRegistry(ASettingRegistry):
|
|||
"""Set item value to registry json.
|
||||
|
||||
Note:
|
||||
See :meth:`pype.lib.JSONSettingRegistry.set_item`
|
||||
See :meth:`openpype.lib.JSONSettingRegistry.set_item`
|
||||
|
||||
"""
|
||||
with open(self._registry_file, "r+") as cfg:
|
||||
|
|
@ -452,8 +478,8 @@ class JSONSettingRegistry(ASettingRegistry):
|
|||
json.dump(data, cfg, indent=4)
|
||||
|
||||
|
||||
class PypeSettingsRegistry(JSONSettingRegistry):
|
||||
"""Class handling Pype general settings registry.
|
||||
class OpenPypeSettingsRegistry(JSONSettingRegistry):
|
||||
"""Class handling OpenPype general settings registry.
|
||||
|
||||
Attributes:
|
||||
vendor (str): Name used for path construction.
|
||||
|
|
@ -461,11 +487,13 @@ class PypeSettingsRegistry(JSONSettingRegistry):
|
|||
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
def __init__(self, name=None):
|
||||
self.vendor = "pypeclub"
|
||||
self.product = "pype"
|
||||
self.product = "openpype"
|
||||
if not name:
|
||||
name = "openpype_settings"
|
||||
path = appdirs.user_data_dir(self.product, self.vendor)
|
||||
super(PypeSettingsRegistry, self).__init__("pype_settings", path)
|
||||
super(OpenPypeSettingsRegistry, self).__init__(name, path)
|
||||
|
||||
|
||||
def _create_local_site_id(registry=None):
|
||||
|
|
@ -473,7 +501,7 @@ def _create_local_site_id(registry=None):
|
|||
from uuid import uuid4
|
||||
|
||||
if registry is None:
|
||||
registry = PypeSettingsRegistry()
|
||||
registry = OpenPypeSettingsRegistry()
|
||||
|
||||
new_id = str(uuid4())
|
||||
|
||||
|
|
@ -489,7 +517,7 @@ def get_local_site_id():
|
|||
|
||||
Identifier is created if does not exists yet.
|
||||
"""
|
||||
registry = PypeSettingsRegistry()
|
||||
registry = OpenPypeSettingsRegistry()
|
||||
try:
|
||||
return registry.get_item("localId")
|
||||
except ValueError:
|
||||
|
|
@ -504,5 +532,9 @@ def change_openpype_mongo_url(new_mongo_url):
|
|||
"""
|
||||
|
||||
validate_mongo_connection(new_mongo_url)
|
||||
registry = PypeSettingsRegistry()
|
||||
registry.set_secure_item("pypeMongo", new_mongo_url)
|
||||
key = "openPypeMongo"
|
||||
registry = OpenPypeSecureRegistry("mongodb")
|
||||
existing_value = registry.get_item(key, None)
|
||||
if existing_value is not None:
|
||||
registry.delete_item(key)
|
||||
registry.set_item(key, new_mongo_url)
|
||||
|
|
|
|||
|
|
@ -400,9 +400,9 @@ class CustomAttributes(BaseAction):
|
|||
|
||||
def tools_attribute(self, event):
|
||||
tools_data = []
|
||||
for tool_name in self.app_manager.tools.keys():
|
||||
for tool_name, tool in self.app_manager.tools.items():
|
||||
tools_data.append({
|
||||
tool_name: tool_name
|
||||
tool_name: tool.label
|
||||
})
|
||||
|
||||
# Make sure there is at least one item
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
import os
|
||||
import time
|
||||
import types
|
||||
import logging
|
||||
import traceback
|
||||
|
|
@ -10,7 +11,6 @@ from openpype.lib import (
|
|||
modules_from_path
|
||||
)
|
||||
|
||||
|
||||
log = PypeLogger.get_logger(__name__)
|
||||
|
||||
"""
|
||||
|
|
@ -120,6 +120,18 @@ class FtrackServer:
|
|||
if not session:
|
||||
session = ftrack_api.Session(auto_connect_event_hub=True)
|
||||
|
||||
# Wait until session has connected event hub
|
||||
if session._auto_connect_event_hub_thread:
|
||||
# Use timeout from session (since ftrack-api 2.1.0)
|
||||
timeout = getattr(session, "request_timeout", 60)
|
||||
started = time.time()
|
||||
while not session.event_hub.connected:
|
||||
if (time.time() - started) > timeout:
|
||||
raise RuntimeError((
|
||||
"Connection to Ftrack was not created in {} seconds"
|
||||
).format(timeout))
|
||||
time.sleep(0.1)
|
||||
|
||||
self.session = session
|
||||
if load_files:
|
||||
if not self.handler_paths:
|
||||
|
|
|
|||
|
|
@ -3,11 +3,11 @@ import sys
|
|||
import logging
|
||||
import getpass
|
||||
import atexit
|
||||
import tempfile
|
||||
import threading
|
||||
import datetime
|
||||
import time
|
||||
import queue
|
||||
import appdirs
|
||||
import pymongo
|
||||
|
||||
import requests
|
||||
|
|
@ -165,7 +165,6 @@ class ProcessEventHub(SocketBaseEventHub):
|
|||
|
||||
def wait(self, duration=None):
|
||||
"""Overriden wait
|
||||
|
||||
Event are loaded from Mongo DB when queue is empty. Handled event is
|
||||
set as processed in Mongo DB.
|
||||
"""
|
||||
|
|
@ -252,7 +251,7 @@ class CustomEventHubSession(ftrack_api.session.Session):
|
|||
self, server_url=None, api_key=None, api_user=None, auto_populate=True,
|
||||
plugin_paths=None, cache=None, cache_key_maker=None,
|
||||
auto_connect_event_hub=False, schema_cache_path=None,
|
||||
plugin_arguments=None, **kwargs
|
||||
plugin_arguments=None, timeout=60, **kwargs
|
||||
):
|
||||
self.kwargs = kwargs
|
||||
|
||||
|
|
@ -331,6 +330,7 @@ class CustomEventHubSession(ftrack_api.session.Session):
|
|||
self._request.auth = ftrack_api.session.SessionAuthentication(
|
||||
self._api_key, self._api_user
|
||||
)
|
||||
self.request_timeout = timeout
|
||||
|
||||
self.auto_populate = auto_populate
|
||||
|
||||
|
|
@ -368,8 +368,9 @@ class CustomEventHubSession(ftrack_api.session.Session):
|
|||
# rebuilding types)?
|
||||
if schema_cache_path is not False:
|
||||
if schema_cache_path is None:
|
||||
schema_cache_path = appdirs.user_cache_dir()
|
||||
schema_cache_path = os.environ.get(
|
||||
'FTRACK_API_SCHEMA_CACHE_PATH', tempfile.gettempdir()
|
||||
'FTRACK_API_SCHEMA_CACHE_PATH', schema_cache_path
|
||||
)
|
||||
|
||||
schema_cache_path = os.path.join(
|
||||
|
|
|
|||
|
|
@ -40,8 +40,7 @@ class IdleManager(PypeModule, ITrayService):
|
|||
name = "idle_manager"
|
||||
|
||||
def initialize(self, module_settings):
|
||||
idle_man_settings = module_settings[self.name]
|
||||
self.enabled = idle_man_settings["enabled"]
|
||||
self.enabled = True
|
||||
|
||||
self.time_callbacks = collections.defaultdict(list)
|
||||
self.idle_thread = None
|
||||
|
|
@ -50,7 +49,8 @@ class IdleManager(PypeModule, ITrayService):
|
|||
return
|
||||
|
||||
def tray_start(self):
|
||||
self.start_thread()
|
||||
if self.time_callbacks:
|
||||
self.start_thread()
|
||||
|
||||
def tray_exit(self):
|
||||
self.stop_thread()
|
||||
|
|
|
|||
|
|
@ -45,11 +45,13 @@ class TimersManager(PypeModule, ITrayService, IIdleManager, IWebServerRoutes):
|
|||
timers_settings = modules_settings[self.name]
|
||||
|
||||
self.enabled = timers_settings["enabled"]
|
||||
auto_stop = timers_settings["auto_stop"]
|
||||
# When timer will stop if idle manager is running (minutes)
|
||||
full_time = int(timers_settings["full_time"] * 60)
|
||||
# How many minutes before the timer is stopped will popup the message
|
||||
message_time = int(timers_settings["message_time"] * 60)
|
||||
|
||||
self.auto_stop = auto_stop
|
||||
self.time_show_message = full_time - message_time
|
||||
self.time_stop_timer = full_time
|
||||
|
||||
|
|
@ -160,6 +162,9 @@ class TimersManager(PypeModule, ITrayService, IIdleManager, IWebServerRoutes):
|
|||
def callbacks_by_idle_time(self):
|
||||
"""Implementation of IIdleManager interface."""
|
||||
# Time when message is shown
|
||||
if not self.auto_stop:
|
||||
return {}
|
||||
|
||||
callbacks = collections.defaultdict(list)
|
||||
callbacks[self.time_show_message].append(lambda: self.time_callback(0))
|
||||
|
||||
|
|
|
|||
|
|
@ -54,11 +54,11 @@ def __main__():
|
|||
print("Got Pype location from environment: {}".format(
|
||||
os.environ.get('OPENPYPE_SETUP_PATH')))
|
||||
|
||||
pype_command = "pype.ps1"
|
||||
pype_command = "openpype.ps1"
|
||||
if platform.system().lower() == "linux":
|
||||
pype_command = "pype"
|
||||
elif platform.system().lower() == "windows":
|
||||
pype_command = "pype.bat"
|
||||
pype_command = "openpype.bat"
|
||||
|
||||
if kwargs.pype:
|
||||
pype_root = kwargs.pype
|
||||
|
|
|
|||
|
|
@ -20,8 +20,6 @@
|
|||
},
|
||||
"variants": {
|
||||
"2020": {
|
||||
"enabled": true,
|
||||
"variant_label": "2020",
|
||||
"executables": {
|
||||
"windows": [
|
||||
"C:\\Program Files\\Autodesk\\Maya2020\\bin\\maya.exe"
|
||||
|
|
@ -41,8 +39,6 @@
|
|||
}
|
||||
},
|
||||
"2019": {
|
||||
"enabled": true,
|
||||
"variant_label": "2019",
|
||||
"executables": {
|
||||
"windows": [
|
||||
"C:\\Program Files\\Autodesk\\Maya2019\\bin\\maya.exe"
|
||||
|
|
@ -62,8 +58,6 @@
|
|||
}
|
||||
},
|
||||
"2018": {
|
||||
"enabled": true,
|
||||
"variant_label": "2018",
|
||||
"executables": {
|
||||
"windows": [
|
||||
"C:\\Program Files\\Autodesk\\Maya2018\\bin\\maya.exe"
|
||||
|
|
@ -84,86 +78,6 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"mayabatch": {
|
||||
"enabled": true,
|
||||
"label": "MayaBatch",
|
||||
"icon": "{}/app_icons/maya.png",
|
||||
"host_name": "maya",
|
||||
"environment": {
|
||||
"PYTHONPATH": [
|
||||
"{OPENPYPE_ROOT}/avalon-core/setup/maya",
|
||||
"{OPENPYPE_ROOT}/maya-look-assigner",
|
||||
"{PYTHON_ENV}/python2/Lib/site-packages",
|
||||
"{PYTHONPATH}"
|
||||
],
|
||||
"MAYA_DISABLE_CLIC_IPM": "Yes",
|
||||
"MAYA_DISABLE_CIP": "Yes",
|
||||
"MAYA_DISABLE_CER": "Yes",
|
||||
"PYMEL_SKIP_MEL_INIT": "Yes",
|
||||
"LC_ALL": "C",
|
||||
"OPENPYPE_LOG_NO_COLORS": "Yes",
|
||||
"MAYA_TEST": "{MAYA_VERSION}"
|
||||
},
|
||||
"variants": {
|
||||
"2020": {
|
||||
"enabled": true,
|
||||
"variant_label": "2020",
|
||||
"executables": {
|
||||
"windows": [
|
||||
"C:\\Program Files\\Autodesk\\Maya2020\\bin\\mayabatch.exe"
|
||||
],
|
||||
"darwin": [],
|
||||
"linux": []
|
||||
},
|
||||
"arguments": {
|
||||
"windows": [],
|
||||
"darwin": [],
|
||||
"linux": []
|
||||
},
|
||||
"environment": {
|
||||
"MAYA_VERSION": "2020"
|
||||
}
|
||||
},
|
||||
"2019": {
|
||||
"enabled": true,
|
||||
"variant_label": "2019",
|
||||
"executables": {
|
||||
"windows": [
|
||||
"C:\\Program Files\\Autodesk\\Maya2019\\bin\\mayabatch.exe"
|
||||
],
|
||||
"darwin": [],
|
||||
"linux": []
|
||||
},
|
||||
"arguments": {
|
||||
"windows": [],
|
||||
"darwin": [],
|
||||
"linux": []
|
||||
},
|
||||
"environment": {
|
||||
"MAYA_VERSION": "2019"
|
||||
}
|
||||
},
|
||||
"2018": {
|
||||
"enabled": true,
|
||||
"variant_label": "2018",
|
||||
"executables": {
|
||||
"windows": [
|
||||
"C:\\Program Files\\Autodesk\\Maya2018\\bin\\mayabatch.exe"
|
||||
],
|
||||
"darwin": [],
|
||||
"linux": []
|
||||
},
|
||||
"arguments": {
|
||||
"windows": [],
|
||||
"darwin": [],
|
||||
"linux": []
|
||||
},
|
||||
"environment": {
|
||||
"MAYA_VERSION": "2018"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"nuke": {
|
||||
"enabled": true,
|
||||
"label": "Nuke",
|
||||
|
|
@ -182,8 +96,6 @@
|
|||
},
|
||||
"variants": {
|
||||
"12-2": {
|
||||
"enabled": true,
|
||||
"variant_label": "12.2",
|
||||
"executables": {
|
||||
"windows": [
|
||||
"C:\\Program Files\\Nuke12.2v3\\Nuke12.2.exe"
|
||||
|
|
@ -201,8 +113,6 @@
|
|||
"environment": {}
|
||||
},
|
||||
"12-0": {
|
||||
"enabled": true,
|
||||
"variant_label": "12.0",
|
||||
"executables": {
|
||||
"windows": [
|
||||
"C:\\Program Files\\Nuke12.0v1\\Nuke12.0.exe"
|
||||
|
|
@ -220,8 +130,6 @@
|
|||
"environment": {}
|
||||
},
|
||||
"11-3": {
|
||||
"enabled": true,
|
||||
"variant_label": "11.3",
|
||||
"executables": {
|
||||
"windows": [
|
||||
"C:\\Program Files\\Nuke11.3v1\\Nuke11.3.exe"
|
||||
|
|
@ -239,8 +147,6 @@
|
|||
"environment": {}
|
||||
},
|
||||
"11-2": {
|
||||
"enabled": true,
|
||||
"variant_label": "11.2",
|
||||
"executables": {
|
||||
"windows": [
|
||||
"C:\\Program Files\\Nuke11.2v2\\Nuke11.2.exe"
|
||||
|
|
@ -254,6 +160,11 @@
|
|||
"linux": []
|
||||
},
|
||||
"environment": {}
|
||||
},
|
||||
"__dynamic_keys_labels__": {
|
||||
"12-2": "12.2",
|
||||
"12-0": "12.0",
|
||||
"11-3": "11.3"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
@ -275,8 +186,6 @@
|
|||
},
|
||||
"variants": {
|
||||
"12-2": {
|
||||
"enabled": true,
|
||||
"variant_label": "12.2",
|
||||
"executables": {
|
||||
"windows": [
|
||||
"C:\\Program Files\\Nuke12.2v3\\Nuke12.2.exe"
|
||||
|
|
@ -300,8 +209,6 @@
|
|||
"environment": {}
|
||||
},
|
||||
"12-0": {
|
||||
"enabled": true,
|
||||
"variant_label": "12.0",
|
||||
"executables": {
|
||||
"windows": [
|
||||
"C:\\Program Files\\Nuke12.0v1\\Nuke12.0.exe"
|
||||
|
|
@ -325,8 +232,6 @@
|
|||
"environment": {}
|
||||
},
|
||||
"11-3": {
|
||||
"enabled": true,
|
||||
"variant_label": "11.3",
|
||||
"executables": {
|
||||
"windows": [
|
||||
"C:\\Program Files\\Nuke11.3v1\\Nuke11.3.exe"
|
||||
|
|
@ -350,8 +255,6 @@
|
|||
"environment": {}
|
||||
},
|
||||
"11-2": {
|
||||
"enabled": true,
|
||||
"variant_label": "11.2",
|
||||
"executables": {
|
||||
"windows": [
|
||||
"C:\\Program Files\\Nuke11.2v2\\Nuke11.2.exe"
|
||||
|
|
@ -371,6 +274,12 @@
|
|||
]
|
||||
},
|
||||
"environment": {}
|
||||
},
|
||||
"__dynamic_keys_labels__": {
|
||||
"12-2": "12.2",
|
||||
"12-0": "12.0",
|
||||
"11-3": "11.3",
|
||||
"11-2": "11.2"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
@ -392,8 +301,6 @@
|
|||
},
|
||||
"variants": {
|
||||
"12-2": {
|
||||
"enabled": true,
|
||||
"variant_label": "12.2",
|
||||
"executables": {
|
||||
"windows": [
|
||||
"C:\\Program Files\\Nuke12.2v3\\Nuke12.2.exe"
|
||||
|
|
@ -417,8 +324,6 @@
|
|||
"environment": {}
|
||||
},
|
||||
"12-0": {
|
||||
"enabled": true,
|
||||
"variant_label": "12.0",
|
||||
"executables": {
|
||||
"windows": [
|
||||
"C:\\Program Files\\Nuke12.0v1\\Nuke12.0.exe"
|
||||
|
|
@ -442,8 +347,6 @@
|
|||
"environment": {}
|
||||
},
|
||||
"11-3": {
|
||||
"enabled": true,
|
||||
"variant_label": "11.3",
|
||||
"executables": {
|
||||
"windows": [
|
||||
"C:\\Program Files\\Nuke11.3v1\\Nuke11.3.exe"
|
||||
|
|
@ -467,8 +370,6 @@
|
|||
"environment": {}
|
||||
},
|
||||
"11-2": {
|
||||
"enabled": true,
|
||||
"variant_label": "11.2",
|
||||
"executables": {
|
||||
"windows": [],
|
||||
"darwin": [],
|
||||
|
|
@ -486,6 +387,12 @@
|
|||
]
|
||||
},
|
||||
"environment": {}
|
||||
},
|
||||
"__dynamic_keys_labels__": {
|
||||
"12-2": "12.2",
|
||||
"12-0": "12.0",
|
||||
"11-3": "11.3",
|
||||
"11-2": "11.2"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
@ -507,8 +414,6 @@
|
|||
},
|
||||
"variants": {
|
||||
"12-2": {
|
||||
"enabled": true,
|
||||
"variant_label": "12.2",
|
||||
"executables": {
|
||||
"windows": [
|
||||
"C:\\Program Files\\Nuke12.2v3\\Nuke12.2.exe"
|
||||
|
|
@ -532,8 +437,6 @@
|
|||
"environment": {}
|
||||
},
|
||||
"12-0": {
|
||||
"enabled": true,
|
||||
"variant_label": "12.0",
|
||||
"executables": {
|
||||
"windows": [
|
||||
"C:\\Program Files\\Nuke12.0v1\\Nuke12.0.exe"
|
||||
|
|
@ -557,8 +460,6 @@
|
|||
"environment": {}
|
||||
},
|
||||
"11-3": {
|
||||
"enabled": true,
|
||||
"variant_label": "11.3",
|
||||
"executables": {
|
||||
"windows": [
|
||||
"C:\\Program Files\\Nuke11.3v1\\Nuke11.3.exe"
|
||||
|
|
@ -582,8 +483,6 @@
|
|||
"environment": {}
|
||||
},
|
||||
"11-2": {
|
||||
"enabled": true,
|
||||
"variant_label": "11.2",
|
||||
"executables": {
|
||||
"windows": [
|
||||
"C:\\Program Files\\Nuke11.2v2\\Nuke11.2.exe"
|
||||
|
|
@ -603,6 +502,12 @@
|
|||
]
|
||||
},
|
||||
"environment": {}
|
||||
},
|
||||
"__dynamic_keys_labels__": {
|
||||
"12-2": "12.2",
|
||||
"12-0": "12.0",
|
||||
"11-3": "11.3",
|
||||
"11-2": "11.2"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
@ -752,8 +657,6 @@
|
|||
},
|
||||
"variants": {
|
||||
"18-5": {
|
||||
"enabled": true,
|
||||
"variant_label": "18.5",
|
||||
"executables": {
|
||||
"windows": [
|
||||
"C:\\Program Files\\Side Effects Software\\Houdini 18.5.499\\bin\\houdini.exe"
|
||||
|
|
@ -769,8 +672,6 @@
|
|||
"environment": {}
|
||||
},
|
||||
"18": {
|
||||
"enabled": true,
|
||||
"variant_label": "18",
|
||||
"executables": {
|
||||
"windows": [],
|
||||
"darwin": [],
|
||||
|
|
@ -784,8 +685,6 @@
|
|||
"environment": {}
|
||||
},
|
||||
"17": {
|
||||
"enabled": true,
|
||||
"variant_label": "17",
|
||||
"executables": {
|
||||
"windows": [],
|
||||
"darwin": [],
|
||||
|
|
@ -797,6 +696,11 @@
|
|||
"linux": []
|
||||
},
|
||||
"environment": {}
|
||||
},
|
||||
"__dynamic_keys_labels__": {
|
||||
"18-5": "18.5",
|
||||
"18": "18",
|
||||
"17": "17"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
@ -815,8 +719,6 @@
|
|||
},
|
||||
"variants": {
|
||||
"2-83": {
|
||||
"enabled": true,
|
||||
"variant_label": "2.83",
|
||||
"executables": {
|
||||
"windows": [
|
||||
"C:\\Program Files\\Blender Foundation\\Blender 2.83\\blender.exe"
|
||||
|
|
@ -838,8 +740,6 @@
|
|||
"environment": {}
|
||||
},
|
||||
"2-90": {
|
||||
"enabled": true,
|
||||
"variant_label": "2.90",
|
||||
"executables": {
|
||||
"windows": [
|
||||
"C:\\Program Files\\Blender Foundation\\Blender 2.90\\blender.exe"
|
||||
|
|
@ -859,6 +759,10 @@
|
|||
]
|
||||
},
|
||||
"environment": {}
|
||||
},
|
||||
"__dynamic_keys_labels__": {
|
||||
"2-83": "2.83",
|
||||
"2-90": "2.90"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
@ -916,8 +820,6 @@
|
|||
},
|
||||
"variants": {
|
||||
"animation_11-64bits": {
|
||||
"enabled": true,
|
||||
"variant_label": "11 (64bits)",
|
||||
"executables": {
|
||||
"windows": [
|
||||
"C:\\Program Files\\TVPaint Developpement\\TVPaint Animation 11 (64bits)\\TVPaint Animation 11 (64bits).exe"
|
||||
|
|
@ -933,8 +835,6 @@
|
|||
"environment": {}
|
||||
},
|
||||
"animation_11-32bits": {
|
||||
"enabled": true,
|
||||
"variant_label": "11 (32bits)",
|
||||
"executables": {
|
||||
"windows": [
|
||||
"C:\\Program Files (x86)\\TVPaint Developpement\\TVPaint Animation 11 (32bits)\\TVPaint Animation 11 (32bits).exe"
|
||||
|
|
@ -948,6 +848,10 @@
|
|||
"linux": []
|
||||
},
|
||||
"environment": {}
|
||||
},
|
||||
"__dynamic_keys_labels__": {
|
||||
"animation_11-64bits": "11 (64bits)",
|
||||
"animation_11-32bits": "11 (32bits)"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
@ -1085,8 +989,6 @@
|
|||
},
|
||||
"variants": {
|
||||
"4-24": {
|
||||
"enabled": true,
|
||||
"variant_label": "4.24",
|
||||
"executables": {
|
||||
"windows": [],
|
||||
"darwin": [],
|
||||
|
|
@ -1106,8 +1008,6 @@
|
|||
"environment": {},
|
||||
"variants": {
|
||||
"python_3-7": {
|
||||
"enabled": true,
|
||||
"variant_label": "3.7",
|
||||
"executables": {
|
||||
"windows": [],
|
||||
"darwin": [],
|
||||
|
|
@ -1121,8 +1021,6 @@
|
|||
"environment": {}
|
||||
},
|
||||
"python_2-7": {
|
||||
"enabled": true,
|
||||
"variant_label": "2.7",
|
||||
"executables": {
|
||||
"windows": [],
|
||||
"darwin": [],
|
||||
|
|
@ -1136,8 +1034,6 @@
|
|||
"environment": {}
|
||||
},
|
||||
"terminal": {
|
||||
"enabled": true,
|
||||
"variant_label": "",
|
||||
"executables": {
|
||||
"windows": [],
|
||||
"darwin": [],
|
||||
|
|
@ -1149,6 +1045,10 @@
|
|||
"linux": []
|
||||
},
|
||||
"environment": {}
|
||||
},
|
||||
"__dynamic_keys_labels__": {
|
||||
"python_3-7": "Python 3.7",
|
||||
"python_2-7": "Python 2.7"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
@ -1160,8 +1060,6 @@
|
|||
"environment": {},
|
||||
"variants": {
|
||||
"1-1": {
|
||||
"enabled": true,
|
||||
"variant_label": "1.1",
|
||||
"executables": {
|
||||
"windows": [],
|
||||
"darwin": [],
|
||||
|
|
@ -1173,6 +1071,9 @@
|
|||
"linux": []
|
||||
},
|
||||
"environment": {}
|
||||
},
|
||||
"__dynamic_keys_labels__": {
|
||||
"1-1": "1.1"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -126,6 +126,7 @@
|
|||
},
|
||||
"timers_manager": {
|
||||
"enabled": true,
|
||||
"auto_stop": true,
|
||||
"full_time": 15.0,
|
||||
"message_time": 0.5
|
||||
},
|
||||
|
|
@ -165,8 +166,5 @@
|
|||
},
|
||||
"standalonepublish_tool": {
|
||||
"enabled": true
|
||||
},
|
||||
"idle_manager": {
|
||||
"enabled": true
|
||||
}
|
||||
}
|
||||
|
|
@ -226,7 +226,16 @@ class DictMutableKeysEntity(EndpointEntity):
|
|||
self.is_group = True
|
||||
|
||||
def schema_validations(self):
|
||||
# Allow to have not set label if keys are collapsible
|
||||
# - this it to bypass label validation
|
||||
used_temp_label = False
|
||||
if self.is_group and not self.label and self.collapsible_key:
|
||||
used_temp_label = True
|
||||
self.label = "LABEL"
|
||||
|
||||
super(DictMutableKeysEntity, self).schema_validations()
|
||||
if used_temp_label:
|
||||
self.label = None
|
||||
|
||||
if not self.schema_data.get("object_type"):
|
||||
reason = (
|
||||
|
|
|
|||
|
|
@ -128,13 +128,21 @@ class AppsEnumEntity(BaseEnumEntity):
|
|||
continue
|
||||
|
||||
group_label = app_group["label"].value
|
||||
|
||||
for variant_name, variant_entity in app_group["variants"].items():
|
||||
variants_entity = app_group["variants"]
|
||||
for variant_name, variant_entity in variants_entity.items():
|
||||
enabled_entity = variant_entity.get("enabled")
|
||||
if enabled_entity and not enabled_entity.value:
|
||||
continue
|
||||
|
||||
variant_label = variant_entity["variant_label"].value
|
||||
variant_label = None
|
||||
if "variant_label" in variant_entity:
|
||||
variant_label = variant_entity["variant_label"].value
|
||||
elif hasattr(variants_entity, "get_key_label"):
|
||||
variant_label = variants_entity.get_key_label(variant_name)
|
||||
|
||||
if not variant_label:
|
||||
variant_label = variant_name
|
||||
|
||||
if group_label:
|
||||
full_label = "{} {}".format(group_label, variant_label)
|
||||
else:
|
||||
|
|
|
|||
|
|
@ -20,24 +20,22 @@
|
|||
"type": "raw-json"
|
||||
},
|
||||
{
|
||||
"type": "dict",
|
||||
"type": "dict-modifiable",
|
||||
"key": "variants",
|
||||
"children": [
|
||||
{
|
||||
"type": "schema_template",
|
||||
"name": "template_host_variant",
|
||||
"template_data": [
|
||||
{
|
||||
"app_variant_label": "2.83",
|
||||
"app_variant": "2-83"
|
||||
},
|
||||
{
|
||||
"app_variant_label": "2.90",
|
||||
"app_variant": "2-90"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
"collapsible_key": true,
|
||||
"dynamic_label": false,
|
||||
"use_label_wrap": false,
|
||||
"object_type": {
|
||||
"type": "dict",
|
||||
"collapsible": true,
|
||||
"checkbox_key": "enabled",
|
||||
"children": [
|
||||
{
|
||||
"type": "schema_template",
|
||||
"name": "template_host_variant_items"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,18 +20,22 @@
|
|||
"type": "raw-json"
|
||||
},
|
||||
{
|
||||
"type": "dict",
|
||||
"type": "dict-modifiable",
|
||||
"key": "variants",
|
||||
"children": [
|
||||
{
|
||||
"type": "schema_template",
|
||||
"name": "template_host_variant",
|
||||
"template_data": {
|
||||
"app_variant_label": "1.1",
|
||||
"app_variant": "1-1"
|
||||
"collapsible_key": true,
|
||||
"dynamic_label": false,
|
||||
"use_label_wrap": false,
|
||||
"object_type": {
|
||||
"type": "dict",
|
||||
"collapsible": true,
|
||||
"checkbox_key": "enabled",
|
||||
"children": [
|
||||
{
|
||||
"type": "schema_template",
|
||||
"name": "template_host_variant_items"
|
||||
}
|
||||
}
|
||||
]
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,28 +20,22 @@
|
|||
"type": "raw-json"
|
||||
},
|
||||
{
|
||||
"type": "dict",
|
||||
"type": "dict-modifiable",
|
||||
"key": "variants",
|
||||
"children": [
|
||||
{
|
||||
"type": "schema_template",
|
||||
"name": "template_host_variant",
|
||||
"template_data": [
|
||||
{
|
||||
"app_variant_label": "18.5",
|
||||
"app_variant": "18-5"
|
||||
},
|
||||
{
|
||||
"app_variant_label": "18",
|
||||
"app_variant": "18"
|
||||
},
|
||||
{
|
||||
"app_variant_label": "17",
|
||||
"app_variant": "17"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
"collapsible_key": true,
|
||||
"dynamic_label": false,
|
||||
"use_label_wrap": false,
|
||||
"object_type": {
|
||||
"type": "dict",
|
||||
"collapsible": true,
|
||||
"checkbox_key": "enabled",
|
||||
"children": [
|
||||
{
|
||||
"type": "schema_template",
|
||||
"name": "template_host_variant_items"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,28 +20,22 @@
|
|||
"type": "raw-json"
|
||||
},
|
||||
{
|
||||
"type": "dict",
|
||||
"type": "dict-modifiable",
|
||||
"key": "variants",
|
||||
"children": [
|
||||
{
|
||||
"type": "schema_template",
|
||||
"name": "template_host_variant",
|
||||
"template_data": [
|
||||
{
|
||||
"app_variant_label": "2020",
|
||||
"app_variant": "2020"
|
||||
},
|
||||
{
|
||||
"app_variant_label": "2019",
|
||||
"app_variant": "2019"
|
||||
},
|
||||
{
|
||||
"app_variant_label": "2018",
|
||||
"app_variant": "2018"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
"collapsible_key": true,
|
||||
"dynamic_label": false,
|
||||
"use_label_wrap": false,
|
||||
"object_type": {
|
||||
"type": "dict",
|
||||
"collapsible": true,
|
||||
"checkbox_key": "enabled",
|
||||
"children": [
|
||||
{
|
||||
"type": "schema_template",
|
||||
"name": "template_host_variant_items"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,47 +0,0 @@
|
|||
{
|
||||
"type": "dict",
|
||||
"key": "mayabatch",
|
||||
"label": "Autodesk Maya Batch",
|
||||
"collapsible": true,
|
||||
"checkbox_key": "enabled",
|
||||
"children": [
|
||||
{
|
||||
"type": "boolean",
|
||||
"key": "enabled",
|
||||
"label": "Enabled"
|
||||
},
|
||||
{
|
||||
"type": "schema_template",
|
||||
"name": "template_host_unchangables"
|
||||
},
|
||||
{
|
||||
"key": "environment",
|
||||
"label": "Environment",
|
||||
"type": "raw-json"
|
||||
},
|
||||
{
|
||||
"type": "dict",
|
||||
"key": "variants",
|
||||
"children": [
|
||||
{
|
||||
"type": "schema_template",
|
||||
"name": "template_host_variant",
|
||||
"template_data": [
|
||||
{
|
||||
"app_variant_label": "2020",
|
||||
"app_variant": "2020"
|
||||
},
|
||||
{
|
||||
"app_variant_label": "2019",
|
||||
"app_variant": "2019"
|
||||
},
|
||||
{
|
||||
"app_variant_label": "2018",
|
||||
"app_variant": "2018"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
@ -16,28 +16,22 @@
|
|||
"type": "raw-json"
|
||||
},
|
||||
{
|
||||
"type": "dict",
|
||||
"type": "dict-modifiable",
|
||||
"key": "variants",
|
||||
"children": [
|
||||
{
|
||||
"type": "schema_template",
|
||||
"name": "template_host_variant",
|
||||
"template_data": [
|
||||
{
|
||||
"app_variant": "python_3-7",
|
||||
"app_variant_label": "Python 3.7"
|
||||
},
|
||||
{
|
||||
"app_variant": "python_2-7",
|
||||
"app_variant_label": "Python 2.7"
|
||||
},
|
||||
{
|
||||
"app_variant": "terminal",
|
||||
"app_variant_label": "Terminal"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
"collapsible_key": true,
|
||||
"dynamic_label": false,
|
||||
"use_label_wrap": false,
|
||||
"object_type": {
|
||||
"type": "dict",
|
||||
"collapsible": true,
|
||||
"checkbox_key": "enabled",
|
||||
"children": [
|
||||
{
|
||||
"type": "schema_template",
|
||||
"name": "template_host_variant_items"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,24 +20,22 @@
|
|||
"type": "raw-json"
|
||||
},
|
||||
{
|
||||
"type": "dict",
|
||||
"type": "dict-modifiable",
|
||||
"key": "variants",
|
||||
"children": [
|
||||
{
|
||||
"type": "schema_template",
|
||||
"name": "template_host_variant",
|
||||
"template_data": [
|
||||
{
|
||||
"app_variant_label": "Animation 11 (64bits)",
|
||||
"app_variant": "animation_11-64bits"
|
||||
},
|
||||
{
|
||||
"app_variant_label": "Animation 11 (32bits)",
|
||||
"app_variant": "animation_11-32bits"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
"collapsible_key": true,
|
||||
"dynamic_label": false,
|
||||
"use_label_wrap": false,
|
||||
"object_type": {
|
||||
"type": "dict",
|
||||
"collapsible": true,
|
||||
"checkbox_key": "enabled",
|
||||
"children": [
|
||||
{
|
||||
"type": "schema_template",
|
||||
"name": "template_host_variant_items"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,20 +20,22 @@
|
|||
"type": "raw-json"
|
||||
},
|
||||
{
|
||||
"type": "dict",
|
||||
"type": "dict-modifiable",
|
||||
"key": "variants",
|
||||
"children": [
|
||||
{
|
||||
"type": "schema_template",
|
||||
"name": "template_host_variant",
|
||||
"template_data": [
|
||||
{
|
||||
"app_variant": "4-24",
|
||||
"app_variant_label": "4.24"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
"collapsible_key": true,
|
||||
"dynamic_label": false,
|
||||
"use_label_wrap": false,
|
||||
"object_type": {
|
||||
"type": "dict",
|
||||
"collapsible": true,
|
||||
"checkbox_key": "enabled",
|
||||
"children": [
|
||||
{
|
||||
"type": "schema_template",
|
||||
"name": "template_host_variant_items"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,48 +15,11 @@
|
|||
"type": "text",
|
||||
"key": "variant_label",
|
||||
"label": "Variant label",
|
||||
"placeholder": "Only \"Label\" is used if not filled."
|
||||
"placeholder": "< {app_variant} >"
|
||||
},
|
||||
{
|
||||
"type": "path",
|
||||
"key": "executables",
|
||||
"label": "Executables",
|
||||
"multiplatform": true,
|
||||
"multipath": true
|
||||
},
|
||||
{
|
||||
"type":"separator"
|
||||
},
|
||||
{
|
||||
"type": "dict",
|
||||
"key": "arguments",
|
||||
"label": "Arguments",
|
||||
"use_label_wrap": false,
|
||||
"children": [
|
||||
{
|
||||
"key": "windows",
|
||||
"label": "Windows",
|
||||
"type": "list",
|
||||
"object_type": "text"
|
||||
},
|
||||
{
|
||||
"key": "darwin",
|
||||
"label": "MacOS",
|
||||
"type": "list",
|
||||
"object_type": "text"
|
||||
},
|
||||
{
|
||||
"key": "linux",
|
||||
"label": "Linux",
|
||||
"type": "list",
|
||||
"object_type": "text"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"key": "environment",
|
||||
"label": "Environment",
|
||||
"type": "raw-json"
|
||||
"type": "schema_template",
|
||||
"name": "template_host_variant_items"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,43 @@
|
|||
[
|
||||
{
|
||||
"type": "path",
|
||||
"key": "executables",
|
||||
"label": "Executables",
|
||||
"multiplatform": true,
|
||||
"multipath": true
|
||||
},
|
||||
{
|
||||
"type":"separator"
|
||||
},
|
||||
{
|
||||
"type": "dict",
|
||||
"key": "arguments",
|
||||
"label": "Arguments",
|
||||
"use_label_wrap": false,
|
||||
"children": [
|
||||
{
|
||||
"key": "windows",
|
||||
"label": "Windows",
|
||||
"type": "list",
|
||||
"object_type": "text"
|
||||
},
|
||||
{
|
||||
"key": "darwin",
|
||||
"label": "MacOS",
|
||||
"type": "list",
|
||||
"object_type": "text"
|
||||
},
|
||||
{
|
||||
"key": "linux",
|
||||
"label": "Linux",
|
||||
"type": "list",
|
||||
"object_type": "text"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"key": "environment",
|
||||
"label": "Environment",
|
||||
"type": "raw-json"
|
||||
}
|
||||
]
|
||||
|
|
@ -21,32 +21,22 @@
|
|||
"type": "raw-json"
|
||||
},
|
||||
{
|
||||
"type": "dict",
|
||||
"type": "dict-modifiable",
|
||||
"key": "variants",
|
||||
"children": [
|
||||
{
|
||||
"type": "schema_template",
|
||||
"name": "template_host_variant",
|
||||
"template_data": [
|
||||
{
|
||||
"app_variant": "12-2",
|
||||
"app_variant_label": "12.2"
|
||||
},
|
||||
{
|
||||
"app_variant": "12-0",
|
||||
"app_variant_label": "12.0"
|
||||
},
|
||||
{
|
||||
"app_variant": "11-3",
|
||||
"app_variant_label": "11.3"
|
||||
},
|
||||
{
|
||||
"app_variant": "11-2",
|
||||
"app_variant_label": "11.2"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
"collapsible_key": true,
|
||||
"dynamic_label": false,
|
||||
"use_label_wrap": false,
|
||||
"object_type": {
|
||||
"type": "dict",
|
||||
"collapsible": true,
|
||||
"checkbox_key": "enabled",
|
||||
"children": [
|
||||
{
|
||||
"type": "schema_template",
|
||||
"name": "template_host_variant_items"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,10 +9,6 @@
|
|||
"type": "schema",
|
||||
"name": "schema_maya"
|
||||
},
|
||||
{
|
||||
"type": "schema",
|
||||
"name": "schema_mayabatch"
|
||||
},
|
||||
{
|
||||
"type": "schema_template",
|
||||
"name": "template_nuke",
|
||||
|
|
|
|||
|
|
@ -42,6 +42,11 @@
|
|||
"key": "enabled",
|
||||
"label": "Enabled"
|
||||
},
|
||||
{
|
||||
"type": "boolean",
|
||||
"key": "auto_stop",
|
||||
"label": "Auto stop timer"
|
||||
},
|
||||
{
|
||||
"type": "number",
|
||||
"decimal": 2,
|
||||
|
|
@ -176,20 +181,6 @@
|
|||
"label": "Enabled"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "dict",
|
||||
"key": "idle_manager",
|
||||
"label": "Idle Manager",
|
||||
"collapsible": true,
|
||||
"checkbox_key": "enabled",
|
||||
"children": [
|
||||
{
|
||||
"type": "boolean",
|
||||
"key": "enabled",
|
||||
"label": "Enabled"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
|
|||
|
|
@ -489,7 +489,7 @@ def apply_local_settings_on_system_settings(system_settings, local_settings):
|
|||
# TODO This is temporary fix until launch arguments will be stored
|
||||
# per platform and not per executable.
|
||||
# - local settings store only executable
|
||||
new_executables = [[executable, ""]]
|
||||
new_executables = [executable]
|
||||
new_executables.extend(platform_executables)
|
||||
variants[app_name]["executables"] = new_executables
|
||||
|
||||
|
|
@ -645,13 +645,22 @@ def apply_local_settings_on_project_settings(
|
|||
sync_server_config["remote_site"] = remote_site
|
||||
|
||||
|
||||
def get_system_settings(clear_metadata=True):
|
||||
def get_system_settings(clear_metadata=True, exclude_locals=None):
|
||||
"""System settings with applied studio overrides."""
|
||||
default_values = get_default_settings()[SYSTEM_SETTINGS_KEY]
|
||||
studio_values = get_studio_system_settings_overrides()
|
||||
result = apply_overrides(default_values, studio_values)
|
||||
|
||||
# Clear overrides metadata from settings
|
||||
if clear_metadata:
|
||||
clear_metadata_from_settings(result)
|
||||
|
||||
# Apply local settings
|
||||
# Default behavior is based on `clear_metadata` value
|
||||
if exclude_locals is None:
|
||||
exclude_locals = not clear_metadata
|
||||
|
||||
if not exclude_locals:
|
||||
# TODO local settings may be required to apply for environments
|
||||
local_settings = get_local_settings()
|
||||
apply_local_settings_on_system_settings(result, local_settings)
|
||||
|
|
@ -659,40 +668,52 @@ def get_system_settings(clear_metadata=True):
|
|||
return result
|
||||
|
||||
|
||||
def get_default_project_settings(clear_metadata=True, exclude_locals=False):
|
||||
def get_default_project_settings(clear_metadata=True, exclude_locals=None):
|
||||
"""Project settings with applied studio's default project overrides."""
|
||||
default_values = get_default_settings()[PROJECT_SETTINGS_KEY]
|
||||
studio_values = get_studio_project_settings_overrides()
|
||||
result = apply_overrides(default_values, studio_values)
|
||||
# Clear overrides metadata from settings
|
||||
if clear_metadata:
|
||||
clear_metadata_from_settings(result)
|
||||
if not exclude_locals:
|
||||
local_settings = get_local_settings()
|
||||
apply_local_settings_on_project_settings(
|
||||
result, local_settings, None
|
||||
)
|
||||
|
||||
# Apply local settings
|
||||
if exclude_locals is None:
|
||||
exclude_locals = not clear_metadata
|
||||
|
||||
if not exclude_locals:
|
||||
local_settings = get_local_settings()
|
||||
apply_local_settings_on_project_settings(
|
||||
result, local_settings, None
|
||||
)
|
||||
return result
|
||||
|
||||
|
||||
def get_default_anatomy_settings(clear_metadata=True, exclude_locals=False):
|
||||
def get_default_anatomy_settings(clear_metadata=True, exclude_locals=None):
|
||||
"""Project anatomy data with applied studio's default project overrides."""
|
||||
default_values = get_default_settings()[PROJECT_ANATOMY_KEY]
|
||||
studio_values = get_studio_project_anatomy_overrides()
|
||||
|
||||
# TODO uncomment and remove hotfix result when overrides of anatomy
|
||||
# are stored correctly.
|
||||
result = apply_overrides(default_values, studio_values)
|
||||
# Clear overrides metadata from settings
|
||||
if clear_metadata:
|
||||
clear_metadata_from_settings(result)
|
||||
if not exclude_locals:
|
||||
local_settings = get_local_settings()
|
||||
apply_local_settings_on_anatomy_settings(
|
||||
result, local_settings, None
|
||||
)
|
||||
|
||||
# Apply local settings
|
||||
if exclude_locals is None:
|
||||
exclude_locals = not clear_metadata
|
||||
|
||||
if not exclude_locals:
|
||||
local_settings = get_local_settings()
|
||||
apply_local_settings_on_anatomy_settings(
|
||||
result, local_settings, None
|
||||
)
|
||||
return result
|
||||
|
||||
|
||||
def get_anatomy_settings(project_name, site_name=None, exclude_locals=False):
|
||||
def get_anatomy_settings(
|
||||
project_name, site_name=None, clear_metadata=True, exclude_locals=None
|
||||
):
|
||||
"""Project anatomy data with applied studio and project overrides."""
|
||||
if not project_name:
|
||||
raise ValueError(
|
||||
|
|
@ -709,7 +730,13 @@ def get_anatomy_settings(project_name, site_name=None, exclude_locals=False):
|
|||
for key, value in project_overrides.items():
|
||||
result[key] = value
|
||||
|
||||
clear_metadata_from_settings(result)
|
||||
# Clear overrides metadata from settings
|
||||
if clear_metadata:
|
||||
clear_metadata_from_settings(result)
|
||||
|
||||
# Apply local settings
|
||||
if exclude_locals is None:
|
||||
exclude_locals = not clear_metadata
|
||||
|
||||
if not exclude_locals:
|
||||
local_settings = get_local_settings()
|
||||
|
|
@ -719,7 +746,9 @@ def get_anatomy_settings(project_name, site_name=None, exclude_locals=False):
|
|||
return result
|
||||
|
||||
|
||||
def get_project_settings(project_name, exclude_locals=False):
|
||||
def get_project_settings(
|
||||
project_name, clear_metadata=True, exclude_locals=None
|
||||
):
|
||||
"""Project settings with applied studio and project overrides."""
|
||||
if not project_name:
|
||||
raise ValueError(
|
||||
|
|
@ -733,7 +762,14 @@ def get_project_settings(project_name, exclude_locals=False):
|
|||
)
|
||||
|
||||
result = apply_overrides(studio_overrides, project_overrides)
|
||||
clear_metadata_from_settings(result)
|
||||
|
||||
# Clear overrides metadata from settings
|
||||
if clear_metadata:
|
||||
clear_metadata_from_settings(result)
|
||||
|
||||
# Apply local settings
|
||||
if exclude_locals is None:
|
||||
exclude_locals = not clear_metadata
|
||||
|
||||
if not exclude_locals:
|
||||
local_settings = get_local_settings()
|
||||
|
|
|
|||
|
|
@ -10,12 +10,20 @@ from .constants import CHILD_OFFSET
|
|||
class AppVariantWidget(QtWidgets.QWidget):
|
||||
exec_placeholder = "< Specific path for this machine >"
|
||||
|
||||
def __init__(self, group_label, variant_entity, parent):
|
||||
def __init__(self, group_label, variant_name, variant_entity, parent):
|
||||
super(AppVariantWidget, self).__init__(parent)
|
||||
|
||||
self.executable_input_widget = None
|
||||
variant_label = variant_entity.label
|
||||
if variant_label is None:
|
||||
parent_entity = variant_entity.parent
|
||||
if hasattr(parent_entity, "get_key_label"):
|
||||
variant_label = parent_entity.get_key_label(variant_name)
|
||||
|
||||
label = " ".join([group_label, variant_entity.label])
|
||||
if not variant_label:
|
||||
variant_label = variant_name
|
||||
|
||||
label = " ".join([group_label, variant_label])
|
||||
|
||||
expading_widget = ExpandingWidget(label, self)
|
||||
content_widget = QtWidgets.QWidget(expading_widget)
|
||||
|
|
@ -102,7 +110,7 @@ class AppGroupWidget(QtWidgets.QWidget):
|
|||
|
||||
valid_variants = {}
|
||||
for key, entity in group_entity["variants"].items():
|
||||
if entity["enabled"].value:
|
||||
if "enabled" not in entity or entity["enabled"].value:
|
||||
valid_variants[key] = entity
|
||||
|
||||
group_label = group_entity.label
|
||||
|
|
@ -114,7 +122,7 @@ class AppGroupWidget(QtWidgets.QWidget):
|
|||
widgets_by_variant_name = {}
|
||||
for variant_name, variant_entity in valid_variants.items():
|
||||
variant_widget = AppVariantWidget(
|
||||
group_label, variant_entity, content_widget
|
||||
group_label, variant_name, variant_entity, content_widget
|
||||
)
|
||||
widgets_by_variant_name[variant_name] = variant_widget
|
||||
content_layout.addWidget(variant_widget)
|
||||
|
|
@ -173,7 +181,10 @@ class LocalApplicationsWidgets(QtWidgets.QWidget):
|
|||
# Check if has enabled any variant
|
||||
enabled_variant = False
|
||||
for variant_entity in entity["variants"].values():
|
||||
if variant_entity["enabled"].value:
|
||||
if (
|
||||
"enabled" not in variant_entity
|
||||
or variant_entity["enabled"].value
|
||||
):
|
||||
enabled_variant = True
|
||||
break
|
||||
|
||||
|
|
|
|||
|
|
@ -103,7 +103,10 @@ class ModifiableDictEmptyItem(QtWidgets.QWidget):
|
|||
self.key_is_valid = KEY_REGEX.match(key)
|
||||
self.is_duplicated = self.entity_widget.is_key_duplicated(key)
|
||||
key_input_state = ""
|
||||
if self.is_duplicated or not self.key_is_valid:
|
||||
# Collapsible key and empty key are not invalid
|
||||
if self.collapsible_key and self.key_input.text() == "":
|
||||
pass
|
||||
elif self.is_duplicated or not self.key_is_valid:
|
||||
key_input_state = "invalid"
|
||||
elif key != "":
|
||||
key_input_state = "modified"
|
||||
|
|
|
|||
4
start.py
4
start.py
|
|
@ -296,7 +296,7 @@ def _determine_mongodb() -> str:
|
|||
if not openpype_mongo:
|
||||
# try system keyring
|
||||
try:
|
||||
openpype_mongo = bootstrap.registry.get_secure_item(
|
||||
openpype_mongo = bootstrap.secure_registry.get_item(
|
||||
"openPypeMongo")
|
||||
except ValueError:
|
||||
print("*** No DB connection string specified.")
|
||||
|
|
@ -305,7 +305,7 @@ def _determine_mongodb() -> str:
|
|||
igniter.open_dialog()
|
||||
|
||||
try:
|
||||
openpype_mongo = bootstrap.registry.get_secure_item(
|
||||
openpype_mongo = bootstrap.secure_registry.get_item(
|
||||
"openPypeMongo")
|
||||
except ValueError:
|
||||
raise RuntimeError("missing mongodb url")
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ import pytest
|
|||
|
||||
from igniter.bootstrap_repos import BootstrapRepos
|
||||
from igniter.bootstrap_repos import PypeVersion
|
||||
from pype.lib import PypeSettingsRegistry
|
||||
from pype.lib import OpenPypeSettingsRegistry
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
|
|
@ -348,7 +348,7 @@ def test_find_pype(fix_bootstrap, tmp_path_factory, monkeypatch, printer):
|
|||
return d_path.as_posix()
|
||||
|
||||
monkeypatch.setattr(appdirs, "user_data_dir", mock_user_data_dir)
|
||||
fix_bootstrap.registry = PypeSettingsRegistry()
|
||||
fix_bootstrap.registry = OpenPypeSettingsRegistry()
|
||||
fix_bootstrap.registry.set_item("pypePath", d_path.as_posix())
|
||||
|
||||
result = fix_bootstrap.find_pype(include_zips=True)
|
||||
|
|
|
|||
|
|
@ -1,10 +1,20 @@
|
|||
import pytest
|
||||
from pype.lib import IniSettingRegistry
|
||||
from pype.lib import JSONSettingRegistry
|
||||
from pype.lib import (
|
||||
IniSettingRegistry,
|
||||
JSONSettingRegistry,
|
||||
OpenPypeSecureRegistry
|
||||
)
|
||||
from uuid import uuid4
|
||||
import configparser
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def secure_registry(tmpdir):
|
||||
name = "pypetest_{}".format(str(uuid4()))
|
||||
r = OpenPypeSecureRegistry(name, tmpdir)
|
||||
yield r
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def json_registry(tmpdir):
|
||||
name = "pypetest_{}".format(str(uuid4()))
|
||||
|
|
@ -19,21 +29,21 @@ def ini_registry(tmpdir):
|
|||
yield r
|
||||
|
||||
|
||||
def test_keyring(json_registry):
|
||||
json_registry.set_secure_item("item1", "foo")
|
||||
json_registry.set_secure_item("item2", "bar")
|
||||
result1 = json_registry.get_secure_item("item1")
|
||||
result2 = json_registry.get_secure_item("item2")
|
||||
def test_keyring(secure_registry):
|
||||
secure_registry.set_item("item1", "foo")
|
||||
secure_registry.set_item("item2", "bar")
|
||||
result1 = secure_registry.get_item("item1")
|
||||
result2 = secure_registry.get_item("item2")
|
||||
|
||||
assert result1 == "foo"
|
||||
assert result2 == "bar"
|
||||
|
||||
json_registry.delete_secure_item("item1")
|
||||
json_registry.delete_secure_item("item2")
|
||||
secure_registry.delete_item("item1")
|
||||
secure_registry.delete_item("item2")
|
||||
|
||||
with pytest.raises(ValueError):
|
||||
json_registry.get_secure_item("item1")
|
||||
json_registry.get_secure_item("item2")
|
||||
secure_registry.get_item("item1")
|
||||
secure_registry.get_item("item2")
|
||||
|
||||
|
||||
def test_ini_registry(ini_registry):
|
||||
|
|
|
|||
|
|
@ -65,23 +65,20 @@ To build pype on linux you wil need:
|
|||
|
||||
- **[curl](https://curl.se)** on systems that doesn't have one preinstalled.
|
||||
- Python header files installed (**python3-dev** on Ubuntu for example).
|
||||
- **[CMake](https://cmake.org/)**: to build some external openPype dependencies.
|
||||
- **bzip2**, **readline** and **sqlite3** libraries.
|
||||
- **bzip2**, **readline**, **sqlite3** and other libraries.
|
||||
|
||||
Because some Linux distros come with newer Python version pre-installed, you might
|
||||
need to install **3.7** version and make use of it explicitly.
|
||||
Your best bet is probably using [pyenv](https://github.com/pyenv/pyenv).
|
||||
|
||||
You can use your package manager to install **git** and **cmake**.
|
||||
You can use your package manager to install **git** and other packages to your build
|
||||
environment.
|
||||
Use curl for pyenv installation
|
||||
|
||||
:::note Install build requirements for **Ubuntu**
|
||||
|
||||
|
||||
```sh
|
||||
sudo apt install build-essential checkinstall
|
||||
sudo apt install git cmake curl
|
||||
sudo apt install libbz2-dev libreadline-dev libsqlite3-dev
|
||||
sudo apt-get update; sudo apt-get install --no-install-recommends make build-essential libssl-dev zlib1g-dev libbz2-dev libreadline-dev libsqlite3-dev wget curl llvm libncurses5-dev xz-utils tk-dev libxml2-dev libxmlsec1-dev libffi-dev liblzma-dev git
|
||||
```
|
||||
|
||||
In case you run in error about `xcb` when running Pype,
|
||||
|
|
@ -95,8 +92,7 @@ sudo apt install qt5-default
|
|||
:::note Install build requirements for **Centos**
|
||||
|
||||
```sh
|
||||
sudo yum install git cmake python3-devel python3-pip
|
||||
sudo yum install bzip2-devel readline-devel sqlite-devel
|
||||
yum install gcc zlib-devel bzip2 bzip2-devel readline-devel sqlite sqlite-devel openssl-devel tk-devel libffi-devel git
|
||||
```
|
||||
|
||||
In case you run in error about `xcb` when running Pype,
|
||||
|
|
@ -108,6 +104,8 @@ sudo yum install qt5-qtbase-devel
|
|||
|
||||
:::
|
||||
|
||||
For more information about setting your build environmet please refer to [pyenv suggested build environment](https://github.com/pyenv/pyenv/wiki#suggested-build-environment)
|
||||
|
||||
#### Common steps for all Distros
|
||||
|
||||
Use pyenv to prepare Python version for Pype build
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue