Merge branch 'develop' into enhancement/AY-5650_Move-Blender-client-code

This commit is contained in:
Jakub Trllo 2024-06-05 12:39:54 +02:00 committed by GitHub
commit 45eeaf28aa
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
156 changed files with 390 additions and 135 deletions

View file

@ -8,7 +8,6 @@ import inspect
import logging
import threading
import collections
from uuid import uuid4
from abc import ABCMeta, abstractmethod
@ -56,6 +55,7 @@ MOVED_ADDON_MILESTONE_VERSIONS = {
"clockify": VersionInfo(0, 2, 0),
"flame": VersionInfo(0, 2, 0),
"fusion": VersionInfo(0, 2, 0),
"hiero": VersionInfo(0, 2, 0),
"max": VersionInfo(0, 2, 0),
"photoshop": VersionInfo(0, 2, 0),
"traypublisher": VersionInfo(0, 2, 0),
@ -553,6 +553,9 @@ class AYONAddon(object):
enabled = True
_id = None
# Temporary variable for 'version' property
_missing_version_warned = False
def __init__(self, manager, settings):
self.manager = manager
@ -583,6 +586,26 @@ class AYONAddon(object):
pass
@property
def version(self):
"""Addon version.
Todo:
Should be abstract property (required). Introduced in
ayon-core 0.3.3 .
Returns:
str: Addon version as semver compatible string.
"""
if not self.__class__._missing_version_warned:
self.__class__._missing_version_warned = True
print(
f"DEV WARNING: Addon '{self.name}' does not have"
f" defined version."
)
return "0.0.0"
def initialize(self, settings):
"""Initialization of addon attributes.
@ -698,6 +721,30 @@ class OpenPypeAddOn(OpenPypeModule):
enabled = True
class _AddonReportInfo:
def __init__(
self, class_name, name, version, report_value_by_label
):
self.class_name = class_name
self.name = name
self.version = version
self.report_value_by_label = report_value_by_label
@classmethod
def from_addon(cls, addon, report):
class_name = addon.__class__.__name__
report_value_by_label = {
label: reported.get(class_name)
for label, reported in report.items()
}
return cls(
addon.__class__.__name__,
addon.name,
addon.version,
report_value_by_label
)
class AddonsManager:
"""Manager of addons that helps to load and prepare them to work.
@ -874,10 +921,6 @@ class AddonsManager:
name_alias = getattr(addon, "openpype_alias", None)
if name_alias:
aliased_names.append((name_alias, addon))
enabled_str = "X"
if not addon.enabled:
enabled_str = " "
self.log.debug("[{}] {}".format(enabled_str, name))
now = time.time()
report[addon.__class__.__name__] = now - prev_start_time
@ -889,6 +932,13 @@ class AddonsManager:
exc_info=True
)
for addon_name in sorted(self._addons_by_name.keys()):
addon = self._addons_by_name[addon_name]
enabled_str = "X" if addon.enabled else " "
self.log.debug(
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:
@ -1177,39 +1227,55 @@ class AddonsManager:
available_col_names |= set(addon_names.keys())
# Prepare ordered dictionary for columns
cols = collections.OrderedDict()
# Add addon names to first columnt
cols["Addon name"] = list(sorted(
addon.__class__.__name__
addons_info = [
_AddonReportInfo.from_addon(addon, self._report)
for addon in self.addons
if addon.__class__.__name__ in available_col_names
))
]
addons_info.sort(key=lambda x: x.name)
addon_name_rows = [
addon_info.name
for addon_info in addons_info
]
addon_version_rows = [
addon_info.version
for addon_info in addons_info
]
# Add total key (as last addon)
cols["Addon name"].append(self._report_total_key)
addon_name_rows.append(self._report_total_key)
addon_version_rows.append(f"({len(addons_info)})")
cols = collections.OrderedDict()
# Add addon names to first columnt
cols["Addon name"] = addon_name_rows
cols["Version"] = addon_version_rows
# Add columns from report
total_by_addon = {
row: 0
for row in addon_name_rows
}
for label in self._report.keys():
cols[label] = []
total_addon_times = {}
for addon_name in cols["Addon name"]:
total_addon_times[addon_name] = 0
for label, reported in self._report.items():
for addon_name in cols["Addon name"]:
col_time = reported.get(addon_name)
if col_time is None:
cols[label].append("N/A")
rows = []
col_total = 0
for addon_info in addons_info:
value = addon_info.report_value_by_label.get(label)
if value is None:
rows.append("N/A")
continue
cols[label].append("{:.3f}".format(col_time))
total_addon_times[addon_name] += col_time
rows.append("{:.3f}".format(value))
total_by_addon[addon_info.name] += value
col_total += value
total_by_addon[self._report_total_key] += col_total
rows.append("{:.3f}".format(col_total))
cols[label] = rows
# Add to also total column that should sum the row
cols[self._report_total_key] = []
for addon_name in cols["Addon name"]:
cols[self._report_total_key].append(
"{:.3f}".format(total_addon_times[addon_name])
)
cols[self._report_total_key] = [
"{:.3f}".format(total_by_addon[addon_name])
for addon_name in cols["Addon name"]
]
# Prepare column widths and total row count
# - column width is by

View file

@ -1,10 +0,0 @@
from .addon import (
HIERO_ROOT_DIR,
HieroAddon,
)
__all__ = (
"HIERO_ROOT_DIR",
"HieroAddon",
)

View file

@ -7,6 +7,8 @@ import six
from ayon_core.lib import Logger
from ayon_core.modules import AYONAddon, IPluginPaths
from .version import __version__
class DeadlineWebserviceError(Exception):
"""
@ -16,6 +18,7 @@ class DeadlineWebserviceError(Exception):
class DeadlineModule(AYONAddon, IPluginPaths):
name = "deadline"
version = __version__
def initialize(self, studio_settings):
# This module is always enabled

View file

@ -1,6 +1,9 @@
from .version import __version__
from .addon import JobQueueAddon
__all__ = (
"__version__",
"JobQueueAddon",
)

View file

@ -44,9 +44,12 @@ import platform
from ayon_core.addon import AYONAddon, click_wrap
from ayon_core.settings import get_studio_settings
from .version import __version__
class JobQueueAddon(AYONAddon):
name = "job_queue"
version = __version__
def initialize(self, studio_settings):
addon_settings = studio_settings.get(self.name) or {}

View file

@ -0,0 +1 @@
__version__ = "1.0.0"

View file

@ -7,6 +7,7 @@ from ayon_core.addon import AYONAddon, ITrayAction
class LauncherAction(AYONAddon, ITrayAction):
label = "Launcher"
name = "launcher_tool"
version = "1.0.0"
def initialize(self, settings):

View file

@ -3,6 +3,7 @@ from ayon_core.addon import AYONAddon, ITrayAddon
class LoaderAddon(AYONAddon, ITrayAddon):
name = "loader_tool"
version = "1.0.0"
def initialize(self, settings):
# Tray attributes

View file

@ -4,6 +4,7 @@ from ayon_core.addon import AYONAddon, ITrayAction
class PythonInterpreterAction(AYONAddon, ITrayAction):
label = "Console"
name = "python_interpreter"
version = "1.0.0"
admin_action = True
def initialize(self, settings):

View file

@ -1,6 +1,9 @@
from .version import __version__
from .addon import RoyalRenderAddon
__all__ = (
"__version__",
"RoyalRenderAddon",
)

View file

@ -4,10 +4,13 @@ import os
from ayon_core.addon import AYONAddon, IPluginPaths
from .version import __version__
class RoyalRenderAddon(AYONAddon, IPluginPaths):
"""Class providing basic Royal Render implementation logic."""
name = "royalrender"
version = __version__
# _rr_api = None
# @property

View file

@ -0,0 +1 @@
__version__ = "0.1.1"

View file

@ -1,7 +1,10 @@
from .version import __version__
from .timers_manager import (
TimersManager
)
__all__ = (
"__version__",
"TimersManager",
)

View file

@ -10,6 +10,7 @@ from ayon_core.addon import (
)
from ayon_core.lib.events import register_event_callback
from .version import __version__
from .exceptions import InvalidContextError
TIMER_MODULE_DIR = os.path.dirname(os.path.abspath(__file__))
@ -96,6 +97,7 @@ class TimersManager(
See `ExampleTimersManagerConnector`.
"""
name = "timers_manager"
version = __version__
label = "Timers Service"
_required_methods = (

View file

@ -0,0 +1 @@
__version__ = "0.1.1"

View file

@ -1,8 +1,11 @@
from .version import __version__
from .webserver_module import (
WebServerAddon
)
__all__ = (
"__version__",
"WebServerAddon",
)

View file

@ -0,0 +1 @@
__version__ = "1.0.0"

View file

@ -26,9 +26,12 @@ import socket
from ayon_core import resources
from ayon_core.addon import AYONAddon, ITrayService
from .version import __version__
class WebServerAddon(AYONAddon, ITrayService):
name = "webserver"
version = __version__
label = "WebServer"
webserver_url_env = "AYON_WEBSERVER_URL"

View file

@ -336,17 +336,16 @@ def get_plugin_settings(plugin, project_settings, log, category=None):
settings_category = getattr(plugin, "settings_category", None)
if settings_category:
try:
return (
project_settings
[settings_category]
["publish"]
[plugin.__name__]
)
category_settings = project_settings[settings_category]
except KeyError:
log.warning((
"Couldn't find plugin '{}' settings"
" under settings category '{}'"
).format(plugin.__name__, settings_category))
"Couldn't find settings category '{}' in project settings"
).format(settings_category))
return {}
try:
return category_settings["publish"][plugin.__name__]
except KeyError:
return {}
# Use project settings based on a category name

