Merge pull request #3179 from pypeclub/feature/OP-3220_Creators-in-Addons-issues

General: Creator plugins from addons can be registered
This commit is contained in:
Jakub Trllo 2022-05-17 17:27:03 +02:00 committed by GitHub
commit d0c66d214e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 86 additions and 3 deletions

View file

@ -14,6 +14,7 @@ from .pipeline import (
class TrayPublishCreator(Creator):
create_allow_context_change = True
host_name = "traypublisher"
def collect_instances(self):
for instance_data in list_instances():

View file

@ -702,6 +702,32 @@ class ModulesManager:
).format(expected_keys, " | ".join(msg_items)))
return output
def collect_creator_plugin_paths(self, host_name):
"""Helper to collect creator plugin paths from modules.
Args:
host_name (str): For which host are creators meants.
Returns:
list: List of creator plugin paths.
"""
# Output structure
from openpype_interfaces import IPluginPaths
output = []
for module in self.get_enabled_modules():
# Skip module that do not inherit from `IPluginPaths`
if not isinstance(module, IPluginPaths):
continue
paths = module.get_creator_plugin_paths(host_name)
if paths:
# Convert to list if value is not list
if not isinstance(paths, (list, tuple, set)):
paths = [paths]
output.extend(paths)
return output
def collect_launch_hook_paths(self):
"""Helper to collect hooks from modules inherited ILaunchHookPaths.

View file

@ -14,11 +14,38 @@ class IPluginPaths(OpenPypeInterface):
"publish": ["path/to/publish_plugins"]
}
"""
# TODO validation of an output
@abstractmethod
def get_plugin_paths(self):
pass
def get_creator_plugin_paths(self, host_name):
"""Retreive creator plugin paths.
Give addons ability to add creator plugin paths based on host name.
NOTES:
- Default implementation uses 'get_plugin_paths' and always return
all creator plugins.
- Host name may help to organize plugins by host, but each creator
alsomay have host filtering.
Args:
host_name (str): For which host are the plugins meant.
"""
paths = self.get_plugin_paths()
if not paths or "create" not in paths:
return []
create_paths = paths["create"]
if not create_paths:
return []
if not isinstance(create_paths, (list, tuple, set)):
create_paths = [create_paths]
return create_paths
class ILaunchHookPaths(OpenPypeInterface):
"""Module has launch hook paths to return.

View file

@ -12,7 +12,7 @@ import pyblish.api
from pyblish.lib import MessageHandler
import openpype
from openpype.modules import load_modules
from openpype.modules import load_modules, ModulesManager
from openpype.settings import get_project_settings
from openpype.lib import (
Anatomy,
@ -107,7 +107,7 @@ def install_host(host):
install_openpype_plugins()
def install_openpype_plugins(project_name=None):
def install_openpype_plugins(project_name=None, host_name=None):
# Make sure modules are loaded
load_modules()
@ -116,6 +116,14 @@ def install_openpype_plugins(project_name=None):
pyblish.api.register_discovery_filter(filter_pyblish_plugins)
register_loader_plugin_path(LOAD_PATH)
if host_name is None:
host_name = os.environ.get("AVALON_APP")
modules_manager = ModulesManager()
creator_paths = modules_manager.collect_creator_plugin_paths(host_name)
for creator_path in creator_paths:
register_creator_plugin_path(creator_path)
if project_name is None:
project_name = os.environ.get("AVALON_PROJECT")

View file

@ -749,6 +749,10 @@ class CreateContext:
"""Is host valid for creation."""
return self._host_is_valid
@property
def host_name(self):
return os.environ["AVALON_APP"]
@property
def log(self):
"""Dynamic access to logger."""
@ -861,6 +865,17 @@ class CreateContext:
"Using first and skipping following"
))
continue
# Filter by host name
if (
creator_class.host_name
and creator_class.host_name != self.host_name
):
self.log.info((
"Creator's host name is not supported for current host {}"
).format(creator_class.host_name, self.host_name))
continue
creator = creator_class(
self,
system_settings,

View file

@ -63,6 +63,12 @@ class BaseCreator:
# `openpype.pipeline.attribute_definitions`
instance_attr_defs = []
# Filtering by host name - can be used to be filtered by host name
# - used on all hosts when set to 'None' for Backwards compatibility
# - was added afterwards
# QUESTION make this required?
host_name = None
def __init__(
self, create_context, system_settings, project_settings, headless=False
):