Skip to content
This repository has been archived by the owner on Sep 20, 2024. It is now read-only.

Fix Avalon plugins attribute overrides #1413

Merged
merged 1 commit into from
Apr 30, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 3 additions & 32 deletions openpype/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
from .lib import (
Anatomy,
filter_pyblish_plugins,
set_plugin_attributes_from_settings,
change_timer_to_current_context
)

Expand Down Expand Up @@ -58,38 +59,8 @@ def patched_discover(superclass):
# run original discover and get plugins
plugins = _original_discover(superclass)

# determine host application to use for finding presets
if avalon.registered_host() is None:
return plugins
host = avalon.registered_host().__name__.split(".")[-1]

# map plugin superclass to preset json. Currenly suppoted is load and
# create (avalon.api.Loader and avalon.api.Creator)
plugin_type = "undefined"
if superclass.__name__.split(".")[-1] == "Loader":
plugin_type = "load"
elif superclass.__name__.split(".")[-1] == "Creator":
plugin_type = "create"

print(">>> Finding presets for {}:{} ...".format(host, plugin_type))
try:
settings = (
get_project_settings(os.environ['AVALON_PROJECT'])
[host][plugin_type]
)
except KeyError:
print("*** no presets found.")
else:
for plugin in plugins:
if plugin.__name__ in settings:
print(">>> We have preset for {}".format(plugin.__name__))
for option, value in settings[plugin.__name__].items():
if option == "enabled" and value is False:
setattr(plugin, "active", False)
print(" - is disabled by preset")
else:
setattr(plugin, option, value)
print(" - setting `{}`: `{}`".format(option, value))
set_plugin_attributes_from_settings(plugins, superclass)

return plugins


Expand Down
2 changes: 2 additions & 0 deletions openpype/lib/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,7 @@
TaskNotSetError,
get_subset_name,
filter_pyblish_plugins,
set_plugin_attributes_from_settings,
source_hash,
get_unique_layer_name,
get_background_layers,
Expand Down Expand Up @@ -207,6 +208,7 @@
"TaskNotSetError",
"get_subset_name",
"filter_pyblish_plugins",
"set_plugin_attributes_from_settings",
"source_hash",
"get_unique_layer_name",
"get_background_layers",
Expand Down
89 changes: 89 additions & 0 deletions openpype/lib/plugin_tools.py
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,95 @@ def filter_pyblish_plugins(plugins):
setattr(plugin, option, value)


def set_plugin_attributes_from_settings(
plugins, superclass, host_name=None, project_name=None
):
"""Change attribute values on Avalon plugins by project settings.

This function should be used only in host context. Modify
behavior of plugins.

Args:
plugins (list): Plugins discovered by origin avalon discover method.
superclass (object): Superclass of plugin type (e.g. Cretor, Loader).
host_name (str): Name of host for which plugins are loaded and from.
Value from environment `AVALON_APP` is used if not entered.
project_name (str): Name of project for which settings will be loaded.
Value from environment `AVALON_PROJECT` is used if not entered.
"""

# determine host application to use for finding presets
if host_name is None:
host_name = os.environ.get("AVALON_APP")

if project_name is None:
project_name = os.environ.get("AVALON_PROJECT")

# map plugin superclass to preset json. Currenly suppoted is load and
# create (avalon.api.Loader and avalon.api.Creator)
plugin_type = None
if superclass.__name__.split(".")[-1] == "Loader":
plugin_type = "load"
elif superclass.__name__.split(".")[-1] == "Creator":
plugin_type = "create"

if not host_name or not project_name or plugin_type is None:
msg = "Skipped attributes override from settings."
if not host_name:
msg += " Host name is not defined."

if not project_name:
msg += " Project name is not defined."

if plugin_type is None:
msg += " Plugin type is unsupported for class {}.".format(
superclass.__name__
)

print(msg)
return

print(">>> Finding presets for {}:{} ...".format(host_name, plugin_type))

project_settings = get_project_settings(project_name)
plugin_type_settings = (
project_settings
.get(host_name, {})
.get(plugin_type, {})
)
global_type_settings = (
project_settings
.get("global", {})
.get(plugin_type, {})
)
if not global_type_settings and not plugin_type_settings:
return

for plugin in plugins:
plugin_name = plugin.__name__

plugin_settings = None
# Look for plugin settings in host specific settings
if plugin_name in plugin_type_settings:
plugin_settings = plugin_type_settings[plugin_name]

# Look for plugin settings in global settings
elif plugin_name in global_type_settings:
plugin_settings = global_type_settings[plugin_name]

if not plugin_settings:
continue

print(">>> We have preset for {}".format(plugin_name))
for option, value in plugin_settings.items():
if option == "enabled" and value is False:
setattr(plugin, "active", False)
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do not call setattr with a constant attribute value, it is not any safer than normal property access.

print(" - is disabled by preset")
else:
setattr(plugin, option, value)
print(" - setting `{}`: `{}`".format(option, value))


def source_hash(filepath, *args):
"""Generate simple identifier for a source file.
This is used to identify whether a source file has previously been
Expand Down