View file

@ -172,12 +172,30 @@ class VersionItem:
def __gt__(self, other):
if not isinstance(other, VersionItem):
return False
if (
other.version == self.version
and self.is_hero
):
# Make sure hero versions are positive
version = abs(self.version)
other_version = abs(other.version)
# Hero version is greater than non-hero
if version == other_version:
return self.is_hero
return version > other_version
def __lt__(self, other):
if not isinstance(other, VersionItem):
return True
return other.version < self.version
# Make sure hero versions are positive
version = abs(self.version)
other_version = abs(other.version)
# Non-hero version is lesser than hero
if version == other_version:
return not self.is_hero
return version < other_version
def __ge__(self, other):
return self.__eq__(other) or self.__gt__(other)
def __le__(self, other):
return self.__eq__(other) or self.__lt__(other)
def to_data(self):
return {

View file

@ -199,7 +199,9 @@ class ProductsModel(QtGui.QStandardItemModel):
product_item = self._product_items_by_id.get(product_id)
if product_item is None:
return None
return list(product_item.version_items.values())
product_items = list(product_item.version_items.values())
product_items.sort(reverse=True)
return product_items
if role == QtCore.Qt.EditRole:
return None

View file

@ -447,8 +447,10 @@ class SystemTrayIcon(QtWidgets.QSystemTrayIcon):
def initialize_addons(self):
self._initializing_addons = True
self.tray_man.initialize_addons()
self._initializing_addons = False
try:
self.tray_man.initialize_addons()
finally:
self._initializing_addons = False
def _click_timer_timeout(self):
self._click_timer.stop()

View file

@ -80,11 +80,11 @@ dummy-variable-rgx = "^(_+|(_+[a-zA-Z0-9_]*[a-zA-Z0-9]+?))$"
exclude = [
"client/ayon_core/hosts/unreal/integration/*",
"client/ayon_core/hosts/aftereffects/api/extension/js/libs/*",
"client/ayon_core/hosts/hiero/api/startup/*",
"client/ayon_core/modules/deadline/repository/custom/plugins/CelAction/*",
"client/ayon_core/modules/deadline/repository/custom/plugins/HarmonyAYON/*",
"client/ayon_core/modules/click_wrap.py",
"client/ayon_core/scripts/slates/__init__.py"
"client/ayon_core/scripts/slates/__init__.py",
"server_addon/hiero/client/ayon_hiero/api/startup/*"
]
[tool.ruff.lint.per-file-ignores]

View file

@ -0,0 +1,13 @@
from .version import __version__
from .addon import (
HIERO_ADDON_ROOT,
HieroAddon,
)
__all__ = (
"__version__",
"HIERO_ADDON_ROOT",
"HieroAddon",
)

View file

@ -2,17 +2,20 @@ import os
import platform
from ayon_core.addon import AYONAddon, IHostAddon
HIERO_ROOT_DIR = os.path.dirname(os.path.abspath(__file__))
from .version import __version__
HIERO_ADDON_ROOT = os.path.dirname(os.path.abspath(__file__))
class HieroAddon(AYONAddon, IHostAddon):
name = "hiero"
version = __version__
host_name = "hiero"
def add_implementation_envs(self, env, _app):
# Add requirements to HIERO_PLUGIN_PATH
new_hiero_paths = [
os.path.join(HIERO_ROOT_DIR, "api", "startup")
os.path.join(HIERO_ADDON_ROOT, "api", "startup")
]
old_hiero_path = env.get("HIERO_PLUGIN_PATH") or ""
for path in old_hiero_path.split(os.pathsep):
@ -36,7 +39,7 @@ class HieroAddon(AYONAddon, IHostAddon):
python_path_parts = []
if python_path:
python_path_parts = python_path.split(os.pathsep)
vendor_path = os.path.join(HIERO_ROOT_DIR, "vendor")
vendor_path = os.path.join(HIERO_ADDON_ROOT, "vendor")
python_path_parts.insert(0, vendor_path)
env["PYTHONPATH"] = os.pathsep.join(python_path_parts)

View file

@ -453,19 +453,19 @@ def get_track_openpype_data(track, container_name=None):
)
@deprecated("ayon_core.hosts.hiero.api.lib.get_trackitem_openpype_tag")
@deprecated("ayon_hiero.api.lib.get_trackitem_openpype_tag")
def get_track_item_pype_tag(track_item):
# backward compatibility alias
return get_trackitem_openpype_tag(track_item)
@deprecated("ayon_core.hosts.hiero.api.lib.set_trackitem_openpype_tag")
@deprecated("ayon_hiero.api.lib.set_trackitem_openpype_tag")
def set_track_item_pype_tag(track_item, data=None):
# backward compatibility alias
return set_trackitem_openpype_tag(track_item, data)
@deprecated("ayon_core.hosts.hiero.api.lib.get_trackitem_openpype_data")
@deprecated("ayon_hiero.api.lib.get_trackitem_openpype_data")
def get_track_item_pype_data(track_item):
# backward compatibility alias
return get_trackitem_openpype_data(track_item)
@ -802,7 +802,7 @@ class PublishAction(QtWidgets.QAction):
#
# '''
# import hiero.core
# from ayon_core.hosts.nuke.api.lib import (
# from ayon_nuke.api.lib import (
# BuildWorkfile,
# imprint
# )

