mirror of
https://github.com/ynput/ayon-core.git
synced 2026-01-01 08:24:53 +01:00
Merge branch 'develop' into enhancement/context_entities_use_task_level_attributes
This commit is contained in:
commit
e0ff114283
31 changed files with 69 additions and 610 deletions
|
|
@ -9,10 +9,6 @@ AYON_CORE_ROOT = os.path.dirname(os.path.abspath(__file__))
|
||||||
# -------------------------
|
# -------------------------
|
||||||
PACKAGE_DIR = AYON_CORE_ROOT
|
PACKAGE_DIR = AYON_CORE_ROOT
|
||||||
PLUGINS_DIR = os.path.join(AYON_CORE_ROOT, "plugins")
|
PLUGINS_DIR = os.path.join(AYON_CORE_ROOT, "plugins")
|
||||||
AYON_SERVER_ENABLED = True
|
|
||||||
|
|
||||||
# Indicate if AYON entities should be used instead of OpenPype entities
|
|
||||||
USE_AYON_ENTITIES = True
|
|
||||||
# -------------------------
|
# -------------------------
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -23,6 +19,4 @@ __all__ = (
|
||||||
"AYON_CORE_ROOT",
|
"AYON_CORE_ROOT",
|
||||||
"PACKAGE_DIR",
|
"PACKAGE_DIR",
|
||||||
"PLUGINS_DIR",
|
"PLUGINS_DIR",
|
||||||
"AYON_SERVER_ENABLED",
|
|
||||||
"USE_AYON_ENTITIES",
|
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -36,9 +36,6 @@ IGNORED_FILENAMES = {
|
||||||
# Files ignored on addons import from "./ayon_core/modules"
|
# Files ignored on addons import from "./ayon_core/modules"
|
||||||
IGNORED_DEFAULT_FILENAMES = {
|
IGNORED_DEFAULT_FILENAMES = {
|
||||||
"__init__.py",
|
"__init__.py",
|
||||||
"base.py",
|
|
||||||
"interfaces.py",
|
|
||||||
"click_wrap.py",
|
|
||||||
}
|
}
|
||||||
|
|
||||||
# When addon was moved from ayon-core codebase
|
# When addon was moved from ayon-core codebase
|
||||||
|
|
@ -124,77 +121,10 @@ class ProcessContext:
|
||||||
print(f"Unknown keys in ProcessContext: {unknown_keys}")
|
print(f"Unknown keys in ProcessContext: {unknown_keys}")
|
||||||
|
|
||||||
|
|
||||||
# Inherit from `object` for Python 2 hosts
|
|
||||||
class _ModuleClass(object):
|
|
||||||
"""Fake module class for storing AYON addons.
|
|
||||||
|
|
||||||
Object of this class can be stored to `sys.modules` and used for storing
|
|
||||||
dynamically imported modules.
|
|
||||||
"""
|
|
||||||
|
|
||||||
def __init__(self, name):
|
|
||||||
# Call setattr on super class
|
|
||||||
super(_ModuleClass, self).__setattr__("name", name)
|
|
||||||
super(_ModuleClass, self).__setattr__("__name__", name)
|
|
||||||
|
|
||||||
# Where modules and interfaces are stored
|
|
||||||
super(_ModuleClass, self).__setattr__("__attributes__", dict())
|
|
||||||
super(_ModuleClass, self).__setattr__("__defaults__", set())
|
|
||||||
|
|
||||||
super(_ModuleClass, self).__setattr__("_log", None)
|
|
||||||
|
|
||||||
def __getattr__(self, attr_name):
|
|
||||||
if attr_name not in self.__attributes__:
|
|
||||||
if attr_name in ("__path__", "__file__"):
|
|
||||||
return None
|
|
||||||
raise AttributeError("'{}' has not attribute '{}'".format(
|
|
||||||
self.name, attr_name
|
|
||||||
))
|
|
||||||
return self.__attributes__[attr_name]
|
|
||||||
|
|
||||||
def __iter__(self):
|
|
||||||
for module in self.values():
|
|
||||||
yield module
|
|
||||||
|
|
||||||
def __setattr__(self, attr_name, value):
|
|
||||||
if attr_name in self.__attributes__:
|
|
||||||
self.log.warning(
|
|
||||||
"Duplicated name \"{}\" in {}. Overriding.".format(
|
|
||||||
attr_name, self.name
|
|
||||||
)
|
|
||||||
)
|
|
||||||
self.__attributes__[attr_name] = value
|
|
||||||
|
|
||||||
def __setitem__(self, key, value):
|
|
||||||
self.__setattr__(key, value)
|
|
||||||
|
|
||||||
def __getitem__(self, key):
|
|
||||||
return getattr(self, key)
|
|
||||||
|
|
||||||
@property
|
|
||||||
def log(self):
|
|
||||||
if self._log is None:
|
|
||||||
super(_ModuleClass, self).__setattr__(
|
|
||||||
"_log", Logger.get_logger(self.name)
|
|
||||||
)
|
|
||||||
return self._log
|
|
||||||
|
|
||||||
def get(self, key, default=None):
|
|
||||||
return self.__attributes__.get(key, default)
|
|
||||||
|
|
||||||
def keys(self):
|
|
||||||
return self.__attributes__.keys()
|
|
||||||
|
|
||||||
def values(self):
|
|
||||||
return self.__attributes__.values()
|
|
||||||
|
|
||||||
def items(self):
|
|
||||||
return self.__attributes__.items()
|
|
||||||
|
|
||||||
|
|
||||||
class _LoadCache:
|
class _LoadCache:
|
||||||
addons_lock = threading.Lock()
|
addons_lock = threading.Lock()
|
||||||
addons_loaded = False
|
addons_loaded = False
|
||||||
|
addon_modules = []
|
||||||
|
|
||||||
|
|
||||||
def load_addons(force=False):
|
def load_addons(force=False):
|
||||||
|
|
@ -308,7 +238,7 @@ def _handle_moved_addons(addon_name, milestone_version, log):
|
||||||
return addon_dir
|
return addon_dir
|
||||||
|
|
||||||
|
|
||||||
def _load_ayon_addons(openpype_modules, modules_key, log):
|
def _load_ayon_addons(log):
|
||||||
"""Load AYON addons based on information from server.
|
"""Load AYON addons based on information from server.
|
||||||
|
|
||||||
This function should not trigger downloading of any addons but only use
|
This function should not trigger downloading of any addons but only use
|
||||||
|
|
@ -316,23 +246,14 @@ def _load_ayon_addons(openpype_modules, modules_key, log):
|
||||||
development).
|
development).
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
openpype_modules (_ModuleClass): Module object where modules are
|
|
||||||
stored.
|
|
||||||
modules_key (str): Key under which will be modules imported in
|
|
||||||
`sys.modules`.
|
|
||||||
log (logging.Logger): Logger object.
|
log (logging.Logger): Logger object.
|
||||||
|
|
||||||
Returns:
|
|
||||||
List[str]: List of v3 addons to skip to load because v4 alternative is
|
|
||||||
imported.
|
|
||||||
"""
|
"""
|
||||||
|
all_addon_modules = []
|
||||||
addons_to_skip_in_core = []
|
|
||||||
|
|
||||||
bundle_info = _get_ayon_bundle_data()
|
bundle_info = _get_ayon_bundle_data()
|
||||||
addons_info = _get_ayon_addons_information(bundle_info)
|
addons_info = _get_ayon_addons_information(bundle_info)
|
||||||
if not addons_info:
|
if not addons_info:
|
||||||
return addons_to_skip_in_core
|
return all_addon_modules
|
||||||
|
|
||||||
addons_dir = os.environ.get("AYON_ADDONS_DIR")
|
addons_dir = os.environ.get("AYON_ADDONS_DIR")
|
||||||
if not addons_dir:
|
if not addons_dir:
|
||||||
|
|
@ -355,7 +276,7 @@ def _load_ayon_addons(openpype_modules, modules_key, log):
|
||||||
addon_version = addon_info["version"]
|
addon_version = addon_info["version"]
|
||||||
|
|
||||||
# core addon does not have any addon object
|
# core addon does not have any addon object
|
||||||
if addon_name in ("openpype", "core"):
|
if addon_name == "core":
|
||||||
continue
|
continue
|
||||||
|
|
||||||
dev_addon_info = dev_addons_info.get(addon_name, {})
|
dev_addon_info = dev_addons_info.get(addon_name, {})
|
||||||
|
|
@ -394,7 +315,7 @@ def _load_ayon_addons(openpype_modules, modules_key, log):
|
||||||
continue
|
continue
|
||||||
|
|
||||||
sys.path.insert(0, addon_dir)
|
sys.path.insert(0, addon_dir)
|
||||||
imported_modules = []
|
addon_modules = []
|
||||||
for name in os.listdir(addon_dir):
|
for name in os.listdir(addon_dir):
|
||||||
# Ignore of files is implemented to be able to run code from code
|
# Ignore of files is implemented to be able to run code from code
|
||||||
# where usually is more files than just the addon
|
# where usually is more files than just the addon
|
||||||
|
|
@ -421,7 +342,7 @@ def _load_ayon_addons(openpype_modules, modules_key, log):
|
||||||
inspect.isclass(attr)
|
inspect.isclass(attr)
|
||||||
and issubclass(attr, AYONAddon)
|
and issubclass(attr, AYONAddon)
|
||||||
):
|
):
|
||||||
imported_modules.append(mod)
|
addon_modules.append(mod)
|
||||||
break
|
break
|
||||||
|
|
||||||
except BaseException:
|
except BaseException:
|
||||||
|
|
@ -430,50 +351,37 @@ def _load_ayon_addons(openpype_modules, modules_key, log):
|
||||||
exc_info=True
|
exc_info=True
|
||||||
)
|
)
|
||||||
|
|
||||||
if not imported_modules:
|
if not addon_modules:
|
||||||
log.warning("Addon {} {} has no content to import".format(
|
log.warning("Addon {} {} has no content to import".format(
|
||||||
addon_name, addon_version
|
addon_name, addon_version
|
||||||
))
|
))
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if len(imported_modules) > 1:
|
if len(addon_modules) > 1:
|
||||||
log.warning((
|
log.warning((
|
||||||
"Skipping addon '{}'."
|
"Multiple modules ({}) were found in addon '{}' in dir {}."
|
||||||
" Multiple modules were found ({}) in dir {}."
|
|
||||||
).format(
|
).format(
|
||||||
|
", ".join([m.__name__ for m in addon_modules]),
|
||||||
addon_name,
|
addon_name,
|
||||||
", ".join([m.__name__ for m in imported_modules]),
|
|
||||||
addon_dir,
|
addon_dir,
|
||||||
))
|
))
|
||||||
continue
|
all_addon_modules.extend(addon_modules)
|
||||||
|
|
||||||
mod = imported_modules[0]
|
return all_addon_modules
|
||||||
addon_alias = getattr(mod, "V3_ALIAS", None)
|
|
||||||
if not addon_alias:
|
|
||||||
addon_alias = addon_name
|
|
||||||
addons_to_skip_in_core.append(addon_alias)
|
|
||||||
new_import_str = "{}.{}".format(modules_key, addon_alias)
|
|
||||||
|
|
||||||
sys.modules[new_import_str] = mod
|
|
||||||
setattr(openpype_modules, addon_alias, mod)
|
|
||||||
|
|
||||||
return addons_to_skip_in_core
|
|
||||||
|
|
||||||
|
|
||||||
def _load_addons_in_core(
|
def _load_addons_in_core(log):
|
||||||
ignore_addon_names, openpype_modules, modules_key, log
|
|
||||||
):
|
|
||||||
# Add current directory at first place
|
# Add current directory at first place
|
||||||
# - has small differences in import logic
|
# - has small differences in import logic
|
||||||
|
addon_modules = []
|
||||||
modules_dir = os.path.join(AYON_CORE_ROOT, "modules")
|
modules_dir = os.path.join(AYON_CORE_ROOT, "modules")
|
||||||
if not os.path.exists(modules_dir):
|
if not os.path.exists(modules_dir):
|
||||||
log.warning(
|
log.warning(
|
||||||
f"Could not find path when loading AYON addons \"{modules_dir}\""
|
f"Could not find path when loading AYON addons \"{modules_dir}\""
|
||||||
)
|
)
|
||||||
return
|
return addon_modules
|
||||||
|
|
||||||
ignored_filenames = IGNORED_FILENAMES | IGNORED_DEFAULT_FILENAMES
|
ignored_filenames = IGNORED_FILENAMES | IGNORED_DEFAULT_FILENAMES
|
||||||
|
|
||||||
for filename in os.listdir(modules_dir):
|
for filename in os.listdir(modules_dir):
|
||||||
# Ignore filenames
|
# Ignore filenames
|
||||||
if filename in ignored_filenames:
|
if filename in ignored_filenames:
|
||||||
|
|
@ -482,9 +390,6 @@ def _load_addons_in_core(
|
||||||
fullpath = os.path.join(modules_dir, filename)
|
fullpath = os.path.join(modules_dir, filename)
|
||||||
basename, ext = os.path.splitext(filename)
|
basename, ext = os.path.splitext(filename)
|
||||||
|
|
||||||
if basename in ignore_addon_names:
|
|
||||||
continue
|
|
||||||
|
|
||||||
# Validations
|
# Validations
|
||||||
if os.path.isdir(fullpath):
|
if os.path.isdir(fullpath):
|
||||||
# Check existence of init file
|
# Check existence of init file
|
||||||
|
|
@ -503,69 +408,43 @@ def _load_addons_in_core(
|
||||||
# - check manifest and content of manifest
|
# - check manifest and content of manifest
|
||||||
try:
|
try:
|
||||||
# Don't import dynamically current directory modules
|
# Don't import dynamically current directory modules
|
||||||
new_import_str = f"{modules_key}.{basename}"
|
|
||||||
|
|
||||||
import_str = f"ayon_core.modules.{basename}"
|
import_str = f"ayon_core.modules.{basename}"
|
||||||
default_module = __import__(import_str, fromlist=("", ))
|
default_module = __import__(import_str, fromlist=("", ))
|
||||||
sys.modules[new_import_str] = default_module
|
addon_modules.append(default_module)
|
||||||
setattr(openpype_modules, basename, default_module)
|
|
||||||
|
|
||||||
except Exception:
|
except Exception:
|
||||||
log.error(
|
log.error(
|
||||||
f"Failed to import in-core addon '{basename}'.",
|
f"Failed to import in-core addon '{basename}'.",
|
||||||
exc_info=True
|
exc_info=True
|
||||||
)
|
)
|
||||||
|
return addon_modules
|
||||||
|
|
||||||
|
|
||||||
def _load_addons():
|
def _load_addons():
|
||||||
# Key under which will be modules imported in `sys.modules`
|
|
||||||
modules_key = "openpype_modules"
|
|
||||||
|
|
||||||
# Change `sys.modules`
|
|
||||||
sys.modules[modules_key] = openpype_modules = _ModuleClass(modules_key)
|
|
||||||
|
|
||||||
log = Logger.get_logger("AddonsLoader")
|
log = Logger.get_logger("AddonsLoader")
|
||||||
|
|
||||||
ignore_addon_names = _load_ayon_addons(
|
addon_modules = _load_ayon_addons(log)
|
||||||
openpype_modules, modules_key, log
|
# All addon in 'modules' folder are tray actions and should be moved
|
||||||
)
|
# to tray tool.
|
||||||
_load_addons_in_core(
|
# TODO remove
|
||||||
ignore_addon_names, openpype_modules, modules_key, log
|
addon_modules.extend(_load_addons_in_core(log))
|
||||||
)
|
|
||||||
|
|
||||||
|
# Store modules to local cache
|
||||||
_MARKING_ATTR = "_marking"
|
_LoadCache.addon_modules = addon_modules
|
||||||
def mark_func(func):
|
|
||||||
"""Mark function to be used in report.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
func (Callable): Function to mark.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
Callable: Marked function.
|
|
||||||
"""
|
|
||||||
|
|
||||||
setattr(func, _MARKING_ATTR, True)
|
|
||||||
return func
|
|
||||||
|
|
||||||
|
|
||||||
def is_func_marked(func):
|
|
||||||
return getattr(func, _MARKING_ATTR, False)
|
|
||||||
|
|
||||||
|
|
||||||
class AYONAddon(ABC):
|
class AYONAddon(ABC):
|
||||||
"""Base class of AYON addon.
|
"""Base class of AYON addon.
|
||||||
|
|
||||||
Attributes:
|
Attributes:
|
||||||
id (UUID): Addon object id.
|
|
||||||
enabled (bool): Is addon enabled.
|
enabled (bool): Is addon enabled.
|
||||||
name (str): Addon name.
|
name (str): Addon name.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
manager (AddonsManager): Manager object who discovered addon.
|
manager (AddonsManager): Manager object who discovered addon.
|
||||||
settings (dict[str, Any]): AYON settings.
|
settings (dict[str, Any]): AYON settings.
|
||||||
"""
|
|
||||||
|
|
||||||
|
"""
|
||||||
enabled = True
|
enabled = True
|
||||||
_id = None
|
_id = None
|
||||||
|
|
||||||
|
|
@ -585,8 +464,8 @@ class AYONAddon(ABC):
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
str: Object id.
|
str: Object id.
|
||||||
"""
|
|
||||||
|
|
||||||
|
"""
|
||||||
if self._id is None:
|
if self._id is None:
|
||||||
self._id = uuid4()
|
self._id = uuid4()
|
||||||
return self._id
|
return self._id
|
||||||
|
|
@ -598,8 +477,8 @@ class AYONAddon(ABC):
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
str: Addon name.
|
str: Addon name.
|
||||||
"""
|
|
||||||
|
|
||||||
|
"""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@property
|
@property
|
||||||
|
|
@ -630,16 +509,16 @@ class AYONAddon(ABC):
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
settings (dict[str, Any]): Settings.
|
settings (dict[str, Any]): Settings.
|
||||||
"""
|
|
||||||
|
|
||||||
|
"""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@mark_func
|
|
||||||
def connect_with_addons(self, enabled_addons):
|
def connect_with_addons(self, enabled_addons):
|
||||||
"""Connect with other enabled addons.
|
"""Connect with other enabled addons.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
enabled_addons (list[AYONAddon]): Addons that are enabled.
|
enabled_addons (list[AYONAddon]): Addons that are enabled.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
@ -673,8 +552,8 @@ class AYONAddon(ABC):
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
dict[str, str]: Environment variables.
|
dict[str, str]: Environment variables.
|
||||||
"""
|
|
||||||
|
|
||||||
|
"""
|
||||||
return {}
|
return {}
|
||||||
|
|
||||||
def modify_application_launch_arguments(self, application, env):
|
def modify_application_launch_arguments(self, application, env):
|
||||||
|
|
@ -686,8 +565,8 @@ class AYONAddon(ABC):
|
||||||
Args:
|
Args:
|
||||||
application (Application): Application that is launched.
|
application (Application): Application that is launched.
|
||||||
env (dict[str, str]): Current environment variables.
|
env (dict[str, str]): Current environment variables.
|
||||||
"""
|
|
||||||
|
|
||||||
|
"""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def on_host_install(self, host, host_name, project_name):
|
def on_host_install(self, host, host_name, project_name):
|
||||||
|
|
@ -706,8 +585,8 @@ class AYONAddon(ABC):
|
||||||
host_name (str): Name of host.
|
host_name (str): Name of host.
|
||||||
project_name (str): Project name which is main part of host
|
project_name (str): Project name which is main part of host
|
||||||
context.
|
context.
|
||||||
"""
|
|
||||||
|
|
||||||
|
"""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def cli(self, addon_click_group):
|
def cli(self, addon_click_group):
|
||||||
|
|
@ -734,31 +613,11 @@ class AYONAddon(ABC):
|
||||||
Args:
|
Args:
|
||||||
addon_click_group (click.Group): Group to which can be added
|
addon_click_group (click.Group): Group to which can be added
|
||||||
commands.
|
commands.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class OpenPypeModule(AYONAddon):
|
|
||||||
"""Base class of OpenPype module.
|
|
||||||
|
|
||||||
Deprecated:
|
|
||||||
Use `AYONAddon` instead.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
manager (AddonsManager): Manager object who discovered addon.
|
|
||||||
settings (dict[str, Any]): Module settings (OpenPype settings).
|
|
||||||
"""
|
|
||||||
|
|
||||||
# Disable by default
|
|
||||||
enabled = False
|
|
||||||
|
|
||||||
|
|
||||||
class OpenPypeAddOn(OpenPypeModule):
|
|
||||||
# Enable Addon by default
|
|
||||||
enabled = True
|
|
||||||
|
|
||||||
|
|
||||||
class _AddonReportInfo:
|
class _AddonReportInfo:
|
||||||
def __init__(
|
def __init__(
|
||||||
self, class_name, name, version, report_value_by_label
|
self, class_name, name, version, report_value_by_label
|
||||||
|
|
@ -790,8 +649,8 @@ class AddonsManager:
|
||||||
settings (Optional[dict[str, Any]]): AYON studio settings.
|
settings (Optional[dict[str, Any]]): AYON studio settings.
|
||||||
initialize (Optional[bool]): Initialize addons on init.
|
initialize (Optional[bool]): Initialize addons on init.
|
||||||
True by default.
|
True by default.
|
||||||
"""
|
|
||||||
|
|
||||||
|
"""
|
||||||
# Helper attributes for report
|
# Helper attributes for report
|
||||||
_report_total_key = "Total"
|
_report_total_key = "Total"
|
||||||
_log = None
|
_log = None
|
||||||
|
|
@ -827,8 +686,8 @@ class AddonsManager:
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
Union[AYONAddon, Any]: Addon found by name or `default`.
|
Union[AYONAddon, Any]: Addon found by name or `default`.
|
||||||
"""
|
|
||||||
|
|
||||||
|
"""
|
||||||
return self._addons_by_name.get(addon_name, default)
|
return self._addons_by_name.get(addon_name, default)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
|
|
@ -855,8 +714,8 @@ class AddonsManager:
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
Union[AYONAddon, None]: Enabled addon found by name or None.
|
Union[AYONAddon, None]: Enabled addon found by name or None.
|
||||||
"""
|
|
||||||
|
|
||||||
|
"""
|
||||||
addon = self.get(addon_name)
|
addon = self.get(addon_name)
|
||||||
if addon is not None and addon.enabled:
|
if addon is not None and addon.enabled:
|
||||||
return addon
|
return addon
|
||||||
|
|
@ -867,8 +726,8 @@ class AddonsManager:
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
list[AYONAddon]: Initialized and enabled addons.
|
list[AYONAddon]: Initialized and enabled addons.
|
||||||
"""
|
|
||||||
|
|
||||||
|
"""
|
||||||
return [
|
return [
|
||||||
addon
|
addon
|
||||||
for addon in self._addons
|
for addon in self._addons
|
||||||
|
|
@ -880,8 +739,6 @@ class AddonsManager:
|
||||||
# Make sure modules are loaded
|
# Make sure modules are loaded
|
||||||
load_addons()
|
load_addons()
|
||||||
|
|
||||||
import openpype_modules
|
|
||||||
|
|
||||||
self.log.debug("*** AYON addons initialization.")
|
self.log.debug("*** AYON addons initialization.")
|
||||||
|
|
||||||
# Prepare settings for addons
|
# Prepare settings for addons
|
||||||
|
|
@ -889,14 +746,12 @@ class AddonsManager:
|
||||||
if settings is None:
|
if settings is None:
|
||||||
settings = get_studio_settings()
|
settings = get_studio_settings()
|
||||||
|
|
||||||
modules_settings = {}
|
|
||||||
|
|
||||||
report = {}
|
report = {}
|
||||||
time_start = time.time()
|
time_start = time.time()
|
||||||
prev_start_time = time_start
|
prev_start_time = time_start
|
||||||
|
|
||||||
addon_classes = []
|
addon_classes = []
|
||||||
for module in openpype_modules:
|
for module in _LoadCache.addon_modules:
|
||||||
# Go through globals in `ayon_core.modules`
|
# Go through globals in `ayon_core.modules`
|
||||||
for name in dir(module):
|
for name in dir(module):
|
||||||
modules_item = getattr(module, name, None)
|
modules_item = getattr(module, name, None)
|
||||||
|
|
@ -905,8 +760,6 @@ class AddonsManager:
|
||||||
if (
|
if (
|
||||||
not inspect.isclass(modules_item)
|
not inspect.isclass(modules_item)
|
||||||
or modules_item is AYONAddon
|
or modules_item is AYONAddon
|
||||||
or modules_item is OpenPypeModule
|
|
||||||
or modules_item is OpenPypeAddOn
|
|
||||||
or not issubclass(modules_item, AYONAddon)
|
or not issubclass(modules_item, AYONAddon)
|
||||||
):
|
):
|
||||||
continue
|
continue
|
||||||
|
|
@ -932,33 +785,14 @@ class AddonsManager:
|
||||||
|
|
||||||
addon_classes.append(modules_item)
|
addon_classes.append(modules_item)
|
||||||
|
|
||||||
aliased_names = []
|
|
||||||
for addon_cls in addon_classes:
|
for addon_cls in addon_classes:
|
||||||
name = addon_cls.__name__
|
name = addon_cls.__name__
|
||||||
if issubclass(addon_cls, OpenPypeModule):
|
|
||||||
# TODO change to warning
|
|
||||||
self.log.debug((
|
|
||||||
"Addon '{}' is inherited from 'OpenPypeModule'."
|
|
||||||
" Please use 'AYONAddon'."
|
|
||||||
).format(name))
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
# Try initialize module
|
addon = addon_cls(self, settings)
|
||||||
if issubclass(addon_cls, OpenPypeModule):
|
|
||||||
addon = addon_cls(self, modules_settings)
|
|
||||||
else:
|
|
||||||
addon = addon_cls(self, settings)
|
|
||||||
# Store initialized object
|
# Store initialized object
|
||||||
self._addons.append(addon)
|
self._addons.append(addon)
|
||||||
self._addons_by_id[addon.id] = addon
|
self._addons_by_id[addon.id] = addon
|
||||||
self._addons_by_name[addon.name] = addon
|
self._addons_by_name[addon.name] = addon
|
||||||
# NOTE This will be removed with release 1.0.0 of ayon-core
|
|
||||||
# please use carefully.
|
|
||||||
# Gives option to use alias name for addon for cases when
|
|
||||||
# name in OpenPype was not the same as in AYON.
|
|
||||||
name_alias = getattr(addon, "openpype_alias", None)
|
|
||||||
if name_alias:
|
|
||||||
aliased_names.append((name_alias, addon))
|
|
||||||
|
|
||||||
now = time.time()
|
now = time.time()
|
||||||
report[addon.__class__.__name__] = now - prev_start_time
|
report[addon.__class__.__name__] = now - prev_start_time
|
||||||
|
|
@ -977,17 +811,6 @@ class AddonsManager:
|
||||||
f"[{enabled_str}] {addon.name} ({addon.version})"
|
f"[{enabled_str}] {addon.name} ({addon.version})"
|
||||||
)
|
)
|
||||||
|
|
||||||
for item in aliased_names:
|
|
||||||
name_alias, addon = item
|
|
||||||
if name_alias not in self._addons_by_name:
|
|
||||||
self._addons_by_name[name_alias] = addon
|
|
||||||
continue
|
|
||||||
self.log.warning(
|
|
||||||
"Alias name '{}' of addon '{}' is already assigned.".format(
|
|
||||||
name_alias, addon.name
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
if self._report is not None:
|
if self._report is not None:
|
||||||
report[self._report_total_key] = time.time() - time_start
|
report[self._report_total_key] = time.time() - time_start
|
||||||
self._report["Initialization"] = report
|
self._report["Initialization"] = report
|
||||||
|
|
@ -1004,16 +827,7 @@ class AddonsManager:
|
||||||
self.log.debug("Has {} enabled addons.".format(len(enabled_addons)))
|
self.log.debug("Has {} enabled addons.".format(len(enabled_addons)))
|
||||||
for addon in enabled_addons:
|
for addon in enabled_addons:
|
||||||
try:
|
try:
|
||||||
if not is_func_marked(addon.connect_with_addons):
|
addon.connect_with_addons(enabled_addons)
|
||||||
addon.connect_with_addons(enabled_addons)
|
|
||||||
|
|
||||||
elif hasattr(addon, "connect_with_modules"):
|
|
||||||
self.log.warning((
|
|
||||||
"DEPRECATION WARNING: Addon '{}' still uses"
|
|
||||||
" 'connect_with_modules' method. Please switch to use"
|
|
||||||
" 'connect_with_addons' method."
|
|
||||||
).format(addon.name))
|
|
||||||
addon.connect_with_modules(enabled_addons)
|
|
||||||
|
|
||||||
except Exception:
|
except Exception:
|
||||||
self.log.error(
|
self.log.error(
|
||||||
|
|
@ -1362,56 +1176,3 @@ class AddonsManager:
|
||||||
# Join rows with newline char and add new line at the end
|
# Join rows with newline char and add new line at the end
|
||||||
output = "\n".join(formatted_rows) + "\n"
|
output = "\n".join(formatted_rows) + "\n"
|
||||||
print(output)
|
print(output)
|
||||||
|
|
||||||
# DEPRECATED - Module compatibility
|
|
||||||
@property
|
|
||||||
def modules(self):
|
|
||||||
self.log.warning(
|
|
||||||
"DEPRECATION WARNING: Used deprecated property"
|
|
||||||
" 'modules' please use 'addons' instead."
|
|
||||||
)
|
|
||||||
return self.addons
|
|
||||||
|
|
||||||
@property
|
|
||||||
def modules_by_id(self):
|
|
||||||
self.log.warning(
|
|
||||||
"DEPRECATION WARNING: Used deprecated property"
|
|
||||||
" 'modules_by_id' please use 'addons_by_id' instead."
|
|
||||||
)
|
|
||||||
return self.addons_by_id
|
|
||||||
|
|
||||||
@property
|
|
||||||
def modules_by_name(self):
|
|
||||||
self.log.warning(
|
|
||||||
"DEPRECATION WARNING: Used deprecated property"
|
|
||||||
" 'modules_by_name' please use 'addons_by_name' instead."
|
|
||||||
)
|
|
||||||
return self.addons_by_name
|
|
||||||
|
|
||||||
def get_enabled_module(self, *args, **kwargs):
|
|
||||||
self.log.warning(
|
|
||||||
"DEPRECATION WARNING: Used deprecated method"
|
|
||||||
" 'get_enabled_module' please use 'get_enabled_addon' instead."
|
|
||||||
)
|
|
||||||
return self.get_enabled_addon(*args, **kwargs)
|
|
||||||
|
|
||||||
def initialize_modules(self):
|
|
||||||
self.log.warning(
|
|
||||||
"DEPRECATION WARNING: Used deprecated method"
|
|
||||||
" 'initialize_modules' please use 'initialize_addons' instead."
|
|
||||||
)
|
|
||||||
self.initialize_addons()
|
|
||||||
|
|
||||||
def get_enabled_modules(self):
|
|
||||||
self.log.warning(
|
|
||||||
"DEPRECATION WARNING: Used deprecated method"
|
|
||||||
" 'get_enabled_modules' please use 'get_enabled_addons' instead."
|
|
||||||
)
|
|
||||||
return self.get_enabled_addons()
|
|
||||||
|
|
||||||
def get_host_module(self, host_name):
|
|
||||||
self.log.warning(
|
|
||||||
"DEPRECATION WARNING: Used deprecated method"
|
|
||||||
" 'get_host_module' please use 'get_host_addon' instead."
|
|
||||||
)
|
|
||||||
return self.get_host_addon(host_name)
|
|
||||||
|
|
|
||||||
|
|
@ -21,21 +21,7 @@ from ayon_core.lib import (
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class AliasedGroup(click.Group):
|
@click.group(invoke_without_command=True)
|
||||||
def __init__(self, *args, **kwargs):
|
|
||||||
super().__init__(*args, **kwargs)
|
|
||||||
self._aliases = {}
|
|
||||||
|
|
||||||
def set_alias(self, src_name, dst_name):
|
|
||||||
self._aliases[dst_name] = src_name
|
|
||||||
|
|
||||||
def get_command(self, ctx, cmd_name):
|
|
||||||
if cmd_name in self._aliases:
|
|
||||||
cmd_name = self._aliases[cmd_name]
|
|
||||||
return super().get_command(ctx, cmd_name)
|
|
||||||
|
|
||||||
|
|
||||||
@click.group(cls=AliasedGroup, invoke_without_command=True)
|
|
||||||
@click.pass_context
|
@click.pass_context
|
||||||
@click.option("--use-staging", is_flag=True,
|
@click.option("--use-staging", is_flag=True,
|
||||||
expose_value=False, help="use staging variants")
|
expose_value=False, help="use staging variants")
|
||||||
|
|
@ -86,10 +72,6 @@ def addon(ctx):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
# Add 'addon' as alias for module
|
|
||||||
main_cli.set_alias("addon", "module")
|
|
||||||
|
|
||||||
|
|
||||||
@main_cli.command()
|
@main_cli.command()
|
||||||
@click.pass_context
|
@click.pass_context
|
||||||
@click.argument("output_json_path")
|
@click.argument("output_json_path")
|
||||||
|
|
|
||||||
|
|
@ -7,13 +7,10 @@ from .local_settings import (
|
||||||
JSONSettingRegistry,
|
JSONSettingRegistry,
|
||||||
AYONSecureRegistry,
|
AYONSecureRegistry,
|
||||||
AYONSettingsRegistry,
|
AYONSettingsRegistry,
|
||||||
OpenPypeSecureRegistry,
|
|
||||||
OpenPypeSettingsRegistry,
|
|
||||||
get_launcher_local_dir,
|
get_launcher_local_dir,
|
||||||
get_launcher_storage_dir,
|
get_launcher_storage_dir,
|
||||||
get_local_site_id,
|
get_local_site_id,
|
||||||
get_ayon_username,
|
get_ayon_username,
|
||||||
get_openpype_username,
|
|
||||||
)
|
)
|
||||||
from .ayon_connection import initialize_ayon_connection
|
from .ayon_connection import initialize_ayon_connection
|
||||||
from .cache import (
|
from .cache import (
|
||||||
|
|
@ -59,13 +56,11 @@ from .env_tools import (
|
||||||
from .terminal import Terminal
|
from .terminal import Terminal
|
||||||
from .execute import (
|
from .execute import (
|
||||||
get_ayon_launcher_args,
|
get_ayon_launcher_args,
|
||||||
get_openpype_execute_args,
|
|
||||||
get_linux_launcher_args,
|
get_linux_launcher_args,
|
||||||
execute,
|
execute,
|
||||||
run_subprocess,
|
run_subprocess,
|
||||||
run_detached_process,
|
run_detached_process,
|
||||||
run_ayon_launcher_process,
|
run_ayon_launcher_process,
|
||||||
run_openpype_process,
|
|
||||||
path_to_subprocess_arg,
|
path_to_subprocess_arg,
|
||||||
CREATE_NO_WINDOW
|
CREATE_NO_WINDOW
|
||||||
)
|
)
|
||||||
|
|
@ -145,13 +140,10 @@ __all__ = [
|
||||||
"JSONSettingRegistry",
|
"JSONSettingRegistry",
|
||||||
"AYONSecureRegistry",
|
"AYONSecureRegistry",
|
||||||
"AYONSettingsRegistry",
|
"AYONSettingsRegistry",
|
||||||
"OpenPypeSecureRegistry",
|
|
||||||
"OpenPypeSettingsRegistry",
|
|
||||||
"get_launcher_local_dir",
|
"get_launcher_local_dir",
|
||||||
"get_launcher_storage_dir",
|
"get_launcher_storage_dir",
|
||||||
"get_local_site_id",
|
"get_local_site_id",
|
||||||
"get_ayon_username",
|
"get_ayon_username",
|
||||||
"get_openpype_username",
|
|
||||||
|
|
||||||
"initialize_ayon_connection",
|
"initialize_ayon_connection",
|
||||||
|
|
||||||
|
|
@ -162,13 +154,11 @@ __all__ = [
|
||||||
"register_event_callback",
|
"register_event_callback",
|
||||||
|
|
||||||
"get_ayon_launcher_args",
|
"get_ayon_launcher_args",
|
||||||
"get_openpype_execute_args",
|
|
||||||
"get_linux_launcher_args",
|
"get_linux_launcher_args",
|
||||||
"execute",
|
"execute",
|
||||||
"run_subprocess",
|
"run_subprocess",
|
||||||
"run_detached_process",
|
"run_detached_process",
|
||||||
"run_ayon_launcher_process",
|
"run_ayon_launcher_process",
|
||||||
"run_openpype_process",
|
|
||||||
"path_to_subprocess_arg",
|
"path_to_subprocess_arg",
|
||||||
"CREATE_NO_WINDOW",
|
"CREATE_NO_WINDOW",
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -235,26 +235,6 @@ def run_ayon_launcher_process(*args, add_sys_paths=False, **kwargs):
|
||||||
return run_subprocess(args, env=env, **kwargs)
|
return run_subprocess(args, env=env, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
def run_openpype_process(*args, **kwargs):
|
|
||||||
"""Execute AYON process with passed arguments and wait.
|
|
||||||
|
|
||||||
Wrapper for 'run_process' which prepends AYON executable arguments
|
|
||||||
before passed arguments and define environments if are not passed.
|
|
||||||
|
|
||||||
Values from 'os.environ' are used for environments if are not passed.
|
|
||||||
They are cleaned using 'clean_envs_for_ayon_process' function.
|
|
||||||
|
|
||||||
Example:
|
|
||||||
>>> run_openpype_process("version")
|
|
||||||
|
|
||||||
Args:
|
|
||||||
*args (tuple): AYON cli arguments.
|
|
||||||
**kwargs (dict): Keyword arguments for subprocess.Popen.
|
|
||||||
|
|
||||||
"""
|
|
||||||
return run_ayon_launcher_process(*args, **kwargs)
|
|
||||||
|
|
||||||
|
|
||||||
def run_detached_process(args, **kwargs):
|
def run_detached_process(args, **kwargs):
|
||||||
"""Execute process with passed arguments as separated process.
|
"""Execute process with passed arguments as separated process.
|
||||||
|
|
||||||
|
|
@ -341,14 +321,12 @@ def path_to_subprocess_arg(path):
|
||||||
|
|
||||||
|
|
||||||
def get_ayon_launcher_args(*args):
|
def get_ayon_launcher_args(*args):
|
||||||
"""Arguments to run ayon-launcher process.
|
"""Arguments to run AYON launcher process.
|
||||||
|
|
||||||
Arguments for subprocess when need to spawn new pype process. Which may be
|
Arguments for subprocess when need to spawn new AYON launcher process.
|
||||||
needed when new python process for pype scripts must be executed in build
|
|
||||||
pype.
|
|
||||||
|
|
||||||
Reasons:
|
Reasons:
|
||||||
Ayon-launcher started from code has different executable set to
|
AYON launcher started from code has different executable set to
|
||||||
virtual env python and must have path to script as first argument
|
virtual env python and must have path to script as first argument
|
||||||
which is not needed for built application.
|
which is not needed for built application.
|
||||||
|
|
||||||
|
|
@ -356,7 +334,8 @@ def get_ayon_launcher_args(*args):
|
||||||
*args (str): Any arguments that will be added after executables.
|
*args (str): Any arguments that will be added after executables.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
list[str]: List of arguments to run ayon-launcher process.
|
list[str]: List of arguments to run AYON launcher process.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
executable = os.environ["AYON_EXECUTABLE"]
|
executable = os.environ["AYON_EXECUTABLE"]
|
||||||
launch_args = [executable]
|
launch_args = [executable]
|
||||||
|
|
@ -414,21 +393,3 @@ def get_linux_launcher_args(*args):
|
||||||
launch_args.extend(args)
|
launch_args.extend(args)
|
||||||
|
|
||||||
return launch_args
|
return launch_args
|
||||||
|
|
||||||
|
|
||||||
def get_openpype_execute_args(*args):
|
|
||||||
"""Arguments to run pype command.
|
|
||||||
|
|
||||||
Arguments for subprocess when need to spawn new pype process. Which may be
|
|
||||||
needed when new python process for pype scripts must be executed in build
|
|
||||||
pype.
|
|
||||||
|
|
||||||
## Why is this needed?
|
|
||||||
Pype executed from code has different executable set to virtual env python
|
|
||||||
and must have path to script as first argument which is not needed for
|
|
||||||
build pype.
|
|
||||||
|
|
||||||
It is possible to pass any arguments that will be added after pype
|
|
||||||
executables.
|
|
||||||
"""
|
|
||||||
return get_ayon_launcher_args(*args)
|
|
||||||
|
|
|
||||||
|
|
@ -584,11 +584,3 @@ def get_ayon_username():
|
||||||
|
|
||||||
"""
|
"""
|
||||||
return ayon_api.get_user()["name"]
|
return ayon_api.get_user()["name"]
|
||||||
|
|
||||||
|
|
||||||
def get_openpype_username():
|
|
||||||
return get_ayon_username()
|
|
||||||
|
|
||||||
|
|
||||||
OpenPypeSecureRegistry = AYONSecureRegistry
|
|
||||||
OpenPypeSettingsRegistry = AYONSettingsRegistry
|
|
||||||
|
|
|
||||||
|
|
@ -1,40 +0,0 @@
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
from . import click_wrap
|
|
||||||
from .interfaces import (
|
|
||||||
IPluginPaths,
|
|
||||||
ITrayAddon,
|
|
||||||
ITrayModule,
|
|
||||||
ITrayAction,
|
|
||||||
ITrayService,
|
|
||||||
IHostAddon,
|
|
||||||
)
|
|
||||||
|
|
||||||
from .base import (
|
|
||||||
AYONAddon,
|
|
||||||
OpenPypeModule,
|
|
||||||
OpenPypeAddOn,
|
|
||||||
|
|
||||||
load_modules,
|
|
||||||
|
|
||||||
ModulesManager,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
__all__ = (
|
|
||||||
"click_wrap",
|
|
||||||
|
|
||||||
"IPluginPaths",
|
|
||||||
"ITrayAddon",
|
|
||||||
"ITrayModule",
|
|
||||||
"ITrayAction",
|
|
||||||
"ITrayService",
|
|
||||||
"IHostAddon",
|
|
||||||
|
|
||||||
"AYONAddon",
|
|
||||||
"OpenPypeModule",
|
|
||||||
"OpenPypeAddOn",
|
|
||||||
|
|
||||||
"load_modules",
|
|
||||||
|
|
||||||
"ModulesManager",
|
|
||||||
)
|
|
||||||
|
|
@ -1,25 +0,0 @@
|
||||||
# Backwards compatibility support
|
|
||||||
# - TODO should be removed before release 1.0.0
|
|
||||||
from ayon_core.addon import (
|
|
||||||
AYONAddon,
|
|
||||||
AddonsManager,
|
|
||||||
load_addons,
|
|
||||||
)
|
|
||||||
from ayon_core.addon.base import (
|
|
||||||
OpenPypeModule,
|
|
||||||
OpenPypeAddOn,
|
|
||||||
)
|
|
||||||
|
|
||||||
ModulesManager = AddonsManager
|
|
||||||
load_modules = load_addons
|
|
||||||
|
|
||||||
|
|
||||||
__all__ = (
|
|
||||||
"AYONAddon",
|
|
||||||
"AddonsManager",
|
|
||||||
"load_addons",
|
|
||||||
"OpenPypeModule",
|
|
||||||
"OpenPypeAddOn",
|
|
||||||
"ModulesManager",
|
|
||||||
"load_modules",
|
|
||||||
)
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
from ayon_core.addon.click_wrap import *
|
|
||||||
|
|
@ -1,21 +0,0 @@
|
||||||
from ayon_core.addon.interfaces import (
|
|
||||||
IPluginPaths,
|
|
||||||
ITrayAddon,
|
|
||||||
ITrayAction,
|
|
||||||
ITrayService,
|
|
||||||
IHostAddon,
|
|
||||||
)
|
|
||||||
|
|
||||||
ITrayModule = ITrayAddon
|
|
||||||
ILaunchHookPaths = object
|
|
||||||
|
|
||||||
|
|
||||||
__all__ = (
|
|
||||||
"IPluginPaths",
|
|
||||||
"ITrayAddon",
|
|
||||||
"ITrayAction",
|
|
||||||
"ITrayService",
|
|
||||||
"IHostAddon",
|
|
||||||
"ITrayModule",
|
|
||||||
"ILaunchHookPaths",
|
|
||||||
)
|
|
||||||
|
|
@ -55,7 +55,6 @@ from .publish import (
|
||||||
PublishXmlValidationError,
|
PublishXmlValidationError,
|
||||||
KnownPublishError,
|
KnownPublishError,
|
||||||
AYONPyblishPluginMixin,
|
AYONPyblishPluginMixin,
|
||||||
OpenPypePyblishPluginMixin,
|
|
||||||
OptionalPyblishPluginMixin,
|
OptionalPyblishPluginMixin,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -77,7 +76,6 @@ from .actions import (
|
||||||
|
|
||||||
from .context_tools import (
|
from .context_tools import (
|
||||||
install_ayon_plugins,
|
install_ayon_plugins,
|
||||||
install_openpype_plugins,
|
|
||||||
install_host,
|
install_host,
|
||||||
uninstall_host,
|
uninstall_host,
|
||||||
is_installed,
|
is_installed,
|
||||||
|
|
@ -168,7 +166,6 @@ __all__ = (
|
||||||
"PublishXmlValidationError",
|
"PublishXmlValidationError",
|
||||||
"KnownPublishError",
|
"KnownPublishError",
|
||||||
"AYONPyblishPluginMixin",
|
"AYONPyblishPluginMixin",
|
||||||
"OpenPypePyblishPluginMixin",
|
|
||||||
"OptionalPyblishPluginMixin",
|
"OptionalPyblishPluginMixin",
|
||||||
|
|
||||||
# --- Actions ---
|
# --- Actions ---
|
||||||
|
|
@ -187,7 +184,6 @@ __all__ = (
|
||||||
|
|
||||||
# --- Process context ---
|
# --- Process context ---
|
||||||
"install_ayon_plugins",
|
"install_ayon_plugins",
|
||||||
"install_openpype_plugins",
|
|
||||||
"install_host",
|
"install_host",
|
||||||
"uninstall_host",
|
"uninstall_host",
|
||||||
"is_installed",
|
"is_installed",
|
||||||
|
|
|
||||||
|
|
@ -234,16 +234,6 @@ def install_ayon_plugins(project_name=None, host_name=None):
|
||||||
register_inventory_action_path(path)
|
register_inventory_action_path(path)
|
||||||
|
|
||||||
|
|
||||||
def install_openpype_plugins(project_name=None, host_name=None):
|
|
||||||
"""Install AYON core plugins and make sure the core is initialized.
|
|
||||||
|
|
||||||
Deprecated:
|
|
||||||
Use `install_ayon_plugins` instead.
|
|
||||||
|
|
||||||
"""
|
|
||||||
install_ayon_plugins(project_name, host_name)
|
|
||||||
|
|
||||||
|
|
||||||
def uninstall_host():
|
def uninstall_host():
|
||||||
"""Undo all of what `install()` did"""
|
"""Undo all of what `install()` did"""
|
||||||
host = registered_host()
|
host = registered_host()
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
# Publish
|
# Publish
|
||||||
AYON is using `pyblish` for publishing process which is a little bit extented and modified mainly for UI purposes. OpenPype's (new) publish UI does not allow to enable/disable instances or plugins that can be done during creation part. Also does support actions only for validators after validation exception.
|
AYON is using `pyblish` for publishing process which is a little bit extented and modified mainly for UI purposes. AYON's (new) publish UI does not allow to enable/disable instances or plugins that can be done during creation part. Also does support actions only for validators after validation exception.
|
||||||
|
|
||||||
## Exceptions
|
## Exceptions
|
||||||
AYON define few specific exceptions that should be used in publish plugins.
|
AYON define few specific exceptions that should be used in publish plugins.
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,6 @@ from .publish_plugins import (
|
||||||
PublishXmlValidationError,
|
PublishXmlValidationError,
|
||||||
KnownPublishError,
|
KnownPublishError,
|
||||||
AYONPyblishPluginMixin,
|
AYONPyblishPluginMixin,
|
||||||
OpenPypePyblishPluginMixin,
|
|
||||||
OptionalPyblishPluginMixin,
|
OptionalPyblishPluginMixin,
|
||||||
|
|
||||||
RepairAction,
|
RepairAction,
|
||||||
|
|
@ -66,7 +65,6 @@ __all__ = (
|
||||||
"PublishXmlValidationError",
|
"PublishXmlValidationError",
|
||||||
"KnownPublishError",
|
"KnownPublishError",
|
||||||
"AYONPyblishPluginMixin",
|
"AYONPyblishPluginMixin",
|
||||||
"OpenPypePyblishPluginMixin",
|
|
||||||
"OptionalPyblishPluginMixin",
|
"OptionalPyblishPluginMixin",
|
||||||
|
|
||||||
"RepairAction",
|
"RepairAction",
|
||||||
|
|
|
||||||
|
|
@ -379,7 +379,7 @@ def get_plugin_settings(plugin, project_settings, log, category=None):
|
||||||
plugin_kind = split_path[-2]
|
plugin_kind = split_path[-2]
|
||||||
|
|
||||||
# TODO: change after all plugins are moved one level up
|
# TODO: change after all plugins are moved one level up
|
||||||
if category_from_file in ("ayon_core", "openpype"):
|
if category_from_file == "ayon_core":
|
||||||
category_from_file = "core"
|
category_from_file = "core"
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
|
|
||||||
|
|
@ -165,9 +165,6 @@ class AYONPyblishPluginMixin:
|
||||||
return self.get_attr_values_from_data_for_plugin(self.__class__, data)
|
return self.get_attr_values_from_data_for_plugin(self.__class__, data)
|
||||||
|
|
||||||
|
|
||||||
OpenPypePyblishPluginMixin = AYONPyblishPluginMixin
|
|
||||||
|
|
||||||
|
|
||||||
class OptionalPyblishPluginMixin(AYONPyblishPluginMixin):
|
class OptionalPyblishPluginMixin(AYONPyblishPluginMixin):
|
||||||
"""Prepare mixin for optional plugins.
|
"""Prepare mixin for optional plugins.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -25,13 +25,7 @@ def create_custom_tempdir(project_name, anatomy=None):
|
||||||
"""
|
"""
|
||||||
env_tmpdir = os.getenv("AYON_TMPDIR")
|
env_tmpdir = os.getenv("AYON_TMPDIR")
|
||||||
if not env_tmpdir:
|
if not env_tmpdir:
|
||||||
env_tmpdir = os.getenv("OPENPYPE_TMPDIR")
|
return
|
||||||
if not env_tmpdir:
|
|
||||||
return
|
|
||||||
print(
|
|
||||||
"DEPRECATION WARNING: Used 'OPENPYPE_TMPDIR' environment"
|
|
||||||
" variable. Please use 'AYON_TMPDIR' instead."
|
|
||||||
)
|
|
||||||
|
|
||||||
custom_tempdir = None
|
custom_tempdir = None
|
||||||
if "{" in env_tmpdir:
|
if "{" in env_tmpdir:
|
||||||
|
|
|
||||||
|
|
@ -15,5 +15,3 @@ class CollectAddons(pyblish.api.ContextPlugin):
|
||||||
manager = AddonsManager()
|
manager = AddonsManager()
|
||||||
context.data["ayonAddonsManager"] = manager
|
context.data["ayonAddonsManager"] = manager
|
||||||
context.data["ayonAddons"] = manager.addons_by_name
|
context.data["ayonAddons"] = manager.addons_by_name
|
||||||
# Backwards compatibility - remove
|
|
||||||
context.data["openPypeModules"] = manager.addons_by_name
|
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ class CollectInputRepresentationsToVersions(pyblish.api.ContextPlugin):
|
||||||
"""Converts collected input representations to input versions.
|
"""Converts collected input representations to input versions.
|
||||||
|
|
||||||
Any data in `instance.data["inputRepresentations"]` gets converted into
|
Any data in `instance.data["inputRepresentations"]` gets converted into
|
||||||
`instance.data["inputVersions"]` as supported in OpenPype v3.
|
`instance.data["inputVersions"]` as supported in OpenPype.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
# This is a ContextPlugin because then we can query the database only once
|
# This is a ContextPlugin because then we can query the database only once
|
||||||
|
|
|
||||||
|
|
@ -138,10 +138,7 @@ class CollectRenderedFiles(pyblish.api.ContextPlugin):
|
||||||
def process(self, context):
|
def process(self, context):
|
||||||
self._context = context
|
self._context = context
|
||||||
|
|
||||||
publish_data_paths = (
|
publish_data_paths = os.environ.get("AYON_PUBLISH_DATA")
|
||||||
os.environ.get("AYON_PUBLISH_DATA")
|
|
||||||
or os.environ.get("OPENPYPE_PUBLISH_DATA")
|
|
||||||
)
|
|
||||||
if not publish_data_paths:
|
if not publish_data_paths:
|
||||||
raise KnownPublishError("Missing `AYON_PUBLISH_DATA`")
|
raise KnownPublishError("Missing `AYON_PUBLISH_DATA`")
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -106,10 +106,19 @@ class ExtractOTIOReview(publish.Extractor):
|
||||||
media_metadata = otio_media.metadata
|
media_metadata = otio_media.metadata
|
||||||
|
|
||||||
# get from media reference metadata source
|
# get from media reference metadata source
|
||||||
if media_metadata.get("openpype.source.width"):
|
# TODO 'openpype' prefix should be removed (added 24/09/03)
|
||||||
width = int(media_metadata.get("openpype.source.width"))
|
# NOTE it looks like it is set only in hiero integration
|
||||||
if media_metadata.get("openpype.source.height"):
|
for key in {"ayon.source.width", "openpype.source.width"}:
|
||||||
height = int(media_metadata.get("openpype.source.height"))
|
value = media_metadata.get(key)
|
||||||
|
if value is not None:
|
||||||
|
width = int(value)
|
||||||
|
break
|
||||||
|
|
||||||
|
for key in {"ayon.source.height", "openpype.source.height"}:
|
||||||
|
value = media_metadata.get(key)
|
||||||
|
if value is not None:
|
||||||
|
height = int(value)
|
||||||
|
break
|
||||||
|
|
||||||
# compare and reset
|
# compare and reset
|
||||||
if width != self.to_width:
|
if width != self.to_width:
|
||||||
|
|
|
||||||
|
|
@ -238,7 +238,7 @@ def add_representation(instance, name,
|
||||||
|
|
||||||
|
|
||||||
class CollectUSDLayerContributions(pyblish.api.InstancePlugin,
|
class CollectUSDLayerContributions(pyblish.api.InstancePlugin,
|
||||||
publish.OpenPypePyblishPluginMixin):
|
publish.AYONPyblishPluginMixin):
|
||||||
"""Collect the USD Layer Contributions and create dependent instances.
|
"""Collect the USD Layer Contributions and create dependent instances.
|
||||||
|
|
||||||
Our contributions go to the layer
|
Our contributions go to the layer
|
||||||
|
|
|
||||||
|
|
@ -70,19 +70,3 @@ def get_ayon_splash_filepath(staging=None):
|
||||||
else:
|
else:
|
||||||
splash_file_name = "AYON_splash.png"
|
splash_file_name = "AYON_splash.png"
|
||||||
return get_resource("icons", splash_file_name)
|
return get_resource("icons", splash_file_name)
|
||||||
|
|
||||||
|
|
||||||
def get_openpype_production_icon_filepath():
|
|
||||||
return get_ayon_production_icon_filepath()
|
|
||||||
|
|
||||||
|
|
||||||
def get_openpype_staging_icon_filepath():
|
|
||||||
return get_ayon_staging_icon_filepath()
|
|
||||||
|
|
||||||
|
|
||||||
def get_openpype_icon_filepath(staging=None):
|
|
||||||
return get_ayon_icon_filepath(staging)
|
|
||||||
|
|
||||||
|
|
||||||
def get_openpype_splash_filepath(staging=None):
|
|
||||||
return get_ayon_splash_filepath(staging)
|
|
||||||
|
|
|
||||||
|
|
@ -1,79 +0,0 @@
|
||||||
# Structure of local settings
|
|
||||||
- local settings do not have any validation schemas right now this should help to see what is stored to local settings and how it works
|
|
||||||
- they are stored by identifier site_id which should be unified identifier of workstation
|
|
||||||
- all keys may and may not available on load
|
|
||||||
- contain main categories: `general`, `applications`, `projects`
|
|
||||||
|
|
||||||
## Categories
|
|
||||||
### General
|
|
||||||
- ATM contain only label of site
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"general": {
|
|
||||||
"site_label": "MySite"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### Applications
|
|
||||||
- modifications of application executables
|
|
||||||
- output should match application groups and variants
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"applications": {
|
|
||||||
"<app group>": {
|
|
||||||
"<app name>": {
|
|
||||||
"executable": "/my/path/to/nuke_12_2"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### Projects
|
|
||||||
- project specific modifications
|
|
||||||
- default project is stored under constant key defined in `pype.settings.contants`
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"projects": {
|
|
||||||
"<project name>": {
|
|
||||||
"active_site": "<name of active site>",
|
|
||||||
"remote_site": "<name of remote site>",
|
|
||||||
"roots": {
|
|
||||||
"<site name>": {
|
|
||||||
"<root name>": "<root dir path>"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
## Final document
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"_id": "<ObjectId(...)>",
|
|
||||||
"site_id": "<site id>",
|
|
||||||
"general": {
|
|
||||||
"site_label": "MySite"
|
|
||||||
},
|
|
||||||
"applications": {
|
|
||||||
"<app group>": {
|
|
||||||
"<app name>": {
|
|
||||||
"executable": "<path to app executable>"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"projects": {
|
|
||||||
"<project name>": {
|
|
||||||
"active_site": "<name of active site>",
|
|
||||||
"remote_site": "<name of remote site>",
|
|
||||||
"roots": {
|
|
||||||
"<site name>": {
|
|
||||||
"<root name>": "<root dir path>"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
@ -1472,14 +1472,6 @@ CreateNextPageOverlay {
|
||||||
border-radius: 5px;
|
border-radius: 5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
#OpenPypeVersionLabel[state="success"] {
|
|
||||||
color: {color:settings:version-exists};
|
|
||||||
}
|
|
||||||
|
|
||||||
#OpenPypeVersionLabel[state="warning"] {
|
|
||||||
color: {color:settings:version-not-found};
|
|
||||||
}
|
|
||||||
|
|
||||||
#ShadowWidget {
|
#ShadowWidget {
|
||||||
font-size: 36pt;
|
font-size: 36pt;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -387,7 +387,7 @@ class OverviewWidget(QtWidgets.QFrame):
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
list[str]: Selected legacy convertor identifiers.
|
list[str]: Selected legacy convertor identifiers.
|
||||||
Example: ['io.openpype.creators.houdini.legacy']
|
Example: ['io.ayon.creators.houdini.legacy']
|
||||||
"""
|
"""
|
||||||
|
|
||||||
_, _, convertor_identifiers = self.get_selected_items()
|
_, _, convertor_identifiers = self.get_selected_items()
|
||||||
|
|
|
||||||
|
|
@ -1364,7 +1364,7 @@ class CreatorAttrsWidget(QtWidgets.QWidget):
|
||||||
Attributes are defined on creator so are dynamic. Their look and type is
|
Attributes are defined on creator so are dynamic. Their look and type is
|
||||||
based on attribute definitions that are defined in
|
based on attribute definitions that are defined in
|
||||||
`~/ayon_core/lib/attribute_definitions.py` and their widget
|
`~/ayon_core/lib/attribute_definitions.py` and their widget
|
||||||
representation in `~/openpype/tools/attribute_defs/*`.
|
representation in `~/ayon_core/tools/attribute_defs/*`.
|
||||||
|
|
||||||
Widgets are disabled if context of instance is not valid.
|
Widgets are disabled if context of instance is not valid.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -135,7 +135,6 @@ class OrderGroups:
|
||||||
|
|
||||||
def env_variable_to_bool(env_key, default=False):
|
def env_variable_to_bool(env_key, default=False):
|
||||||
"""Boolean based on environment variable value."""
|
"""Boolean based on environment variable value."""
|
||||||
# TODO: move to pype lib
|
|
||||||
value = os.environ.get(env_key)
|
value = os.environ.get(env_key)
|
||||||
if value is not None:
|
if value is not None:
|
||||||
value = value.lower()
|
value = value.lower()
|
||||||
|
|
|
||||||
|
|
@ -237,11 +237,8 @@ class TrayAddonsManager(AddonsManager):
|
||||||
webserver_url = self.webserver_url
|
webserver_url = self.webserver_url
|
||||||
statics_url = f"{webserver_url}/res"
|
statics_url = f"{webserver_url}/res"
|
||||||
|
|
||||||
|
# Deprecated
|
||||||
# TODO stop using these env variables
|
# TODO stop using these env variables
|
||||||
# - function 'get_tray_server_url' should be used instead
|
# - function 'get_tray_server_url' should be used instead
|
||||||
os.environ[self.webserver_url_env] = webserver_url
|
os.environ[self.webserver_url_env] = webserver_url
|
||||||
os.environ["AYON_STATICS_SERVER"] = statics_url
|
os.environ["AYON_STATICS_SERVER"] = statics_url
|
||||||
|
|
||||||
# Deprecated
|
|
||||||
os.environ["OPENPYPE_WEBSERVER_URL"] = webserver_url
|
|
||||||
os.environ["OPENPYPE_STATICS_SERVER"] = statics_url
|
|
||||||
|
|
|
||||||
|
|
@ -38,7 +38,6 @@ from .lib import (
|
||||||
qt_app_context,
|
qt_app_context,
|
||||||
get_qt_app,
|
get_qt_app,
|
||||||
get_ayon_qt_app,
|
get_ayon_qt_app,
|
||||||
get_openpype_qt_app,
|
|
||||||
get_qt_icon,
|
get_qt_icon,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -122,7 +121,6 @@ __all__ = (
|
||||||
"qt_app_context",
|
"qt_app_context",
|
||||||
"get_qt_app",
|
"get_qt_app",
|
||||||
"get_ayon_qt_app",
|
"get_ayon_qt_app",
|
||||||
"get_openpype_qt_app",
|
|
||||||
"get_qt_icon",
|
"get_qt_icon",
|
||||||
|
|
||||||
"RecursiveSortFilterProxyModel",
|
"RecursiveSortFilterProxyModel",
|
||||||
|
|
|
||||||
|
|
@ -196,10 +196,6 @@ def get_ayon_qt_app():
|
||||||
return app
|
return app
|
||||||
|
|
||||||
|
|
||||||
def get_openpype_qt_app():
|
|
||||||
return get_ayon_qt_app()
|
|
||||||
|
|
||||||
|
|
||||||
def iter_model_rows(model, column=0, include_root=False):
|
def iter_model_rows(model, column=0, include_root=False):
|
||||||
"""Iterate over all row indices in a model"""
|
"""Iterate over all row indices in a model"""
|
||||||
indexes_queue = collections.deque()
|
indexes_queue = collections.deque()
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue