mirror of
https://github.com/ynput/ayon-core.git
synced 2025-12-24 21:04:40 +01:00
moved remaining plugins/actions from avalon into openpype
This commit is contained in:
parent
7fa905a5e3
commit
d16f8f1384
4 changed files with 327 additions and 1 deletions
|
|
@ -41,6 +41,22 @@ from .publish import (
|
|||
OpenPypePyblishPluginMixin
|
||||
)
|
||||
|
||||
from .actions import (
|
||||
LauncherAction,
|
||||
|
||||
InventoryAction,
|
||||
|
||||
discover_launcher_actions,
|
||||
register_launcher_action,
|
||||
register_launcher_action_path,
|
||||
|
||||
discover_inventory_actions,
|
||||
register_inventory_action,
|
||||
register_inventory_action_path,
|
||||
deregister_inventory_action,
|
||||
deregister_inventory_action_path,
|
||||
)
|
||||
|
||||
|
||||
__all__ = (
|
||||
"attribute_definitions",
|
||||
|
|
@ -82,5 +98,19 @@ __all__ = (
|
|||
"PublishValidationError",
|
||||
"PublishXmlValidationError",
|
||||
"KnownPublishError",
|
||||
"OpenPypePyblishPluginMixin"
|
||||
"OpenPypePyblishPluginMixin",
|
||||
|
||||
# --- Plugins ---
|
||||
"LauncherAction",
|
||||
"InventoryAction",
|
||||
|
||||
"discover_launcher_actions",
|
||||
"register_launcher_action",
|
||||
"register_launcher_action_path",
|
||||
|
||||
"discover_inventory_actions",
|
||||
"register_inventory_action",
|
||||
"register_inventory_action_path",
|
||||
"deregister_inventory_action",
|
||||
"deregister_inventory_action_path",
|
||||
)
|
||||
|
|
|
|||
148
openpype/pipeline/actions.py
Normal file
148
openpype/pipeline/actions.py
Normal file
|
|
@ -0,0 +1,148 @@
|
|||
import os
|
||||
import copy
|
||||
import logging
|
||||
|
||||
|
||||
class LauncherAction(object):
|
||||
"""A custom action available"""
|
||||
name = None
|
||||
label = None
|
||||
icon = None
|
||||
color = None
|
||||
order = 0
|
||||
|
||||
log = logging.getLogger("LauncherAction")
|
||||
log.propagate = True
|
||||
|
||||
def is_compatible(self, session):
|
||||
"""Return whether the class is compatible with the Session."""
|
||||
return True
|
||||
|
||||
def process(self, session, **kwargs):
|
||||
pass
|
||||
|
||||
|
||||
class InventoryAction(object):
|
||||
"""A custom action for the scene inventory tool
|
||||
|
||||
If registered the action will be visible in the Right Mouse Button menu
|
||||
under the submenu "Actions".
|
||||
|
||||
"""
|
||||
|
||||
label = None
|
||||
icon = None
|
||||
color = None
|
||||
order = 0
|
||||
|
||||
log = logging.getLogger("InventoryAction")
|
||||
log.propagate = True
|
||||
|
||||
@staticmethod
|
||||
def is_compatible(container):
|
||||
"""Override function in a custom class
|
||||
|
||||
This method is specifically used to ensure the action can operate on
|
||||
the container.
|
||||
|
||||
Args:
|
||||
container(dict): the data of a loaded asset, see host.ls()
|
||||
|
||||
Returns:
|
||||
bool
|
||||
"""
|
||||
return bool(container.get("objectName"))
|
||||
|
||||
def process(self, containers):
|
||||
"""Override function in a custom class
|
||||
|
||||
This method will receive all containers even those which are
|
||||
incompatible. It is advised to create a small filter along the lines
|
||||
of this example:
|
||||
|
||||
valid_containers = filter(self.is_compatible(c) for c in containers)
|
||||
|
||||
The return value will need to be a True-ish value to trigger
|
||||
the data_changed signal in order to refresh the view.
|
||||
|
||||
You can return a list of container names to trigger GUI to select
|
||||
treeview items.
|
||||
|
||||
You can return a dict to carry extra GUI options. For example:
|
||||
{
|
||||
"objectNames": [container names...],
|
||||
"options": {"mode": "toggle",
|
||||
"clear": False}
|
||||
}
|
||||
Currently workable GUI options are:
|
||||
- clear (bool): Clear current selection before selecting by action.
|
||||
Default `True`.
|
||||
- mode (str): selection mode, use one of these:
|
||||
"select", "deselect", "toggle". Default is "select".
|
||||
|
||||
Args:
|
||||
containers (list): list of dictionaries
|
||||
|
||||
Return:
|
||||
bool, list or dict
|
||||
|
||||
"""
|
||||
return True
|
||||
|
||||
|
||||
# Launcher action
|
||||
def discover_launcher_actions():
|
||||
import avalon.api
|
||||
|
||||
return avalon.api.discover(LauncherAction)
|
||||
|
||||
|
||||
def register_launcher_action(plugin):
|
||||
import avalon.api
|
||||
|
||||
return avalon.api.register_plugin(LauncherAction, plugin)
|
||||
|
||||
|
||||
def register_launcher_action_path(path):
|
||||
import avalon.api
|
||||
|
||||
return avalon.api.register_plugin_path(LauncherAction, path)
|
||||
|
||||
|
||||
# Inventory action
|
||||
def discover_inventory_actions():
|
||||
import avalon.api
|
||||
|
||||
actions = avalon.api.discover(InventoryAction)
|
||||
filtered_actions = []
|
||||
for action in actions:
|
||||
if action is not InventoryAction:
|
||||
print("DISCOVERED", action)
|
||||
filtered_actions.append(action)
|
||||
else:
|
||||
print("GOT SOURCE")
|
||||
return filtered_actions
|
||||
|
||||
|
||||
def register_inventory_action(plugin):
|
||||
import avalon.api
|
||||
|
||||
return avalon.api.register_plugin(InventoryAction, plugin)
|
||||
|
||||
|
||||
def deregister_inventory_action(plugin):
|
||||
import avalon.api
|
||||
|
||||
avalon.api.deregister_plugin(InventoryAction, plugin)
|
||||
|
||||
|
||||
def register_inventory_action_path(path):
|
||||
import avalon.api
|
||||
|
||||
return avalon.api.register_plugin_path(InventoryAction, path)
|
||||
|
||||
|
||||
def deregister_inventory_action_path(path):
|
||||
import avalon.api
|
||||
|
||||
return avalon.api.deregister_plugin_path(InventoryAction, path)
|
||||
|
|
@ -127,4 +127,5 @@ def register_loader_plugin_path(path):
|
|||
|
||||
def deregister_loader_plugin(plugin):
|
||||
import avalon.api
|
||||
|
||||
avalon.api.deregister_plugin(LoaderPlugin, plugin)
|
||||
|
|
|
|||
147
openpype/pipeline/thumbnails.py
Normal file
147
openpype/pipeline/thumbnails.py
Normal file
|
|
@ -0,0 +1,147 @@
|
|||
import os
|
||||
import copy
|
||||
import logging
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def get_thumbnail_binary(thumbnail_entity, thumbnail_type, dbcon=None):
|
||||
if not thumbnail_entity:
|
||||
return
|
||||
|
||||
resolvers = discover_thumbnail_resolvers()
|
||||
resolvers = sorted(resolvers, key=lambda cls: cls.priority)
|
||||
if dbcon is None:
|
||||
from avalon import io
|
||||
dbcon = io
|
||||
|
||||
for Resolver in resolvers:
|
||||
available_types = Resolver.thumbnail_types
|
||||
if (
|
||||
thumbnail_type not in available_types
|
||||
and "*" not in available_types
|
||||
and (
|
||||
isinstance(available_types, (list, tuple))
|
||||
and len(available_types) == 0
|
||||
)
|
||||
):
|
||||
continue
|
||||
try:
|
||||
instance = Resolver(dbcon)
|
||||
result = instance.process(thumbnail_entity, thumbnail_type)
|
||||
if result:
|
||||
return result
|
||||
|
||||
except Exception:
|
||||
log.warning("Resolver {0} failed durring process.".format(
|
||||
Resolver.__class__.__name__, exc_info=True
|
||||
))
|
||||
|
||||
|
||||
class ThumbnailResolver(object):
|
||||
"""Determine how to get data from thumbnail entity.
|
||||
|
||||
"priority" - determines the order of processing in `get_thumbnail_binary`,
|
||||
lower number is processed earlier.
|
||||
"thumbnail_types" - it is expected that thumbnails will be used in more
|
||||
more than one level, there is only ["thumbnail"] type at the moment
|
||||
of creating this docstring but it is expected to add "ico" and "full"
|
||||
in future.
|
||||
"""
|
||||
|
||||
priority = 100
|
||||
thumbnail_types = ["*"]
|
||||
|
||||
def __init__(self, dbcon):
|
||||
self._log = None
|
||||
self.dbcon = dbcon
|
||||
|
||||
@property
|
||||
def log(self):
|
||||
if self._log is None:
|
||||
self._log = logging.getLogger(self.__class__.__name__)
|
||||
return self._log
|
||||
|
||||
def process(self, thumbnail_entity, thumbnail_type):
|
||||
pass
|
||||
|
||||
|
||||
class TemplateResolver(ThumbnailResolver):
|
||||
|
||||
priority = 90
|
||||
|
||||
def process(self, thumbnail_entity, thumbnail_type):
|
||||
|
||||
if not os.environ.get("AVALON_THUMBNAIL_ROOT"):
|
||||
return
|
||||
|
||||
template = thumbnail_entity["data"].get("template")
|
||||
if not template:
|
||||
self.log.debug("Thumbnail entity does not have set template")
|
||||
return
|
||||
|
||||
project = self.dbcon.find_one(
|
||||
{"type": "project"},
|
||||
{
|
||||
"name": True,
|
||||
"data.code": True
|
||||
}
|
||||
)
|
||||
|
||||
template_data = copy.deepcopy(
|
||||
thumbnail_entity["data"].get("template_data") or {}
|
||||
)
|
||||
template_data.update({
|
||||
"_id": str(thumbnail_entity["_id"]),
|
||||
"thumbnail_type": thumbnail_type,
|
||||
"thumbnail_root": os.environ.get("AVALON_THUMBNAIL_ROOT"),
|
||||
"project": {
|
||||
"name": project["name"],
|
||||
"code": project["data"].get("code")
|
||||
}
|
||||
})
|
||||
|
||||
try:
|
||||
filepath = os.path.normpath(template.format(**template_data))
|
||||
except KeyError:
|
||||
self.log.warning((
|
||||
"Missing template data keys for template <{0}> || Data: {1}"
|
||||
).format(template, str(template_data)))
|
||||
return
|
||||
|
||||
if not os.path.exists(filepath):
|
||||
self.log.warning("File does not exist \"{0}\"".format(filepath))
|
||||
return
|
||||
|
||||
with open(filepath, "rb") as _file:
|
||||
content = _file.read()
|
||||
|
||||
return content
|
||||
|
||||
|
||||
class BinaryThumbnail(ThumbnailResolver):
|
||||
def process(self, thumbnail_entity, thumbnail_type):
|
||||
return thumbnail_entity["data"].get("binary_data")
|
||||
|
||||
|
||||
# Thumbnail resolvers
|
||||
def discover_thumbnail_resolvers():
|
||||
import avalon.api
|
||||
|
||||
return avalon.api.discover(ThumbnailResolver)
|
||||
|
||||
|
||||
def register_thumbnail_resolver(plugin):
|
||||
import avalon.api
|
||||
|
||||
return avalon.api.register_plugin(ThumbnailResolver, plugin)
|
||||
|
||||
|
||||
def register_thumbnail_resolver_path(path):
|
||||
import avalon.api
|
||||
|
||||
return avalon.api.register_plugin_path(ThumbnailResolver, path)
|
||||
|
||||
|
||||
register_thumbnail_resolver(TemplateResolver)
|
||||
register_thumbnail_resolver(BinaryThumbnail)
|
||||
Loading…
Add table
Add a link
Reference in a new issue