View file

@ -6,7 +6,9 @@ import os
import contextlib
from collections import OrderedDict
import hiero
from pyblish import api as pyblish
from ayon_core.lib import Logger
from ayon_core.pipeline import (
schema,
@ -18,15 +20,14 @@ from ayon_core.pipeline import (
AYON_CONTAINER_ID,
)
from ayon_core.tools.utils import host_tools
from ayon_hiero import HIERO_ADDON_ROOT
from . import lib, menu, events
import hiero
log = Logger.get_logger(__name__)
# plugin paths
API_DIR = os.path.dirname(os.path.abspath(__file__))
HOST_DIR = os.path.dirname(API_DIR)
PLUGINS_DIR = os.path.join(HOST_DIR, "plugins")
PLUGINS_DIR = os.path.join(HIERO_ADDON_ROOT, "plugins")
PUBLISH_PATH = os.path.join(PLUGINS_DIR, "publish").replace("\\", "/")
LOAD_PATH = os.path.join(PLUGINS_DIR, "load").replace("\\", "/")
CREATE_PATH = os.path.join(PLUGINS_DIR, "create").replace("\\", "/")
@ -308,9 +309,9 @@ def reload_config():
import importlib
for module in (
"ayon_core.hosts.hiero.lib",
"ayon_core.hosts.hiero.menu",
"ayon_core.hosts.hiero.tags"
"ayon_hiero.lib",
"ayon_hiero.menu",
"ayon_hiero.tags"
):
log.info("Reloading module: {}...".format(module))
try:
@ -328,7 +329,7 @@ def on_pyblish_instance_toggled(instance, old_value, new_value):
log.info("instance toggle: {}, old_value: {}, new_value:{} ".format(
instance, old_value, new_value))
from ayon_core.hosts.hiero.api import (
from ayon_hiero.api import (
get_trackitem_openpype_tag,
set_publish_attribute
)

View file

@ -550,7 +550,8 @@ class ClipLoader:
log.debug("__ self.timeline_out: {}".format(self.timeline_out))
# check if slate is included
slate_on = "slate" in self.context["version"]["data"]["families"]
slate_on = "slate" in self.context["version"]["data"].get(
"families", [])
log.debug("__ slate_on: {}".format(slate_on))
# if slate is on then remove the slate frame from beginning
@ -600,7 +601,7 @@ class Creator(LegacyCreator):
def __init__(self, *args, **kwargs):
super(Creator, self).__init__(*args, **kwargs)
import ayon_core.hosts.hiero.api as phiero
import ayon_hiero.api as phiero
self.presets = get_current_project_settings()[
"hiero"]["create"].get(self.__class__.__name__, {})

View file

Before

Width:  |  Height:  |  Size: 6.1 KiB

After

Width:  |  Height:  |  Size: 6.1 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 10 KiB

After

Width:  |  Height:  |  Size: 10 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 7.8 KiB

After

Width:  |  Height:  |  Size: 7.8 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 8.2 KiB

After

Width:  |  Height:  |  Size: 8.2 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 8 KiB

After

Width:  |  Height:  |  Size: 8 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 5.6 KiB

After

Width:  |  Height:  |  Size: 5.6 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 5.1 KiB

After

Width:  |  Height:  |  Size: 5.1 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 12 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 13 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 4.5 KiB

After

Width:  |  Height:  |  Size: 4.5 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 7.5 KiB

After

Width:  |  Height:  |  Size: 7.5 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 3.7 KiB

After

Width:  |  Height:  |  Size: 3.7 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 3.8 KiB

After

Width:  |  Height:  |  Size: 3.8 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 8.1 KiB

After

Width:  |  Height:  |  Size: 8.1 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 5.5 KiB

After

Width:  |  Height:  |  Size: 5.5 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 4.7 KiB

After

Width:  |  Height:  |  Size: 4.7 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 7.9 KiB

After

Width:  |  Height:  |  Size: 7.9 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 7.8 KiB

After

Width:  |  Height:  |  Size: 7.8 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 7.4 KiB

After

Width:  |  Height:  |  Size: 7.4 KiB

Before After
Before After

View file

@ -2,11 +2,11 @@ import traceback
# activate hiero from pype
from ayon_core.pipeline import install_host
import ayon_core.hosts.hiero.api as phiero
import ayon_hiero.api as phiero
install_host(phiero)
try:
__import__("ayon_core.hosts.hiero.api")
__import__("ayon_hiero.api")
__import__("pyblish")
except ImportError as e:
@ -15,5 +15,5 @@ except ImportError as e:
else:
# Setup integration
import ayon_core.hosts.hiero.api as phiero
import ayon_hiero.api as phiero
phiero.lib.setup()

View file

@ -8,7 +8,7 @@ import hiero.core
from hiero.core import util
import opentimelineio as otio
from ayon_core.hosts.hiero.api.otio import hiero_export
from ayon_hiero.api.otio import hiero_export
class OTIOExportTask(hiero.core.TaskBase):

View file

@ -22,7 +22,7 @@ except ImportError:
FormLayout = QFormLayout # lint:ok
from ayon_core.hosts.hiero.api.otio import hiero_export
from ayon_hiero.api.otio import hiero_export
class OTIOExportUI(hiero.ui.TaskUIBase):
def __init__(self, preset):

View file

@ -9,7 +9,7 @@ import hiero.core
import PySide2.QtWidgets as qw
from ayon_core.hosts.hiero.api.otio.hiero_import import load_otio
from ayon_hiero.api.otio.hiero_import import load_otio
class OTIOProjectSelect(qw.QDialog):

View file

@ -1,6 +1,6 @@
from copy import deepcopy
import ayon_core.hosts.hiero.api as phiero
# from ayon_core.hosts.hiero.api import plugin, lib
import ayon_hiero.api as phiero
# from ayon_hiero.api import plugin, lib
# reload(lib)
# reload(plugin)
# reload(phiero)

View file

@ -5,7 +5,7 @@ from ayon_core.lib.transcoding import (
VIDEO_EXTENSIONS,
IMAGE_EXTENSIONS
)
import ayon_core.hosts.hiero.api as phiero
import ayon_hiero.api as phiero
class LoadClip(phiero.SequenceLoader):

View file

@ -7,7 +7,7 @@ from ayon_core.pipeline import (
load,
get_representation_path,
)
from ayon_core.hosts.hiero import api as phiero
from ayon_hiero import api as phiero
from ayon_core.lib import Logger

View file

@ -9,6 +9,7 @@ class CollectClipEffects(pyblish.api.InstancePlugin):
order = pyblish.api.CollectorOrder - 0.078
label = "Collect Clip Effects Instances"
families = ["clip"]
settings_category = "hiero"
effect_categories = []

View file

@ -1,4 +1,3 @@
# from ayon_core import plugins
import os
import json
import pyblish.api

View file

@ -3,8 +3,8 @@ import pyblish
from ayon_core.pipeline import AYON_INSTANCE_ID, AVALON_INSTANCE_ID
from ayon_core.pipeline.editorial import is_overlapping_otio_ranges
from ayon_core.hosts.hiero import api as phiero
from ayon_core.hosts.hiero.api.otio import hiero_export
from ayon_hiero import api as phiero
from ayon_hiero.api.otio import hiero_export
import hiero
# # developer reload modules

View file

@ -7,7 +7,7 @@ from qtpy.QtGui import QPixmap
import hiero.ui
from ayon_core.hosts.hiero.api.otio import hiero_export
from ayon_hiero.api.otio import hiero_export
class PrecollectWorkfile(pyblish.api.ContextPlugin):

View file

@ -1,7 +1,7 @@
from pyblish import api
import hiero
import math
from ayon_core.hosts.hiero.api.otio.hiero_export import create_otio_time_range
from ayon_hiero.api.otio.hiero_export import create_otio_time_range
class PrecollectRetime(api.InstancePlugin):
"""Calculate Retiming of selected track items."""

Some files were not shown because too many files have changed in this diff Show more